DiracSplitter.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:18k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "StdAfx.h"
  22. #include <mmreg.h>
  23. #include <initguid.h>
  24. #include "DiracSplitter.h"
  25. #include "........includemoreuuids.h"
  26. #ifdef REGISTER_FILTER
  27. const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
  28. {
  29. {&MEDIATYPE_Stream, &MEDIASUBTYPE_Dirac},
  30. {&MEDIATYPE_Stream, &MEDIASUBTYPE_NULL}
  31. };
  32. const AMOVIESETUP_PIN sudpPins[] =
  33. {
  34. {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
  35. {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, 0, NULL}
  36. };
  37. const AMOVIESETUP_MEDIATYPE sudPinTypesIn2[] =
  38. {
  39. {&MEDIATYPE_Video, &MEDIASUBTYPE_DiracVideo},
  40. };
  41. const AMOVIESETUP_MEDIATYPE sudPinTypesOut2[] =
  42. {
  43. {&MEDIATYPE_Video, &MEDIASUBTYPE_NULL},
  44. };
  45. const AMOVIESETUP_PIN sudpPins2[] =
  46. {
  47.     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn2), sudPinTypesIn2},
  48.     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut2), sudPinTypesOut2}
  49. };
  50. const AMOVIESETUP_FILTER sudFilter[] =
  51. {
  52. {&__uuidof(CDiracSplitterFilter), L"Dirac Splitter", MERIT_NORMAL, countof(sudpPins), sudpPins},
  53. {&__uuidof(CDiracSourceFilter), L"Dirac Source", MERIT_NORMAL, 0, NULL},
  54. {&__uuidof(CDiracVideoDecoder), L"Dirac Video Decoder", MERIT_UNLIKELY, countof(sudpPins2), sudpPins2},
  55. };
  56. CFactoryTemplate g_Templates[] =
  57. {
  58. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDiracSplitterFilter>, NULL, &sudFilter[0]},
  59. {sudFilter[1].strName, sudFilter[1].clsID, CreateInstance<CDiracSourceFilter>, NULL, &sudFilter[1]},
  60.     {sudFilter[2].strName, sudFilter[2].clsID, CreateInstance<CDiracVideoDecoder>, NULL, &sudFilter[2]},
  61. };
  62. int g_cTemplates = countof(g_Templates);
  63. STDAPI DllRegisterServer()
  64. {
  65. RegisterSourceFilter(
  66. CLSID_AsyncReader, 
  67. MEDIASUBTYPE_Dirac, 
  68. _T("0,8,,4B572D4449524143"), // KW-DIRAC
  69. _T(".drc"), NULL);
  70. return AMovieDllRegisterServer2(TRUE);
  71. }
  72. STDAPI DllUnregisterServer()
  73. {
  74. UnRegisterSourceFilter(MEDIASUBTYPE_Dirac);
  75. return AMovieDllRegisterServer2(FALSE);
  76. }
  77. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  78. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  79. {
  80. return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  81. }
  82. #endif
  83. //
  84. // CDiracSplitterFilter
  85. //
  86. CDiracSplitterFilter::CDiracSplitterFilter(LPUNKNOWN pUnk, HRESULT* phr)
  87. : CBaseSplitterFilter(NAME("CDiracSplitterFilter"), pUnk, phr, __uuidof(this))
  88. {
  89. }
  90. STDMETHODIMP CDiracSplitterFilter::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  91. {
  92.     CheckPointer(ppv, E_POINTER);
  93.     return 
  94. __super::NonDelegatingQueryInterface(riid, ppv);
  95. }
  96. HRESULT CDiracSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
  97. {
  98. CheckPointer(pAsyncReader, E_POINTER);
  99. HRESULT hr = E_FAIL;
  100. m_pFile.Free();
  101. m_pFile.Attach(new CDiracSplitterFile(pAsyncReader, hr));
  102. if(!m_pFile) return E_OUTOFMEMORY;
  103. if(FAILED(hr)) {m_pFile.Free(); return hr;}
  104. CArray<CMediaType> mts;
  105. mts.Add(m_pFile->GetMediaType());
  106. CAutoPtr<CBaseSplitterOutputPin> pPinOut(new CBaseSplitterOutputPin(mts, L"Video", this, this, &hr));
  107. AddOutputPin(0, pPinOut);
  108. m_rtNewStart = m_rtCurrent = 0;
  109. m_rtNewStop = m_rtStop = m_rtDuration = m_pFile->GetDuration();
  110. return m_pOutputs.GetCount() > 0 ? S_OK : E_FAIL;
  111. }
  112. bool CDiracSplitterFilter::DemuxInit()
  113. {
  114. if(!m_pFile) return(false);
  115. // TODO
  116. return(true);
  117. }
  118. void CDiracSplitterFilter::DemuxSeek(REFERENCE_TIME rt)
  119. {
  120. REFERENCE_TIME rtPreroll = 0; //10000000;
  121. if(rt <= rtPreroll || m_rtDuration <= 0)
  122. {
  123. m_pFile->Seek(8);
  124. }
  125. else
  126. {
  127. // TODO
  128. __int64 len = m_pFile->GetLength();
  129. __int64 seekpos = (__int64)(1.0*rt/m_rtDuration*len);
  130. m_pFile->Seek(seekpos);
  131. seekpos = 8;
  132. REFERENCE_TIME rtmax = rt - rtPreroll;
  133. REFERENCE_TIME rtmin = rtmax - 5000000;
  134. REFERENCE_TIME pdt = _I64_MIN;
  135. for(int j = 0; j < 10; j++)
  136. {
  137. BYTE code = NOT_START_CODE;
  138. while(m_pFile->Next(code) && code != IFRAME_START_CODE);
  139. if(code != IFRAME_START_CODE) {m_pFile->Seek(seekpos >>= 1); continue;}
  140. __int64 pos = m_pFile->GetPos() - 5;
  141. REFERENCE_TIME rt = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame * m_pFile->UnsignedGolombDecode();
  142. REFERENCE_TIME dt = rt - rtmax;
  143. if(dt > 0 && dt == pdt) dt = 10000000i64;
  144. if(rtmin <= rt && rt <= rtmax || pdt > 0 && dt < 0)
  145. {
  146. seekpos = pos;
  147. break;
  148. }
  149. m_pFile->Seek(pos - (__int64)(1.0*dt/m_rtDuration*len));
  150. pdt = dt;
  151. }
  152. m_pFile->Seek(seekpos);
  153. }
  154. }
  155. bool CDiracSplitterFilter::DemuxLoop()
  156. {
  157. HRESULT hr = S_OK;
  158. REFERENCE_TIME rtAvgTimePerFrame = ((DIRACINFOHEADER*)m_pFile->GetMediaType().Format())->hdr.AvgTimePerFrame;
  159. while(SUCCEEDED(hr) && !CheckRequest(NULL))
  160. {
  161. BYTE code = NOT_START_CODE;
  162. int size = 0, fnum = 0;
  163. const BYTE* pBuff = m_pFile->NextBlock(code, size, fnum);
  164. if(!pBuff || size < 5) break;
  165. if(isFrameStartCode(code))
  166. {
  167. CAutoPtr<Packet> p(new Packet());
  168. p->pData.SetSize(size);
  169. memcpy(p->pData.GetData(), pBuff, size);
  170. p->TrackNumber = 0;
  171. p->rtStart = rtAvgTimePerFrame*fnum;
  172. p->rtStop = p->rtStart + rtAvgTimePerFrame;
  173. p->bSyncPoint = code == IFRAME_START_CODE;
  174. hr = DeliverPacket(p);
  175. }
  176. if(code == SEQ_END_CODE)
  177. break;
  178. }
  179. return(true);
  180. }
  181. //
  182. // CDiracSourceFilter
  183. //
  184. CDiracSourceFilter::CDiracSourceFilter(LPUNKNOWN pUnk, HRESULT* phr)
  185. : CDiracSplitterFilter(pUnk, phr)
  186. {
  187. m_clsid = __uuidof(this);
  188. m_pInput.Free();
  189. }
  190. //
  191. // CDiracVideoDecoder
  192. //
  193. CDiracVideoDecoder::CDiracVideoDecoder(LPUNKNOWN lpunk, HRESULT* phr)
  194. : CTransformFilter(NAME("CDiracVideoDecoder"), lpunk, __uuidof(this))
  195. {
  196. if(phr) *phr = S_OK;
  197. m_decoder = NULL;
  198. m_pYUV[0] = NULL;
  199. }
  200. CDiracVideoDecoder::~CDiracVideoDecoder()
  201. {
  202. delete [] m_pYUV[0];
  203. }
  204. void CDiracVideoDecoder::InitDecoder()
  205. {
  206. FreeDecoder();
  207. dirac_decoder_t* decoder = dirac_decoder_init(0);
  208. DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
  209. dirac_buffer(decoder, (BYTE*)&dvih->dwSequenceHeader[0], (BYTE*)&dvih->dwSequenceHeader[0] + dvih->cbSequenceHeader);
  210. m_decoder = decoder;
  211. }
  212. void CDiracVideoDecoder::FreeDecoder()
  213. {
  214. if(m_decoder)
  215. {
  216. dirac_decoder_close((dirac_decoder_t*)m_decoder);
  217. m_decoder = NULL;
  218. delete [] m_pYUV[0]; m_pYUV[0] = NULL;
  219. }
  220. }
  221. HRESULT CDiracVideoDecoder::Receive(IMediaSample* pIn)
  222. {
  223. CAutoLock cAutoLock(&m_csReceive);
  224. HRESULT hr;
  225.     AM_SAMPLE2_PROPERTIES* const pProps = m_pInput->SampleProps();
  226.     if(pProps->dwStreamId != AM_STREAM_MEDIA)
  227. return m_pOutput->Deliver(pIn);
  228. BYTE* pDataIn = NULL;
  229. if(FAILED(hr = pIn->GetPointer(&pDataIn))) return hr;
  230. long len = pIn->GetActualDataLength();
  231. if(len <= 0) return S_OK; // nothing to do
  232. if(pIn->IsDiscontinuity() == S_OK) 
  233. InitDecoder();
  234. dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
  235. hr = S_OK;
  236. while(SUCCEEDED(hr))
  237. {
  238.         switch(dirac_parse(decoder))
  239.         {
  240.         case STATE_BUFFER:
  241. if(len == 0) return S_OK;
  242. dirac_buffer(decoder, pDataIn, pDataIn + len);
  243. len = 0;
  244. break;
  245.         case STATE_SEQUENCE:
  246. TRACE(_T("STATE_SEQUENCEn"));
  247. {
  248. DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)m_pInput->CurrentMediaType().Format();
  249. if(dvih->hdr.bmiHeader.biWidth != decoder->seq_params.width
  250. || dvih->hdr.bmiHeader.biHeight != decoder->seq_params.height)
  251. return E_FAIL; // hmm
  252. }
  253. if(!m_pYUV[0])
  254. {
  255. int w = decoder->seq_params.width;
  256. int h = decoder->seq_params.height;
  257. int wc = decoder->seq_params.chroma_width;
  258. int hc = decoder->seq_params.chroma_height; 
  259. delete [] m_pYUV[0]; m_pYUV[0] = NULL;
  260. m_pYUV[0] = new BYTE[w*h + wc*hc*2 + w/2*h/2];
  261. m_pYUV[1] = m_pYUV[0] + w*h;
  262. m_pYUV[2] = m_pYUV[1] + wc*hc;
  263. m_pYUV[3] = m_pYUV[2] + wc*hc;
  264. memset(m_pYUV[3], 0x80, w/2*h/2);
  265. m_rtAvgTimePerFrame = 10000000i64 * decoder->seq_params.frame_rate.denominator / decoder->seq_params.frame_rate.numerator;
  266. dirac_set_buf(decoder, m_pYUV, NULL);
  267. }
  268. break;
  269.         case STATE_SEQUENCE_END:
  270. TRACE(_T("STATE_SEQUENCE_ENDn"));
  271.             break;
  272.         case STATE_PICTURE_START:
  273. TRACE(_T("STATE_PICTURE_START, frame_type=%d frame_num=%dn"), decoder->frame_params.ftype, decoder->frame_params.fnum);
  274. dirac_skip(decoder, (m_fDropFrames || decoder->frame_params.fnum * m_rtAvgTimePerFrame < m_tStart) && decoder->frame_params.ftype == L2_frame ? 1 : 0);
  275. if(m_fDropFrames && decoder->frame_params.ftype == L2_frame) return S_OK;
  276.             break;
  277.         case STATE_PICTURE_AVAIL:
  278. TRACE(_T("STATE_PICTURE_AVAIL, frame_type=%d frame_num=%dn"), decoder->frame_params.ftype, decoder->frame_params.fnum);
  279. hr = Deliver(pIn, decoder->frame_params.fnum * m_rtAvgTimePerFrame - m_tStart, (decoder->frame_params.fnum + 1) * m_rtAvgTimePerFrame - m_tStart);
  280. break;
  281.         case STATE_INVALID:
  282. TRACE(_T("STATE_INVALIDn"));
  283. return E_FAIL; // TODO: can we recover from this state?
  284. // break;
  285.         default:
  286. TRACE(_T("unknown staten"));
  287.             continue;
  288.         }
  289.     }
  290. return hr;
  291. }
  292. HRESULT CDiracVideoDecoder::Deliver(IMediaSample* pIn, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop)
  293. {
  294. CheckPointer(pIn, E_POINTER);
  295. HRESULT hr;
  296. if(pIn->IsPreroll() == S_OK || rtStart < 0)
  297. return S_OK;
  298.     CComPtr<IMediaSample> pOut;
  299. BYTE* pDataOut = NULL;
  300. if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pOut, NULL, NULL, 0))
  301. || FAILED(hr = pOut->GetPointer(&pDataOut)))
  302. return hr;
  303. AM_MEDIA_TYPE* pmt;
  304. if(SUCCEEDED(pOut->GetMediaType(&pmt)) && pmt)
  305. {
  306. CMediaType mt(*pmt);
  307. m_pOutput->SetMediaType(&mt);
  308. DeleteMediaType(pmt);
  309. }
  310. TRACE(_T("CDiracVideoDecoder::Deliver(%I64d, %I64d)n"), rtStart, rtStop);
  311. pOut->SetTime(&rtStart, &rtStop);
  312. pOut->SetMediaTime(NULL, NULL);
  313. pOut->SetDiscontinuity(pIn->IsDiscontinuity() == S_OK);
  314. pOut->SetSyncPoint(TRUE);
  315. if(GetCLSID(m_pOutput->GetConnected()) == CLSID_OverlayMixer)
  316. pOut->SetDiscontinuity(TRUE);
  317. Copy(pDataOut);
  318. return m_pOutput->Deliver(pOut);
  319. }
  320. void CDiracVideoDecoder::Copy(BYTE* pOut)
  321. {
  322. // FIXME: modes other than I420 and Y-only
  323. BITMAPINFOHEADER bihOut;
  324. ExtractBIH(&m_pOutput->CurrentMediaType(), &bihOut);
  325. dirac_decoder_t* decoder = (dirac_decoder_t*)m_decoder;
  326. int w = decoder->seq_params.width;
  327. int h = decoder->seq_params.height;
  328. int wc = decoder->seq_params.chroma_width;
  329. int hc = decoder->seq_params.chroma_height;
  330. int pitchIn = w;
  331. BYTE* pY = m_pYUV[0];
  332. BYTE* pU = w/2 == wc && h/2 == hc ? m_pYUV[1] : m_pYUV[3]; // FIXME
  333. BYTE* pV = w/2 == wc && h/2 == hc ? m_pYUV[2] : m_pYUV[3]; // FIXME
  334. if(bihOut.biCompression == '2YUY')
  335. {
  336. BitBltFromI420ToYUY2(w, h, pOut, bihOut.biWidth*2, pY, pU, pV, pitchIn);
  337. }
  338. else if(bihOut.biCompression == 'I420' || bihOut.biCompression == 'VUYI')
  339. {
  340. BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h, pOut + bihOut.biWidth*h*5/4, bihOut.biWidth, pY, pU, pV, pitchIn);
  341. }
  342. else if(bihOut.biCompression == '21VY')
  343. {
  344. BitBltFromI420ToI420(w, h, pOut, pOut + bihOut.biWidth*h*5/4, pOut + bihOut.biWidth*h, bihOut.biWidth, pY, pU, pV, pitchIn);
  345. }
  346. else if(bihOut.biCompression == BI_RGB || bihOut.biCompression == BI_BITFIELDS)
  347. {
  348. int pitchOut = bihOut.biWidth*bihOut.biBitCount>>3;
  349. if(bihOut.biHeight > 0)
  350. {
  351. pOut += pitchOut*(h-1);
  352. pitchOut = -pitchOut;
  353. }
  354. if(!BitBltFromI420ToRGB(w, h, pOut, pitchOut, bihOut.biBitCount, pY, pU, pV, pitchIn))
  355. {
  356. for(DWORD y = 0; y < h; y++, pOut += pitchOut)
  357. memset(pOut, 0, pitchOut);
  358. }
  359. }
  360. }
  361. HRESULT CDiracVideoDecoder::CheckInputType(const CMediaType* mtIn)
  362. {
  363. DIRACINFOHEADER* dvih = (DIRACINFOHEADER*)mtIn->Format();
  364. if(mtIn->majortype != MEDIATYPE_Video 
  365. || mtIn->subtype != MEDIASUBTYPE_DiracVideo
  366. || mtIn->formattype != FORMAT_DiracVideoInfo
  367. || (dvih->hdr.bmiHeader.biWidth&1) || (dvih->hdr.bmiHeader.biHeight&1))
  368. return VFW_E_TYPE_NOT_ACCEPTED;
  369. return S_OK;
  370. }
  371. HRESULT CDiracVideoDecoder::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
  372. {
  373. if(m_pOutput && m_pOutput->IsConnected())
  374. {
  375. BITMAPINFOHEADER bih1, bih2;
  376. if(ExtractBIH(mtOut, &bih1) && ExtractBIH(&m_pOutput->CurrentMediaType(), &bih2)
  377. && abs(bih1.biHeight) != abs(bih2.biHeight))
  378. return VFW_E_TYPE_NOT_ACCEPTED;
  379. }
  380. return mtIn->majortype == MEDIATYPE_Video && mtIn->subtype == MEDIASUBTYPE_DiracVideo
  381. && mtOut->majortype == MEDIATYPE_Video && (mtOut->subtype == MEDIASUBTYPE_YUY2
  382. || mtOut->subtype == MEDIASUBTYPE_YV12
  383. || mtOut->subtype == MEDIASUBTYPE_I420
  384. || mtOut->subtype == MEDIASUBTYPE_IYUV
  385. || mtOut->subtype == MEDIASUBTYPE_ARGB32
  386. || mtOut->subtype == MEDIASUBTYPE_RGB32
  387. || mtOut->subtype == MEDIASUBTYPE_RGB24
  388. || mtOut->subtype == MEDIASUBTYPE_RGB565
  389. || mtOut->subtype == MEDIASUBTYPE_RGB555)
  390. ? S_OK
  391. : VFW_E_TYPE_NOT_ACCEPTED;
  392. }
  393. HRESULT CDiracVideoDecoder::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
  394. {
  395. if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  396. BITMAPINFOHEADER bih;
  397. ExtractBIH(&m_pOutput->CurrentMediaType(), &bih);
  398. pProperties->cBuffers = 1;
  399. pProperties->cbBuffer = bih.biSizeImage;
  400. pProperties->cbAlign = 1;
  401. pProperties->cbPrefix = 0;
  402. HRESULT hr;
  403. ALLOCATOR_PROPERTIES Actual;
  404.     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
  405. return hr;
  406.     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
  407. ? E_FAIL
  408. : NOERROR);
  409. }
  410. HRESULT CDiracVideoDecoder::GetMediaType(int iPosition, CMediaType* pmt)
  411. {
  412.     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
  413. struct {const GUID* subtype; WORD biPlanes, biBitCount; DWORD biCompression;} fmts[] =
  414. {
  415. {&MEDIASUBTYPE_YV12, 3, 12, '21VY'},
  416. {&MEDIASUBTYPE_I420, 3, 12, '024I'},
  417. {&MEDIASUBTYPE_IYUV, 3, 12, 'VUYI'},
  418. {&MEDIASUBTYPE_YUY2, 1, 16, '2YUY'},
  419. {&MEDIASUBTYPE_ARGB32, 1, 32, BI_RGB},
  420. {&MEDIASUBTYPE_RGB32, 1, 32, BI_RGB},
  421. {&MEDIASUBTYPE_RGB24, 1, 24, BI_RGB},
  422. {&MEDIASUBTYPE_RGB565, 1, 16, BI_RGB},
  423. {&MEDIASUBTYPE_RGB555, 1, 16, BI_RGB},
  424. {&MEDIASUBTYPE_ARGB32, 1, 32, BI_BITFIELDS},
  425. {&MEDIASUBTYPE_RGB32, 1, 32, BI_BITFIELDS},
  426. {&MEDIASUBTYPE_RGB24, 1, 24, BI_BITFIELDS},
  427. {&MEDIASUBTYPE_RGB565, 1, 16, BI_BITFIELDS},
  428. {&MEDIASUBTYPE_RGB555, 1, 16, BI_BITFIELDS},
  429. };
  430. if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo)
  431. iPosition = iPosition*2 + 1;
  432. if(iPosition < 0) return E_INVALIDARG;
  433. if(iPosition >= 2*countof(fmts)) return VFW_S_NO_MORE_ITEMS;
  434. BITMAPINFOHEADER bih;
  435. ExtractBIH(&m_pInput->CurrentMediaType(), &bih);
  436. pmt->majortype = MEDIATYPE_Video;
  437. pmt->subtype = *fmts[iPosition/2].subtype;
  438. BITMAPINFOHEADER bihOut;
  439. memset(&bihOut, 0, sizeof(bihOut));
  440. bihOut.biSize = sizeof(bihOut);
  441. bihOut.biWidth = bih.biWidth;
  442. bihOut.biHeight = bih.biHeight;
  443. bihOut.biPlanes = fmts[iPosition/2].biPlanes;
  444. bihOut.biBitCount = fmts[iPosition/2].biBitCount;
  445. bihOut.biCompression = fmts[iPosition/2].biCompression;
  446. bihOut.biSizeImage = bih.biWidth*bih.biHeight*bihOut.biBitCount>>3;
  447. if(iPosition&1)
  448. {
  449. pmt->formattype = FORMAT_VideoInfo;
  450. VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  451. memset(vih, 0, sizeof(VIDEOINFOHEADER));
  452. vih->bmiHeader = bihOut;
  453. if(m_pInput->CurrentMediaType().formattype == FORMAT_VideoInfo2)
  454. {
  455. vih->bmiHeader.biWidth = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
  456. vih->bmiHeader.biHeight = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
  457. vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth*vih->bmiHeader.biHeight*vih->bmiHeader.biBitCount>>3;
  458. }
  459. }
  460. else
  461. {
  462. pmt->formattype = FORMAT_VideoInfo2;
  463. VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER2));
  464. memset(vih2, 0, sizeof(VIDEOINFOHEADER2));
  465. vih2->bmiHeader = bihOut;
  466. vih2->dwPictAspectRatioX = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioX;
  467. vih2->dwPictAspectRatioY = ((VIDEOINFOHEADER2*)m_pInput->CurrentMediaType().Format())->dwPictAspectRatioY;
  468. }
  469. CorrectMediaType(pmt);
  470. return S_OK;
  471. }
  472. HRESULT CDiracVideoDecoder::StartStreaming()
  473. {
  474. InitDecoder();
  475. return __super::StartStreaming();
  476. }
  477. HRESULT CDiracVideoDecoder::StopStreaming()
  478. {
  479. FreeDecoder();
  480. return __super::StopStreaming();
  481. }
  482. HRESULT CDiracVideoDecoder::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
  483. {
  484. CAutoLock cAutoLock(&m_csReceive);
  485. m_fDropFrames = false;
  486. m_tStart = tStart;
  487. return __super::NewSegment(tStart, tStop, dRate);
  488. }
  489. HRESULT CDiracVideoDecoder::AlterQuality(Quality q)
  490. {
  491. if(q.Late > 500*10000i64) m_fDropFrames = true;
  492. if(q.Late <= 0) m_fDropFrames = false;
  493. return E_NOTIMPL;
  494. }