00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021 #include "D2VSource.h"
00022 #include "mpeg2dec.h"
00023 #include "..\..\..\DSUtil\DSUtil.h"
00024
00025 #ifdef REGISTER_FILTER
00026
00027 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00028 {
00029 {&MEDIATYPE_Video, &MEDIASUBTYPE_YUY2}
00030 };
00031
00032 const AMOVIESETUP_PIN sudOpPin[] =
00033 {
00034 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00035 };
00036
00037 const AMOVIESETUP_FILTER sudFilter[] =
00038 {
00039 {&__uuidof(CD2VSource), L"D2VSource", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin}
00040 };
00041
00042 CFactoryTemplate g_Templates[] =
00043 {
00044 {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CD2VSource>, NULL, &sudFilter[0]}
00045 };
00046
00047 int g_cTemplates = countof(g_Templates);
00048
00049 STDAPI DllRegisterServer()
00050 {
00051 SetRegKeyValue(
00052 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"),
00053 _T("0"), _T("0,18,,4456443241564950726F6A65637446696C65"));
00054
00055 SetRegKeyValue(
00056 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"),
00057 _T("Source Filter"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
00058
00059 SetRegKeyValue(
00060 _T("Media Type\\Extensions"), _T(".d2v"),
00061 _T("Source Filter"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
00062
00063 return AMovieDllRegisterServer2(TRUE);
00064 }
00065
00066 STDAPI DllUnregisterServer()
00067 {
00068 DeleteRegKey(_T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{47CE0591-C4D5-4b41-BED7-28F59AD76228}"));
00069 DeleteRegKey(_T("Media Type\\Extensions"), _T(".d2v"));
00070
00071 return AMovieDllRegisterServer2(FALSE);
00072 }
00073
00074 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00075
00076 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00077 {
00078 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00079 }
00080
00081 #endif
00082
00083
00084
00085
00086
00087 CD2VSource::CD2VSource(LPUNKNOWN lpunk, HRESULT* phr)
00088 : CBaseSource<CD2VStream>(NAME("CD2VSource"), lpunk, phr, __uuidof(this))
00089 {
00090 if(phr) *phr = S_OK;
00091 }
00092
00093 CD2VSource::~CD2VSource()
00094 {
00095 }
00096
00097
00098
00099
00100
00101 CD2VStream::CD2VStream(const WCHAR* fn, CSource* pParent, HRESULT* phr)
00102 : CBaseStream(NAME("D2VSourceStream"), pParent, phr)
00103 , m_pFrameBuffer(NULL)
00104 {
00105 CAutoLock cAutoLock(&m_cSharedState);
00106
00107 m_pDecoder.Attach(new CMPEG2Dec());
00108 if(!m_pDecoder)
00109 {
00110 if(phr) *phr = E_OUTOFMEMORY;
00111 return;
00112 }
00113
00114 if(!m_pDecoder->Open(CStringA(fn), CMPEG2Dec::YUY2))
00115 {
00116 if(phr) *phr = E_FAIL;
00117 return;
00118 }
00119
00120 if(!m_pFrameBuffer.Allocate(m_pDecoder->Clip_Width*m_pDecoder->Clip_Height*4))
00121 {
00122 if(phr) *phr = E_OUTOFMEMORY;
00123 return;
00124 }
00125
00126 m_AvgTimePerFrame = 10000000000i64/m_pDecoder->VF_FrameRate;
00127 m_rtDuration = m_rtStop = m_AvgTimePerFrame*m_pDecoder->VF_FrameLimit;
00128
00129 if(phr) *phr = m_rtDuration > 0 ? S_OK : E_FAIL;
00130 }
00131
00132 CD2VStream::~CD2VStream()
00133 {
00134 CAutoLock cAutoLock(&m_cSharedState);
00135 }
00136
00137 HRESULT CD2VStream::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
00138 {
00139
00140
00141 ASSERT(pAlloc);
00142 ASSERT(pProperties);
00143
00144 HRESULT hr = NOERROR;
00145
00146 int w, h, bpp;
00147 if(!GetDim(w, h, bpp))
00148 return E_FAIL;
00149
00150 pProperties->cBuffers = 1;
00151 pProperties->cbBuffer = w*h*bpp>>3;
00152
00153 ALLOCATOR_PROPERTIES Actual;
00154 if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
00155
00156 if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
00157 ASSERT(Actual.cBuffers == pProperties->cBuffers);
00158
00159 return NOERROR;
00160 }
00161
00162 HRESULT CD2VStream::FillBuffer(IMediaSample* pSample, int nFrame, BYTE* pOut, long& len)
00163 {
00164 if(!m_pDecoder)
00165 return S_FALSE;
00166
00167 AM_MEDIA_TYPE* pmt;
00168 if(SUCCEEDED(pSample->GetMediaType(&pmt)) && pmt)
00169 {
00170 CMediaType mt(*pmt);
00171 SetMediaType(&mt);
00172
00173 DeleteMediaType(pmt);
00174 }
00175
00176 int w, h, bpp;
00177 if(!GetDim(w, h, bpp))
00178 return S_FALSE;
00179
00180 BYTE* pIn = m_pFrameBuffer;
00181
00182 int pitchIn, pitchOut = 0;
00183
00184 pitchIn = m_pDecoder->Clip_Width*bpp>>3;
00185 pitchOut = w*bpp>>3;
00186
00187 m_pDecoder->Decode(pIn, (unsigned long)(nFrame), pitchIn);
00188
00189 for(int y = 0, p = min(pitchIn, pitchOut);
00190 y < h;
00191 y++, pIn += pitchIn, pOut += pitchOut)
00192 {
00193 memcpy(pOut, pIn, p);
00194 }
00195
00196 len = pitchOut*h;
00197
00198 return S_OK;
00199 }
00200
00201 HRESULT CD2VStream::GetMediaType(int iPosition, CMediaType* pmt)
00202 {
00203 CAutoLock cAutoLock(m_pFilter->pStateLock());
00204
00205 if(iPosition < 0) return E_INVALIDARG;
00206 if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
00207
00208 pmt->SetType(&MEDIATYPE_Video);
00209 pmt->SetSubtype(&MEDIASUBTYPE_YUY2);
00210 pmt->SetFormatType(&FORMAT_VideoInfo);
00211 pmt->SetTemporalCompression(FALSE);
00212
00213 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
00214 memset(vih, 0, sizeof(VIDEOINFOHEADER));
00215 vih->AvgTimePerFrame = m_AvgTimePerFrame;
00216 vih->bmiHeader.biSize = sizeof(vih->bmiHeader);
00217 vih->bmiHeader.biWidth = m_pDecoder->Clip_Width;
00218 vih->bmiHeader.biHeight = m_pDecoder->Clip_Height;
00219 vih->bmiHeader.biPlanes = 1;
00220 vih->bmiHeader.biBitCount = 16;
00221 vih->bmiHeader.biCompression = '2YUY';
00222 vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth*abs(vih->bmiHeader.biHeight)*vih->bmiHeader.biBitCount>>3;
00223
00224 pmt->SetSampleSize(vih->bmiHeader.biSizeImage);
00225
00226 return NOERROR;
00227 }
00228
00229 HRESULT CD2VStream::SetMediaType(const CMediaType* pmt)
00230 {
00231 if(m_pDecoder)
00232 {
00233 if(pmt->subtype == MEDIASUBTYPE_YUY2)
00234 m_pDecoder->m_dstFormat = CMPEG2Dec::YUY2;
00235 else
00236 return E_FAIL;
00237 }
00238
00239 return CSourceStream::SetMediaType(pmt);
00240 }
00241
00242 HRESULT CD2VStream::CheckMediaType(const CMediaType* pmt)
00243 {
00244 return pmt->majortype == MEDIATYPE_Video
00245 && pmt->subtype == MEDIASUBTYPE_YUY2
00246 && pmt->formattype == FORMAT_VideoInfo
00247 ? S_OK
00248 : E_INVALIDARG;
00249 }
00250
00251 STDMETHODIMP CD2VStream::Notify(IBaseFilter* pSender, Quality q)
00252 {
00253 if(q.Late > 0 && q.Late < 100000000)
00254 {
00255 CAutoLock cAutoLockShared(&m_cSharedState);
00256
00257 m_rtSampleTime += (q.Late/m_AvgTimePerFrame)*m_AvgTimePerFrame;
00258 m_rtPosition += (q.Late/m_AvgTimePerFrame)*m_AvgTimePerFrame;
00259 }
00260
00261 return S_OK;
00262 }
00263
00264
00265
00266 bool CD2VStream::GetDim(int& w, int& h, int& bpp)
00267 {
00268 if(m_mt.formattype == FORMAT_VideoInfo)
00269 {
00270 w = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biWidth;
00271 h = abs(((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biHeight);
00272 bpp = ((VIDEOINFOHEADER*)m_mt.pbFormat)->bmiHeader.biBitCount;
00273 }
00274 else if(m_mt.formattype == FORMAT_VideoInfo2)
00275 {
00276 w = ((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biWidth;
00277 h = abs(((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biHeight);
00278 bpp = ((VIDEOINFOHEADER2*)m_mt.pbFormat)->bmiHeader.biBitCount;
00279 }
00280 else
00281 {
00282 return(false);
00283 }
00284
00285 return(true);
00286 }