Reactos
at master 250 lines 6.8 kB view raw
1/* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy 4 * FILE: dll/directx/ksproxy/datatype.cpp 5 * PURPOSE: IKsDataTypeHandler interface 6 * 7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org) 8 */ 9#include "precomp.h" 10 11/* FIXME guid mess */ 12const GUID IID_IUnknown = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; 13const GUID IID_IClassFactory = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; 14 15class CKsDataTypeHandler : public IKsDataTypeHandler 16{ 17public: 18 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 19 20 STDMETHODIMP_(ULONG) AddRef() 21 { 22 InterlockedIncrement(&m_Ref); 23 return m_Ref; 24 } 25 STDMETHODIMP_(ULONG) Release() 26 { 27 InterlockedDecrement(&m_Ref); 28 29 if (!m_Ref) 30 { 31 delete this; 32 return 0; 33 } 34 return m_Ref; 35 } 36 37 HRESULT STDMETHODCALLTYPE KsCompleteIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation, IN BOOL Cancelled); 38 HRESULT STDMETHODCALLTYPE KsIsMediaTypeInRanges(IN PVOID DataRanges); 39 HRESULT STDMETHODCALLTYPE KsPrepareIoOperation(IN OUT IMediaSample *Sample, IN OUT PVOID StreamHeader, IN KSIOOPERATION IoOperation); 40 HRESULT STDMETHODCALLTYPE KsQueryExtendedSize(OUT ULONG* ExtendedSize); 41 HRESULT STDMETHODCALLTYPE KsSetMediaType(IN const AM_MEDIA_TYPE* AmMediaType); 42 43 CKsDataTypeHandler() : m_Ref(0), m_Type(0){}; 44 virtual ~CKsDataTypeHandler() 45 { 46 if (m_Type) 47 { 48 if (m_Type->pbFormat) 49 CoTaskMemFree(m_Type->pbFormat); 50 51 if (m_Type->pUnk) 52 m_Type->pUnk->Release(); 53 54 CoTaskMemFree(m_Type); 55 } 56 57 }; 58 59protected: 60 LONG m_Ref; 61 AM_MEDIA_TYPE * m_Type; 62}; 63 64 65HRESULT 66STDMETHODCALLTYPE 67CKsDataTypeHandler::QueryInterface( 68 IN REFIID refiid, 69 OUT PVOID* Output) 70{ 71 if (IsEqualGUID(refiid, IID_IUnknown) || 72 IsEqualGUID(refiid, IID_IKsDataTypeHandler)) 73 { 74 *Output = PVOID(this); 75 reinterpret_cast<IUnknown*>(*Output)->AddRef(); 76 return NOERROR; 77 } 78 return E_NOINTERFACE; 79} 80 81 82HRESULT 83STDMETHODCALLTYPE 84CKsDataTypeHandler::KsCompleteIoOperation( 85 IN OUT IMediaSample *Sample, 86 IN OUT PVOID StreamHeader, 87 IN KSIOOPERATION IoOperation, 88 IN BOOL Cancelled) 89{ 90 return NOERROR; 91} 92 93 94HRESULT 95STDMETHODCALLTYPE 96CKsDataTypeHandler::KsIsMediaTypeInRanges( 97 IN PVOID DataRanges) 98{ 99 PKSMULTIPLE_ITEM DataList; 100 PKSDATARANGE DataRange; 101 ULONG Index; 102 //HRESULT hr = S_FALSE; 103 104#ifdef KSPROXY_TRACE 105 OutputDebugStringW(L"CKsDataTypeHandler::KsIsMediaTypeInRanges\n"); 106#endif 107 108 DataList = (PKSMULTIPLE_ITEM)DataRanges; 109 DataRange = (PKSDATARANGE)(DataList + 1); 110 111 for(Index = 0; Index < DataList->Count; Index++) 112 { 113 BOOL bMatch = FALSE; 114 115 if (DataRange->FormatSize >= sizeof(KSDATARANGE)) 116 { 117 bMatch = IsEqualGUID(DataRange->MajorFormat, GUID_NULL); 118 } 119 120 if (!bMatch && DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO)) 121 { 122 bMatch = IsEqualGUID(DataRange->MajorFormat, MEDIATYPE_Audio); 123 } 124 125 if (bMatch) 126 { 127 if (IsEqualGUID(DataRange->SubFormat, m_Type->subtype) || 128 IsEqualGUID(DataRange->SubFormat, GUID_NULL)) 129 { 130 if (IsEqualGUID(DataRange->Specifier, m_Type->formattype) || 131 IsEqualGUID(DataRange->Specifier, GUID_NULL)) 132 { 133 if (!IsEqualGUID(m_Type->formattype, FORMAT_WaveFormatEx) && !IsEqualGUID(DataRange->Specifier, FORMAT_WaveFormatEx)) 134 { 135 //found match 136 //hr = S_OK; 137 break; 138 } 139 140 if (DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO) && m_Type->cbFormat >= sizeof(WAVEFORMATEX)) 141 { 142 LPWAVEFORMATEX Format = (LPWAVEFORMATEX)m_Type->pbFormat; 143 PKSDATARANGE_AUDIO AudioRange = (PKSDATARANGE_AUDIO)DataRange; 144 145 if (Format->nSamplesPerSec >= AudioRange->MinimumSampleFrequency && 146 Format->nSamplesPerSec <= AudioRange->MaximumSampleFrequency && 147 Format->wBitsPerSample >= AudioRange->MinimumSampleFrequency && 148 Format->wBitsPerSample <= AudioRange->MaximumBitsPerSample && 149 Format->nChannels <= AudioRange->MaximumChannels) 150 { 151 // found match 152 //hr = S_OK; 153 break; 154 } 155 } 156 } 157 } 158 } 159 160 DataRange = (PKSDATARANGE)(((ULONG_PTR)DataRange + DataRange->FormatSize + 7) & ~7); 161 } 162 return S_OK; 163} 164 165HRESULT 166STDMETHODCALLTYPE 167CKsDataTypeHandler::KsPrepareIoOperation( 168 IN OUT IMediaSample *Sample, 169 IN OUT PVOID StreamHeader, 170 IN KSIOOPERATION IoOperation) 171{ 172 return NOERROR; 173} 174 175HRESULT 176STDMETHODCALLTYPE 177CKsDataTypeHandler::KsQueryExtendedSize( 178 OUT ULONG* ExtendedSize) 179{ 180 /* no header extension required */ 181 *ExtendedSize = 0; 182 return NOERROR; 183} 184 185HRESULT 186STDMETHODCALLTYPE 187CKsDataTypeHandler::KsSetMediaType( 188 IN const AM_MEDIA_TYPE* AmMediaType) 189{ 190#ifdef KSPROXY_TRACE 191 OutputDebugString("CKsDataTypeHandler::KsSetMediaType\n"); 192#endif 193 194 if (m_Type) 195 { 196 /* media type can only be set once */ 197 return E_FAIL; 198 } 199 200 m_Type = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); 201 if (!m_Type) 202 return E_OUTOFMEMORY; 203 204 CopyMemory(m_Type, AmMediaType, sizeof(AM_MEDIA_TYPE)); 205 206 if (m_Type->cbFormat) 207 { 208 m_Type->pbFormat = (BYTE*)CoTaskMemAlloc(m_Type->cbFormat); 209 210 if (!m_Type->pbFormat) 211 { 212 CoTaskMemFree(m_Type); 213 return E_OUTOFMEMORY; 214 } 215 216 CopyMemory(m_Type->pbFormat, AmMediaType->pbFormat, m_Type->cbFormat); 217 } 218 219 if (m_Type->pUnk) 220 m_Type->pUnk->AddRef(); 221 222 223 return S_OK; 224} 225 226HRESULT 227WINAPI 228CKsDataTypeHandler_Constructor ( 229 IUnknown * pUnkOuter, 230 REFIID riid, 231 LPVOID * ppv) 232{ 233#ifdef KSPROXY_TRACE 234 OutputDebugStringW(L"CKsDataTypeHandler_Constructor\n"); 235#endif 236 237 CKsDataTypeHandler * handler = new CKsDataTypeHandler(); 238 239 if (!handler) 240 return E_OUTOFMEMORY; 241 242 if (FAILED(handler->QueryInterface(riid, ppv))) 243 { 244 /* not supported */ 245 delete handler; 246 return E_NOINTERFACE; 247 } 248 249 return NOERROR; 250}