00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "stdafx.h"
00033 #include "OGMDecodeInputPin.h"
00034
00035 OGMDecodeInputPin::OGMDecodeInputPin(OGMDecodeFilter* inParentFilter, HRESULT* outHR)
00036 : CTransformInputPin(NAME("OGMDecodeInputPin"), inParentFilter, outHR, L"OGM In")
00037 , mVideoFormatBlock(NULL)
00038 , mAudioFormatBlock(NULL)
00039 , mSetupState(VSS_SEEN_NOTHING)
00040 , mOGMMediaType(OGM_UNKNOWN_TYPE)
00041 , mGranuleRateNumerator(1)
00042 , mGranuleRateDenominator(0)
00043 {
00044
00045 }
00046
00047 OGMDecodeInputPin::~OGMDecodeInputPin(void)
00048 {
00049
00050 }
00051
00052 STDMETHODIMP OGMDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00053 {
00054 if (riid == IID_IMediaSeeking) {
00055 *ppv = (IMediaSeeking*)this;
00056 ((IUnknown*)*ppv)->AddRef();
00057 return NOERROR;
00058 } else if (riid == IID_IOggDecoder) {
00059 *ppv = (IOggDecoder*)this;
00060
00061 return NOERROR;
00062
00063 }
00064
00065 return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv);
00066 }
00067
00068 HRESULT OGMDecodeInputPin::SetMediaType(const CMediaType* inMediaType)
00069 {
00070
00071
00072 if (CheckMediaType(inMediaType) == S_OK) {
00073
00074
00075 } else {
00076 throw 0;
00077 }
00078 return CBaseInputPin::SetMediaType(inMediaType);
00079
00080 }
00081
00082 HRESULT OGMDecodeInputPin::CheckMediaType(const CMediaType* inMediaType)
00083 {
00084
00085 if ( (inMediaType->majortype == MEDIATYPE_OggPacketStream)
00086 && (inMediaType->subtype == MEDIASUBTYPE_None)
00087 && (inMediaType->formattype == FORMAT_OggIdentHeader)) {
00088
00089
00090
00091
00092
00093
00094 if (inMediaType->cbFormat >= OGM_IDENT_HEADER_SIZE) {
00095 if (strncmp((char*)inMediaType->pbFormat, "\001video\000\000\000", 9) == 0) {
00096
00097 return S_OK;
00098 } else if (strncmp((char*)inMediaType->pbFormat, "\001audio\000\000\000", 9) == 0) {
00099 return S_OK;
00100 } else if (strncmp((char*)inMediaType->pbFormat, "\001text\000\000\000\000", 9) == 0) {
00101 return S_OK;
00102 }
00103 }
00104 }
00105 return S_FALSE;
00106
00107 }
00108 HRESULT OGMDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
00109 {
00110 outRequestedProps->cbBuffer = OGM_BUFFER_SIZE;
00111 outRequestedProps->cBuffers = OGM_NUM_BUFFERS;
00112 outRequestedProps->cbAlign = 1;
00113 outRequestedProps->cbPrefix = 0;
00114
00115 return S_OK;
00116 }
00117 LOOG_INT64 OGMDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
00118 {
00119 switch (mOGMMediaType) {
00120 case OGM_VIDEO_TYPE:
00121 return inGranule * mVideoFormatBlock->AvgTimePerFrame;
00122 case OGM_AUDIO_TYPE:
00123 return (inGranule * UNITS) / mAudioFormatBlock->nSamplesPerSec;
00124 case OGM_TEXT_TYPE:
00125 return (inGranule * UNITS * mGranuleRateDenominator) / mGranuleRateNumerator;
00126 default:
00127 return 0;
00128 };
00129
00130 }
00131
00132 LOOG_INT64 OGMDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
00133 {
00134
00135 return inGranule;
00136 }
00137 IOggDecoder::eAcceptHeaderResult OGMDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
00138 {
00139 switch (mSetupState) {
00140 case VSS_SEEN_NOTHING:
00141
00142 if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001video\000\000\000", 9) == 0) {
00143 mOGMMediaType = OGM_VIDEO_TYPE;
00144 handleHeaderPacket(inCodecHeaderPacket);
00145 mSetupState = VSS_SEEN_BOS;
00146 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00147 } else if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001audio\000\000\000", 9) == 0) {
00148
00149 mOGMMediaType = OGM_AUDIO_TYPE;
00150 handleHeaderPacket(inCodecHeaderPacket);
00151 mSetupState = VSS_SEEN_BOS;
00152 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00153 } else if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001text\000\000\000\000", 9) == 0) {
00154 mOGMMediaType = OGM_TEXT_TYPE;
00155 handleHeaderPacket(inCodecHeaderPacket);
00156 mSetupState = VSS_SEEN_BOS;
00157 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00158 } else {
00159 mOGMMediaType = OGM_UNKNOWN_TYPE;
00160 }
00161 mSetupState = VSS_ERROR;
00162 return IOggDecoder::AHR_INVALID_HEADER;
00163
00164 case VSS_SEEN_BOS:
00165 if (inCodecHeaderPacket->packetData()[0] == 0x03) {
00166 mSetupState = VSS_ALL_HEADERS_SEEN;
00167 return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
00168 }
00169 return IOggDecoder::AHR_INVALID_HEADER;
00170
00171
00172 case VSS_ALL_HEADERS_SEEN:
00173 case VSS_ERROR:
00174 default:
00175 return IOggDecoder::AHR_UNEXPECTED;
00176 }
00177 }
00178
00179 bool OGMDecodeInputPin::handleHeaderPacket(OggPacket* inHeaderPack)
00180 {
00181 switch(mOGMMediaType) {
00182 case OGM_VIDEO_TYPE:
00183 return handleVideoHeaderPacket(inHeaderPack);
00184 case OGM_AUDIO_TYPE:
00185 return handleAudioHeaderPacket(inHeaderPack);
00186
00187 case OGM_TEXT_TYPE:
00188 return handleTextHeaderPacket(inHeaderPack);
00189 default:
00190 return false;
00191
00192 };
00193 }
00194
00195 bool OGMDecodeInputPin::handleTextHeaderPacket(OggPacket* inHeaderPack)
00196 {
00197 mGranuleRateNumerator = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 17);
00198 mGranuleRateDenominator = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 25);
00199
00200
00201 return true;
00202 }
00203 bool OGMDecodeInputPin::handleAudioHeaderPacket(OggPacket* inHeaderPack)
00204 {
00205 delete mAudioFormatBlock;
00206
00207
00208
00209 mAudioFormatBlock = new WAVEFORMATEX;
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 mAudioFormatBlock->nAvgBytesPerSec = iLE_Math::charArrToULong(inHeaderPack->packetData() + 49);
00228 mAudioFormatBlock->nChannels = iLE_Math::charArrToUShort(inHeaderPack->packetData() + 45);
00229 mAudioFormatBlock->nBlockAlign = iLE_Math::charArrToUShort(inHeaderPack->packetData() + 47);
00230
00231
00232 mAudioFormatBlock->nSamplesPerSec = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 25);
00233
00234 mAudioFormatBlock->wBitsPerSample = iLE_Math::charArrToUShort(inHeaderPack->packetData() + 41);
00235
00236
00237 mAudioFormatBlock->cbSize = sizeof(WAVEFORMATEX);
00238
00239
00240 unsigned short locFormatCode = 0;
00241 unsigned char locHexDigitValue = 0;
00242 for (int i = 0; i < 4; i++) {
00243 locFormatCode <<= 4;
00244 locHexDigitValue = inHeaderPack->packetData()[9 + i];
00245
00246 if ((locHexDigitValue >= '0') && (locHexDigitValue <= '9')) {
00247 locHexDigitValue -= '0';
00248 } else if ((locHexDigitValue >= 'a') && (locHexDigitValue <= 'f')) {
00249 locHexDigitValue -= 'a';
00250 locHexDigitValue += 10;
00251 } else if ((locHexDigitValue >= 'A') && (locHexDigitValue <= 'F')) {
00252 locHexDigitValue -= 'A';
00253 locHexDigitValue += 10;
00254 } else {
00255
00256 throw 0;
00257 }
00258
00259 locFormatCode += locHexDigitValue;
00260 }
00261
00262 mAudioFormatBlock->wFormatTag = locFormatCode;
00263
00264 return true;
00265
00266 }
00267 bool OGMDecodeInputPin::handleVideoHeaderPacket(OggPacket* inHeaderPack)
00268 {
00269
00270 delete mVideoFormatBlock;
00271 mVideoFormatBlock = new VIDEOINFOHEADER;
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 __int64 locTimePerBlock = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 17);
00296
00297
00298 __int64 locSamplesPerBlock = iLE_Math::CharArrToInt64(inHeaderPack->packetData() + 25);
00299
00300
00301
00302 mVideoFormatBlock->AvgTimePerFrame = locTimePerBlock / locSamplesPerBlock;
00303
00304
00305
00306 __int64 locFPSec = (UNITS / locTimePerBlock) * locSamplesPerBlock;
00307
00308
00309 unsigned short locBPSample = ((unsigned char)(inHeaderPack->packetData()[41])) + (((unsigned short)(inHeaderPack->packetData()[42])) * 256);
00310
00311
00312
00313 mVideoFormatBlock->bmiHeader.biBitCount = locBPSample;
00314 mVideoFormatBlock->bmiHeader.biClrImportant = 0;
00315 mVideoFormatBlock->bmiHeader.biClrUsed = 0;
00316 mVideoFormatBlock->bmiHeader.biCompression = MAKEFOURCC(inHeaderPack->packetData()[9], inHeaderPack->packetData()[10], inHeaderPack->packetData()[11], inHeaderPack->packetData()[12]);;
00317
00318 unsigned long locHeight = iLE_Math::charArrToULong(inHeaderPack->packetData() + 49);
00319 unsigned long locWidth = iLE_Math::charArrToULong(inHeaderPack->packetData() + 45);
00320
00321 mVideoFormatBlock->dwBitRate = 0;
00322
00323 mVideoFormatBlock->bmiHeader.biHeight = locHeight;
00324 mVideoFormatBlock->bmiHeader.biPlanes = 1;
00325 mVideoFormatBlock->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00326 mVideoFormatBlock->bmiHeader.biSizeImage = (locHeight * locWidth * locBPSample) / 8;
00327 mVideoFormatBlock->bmiHeader.biWidth = locWidth;
00328 mVideoFormatBlock->bmiHeader.biXPelsPerMeter = 2000;
00329 mVideoFormatBlock->bmiHeader.biYPelsPerMeter = 2000;
00330
00331 mVideoFormatBlock->rcSource.top = 0;
00332 mVideoFormatBlock->rcSource.bottom = locHeight;
00333 mVideoFormatBlock->rcSource.left = 0;
00334 mVideoFormatBlock->rcSource.right = locWidth;
00335
00336 mVideoFormatBlock->rcTarget.top = 0;
00337 mVideoFormatBlock->rcTarget.bottom = locHeight;
00338 mVideoFormatBlock->rcTarget.left = 0;
00339 mVideoFormatBlock->rcTarget.right = locWidth;
00340
00341 mVideoFormatBlock->dwBitErrorRate=0;
00342 return true;
00343 }
00344 string OGMDecodeInputPin::getCodecShortName()
00345 {
00346
00347 return "OGM";
00348 }
00349 string OGMDecodeInputPin::getCodecIdentString()
00350 {
00351
00352 return "OGM";
00353 }
00354