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 "OGMDecodeFilter.h"
00034
00035
00036
00037
00038 CFactoryTemplate g_Templates[] =
00039 {
00040 {
00041 L"OGM Decode Filter",
00042 &CLSID_OGMDecodeFilter,
00043 OGMDecodeFilter::CreateInstance,
00044 NULL,
00045 NULL
00046 }
00047
00048 };
00049
00050
00051 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
00052
00053 OGMDecodeFilter::OGMDecodeFilter()
00054 : CTransformFilter(NAME("OGM Video Decoder"), NULL, CLSID_OGMDecodeFilter)
00055 , mInputPin(NULL)
00056 , mOutputPin(NULL)
00057 , mOGMGranulesBuffered(0)
00058 , mSegStart(0)
00059 , mSegEnd(0)
00060 , mSegRate(0)
00061
00062 {
00063
00064
00065 }
00066
00067
00068
00069 OGMDecodeFilter::~OGMDecodeFilter(void)
00070 {
00071
00072 }
00073
00074 CUnknown* WINAPI OGMDecodeFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
00075 {
00076
00077 OGMDecodeFilter *pNewObject = new OGMDecodeFilter();
00078 if (pNewObject == NULL) {
00079 *pHr = E_OUTOFMEMORY;
00080 }
00081 return pNewObject;
00082 }
00083
00084 HRESULT OGMDecodeFilter::CheckInputType(const CMediaType* inMediaType)
00085 {
00086 return mInputPin->CheckMediaType(inMediaType);
00087 }
00088 HRESULT OGMDecodeFilter::CheckTransform(const CMediaType* inInputMediaType, const CMediaType* inOutputMediaType)
00089 {
00090
00091 return S_OK;
00092 }
00093 HRESULT OGMDecodeFilter::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest)
00094 {
00095 HRESULT locHR = S_OK;
00096
00097 ALLOCATOR_PROPERTIES locReqAlloc;
00098 ALLOCATOR_PROPERTIES locActualAlloc;
00099
00100 if (inPropertyRequest->cbAlign <= 0) {
00101 locReqAlloc.cbAlign = 1;
00102 } else {
00103 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00104 }
00105
00106
00107 if (inPropertyRequest->cbBuffer == 0) {
00108
00109 locReqAlloc.cbBuffer = 65536*16;
00110 } else {
00111 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00112 }
00113
00114
00115 if (inPropertyRequest->cbPrefix < 0) {
00116 locReqAlloc.cbPrefix = 0;
00117 } else {
00118 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00119 }
00120
00121 if (inPropertyRequest->cBuffers == 0) {
00122 locReqAlloc.cBuffers = 5;
00123 } else {
00124 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00125 }
00126
00127
00128 locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00129
00130 if (locHR != S_OK) {
00131
00132 return locHR;
00133 } else {
00134
00135 locHR = inAllocator->Commit();
00136
00137
00138 return locHR;
00139 }
00140
00141 }
00142
00143 HRESULT OGMDecodeFilter::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate)
00144 {
00145 mSegStart = inStartTime;
00146 mSegEnd = inStopTime;
00147 mSegRate = inRate;
00148 return CTransformFilter::NewSegment(inStartTime, inStopTime, inRate);
00149 }
00150 HRESULT OGMDecodeFilter::GetMediaType(int inPosition, CMediaType* outMediaType)
00151 {
00152
00153 if (inPosition < 0) {
00154 return E_INVALIDARG;
00155 }
00156
00157 if ((inPosition == 0) && (mInputPin != NULL) && (mInputPin->IsConnected())) {
00158
00159
00160 switch(mInputPin->getOGMMediaType()) {
00161 case OGMDecodeInputPin::OGM_VIDEO_TYPE:
00162 {
00163 VIDEOINFOHEADER* locVideoFormat = (VIDEOINFOHEADER*)outMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00164 *locVideoFormat = *mInputPin->getVideoFormatBlock();
00165
00166 outMediaType->majortype = MEDIATYPE_Video;
00167 outMediaType->subtype = (GUID)(FOURCCMap(locVideoFormat->bmiHeader.biCompression));;
00168 outMediaType->formattype = FORMAT_VideoInfo;
00169
00170
00171 }
00172 break;
00173
00174 case OGMDecodeInputPin::OGM_AUDIO_TYPE:
00175 {
00176 WAVEFORMATEX* locAudioFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00177 *locAudioFormat = *mInputPin->getAudioFormatBlock();
00178 outMediaType->majortype = MEDIATYPE_Audio;
00179 outMediaType->subtype = MEDIASUBTYPE_PCM;
00180 outMediaType->subtype.Data1 = locAudioFormat->wFormatTag;
00181 outMediaType->formattype = FORMAT_WaveFormatEx;
00182 }
00183
00184 break;
00185 case OGMDecodeInputPin::OGM_TEXT_TYPE:
00186
00187 outMediaType->majortype = MEDIATYPE_Text;
00188 outMediaType->subtype = MEDIASUBTYPE_None;
00189 outMediaType->formattype = FORMAT_None;
00190 break;
00191
00192 default:
00193 return E_FAIL;
00194
00195 }
00196
00197
00198 return S_OK;
00199 } else {
00200 return VFW_S_NO_MORE_ITEMS;
00201 }
00202
00203
00204 }
00205
00206 HRESULT OGMDecodeFilter::Receive(IMediaSample* inSample)
00207 {
00208
00209 BYTE* locInBuff = NULL;
00210 HRESULT locHR = inSample->GetPointer(&locInBuff);
00211
00212 if (locHR == S_OK) {
00213
00214 REFERENCE_TIME locStart = -1;
00215 REFERENCE_TIME locEnd = -1;
00216 inSample->GetTime(&locStart, &locEnd);
00217
00218
00219 if ((locInBuff[0] & 1) != 0) {
00220 return S_OK;
00221 }
00222
00223
00224 unsigned long locLength = inSample->GetActualDataLength();
00225 unsigned char* locBuff = new unsigned char[locLength];
00226 sSimplePack locPack;
00227 memcpy((void*)locBuff, (const void*)locInBuff, locLength);
00228 locPack.mBuff = locBuff;
00229 locPack.mLength = locLength;
00230
00231
00232
00233 unsigned long locNumLenBytes = locInBuff[0];
00234 const unsigned char LEN_MASK = 0xC2;
00235 locNumLenBytes &= LEN_MASK;
00236 locNumLenBytes = (locNumLenBytes >> 6) | ((locNumLenBytes&2) << 1);
00237
00238
00239
00240
00241
00242
00243
00244 __int64 locPackTime = 0;
00245 if (locNumLenBytes != 0) {
00246 for (int i = 0; i < locNumLenBytes; i++) {
00247 locPackTime |= ((__int64)locInBuff[1+i] << (i * 8));
00248 }
00249 } else {
00250 locPackTime = 1;
00251 }
00252
00253
00254 mOGMGranulesBuffered += locPackTime;
00255 locPack.mDuration = locPackTime;
00256 locPack.mHeaderSize = locNumLenBytes + 1;
00257 locPack.mIsKeyframe = ((locInBuff[0] & (1<<3)) != 0);
00258
00259 mPacketBuffer.push_back(locPack);
00260
00261 if (locEnd > 0) {
00262 REFERENCE_TIME locGlobalStart = 0;
00263 REFERENCE_TIME locGlobalEnd = 0;
00264
00265
00266 __int64 locNumBuffered = mPacketBuffer.size();
00267
00268 locGlobalEnd = mInputPin->convertGranuleToTime(locEnd);
00269 locGlobalStart = locGlobalEnd - (mInputPin->convertGranuleToTime(mOGMGranulesBuffered));
00270
00271 __int64 locUptoStart = locGlobalStart;
00272 __int64 locUptoEnd = locGlobalStart;
00273
00274 __int64 locAdjustedStart = 0;
00275 __int64 locAdjustedEnd = 0;
00276 for (int i = 0; i < locNumBuffered; i++) {
00277 IMediaSample* locOutSample = NULL;
00278
00279 locHR = InitializeOutputSample(inSample, &locOutSample);
00280 if (locHR == S_OK) {
00281 locUptoEnd = locUptoStart + (mInputPin->convertGranuleToTime(mPacketBuffer[i].mDuration));
00282
00283 locAdjustedStart = locUptoStart - mSegStart;
00284 locAdjustedEnd = locUptoEnd - mSegStart;
00285 locOutSample->SetTime(&locAdjustedStart, &locAdjustedEnd);
00286 locOutSample->SetMediaTime(&locAdjustedStart, &locAdjustedEnd);
00287 locOutSample->SetSyncPoint(mPacketBuffer[i].mIsKeyframe);
00288 locOutSample->SetActualDataLength(mPacketBuffer[i].mLength - mPacketBuffer[i].mHeaderSize);
00289 BYTE* locOutBuff = NULL;
00290 locOutSample->GetPointer(&locOutBuff);
00291 memcpy((void*)locOutBuff, (const void*)(mPacketBuffer[i].mBuff + mPacketBuffer[i].mHeaderSize), mPacketBuffer[i].mLength - mPacketBuffer[i].mHeaderSize);
00292 locHR = m_pOutput->Deliver(locOutSample);
00293 locOutSample->Release();
00294
00295 if (locHR != S_OK) {
00296 deleteBufferedPackets();
00297 return S_FALSE;
00298 }
00299
00300
00301 locUptoStart = locUptoEnd;
00302
00303
00304 } else {
00305 deleteBufferedPackets();
00306 return S_FALSE;
00307 }
00308
00309 }
00310
00311 deleteBufferedPackets();
00312 return S_OK;
00313
00314
00315
00316
00317
00318 } else {
00319 return S_OK;
00320 }
00321
00322 } else {
00323 return locHR;
00324 }
00325 }
00326
00327 void OGMDecodeFilter::deleteBufferedPackets()
00328 {
00329 for (size_t i = 0; i < mPacketBuffer.size(); i++) {
00330 delete[] mPacketBuffer[i].mBuff;
00331 }
00332 mPacketBuffer.clear();
00333 mOGMGranulesBuffered = 0;
00334 }
00335 HRESULT OGMDecodeFilter::Transform(IMediaSample* inInputSample, IMediaSample* inOutputSample)
00336 {
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 return S_OK;
00361 }
00362
00363 CBasePin* OGMDecodeFilter::GetPin(int inPinNo)
00364 {
00365
00366 HRESULT locHR = S_OK;
00367
00368
00369
00370 if (m_pInput == NULL) {
00371
00372 m_pInput = new OGMDecodeInputPin(this, &locHR);
00373
00374
00375 if (m_pInput == NULL) {
00376 return NULL;
00377 }
00378
00379 mInputPin = (OGMDecodeInputPin*)m_pInput;
00380 m_pOutput = new CTransformOutputPin(NAME("OGM Out"), this, &locHR, L"Video Out");
00381
00382
00383 if (m_pOutput == NULL) {
00384 delete m_pInput;
00385 m_pInput = NULL;
00386 }
00387 }
00388
00389
00390
00391 if (inPinNo == 0) {
00392 return m_pInput;
00393 } else if (inPinNo == 1) {
00394 return m_pOutput;
00395 } else {
00396 return NULL;
00397 }
00398
00399 }