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

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  *
  4.  *  This Program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2, or (at your option)
  7.  *  any later version.
  8.  *   
  9.  *  This Program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12.  *  GNU General Public License for more details.
  13.  *   
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with GNU Make; see the file COPYING.  If not, write to
  16.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  17.  *
  18.  */
  19. #include "stdafx.h"
  20. #include "D2VSource.h"
  21. #include "mpeg2dec.h"
  22. #include "......DSUtilDSUtil.h"
  23. #ifdef REGISTER_FILTER
  24. const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
  25. {
  26. {&MEDIATYPE_Video, &MEDIASUBTYPE_YUY2}
  27. };
  28. const AMOVIESETUP_PIN sudOpPin[] =
  29. {
  30. {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
  31. };
  32. const AMOVIESETUP_FILTER sudFilter[] =
  33. {
  34. {&__uuidof(CD2VSource), L"D2VSource", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin}
  35. };
  36. CFactoryTemplate g_Templates[] =
  37. {
  38. {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CD2VSource>, NULL, &sudFilter[0]}
  39. };
  40. int g_cTemplates = countof(g_Templates);
  41. STDAPI DllRegisterServer()
  42. {
  43. SetRegKeyValue(
  44. _T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"), 
  45. _T("0"), _T("0,18,,4456443241564950726F6A65637446696C65")); // "DVD2AVIProjectFile"
  46. SetRegKeyValue(
  47. _T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"), 
  48. _T("Source Filter"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
  49. SetRegKeyValue(
  50. _T("Media Type\Extensions"), _T(".d2v"), 
  51. _T("Source Filter"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
  52. return AMovieDllRegisterServer2(TRUE);
  53. }
  54. STDAPI DllUnregisterServer()
  55. {
  56. DeleteRegKey(_T("Media Type\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
  57. DeleteRegKey(_T("Media Type\Extensions"), _T(".d2v"));
  58. return AMovieDllRegisterServer2(FALSE);
  59. }
  60. extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
  61. BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
  62. {
  63.     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
  64. }
  65. #endif
  66. //
  67. // CD2VSource
  68. //
  69. CD2VSource::CD2VSource(LPUNKNOWN lpunk, HRESULT* phr)
  70. : CBaseSource<CD2VStream>(NAME("CD2VSource"), lpunk, phr, __uuidof(this))
  71. {
  72. if(phr) *phr = S_OK;
  73. }
  74. CD2VSource::~CD2VSource()
  75. {
  76. }
  77. //
  78. // CD2VStream
  79. //
  80. CD2VStream::CD2VStream(const WCHAR* fn, CSource* pParent, HRESULT* phr) 
  81. : CBaseStream(NAME("D2VSourceStream"), pParent, phr)
  82. , m_pFrameBuffer(NULL)
  83. {
  84. CAutoLock cAutoLock(&m_cSharedState);
  85. m_pDecoder.Attach(new CMPEG2Dec());
  86. if(!m_pDecoder)
  87. {
  88. if(phr) *phr = E_OUTOFMEMORY;
  89. return;
  90. }
  91. if(!m_pDecoder->Open(CStringA(fn), CMPEG2Dec::YUY2))
  92. {
  93. if(phr) *phr = E_FAIL;
  94. return;
  95. }
  96. if(!m_pFrameBuffer.Allocate(m_pDecoder->Clip_Width*m_pDecoder->Clip_Height*4))
  97. {
  98. if(phr) *phr = E_OUTOFMEMORY;
  99. return;
  100. }
  101. m_AvgTimePerFrame = 10000000000i64/m_pDecoder->VF_FrameRate;
  102. m_rtDuration = m_rtStop = m_AvgTimePerFrame*m_pDecoder->VF_FrameLimit;
  103. if(phr) *phr = m_rtDuration > 0 ? S_OK : E_FAIL;
  104. }
  105. CD2VStream::~CD2VStream()
  106. {
  107. CAutoLock cAutoLock(&m_cSharedState);
  108. }
  109. HRESULT CD2VStream::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
  110. {
  111. //    CAutoLock cAutoLock(m_pFilter->pStateLock());
  112.     ASSERT(pAlloc);
  113.     ASSERT(pProperties);
  114.     HRESULT hr = NOERROR;
  115. int w, h, bpp;
  116. if(!GetDim(w, h, bpp))
  117. return E_FAIL;
  118. pProperties->cBuffers = 1;
  119. pProperties->cbBuffer = w*h*bpp>>3;
  120.     ALLOCATOR_PROPERTIES Actual;
  121.     if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
  122.     if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
  123.     ASSERT(Actual.cBuffers == pProperties->cBuffers);
  124.     return NOERROR;
  125. }
  126. HRESULT CD2VStream::FillBuffer(IMediaSample* pSample, int nFrame, BYTE* pOut, long& len)
  127. {
  128. if(!m_pDecoder)
  129. return S_FALSE;
  130. AM_MEDIA_TYPE* pmt;
  131. if(SUCCEEDED(pSample->GetMediaType(&pmt)) && pmt)
  132. {
  133. CMediaType mt(*pmt);
  134. SetMediaType(&mt);
  135. DeleteMediaType(pmt);
  136. }
  137. int w, h, bpp;
  138. if(!GetDim(w, h, bpp))
  139. return S_FALSE;
  140. BYTE* pIn = m_pFrameBuffer;
  141. int pitchIn, pitchOut = 0;
  142. pitchIn = m_pDecoder->Clip_Width*bpp>>3;
  143. pitchOut = w*bpp>>3;
  144. m_pDecoder->Decode(pIn, (unsigned long)(nFrame), pitchIn);
  145. for(int y = 0, p = min(pitchIn, pitchOut); 
  146. y < h; 
  147. y++, pIn += pitchIn, pOut += pitchOut)
  148. {
  149. memcpy(pOut, pIn, p);
  150. }
  151. len = pitchOut*h;
  152. return S_OK;
  153. }
  154. HRESULT CD2VStream::GetMediaType(int iPosition, CMediaType* pmt)
  155. {
  156.     CAutoLock cAutoLock(m_pFilter->pStateLock());
  157.     if(iPosition < 0) return E_INVALIDARG;
  158.     if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
  159.     pmt->SetType(&MEDIATYPE_Video);
  160.     pmt->SetSubtype(&MEDIASUBTYPE_YUY2);
  161.     pmt->SetFormatType(&FORMAT_VideoInfo);
  162.     pmt->SetTemporalCompression(FALSE);
  163. VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  164. memset(vih, 0, sizeof(VIDEOINFOHEADER));
  165. vih->AvgTimePerFrame = m_AvgTimePerFrame;
  166. vih->bmiHeader.biSize = sizeof(vih->bmiHeader);
  167. vih->bmiHeader.biWidth = m_pDecoder->Clip_Width;
  168. vih->bmiHeader.biHeight = m_pDecoder->Clip_Height;
  169. vih->bmiHeader.biPlanes = 1;
  170. vih->bmiHeader.biBitCount = 16;
  171. vih->bmiHeader.biCompression = '2YUY';
  172. vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth*abs(vih->bmiHeader.biHeight)*vih->bmiHeader.biBitCount>>3;
  173. pmt->SetSampleSize(vih->bmiHeader.biSizeImage);
  174.     return NOERROR;
  175. }
  176. HRESULT CD2VStream::SetMediaType(const CMediaType* pmt)
  177. {
  178. if(m_pDecoder)
  179. {
  180. if(pmt->subtype == MEDIASUBTYPE_YUY2)
  181. m_pDecoder->m_dstFormat = CMPEG2Dec::YUY2;
  182. else
  183. return E_FAIL;
  184. }
  185. return CSourceStream::SetMediaType(pmt);
  186. }
  187. HRESULT CD2VStream::CheckMediaType(const CMediaType* pmt)
  188. {
  189. return pmt->majortype == MEDIATYPE_Video
  190. && pmt->subtype == MEDIASUBTYPE_YUY2
  191. && pmt->formattype == FORMAT_VideoInfo
  192. ? S_OK
  193. : E_INVALIDARG;
  194. }
  195. STDMETHODIMP CD2VStream::Notify(IBaseFilter* pSender, Quality q)
  196. {
  197. if(q.Late > 0 && q.Late < 100000000)
  198. {
  199. CAutoLock cAutoLockShared(&m_cSharedState);
  200.         m_rtSampleTime += (q.Late/m_AvgTimePerFrame)*m_AvgTimePerFrame;
  201.         m_rtPosition += (q.Late/m_AvgTimePerFrame)*m_AvgTimePerFrame;
  202. }
  203. return S_OK;
  204. }
  205. //
  206. bool CD2VStream::GetDim(int& w, int& h, int& bpp)
  207. {
  208. if(m_mt.formattype == FORMAT_VideoInfo)
  209. {
  210. w = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biWidth;
  211. h = abs(((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biHeight);
  212. bpp = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biBitCount;
  213. }
  214. else if(m_mt.formattype == FORMAT_VideoInfo2)
  215. {
  216. w = ((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biWidth;
  217. h = abs(((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biHeight);
  218. bpp = ((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biBitCount;
  219. }
  220. else
  221. {
  222. return(false);
  223. }
  224. return(true);
  225. }