00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include <mmreg.h>
00024 #include <initguid.h>
00025 #include "DiracSplitter.h"
00026 #include "..\..\..\..\include\moreuuids.h"
00027
00028 #ifdef REGISTER_FILTER
00029
00030 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00031 {
00032 {&MEDIATYPE_Stream, &MEDIASUBTYPE_Dirac},
00033 {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
00034 };
00035
00036 const AMOVIESETUP_PIN sudpPins[] =
00037 {
00038 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00039 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
00040 };
00041
00042 const AMOVIESETUP_MEDIATYPE sudPinTypesIn2[] =
00043 {
00044 {&MEDIATYPE_Video, &MEDIASUBTYPE_DiracVideo},
00045 };
00046
00047 const AMOVIESETUP_MEDIATYPE sudPinTypesOut2[] =
00048 {
00049 {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
00050 };
00051
00052 const AMOVIESETUP_PIN sudpPins2[] =
00053 {
00054 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn2), sudPinTypesIn2},
00055 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut2), sudPinTypesOut2}
00056 };
00057
00058 const AMOVIESETUP_FILTER sudFilter[] =
00059 {
00060 {&__uuidof(CDiracSplitterFilter), L"Dirac Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
00061 {&__uuidof(CDiracSourceFilter), L"Dirac Source", MERIT_NORMAL, 0, NULL},
00062 {&__uuidof(CDiracVideoDecoder), L"Dirac Video Decoder", MERIT_UNLIKELY, countof(sudpPins2), sudpPins2},
00063 };
00064
00065 CFactoryTemplate g_Templates[] =
00066 {
00067 {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDiracSplitterFilter>, NULL, &sudFilter[0]},
00068 {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDiracSourceFilter>, NULL, &sudFilter[1]},
00069 {sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CDiracVideoDecoder>, NULL, &sudFilter[2]},
00070 };
00071
00072 int g_cTemplates = countof(g_Templates);
00073
00074 STDAPI DllRegisterServer()
00075 {
00076 RegisterSourceFilter(
00077 CLSID_AsyncReader,
00078 MEDIASUBTYPE_Dirac,
00079 _T("0,8,,4B572D4449524143"),
00080 _T(".drc"), NULL);
00081
00082 return AMovieDllRegisterServer2(TRUE);
00083 }
00084
00085 STDAPI DllUnregisterServer()
00086 {
00087 UnRegisterSourceFilter(MEDIASUBTYPE_Dirac);
00088
00089 return AMovieDllRegisterServer2(FALSE);
00090 }
00091
00092 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00093
00094 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00095 {
00096 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00097 }
00098
00099 #endif
00100
00101
00102
00103
00104
00105 CDiracSplitterFilter::CDiracSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
00106 : CBaseSplitterFilter(NAME("CDiracSplitterFilter"), pUnk, phr, __uuidof(this))
00107 {
00108 }
00109
00110 STDMETHODIMP CDiracSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00111 {
00112 CheckPointer(ppv, E_POINTER);
00113
00114 return
00115 __super::NonDelegatingQueryInterface(riid, ppv);
00116 }
00117
00118 HRESULT CDiracSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
00119 {
00120 CheckPointer(pAsyncReader, E_POINTER);
00121
00122 HRESULT hr = E_FAIL;
00123
00124 m_pFile.Free();
00125
00126 m_pFile.Attach(new CDiracSplitterFile(pAsyncReader, hr));
00127 if(!m_pFile) return E_OUTOFMEMORY;
00128 if(FAILED(hr)) {m_pFile.Free(); return hr;}
00129
00130 CArray<CMediaType> mts;
00131 mts.Add(m_pFile->GetMediaType());
00132
00133 CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Video", this, this, &hr));
00134 AddOutputPin(0, pPinOut);
00135
00136 m_rtNewStart = m_rtCurrent = 0;
00137 m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->GetDuration();
00138
00139 return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
00140 }
00141
00142 bool CDiracSplitterFilter::DemuxInit()
00143 {
00144 if(!m_pFile) return(false);
00145
00146
00147
00148 return(true);
00149 }
00150
00151 void CDiracSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
00152 {
00153 REFERENCE_TIME rtPreroll = 0;
00154
00155 if(rt <= rtPreroll || m_rtDuration <= 0)
00156 {
00157 m_pFile->Seek(8);
00158 }
00159 else
00160 {
00161
00162
00163 __int64 len = m_pFile->GetLength();
00164 __int64 seekpos = (__int64)(1.0*rt/m_rtDuration*len);
00165
00166 m_pFile->Seek(seekpos);
00167 seekpos = 8;
00168
00169 REFERENCE_TIME rtmax = rt - rtPreroll;
00170 REFERENCE_TIME rtmin = rtmax - 5000000;
00171
00172 REFERENCE_TIME pdt = _I64_MIN;
00173
00174 for(int j = 0; j < 10; j++)
00175 {
00176 BYTE code = NOT_START_CODE;
00177 while(m_pFile->Next(code) && code != IFRAME_START_CODE);
00178 if(code != IFRAME_START_CODE) {m_pFile->Seek(seekpos >>= 1); continue;}
00179
00180 __int64 pos = m_pFile->GetPos() - 5;
00181
00182 REFERENCE_TIME rt = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame * m_pFile->UnsignedGolombDecode();
00183 REFERENCE_TIME dt = rt - rtmax;
00184 if(dt > 0 && dt == pdt) dt = 10000000i64;
00185
00186 if(rtmin <= rt && rt <= rtmax || pdt > 0 && dt < 0)
00187 {
00188 seekpos = pos;
00189 break;
00190 }
00191
00192 m_pFile->Seek(pos - (__int64)(1.0*dt/m_rtDuration*len));
00193
00194 pdt = dt;
00195 }
00196
00197 m_pFile->Seek(seekpos);
00198 }
00199 }
00200
00201 bool CDiracSplitterFilter::DemuxLoop()
00202 {
00203 HRESULT hr = S_OK;
00204 REFERENCE_TIME rtAvgTimePerFrame = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame;
00205
00206 while(SUCCEEDED(hr) && !CheckRequest(NULL))
00207 {
00208 BYTE code = NOT_START_CODE;
00209 int size = 0, fnum = 0;
00210 const BYTE* pBuff = m_pFile->NextBlock(code, size, fnum);
00211 if(!pBuff || size < 5) break;
00212
00213 if(isFrameStartCode(code))
00214 {
00215 CAutoPtr<Packet> p(new Packet());
00216 p->pData.SetSize(size);
00217 memcpy(p->pData.GetData(), pBuff, size);
00218
00219 p->TrackNumber = 0;
00220 p->rtStart = rtAvgTimePerFrame*fnum;
00221 p->rtStop = p->rtStart + rtAvgTimePerFrame;
00222 p->bSyncPoint = code == IFRAME_START_CODE;
00223
00224 hr = DeliverPacket(p);
00225 }
00226
00227 if(code == SEQ_END_CODE)
00228 break;
00229 }
00230
00231 return(true);
00232 }
00233
00234
00235
00236
00237
00238 CDiracSourceFilter::CDiracSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
00239 : CDiracSplitterFilter(pUnk, phr)
00240 {
00241 m_clsid = __uuidof(this);
00242 m_pInput.Free();
00243 }
00244
00245
00246
00247
00248
00249 CDiracVideoDecoder::CDiracVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr)
00250 : CTransformFilter(NAME("CDiracVideoDecoder"), lpunk, __uuidof(this))
00251 {
00252 if(phr) *phr = S_OK;
00253
00254 m_decoder = NULL;
00255 m_pYUV[0] = NULL;
00256 }
00257
00258 CDiracVideoDecoder::~CDiracVideoDecoder()
00259 {
00260 delete [] m_pYUV[0];
00261 }
00262
00263 void CDiracVideoDecoder::InitDecoder()
00264 {
00265 FreeDecoder();
00266
00267 dirac_decoder_t* decoder = dirac_decoder_init(0);
00268
00269 DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
00270 dirac_buffer(decoder, (BYTE*)&dvih->dwSequenceHeader[0], (BYTE*)&dvih->dwSequenceHeader[0] + dvih->cbSequenceHeader);
00271
00272 m_decoder = decoder;
00273 }
00274
00275 void CDiracVideoDecoder::FreeDecoder()
00276 {
00277 if(m_decoder)
00278 {
00279 dirac_decoder_close((dirac_decoder_t*)m_decoder);
00280 m_decoder = NULL;
00281 delete [] m_pYUV[0]; m_pYUV[0] = NULL;
00282 }
00283 }
00284
00285 HRESULT CDiracVideoDecoder::Receive(IMediaSample* pIn)
00286 {
00287 CAutoLock cAutoLock(&m_csReceive);
00288
00289 HRESULT hr;
00290
00291 AM_SAMPLE2_PROPERTIES* const pProps = m_pInput->SampleProps();
00292 if(pProps->dwStreamId != AM_STREAM_MEDIA)
00293 return m_pOutput->Deliver(pIn);
00294
00295 BYTE* pDataIn = NULL;
00296 if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
00297
00298 long len = pIn->GetActualDataLength();
00299 if(len <= 0) return S_OK;
00300
00301 if(pIn->IsDiscontinuity() == S_OK)
00302 InitDecoder();
00303
00304 dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
00305
00306 hr = S_OK;
00307 while(SUCCEEDED(hr))
00308 {
00309 switch(dirac_parse(decoder))
00310 {
00311 case STATE_BUFFER:
00312 if(len == 0) return S_OK;
00313 dirac_buffer(decoder, pDataIn, pDataIn + len);
00314 len = 0;
00315 break;
00316
00317 case STATE_SEQUENCE:
00318 TRACE(_T("STATE_SEQUENCE\n"));
00319
00320 {
00321 DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
00322 if(dvih->hdr.bmiHeader.biWidth != decoder->seq_params.width
00323 || dvih->hdr.bmiHeader.biHeight != decoder->seq_params.height)
00324 return E_FAIL;
00325 }
00326
00327 if(!m_pYUV[0])
00328 {
00329 int w = decoder->seq_params.width;
00330 int h = decoder->seq_params.height;
00331 int wc = decoder->seq_params.chroma_width;
00332 int hc = decoder->seq_params.chroma_height;
00333 delete [] m_pYUV[0]; m_pYUV[0] = NULL;
00334 m_pYUV[0] = new BYTE[w*h + wc*hc*2 + w/2*h/2];
00335 m_pYUV[1] = m_pYUV[0] + w*h;
00336 m_pYUV[2] = m_pYUV[1] + wc*hc;
00337 m_pYUV[3] = m_pYUV[2] + wc*hc;
00338 memset(m_pYUV[3], 0x80, w/2*h/2);
00339 m_rtAvgTimePerFrame = 10000000i64 * decoder->seq_params.frame_rate.denominator / decoder->seq_params.frame_rate.numerator;
00340 dirac_set_buf(decoder, m_pYUV, NULL);
00341 }
00342
00343 break;
00344
00345 case STATE_SEQUENCE_END:
00346 TRACE(_T("STATE_SEQUENCE_END\n"));
00347 break;
00348
00349 case STATE_PICTURE_START:
00350 TRACE(_T("STATE_PICTURE_START, frame_type=%d frame_num=%d\n"), decoder->frame_params.ftype, decoder->frame_params.fnum);
00351 dirac_skip(decoder, (m_fDropFrames || decoder->frame_params.fnum * m_rtAvgTimePerFrame < m_tStart) && decoder->frame_params.ftype == L2_frame ? 1 : 0);
00352 if(m_fDropFrames && decoder->frame_params.ftype == L2_frame) return S_OK;
00353 break;
00354
00355 case STATE_PICTURE_AVAIL:
00356 TRACE(_T("STATE_PICTURE_AVAIL, frame_type=%d frame_num=%d\n"), decoder->frame_params.ftype, decoder->frame_params.fnum);
00357 hr = Deliver(pIn, decoder->frame_params.fnum * m_rtAvgTimePerFrame - m_tStart, (decoder->frame_params.fnum + 1) * m_rtAvgTimePerFrame - m_tStart);
00358 break;
00359
00360 case STATE_INVALID:
00361 TRACE(_T("STATE_INVALID\n"));
00362 return E_FAIL;
00363
00364
00365 default:
00366 TRACE(_T("unknown state\n"));
00367 continue;
00368 }
00369 }
00370
00371 return hr;
00372 }
00373
00374 HRESULT CDiracVideoDecoder::Deliver(IMediaSample* pIn, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
00375 {
00376 CheckPointer(pIn, E_POINTER);
00377
00378 HRESULT hr;
00379
00380 if(pIn->IsPreroll() == S_OK || rtStart < 0)
00381 return S_OK;
00382
00383 CComPtr<IMediaSample> pOut;
00384 BYTE* pDataOut = NULL;
00385 if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))
00386 || FAILED(hr = pOut->GetPointer(&pDataOut)))
00387 return hr;
00388
00389 AM_MEDIA_TYPE* pmt;
00390 if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
00391 {
00392 CMediaType mt(*pmt);
00393 m_pOutput->SetMediaType(&mt);
00394 DeleteMediaType(pmt);
00395 }
00396
00397 TRACE(_T("CDiracVideoDecoder::Deliver(%I64d, %I64d)\n"), rtStart, rtStop);
00398
00399 pOut->SetTime(&rtStart, &rtStop);
00400 pOut->SetMediaTime(NULL, NULL);
00401
00402 pOut->SetDiscontinuity(pIn->IsDiscontinuity() == S_OK);
00403 pOut->SetSyncPoint(TRUE);
00404
00405 if(GetCLSID(m_pOutput->GetConnected()) == CLSID_OverlayMixer)
00406 pOut->SetDiscontinuity(TRUE);
00407
00408 Copy(pDataOut);
00409
00410 return m_pOutput->Deliver(pOut);
00411 }
00412
00413 void CDiracVideoDecoder::Copy(BYTE* pOut)
00414 {
00415
00416
00417 BITMAPINFOHEADER bihOut;
00418 ExtractBIH(&m_pOutput->CurrentMediaType(), &bihOut);
00419
00420 dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
00421
00422 int w = decoder->seq_params.width;
00423 int h = decoder->seq_params.height;
00424 int wc = decoder->seq_params.chroma_width;
00425 int hc = decoder->seq_params.chroma_height;
00426
00427 int pitchIn = w;
00428
00429 BYTE* pY = m_pYUV[0];
00430 BYTE* pU = w/2 == wc && h/2 == hc ? m_pYUV[1] : m_pYUV[3];
00431 BYTE* pV = w/2 == wc && h/2 == hc ? m_pYUV[2] : m_pYUV[3];
00432
00433 if(bihOut.biCompression == '2YUY')
00434 {
00435 BitBltFromI420ToYUY2(w, h, pOut, bihOut.biWidth*2, pY, pU, pV, pitchIn);
00436 }
00437 else if(bihOut.biCompression == 'I420' || bihOut.biCompression == 'VUYI')
00438 {
00439 BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h, pOut + bihOut.biWidth*h*5/4, bihOut.biWidth, pY, pU, pV, pitchIn);
00440 }
00441 else if(bihOut.biCompression == '21VY')
00442 {
00443 BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h*5/4, pOut + bihOut.biWidth*h, bihOut.biWidth, pY, pU, pV, pitchIn);
00444 }
00445 else if(bihOut.biCompression == BI_RGB || bihOut.biCompression == BI_BITFIELDS)
00446 {
00447 int pitchOut = bihOut.biWidth*bihOut.biBitCount>>3;
00448
00449 if(bihOut.biHeight > 0)
00450 {
00451 pOut += pitchOut*(h-1);
00452 pitchOut = -pitchOut;
00453 }
00454
00455 if(!BitBltFromI420ToRGB(w, h, pOut, pitchOut, bihOut.biBitCount, pY, pU, pV, pitchIn))
00456 {
00457 for(DWORD y = 0; y < h; y++, pOut += pitchOut)
00458 memset(pOut, 0, pitchOut);
00459 }
00460 }
00461 }
00462
00463 HRESULT CDiracVideoDecoder::CheckInputType(const CMediaType* mtIn)
00464 {
00465 DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)mtIn->Format();
00466
00467 if(mtIn->majortype != MEDIATYPE_Video
00468 || mtIn->subtype != MEDIASUBTYPE_DiracVideo
00469 || mtIn->formattype != FORMAT_DiracVideoInfo
00470 || (dvih->hdr.bmiHeader.biWidth&1) || (dvih->hdr.bmiHeader.biHeight&1))
00471 return VFW_E_TYPE_NOT_ACCEPTED;
00472
00473 return S_OK;
00474 }
00475
00476 HRESULT CDiracVideoDecoder::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
00477 {
00478 if(m_pOutput && m_pOutput->IsConnected())
00479 {
00480 BITMAPINFOHEADER bih1, bih2;
00481 if(ExtractBIH(mtOut, &bih1) && ExtractBIH(&m_pOutput->CurrentMediaType(), &bih2)
00482 && abs(bih1.biHeight) != abs(bih2.biHeight))
00483 return VFW_E_TYPE_NOT_ACCEPTED;
00484 }
00485
00486 return mtIn->majortype == MEDIATYPE_Video && mtIn->subtype == MEDIASUBTYPE_DiracVideo
00487 && mtOut->majortype == MEDIATYPE_Video && (mtOut->subtype == MEDIASUBTYPE_YUY2
00488 || mtOut->subtype == MEDIASUBTYPE_YV12
00489 || mtOut->subtype == MEDIASUBTYPE_I420
00490 || mtOut->subtype == MEDIASUBTYPE_IYUV
00491 || mtOut->subtype == MEDIASUBTYPE_ARGB32
00492 || mtOut->subtype == MEDIASUBTYPE_RGB32
00493 || mtOut->subtype == MEDIASUBTYPE_RGB24
00494 || mtOut->subtype == MEDIASUBTYPE_RGB565
00495 || mtOut->subtype == MEDIASUBTYPE_RGB555)
00496 ? S_OK
00497 : VFW_E_TYPE_NOT_ACCEPTED;
00498 }
00499
00500 HRESULT CDiracVideoDecoder::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
00501 {
00502 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00503
00504 BITMAPINFOHEADER bih;
00505 ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
00506
00507 pProperties->cBuffers = 1;
00508 pProperties->cbBuffer = bih.biSizeImage;
00509 pProperties->cbAlign = 1;
00510 pProperties->cbPrefix = 0;
00511
00512 HRESULT hr;
00513 ALLOCATOR_PROPERTIES Actual;
00514 if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
00515 return hr;
00516
00517 return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
00518 ? E_FAIL
00519 : NOERROR);
00520 }
00521
00522 HRESULT CDiracVideoDecoder::GetMediaType(int iPosition, CMediaType* pmt)
00523 {
00524 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00525
00526 struct {const GUID* subtype; WORD biPlanes, biBitCount; DWORD biCompression;} fmts[] =
00527 {
00528 {&MEDIASUBTYPE_YV12, 3, 12, '21VY'},
00529 {&MEDIASUBTYPE_I420, 3, 12, '024I'},
00530 {&MEDIASUBTYPE_IYUV, 3, 12, 'VUYI'},
00531 {&MEDIASUBTYPE_YUY2, 1, 16, '2YUY'},
00532 {&MEDIASUBTYPE_ARGB32, 1, 32, BI_RGB},
00533 {&MEDIASUBTYPE_RGB32, 1, 32, BI_RGB},
00534 {&MEDIASUBTYPE_RGB24, 1, 24, BI_RGB},
00535 {&MEDIASUBTYPE_RGB565, 1, 16, BI_RGB},
00536 {&MEDIASUBTYPE_RGB555, 1, 16, BI_RGB},
00537 {&MEDIASUBTYPE_ARGB32, 1, 32, BI_BITFIELDS},
00538 {&MEDIASUBTYPE_RGB32, 1, 32, BI_BITFIELDS},
00539 {&MEDIASUBTYPE_RGB24, 1, 24, BI_BITFIELDS},
00540 {&MEDIASUBTYPE_RGB565, 1, 16, BI_BITFIELDS},
00541 {&MEDIASUBTYPE_RGB555, 1, 16, BI_BITFIELDS},
00542 };
00543
00544 if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo)
00545 iPosition = iPosition*2 + 1;
00546
00547 if(iPosition < 0) return E_INVALIDARG;
00548 if(iPosition >= 2*countof(fmts)) return VFW_S_NO_MORE_ITEMS;
00549
00550 BITMAPINFOHEADER bih;
00551 ExtractBIH(&m_pInput->CurrentMediaType(), &bih);
00552
00553 pmt->majortype = MEDIATYPE_Video;
00554 pmt->subtype = *fmts[iPosition/2].subtype;
00555
00556 BITMAPINFOHEADER bihOut;
00557 memset(&bihOut, 0, sizeof(bihOut));
00558 bihOut.biSize = sizeof(bihOut);
00559 bihOut.biWidth = bih.biWidth;
00560 bihOut.biHeight = bih.biHeight;
00561 bihOut.biPlanes = fmts[iPosition/2].biPlanes;
00562 bihOut.biBitCount = fmts[iPosition/2].biBitCount;
00563 bihOut.biCompression = fmts[iPosition/2].biCompression;
00564 bihOut.biSizeImage = bih.biWidth*bih.biHeight*bihOut.biBitCount>>3;
00565
00566 if(iPosition&1)
00567 {
00568 pmt->formattype = FORMAT_VideoInfo;
00569 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00570 memset(vih, 0, sizeof(VIDEOINFOHEADER));
00571 vih->bmiHeader = bihOut;
00572
00573 if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo2)
00574 {
00575 vih->bmiHeader.biWidth = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
00576 vih->bmiHeader.biHeight = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
00577 vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth*vih->bmiHeader.biHeight*vih->bmiHeader.biBitCount>>3;
00578 }
00579 }
00580 else
00581 {
00582 pmt->formattype = FORMAT_VideoInfo2;
00583 VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER2));
00584 memset(vih2, 0, sizeof(VIDEOINFOHEADER2));
00585 vih2->bmiHeader = bihOut;
00586 vih2->dwPictAspectRatioX = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
00587 vih2->dwPictAspectRatioY = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
00588 }
00589
00590 CorrectMediaType(pmt);
00591
00592 return S_OK;
00593 }
00594
00595 HRESULT CDiracVideoDecoder::StartStreaming()
00596 {
00597 InitDecoder();
00598 return __super::StartStreaming();
00599 }
00600
00601 HRESULT CDiracVideoDecoder::StopStreaming()
00602 {
00603 FreeDecoder();
00604 return __super::StopStreaming();
00605 }
00606
00607 HRESULT CDiracVideoDecoder::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
00608 {
00609 CAutoLock cAutoLock(&m_csReceive);
00610
00611 m_fDropFrames = false;
00612 m_tStart = tStart;
00613
00614 return __super::NewSegment(tStart, tStop, dRate);
00615 }
00616
00617 HRESULT CDiracVideoDecoder::AlterQuality(Quality q)
00618 {
00619 if(q.Late > 500*10000i64) m_fDropFrames = true;
00620 if(q.Late <= 0) m_fDropFrames = false;
00621 return E_NOTIMPL;
00622 }