00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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);
00074 }
00075
00076 #endif
00077
00078
00079
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
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)
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 }