- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }