- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# D2VSource.cpp

    00001 /*
    00002  *      Copyright (C) 2003-2005 Gabest
    00003  *
    00004  *  This Program is free software; you can redistribute it and/or modify
    00005  *  it under the terms of the GNU General Public License as published by
    00006  *  the Free Software Foundation; either version 2, or (at your option)
    00007  *  any later version.
    00008  *
    00009  *  This Program is distributed in the hope that it will be useful,
    00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    00012  *  GNU General Public License for more details.
    00013  *
    00014  *  You should have received a copy of the GNU General Public License
    00015  *  along with GNU Make; see the file COPYING.  If not, write to
    00016  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
    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")); // "DVD2AVIProjectFile"
    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); // "DllMain" of the dshow baseclasses;
    00079 }
    00080
    00081 #endif
    00082
    00083 //
    00084 // CD2VSource
    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 // CD2VStream
    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 //    CAutoLock cAutoLock(m_pFilter->pStateLock());
    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 }