DeCSSFilter.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "stdafx.h"
00023 #include <atlbase.h>
00024 #include "DeCSSFilter.h"
00025 #include "..\..\..\decss\DeCSSInputPin.h"
00026 #include "..\..\..\DSUtil\DSUtil.h"
00027 
00028 #ifdef REGISTER_FILTER
00029 
00030 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00031 {
00032         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_NULL},
00033 };
00034 
00035 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00036 {
00037         {&MEDIATYPE_MPEG2_PACK, &MEDIASUBTYPE_NULL},
00038         {&MEDIATYPE_MPEG2_PES, &MEDIASUBTYPE_NULL},
00039 };
00040 
00041 const AMOVIESETUP_PIN sudpPins[] =
00042 {
00043     {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00044     {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00045 };
00046 
00047 const AMOVIESETUP_FILTER sudFilter[] =
00048 {
00049         {&__uuidof(CDeCSSFilter), L"DeCSSFilter", MERIT_DO_NOT_USE, countof(sudpPins), sudpPins},
00050 };
00051 
00052 CFactoryTemplate g_Templates[] =
00053 {
00054     {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDeCSSFilter>, NULL, &sudFilter[0]},
00055 };
00056 
00057 int g_cTemplates = countof(g_Templates);
00058 
00059 STDAPI DllRegisterServer()
00060 {
00061         return AMovieDllRegisterServer2(TRUE);
00062 }
00063 
00064 STDAPI DllUnregisterServer()
00065 {
00066         return AMovieDllRegisterServer2(FALSE);
00067 }
00068 
00069 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00070 
00071 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00072 {
00073     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
00074 }
00075 
00076 #endif
00077 
00078 //
00079 // CDeCSSFilter
00080 //
00081 
00082 class CKsPSInputPin : public CDeCSSInputPin
00083 {
00084 public:
00085     CKsPSInputPin(TCHAR* pObjectName, CTransformFilter* pFilter, HRESULT* phr, LPWSTR pName)
00086                 : CDeCSSInputPin(pObjectName, pFilter, phr, pName)
00087         {
00088         }
00089 
00090         // IKsPropertySet
00091     STDMETHODIMP Set(REFGUID PropSet, ULONG Id, LPVOID InstanceData, ULONG InstanceLength, LPVOID PropertyData, ULONG DataLength)
00092         {
00093                 if(CComQIPtr<IKsPropertySet> pKsPS = ((CDeCSSFilter*)m_pFilter)->m_pOutput->GetConnected())
00094                         return pKsPS->Set(PropSet, Id, InstanceData, InstanceLength, PropertyData, DataLength);
00095                 return E_NOTIMPL;
00096         }
00097     STDMETHODIMP Get(REFGUID PropSet, ULONG Id, LPVOID InstanceData, ULONG InstanceLength, LPVOID PropertyData, ULONG DataLength, ULONG* pBytesReturned)
00098         {
00099                 if(CComQIPtr<IKsPropertySet> pKsPS = ((CDeCSSFilter*)m_pFilter)->m_pOutput->GetConnected())
00100                         return pKsPS->Get(PropSet, Id, InstanceData, InstanceLength, PropertyData, DataLength, pBytesReturned);
00101                 return E_NOTIMPL;
00102         }
00103     STDMETHODIMP QuerySupported(REFGUID PropSet, ULONG Id, ULONG* pTypeSupport)
00104         {
00105                 if(CComQIPtr<IKsPropertySet> pKsPS = ((CDeCSSFilter*)m_pFilter)->m_pOutput->GetConnected())
00106                         return pKsPS->QuerySupported(PropSet, Id, pTypeSupport);
00107                 return E_NOTIMPL;
00108         }
00109 };
00110 
00111 CDeCSSFilter::CDeCSSFilter(LPUNKNOWN lpunk, HRESULT* phr) 
00112         : CTransformFilter(NAME("CDeCSSFilter"), lpunk, __uuidof(this))
00113 {
00114         if(phr) *phr = S_OK;
00115 
00116         if(!(m_pInput = new CKsPSInputPin(NAME("CKsPSInputPin"), this, phr, L"In"))) *phr = E_OUTOFMEMORY;
00117         if(FAILED(*phr)) return;
00118 
00119         if(!(m_pOutput = new CTransformOutputPin(NAME("CTransformOutputPin"), this, phr, L"Out"))) *phr = E_OUTOFMEMORY;
00120         if(FAILED(*phr))  {delete m_pInput, m_pInput = NULL; return;}
00121 }
00122 
00123 CDeCSSFilter::~CDeCSSFilter()
00124 {
00125 }
00126 
00127 HRESULT CDeCSSFilter::Transform(IMediaSample* pIn, IMediaSample* pOut)
00128 {
00129         AM_MEDIA_TYPE* pmt;
00130         if(SUCCEEDED(pIn->GetMediaType(&pmt)) && pmt)
00131         {
00132                 CMediaType mt = *pmt;
00133                 m_pInput->SetMediaType(&mt);
00134                 mt.majortype = m_pOutput->CurrentMediaType().majortype;
00135                 m_pOutput->SetMediaType(&mt);
00136                 pOut->SetMediaType(&mt);
00137                 DeleteMediaType(pmt);
00138         }
00139 
00140         BYTE* pDataIn = NULL;
00141         BYTE* pDataOut = NULL;
00142 
00143         pIn->GetPointer(&pDataIn);
00144         pOut->GetPointer(&pDataOut);
00145 
00146         long len = pIn->GetActualDataLength();
00147         long size = pOut->GetSize();
00148 
00149         if(len == 0 || pDataIn == NULL) // format changes do not carry any data
00150         {
00151                 pOut->SetActualDataLength(0);
00152                 return S_OK;
00153         }
00154 
00155         if(m_pOutput->CurrentMediaType().majortype == MEDIATYPE_MPEG2_PES)
00156         {
00157                 if(*(DWORD*)pDataIn == 0xBA010000)
00158                 {
00159                         len -= 14; pDataIn += 14;
00160                         if(int stuffing = (pDataIn[-1]&7)) {len -= stuffing; pDataIn += stuffing;}
00161                 }
00162                 if(len <= 0) return S_FALSE;
00163                 if(*(DWORD*)pDataIn == 0xBB010000)
00164                 {
00165                         len -= 4; pDataIn += 4;
00166                         int hdrlen = ((pDataIn[0]<<8)|pDataIn[1]) + 2;
00167                         len -= hdrlen; pDataIn += hdrlen;
00168                 }
00169                 if(len <= 0) return S_FALSE;
00170         }
00171 
00172         if(!pDataIn || !pDataOut || len > size || len < 0) return S_FALSE;
00173 
00174         memcpy(pDataOut, pDataIn, min(len, size));
00175         pOut->SetActualDataLength(min(len, size));
00176 
00177         return S_OK;
00178 }
00179 
00180 HRESULT CDeCSSFilter::CheckInputType(const CMediaType* mtIn)
00181 {
00182         return mtIn->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK
00183                 ? S_OK 
00184                 : VFW_E_TYPE_NOT_ACCEPTED;
00185 }
00186 
00187 HRESULT CDeCSSFilter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
00188 {
00189         return SUCCEEDED(CheckInputType(mtIn))
00190                 && mtOut->majortype == MEDIATYPE_MPEG2_PACK || mtOut->majortype == MEDIATYPE_MPEG2_PES
00191                 ? S_OK 
00192                 : VFW_E_TYPE_NOT_ACCEPTED;
00193 }
00194 
00195 HRESULT CDeCSSFilter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
00196 {
00197         if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00198 
00199         pProperties->cbAlign = 1;
00200         pProperties->cBuffers = 1;
00201         pProperties->cbBuffer = 2048;
00202         pProperties->cbPrefix = 0;
00203 
00204         HRESULT hr;
00205         ALLOCATOR_PROPERTIES Actual;
00206     if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual))) 
00207                 return hr;
00208 
00209     return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
00210                 ? E_FAIL
00211                 : NOERROR);
00212 }
00213 
00214 HRESULT CDeCSSFilter::GetMediaType(int iPosition, CMediaType* pmt)
00215 {
00216     if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00217 
00218         if(iPosition < 0) return E_INVALIDARG;
00219     if(iPosition > 1) return VFW_S_NO_MORE_ITEMS;
00220 
00221         CopyMediaType(pmt, &m_pInput->CurrentMediaType());
00222         if(iPosition == 0) pmt->majortype = MEDIATYPE_MPEG2_PACK;
00223         if(iPosition == 1) pmt->majortype = MEDIATYPE_MPEG2_PES;
00224 
00225         return S_OK;
00226 }

Generated on Tue Dec 13 14:47:27 2005 for guliverkli by  doxygen 1.4.5