cleanup: Silence compilation warnings on MinGW-w64
[mplayer.git] / loader / dshow / DS_Filter.c
blob88f881523ae7b2bc4352b2875b85caa0302719e4
1 /*
2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
4 */
6 #include "config.h"
7 #include "DS_Filter.h"
8 #include "graph.h"
9 #include "loader/drv.h"
10 #include "loader/com.h"
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include "loader/win32.h" // printf macro
16 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
18 #ifndef WIN32_LOADER
19 const GUID IID_IUnknown =
21 0x00000000, 0x0000, 0x0000,
22 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
24 const GUID IID_IClassFactory =
26 0x00000001, 0x0000, 0x0000,
27 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
30 HRESULT STDCALL CoInitialize(LPVOID pvReserved);
31 void STDCALL CoUninitialize(void);
32 #endif
34 static void DS_Filter_Start(DS_Filter* This)
36 HRESULT hr;
38 //Debug printf("DS_Filter_Start(%p)\n", This);
39 hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0);
40 if (hr != 0)
42 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr);
46 static void DS_Filter_Stop(DS_Filter* This)
48 if (This->m_pAll)
50 //Debug printf("DS_Filter_Stop(%p)\n", This);
51 This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME
52 This->m_pAll->vt->Release((IUnknown*)This->m_pAll);
53 This->m_pAll = 0;
57 void DS_Filter_Destroy(DS_Filter* This)
59 This->Stop(This);
61 if (This->m_pOurInput)
62 This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput);
63 if (This->m_pInputPin)
64 This->m_pInputPin->vt->Disconnect(This->m_pInputPin);
65 if (This->m_pOutputPin)
66 This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin);
67 if (This->m_pFilter)
68 This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter);
69 if (This->m_pOutputPin)
70 This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin);
71 if (This->m_pInputPin)
72 This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin);
73 if (This->m_pImp)
74 This->m_pImp->vt->Release((IUnknown*)This->m_pImp);
76 if (This->m_pOurOutput)
77 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput);
78 if (This->m_pParentFilter)
79 This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter);
80 if (This->m_pSrcFilter)
81 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter);
83 // FIXME - we are still leaving few things allocated!
84 if (This->m_iHandle)
85 FreeLibrary((unsigned)This->m_iHandle);
87 free(This);
89 #ifdef WIN32_LOADER
90 CodecRelease();
91 #else
92 CoUninitialize();
93 #endif
96 static HRESULT STDCALL DS_Filter_CopySample(void* pUserData,IMediaSample* pSample){
97 BYTE* pointer;
98 int len;
99 SampleProcUserData* pData=pUserData;
100 Debug printf("CopySample called(%p,%p)\n",pSample,pUserData);
101 if (pSample->vt->GetPointer(pSample, &pointer))
102 return 1;
103 len = pSample->vt->GetActualDataLength(pSample);
104 if (len == 0)
105 len = pSample->vt->GetSize(pSample);//for iv50
107 pData->frame_pointer = pointer;
108 pData->frame_size = len;
110 FILE* file=fopen("./uncompr.bmp", "wb");
111 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
112 *(int*)(&head[2])=len+0x36;
113 fwrite(head, 14, 1, file);
114 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
115 fwrite(pointer, len, 1, file);
116 fclose(file);
118 return 0;
121 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
122 AM_MEDIA_TYPE* in_fmt,
123 AM_MEDIA_TYPE* out_fmt,SampleProcUserData* pUserData)
125 int init = 0;
126 // char eb[250];
127 const char* em = NULL;
128 MemAllocator* tempAll;
129 FilterGraph* graph;
130 ALLOCATOR_PROPERTIES props,props1;
131 DS_Filter* This = malloc(sizeof(DS_Filter));
132 if (!This)
133 return NULL;
135 #ifdef WIN32_LOADER
136 CodecAlloc();
137 #else
138 CoInitialize(0L);
139 #endif
142 tempAll is not used anywhere.
143 MemAllocatorCreate() is called to ensure that RegisterComObject for IMemoryAllocator
144 will be called before possible call
145 to CoCreateInstance(...,&IID_IMemoryAllocator,...) from binary codec.
147 tempAll=MemAllocatorCreate();
148 This->m_pFilter = NULL;
149 This->m_pInputPin = NULL;
150 This->m_pOutputPin = NULL;
151 This->m_pSrcFilter = NULL;
152 This->m_pParentFilter = NULL;
153 This->m_pOurInput = NULL;
154 This->m_pOurOutput = NULL;
155 This->m_pAll = NULL;
156 This->m_pImp = NULL;
158 This->Start = DS_Filter_Start;
159 This->Stop = DS_Filter_Stop;
161 for (;;)
163 GETCLASS func;
164 struct IClassFactory* factory = NULL;
165 struct IUnknown* object = NULL;
166 IEnumPins* enum_pins = 0;
167 IPin* array[256];
168 ULONG fetched;
169 HRESULT result;
170 unsigned int i;
171 static const uint16_t filter_name[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 };
173 This->m_iHandle = LoadLibraryA(dllname);
174 if (!This->m_iHandle)
176 em = "could not open DirectShow DLL";
177 break;
179 func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject");
180 if (!func)
182 em = "illegal or corrupt DirectShow DLL";
183 break;
185 result = func(id, &IID_IClassFactory, (void*)&factory);
186 if (result || !factory)
188 em = "no such class object";
189 break;
191 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void*)&object);
192 factory->vt->Release((IUnknown*)factory);
193 if (result || !object)
195 em = "class factory failure";
196 break;
198 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void*)&This->m_pFilter);
199 object->vt->Release((IUnknown*)object);
200 if (result || !This->m_pFilter)
202 em = "object does not provide IBaseFilter interface";
203 break;
206 graph = FilterGraphCreate();
207 result = This->m_pFilter->vt->JoinFilterGraph(This->m_pFilter, (IFilterGraph*)graph, filter_name);
209 // enumerate pins
210 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
211 if (result || !enum_pins)
213 em = "could not enumerate pins";
214 break;
217 enum_pins->vt->Reset(enum_pins);
218 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
219 enum_pins->vt->Release((IUnknown*)enum_pins);
220 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result);
222 for (i = 0; i < fetched; i++)
224 PIN_DIRECTION direction = -1;
225 array[i]->vt->QueryDirection(array[i], &direction);
226 if (!This->m_pInputPin && direction == PINDIR_INPUT)
228 This->m_pInputPin = array[i];
229 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin);
231 if (!This->m_pOutputPin && direction == PINDIR_OUTPUT)
233 This->m_pOutputPin = array[i];
234 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin);
236 array[i]->vt->Release((IUnknown*)(array[i]));
238 if (!This->m_pInputPin)
240 em = "could not find input pin";
241 break;
243 if (!This->m_pOutputPin)
245 em = "could not find output pin";
246 break;
248 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin,
249 &IID_IMemInputPin,
250 (void*)&This->m_pImp);
251 if (result)
253 em = "could not get IMemInputPin interface";
254 break;
257 This->m_pOurType = in_fmt;
258 This->m_pDestType = out_fmt;
259 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType);
260 if (result)
262 em = "source format is not accepted";
263 break;
265 This->m_pParentFilter = CBaseFilter2Create();
266 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter);
267 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter);
268 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput);
270 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin,
271 This->m_pOurInput,
272 This->m_pOurType);
273 if (result)
275 em = "could not connect to input pin";
276 break;
278 result = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll);
279 if (result || !This->m_pAll)
281 em="error getting IMemAllocator interface";
282 break;
285 //Seting allocator property according to our media type
286 props.cBuffers=1;
287 props.cbBuffer=This->m_pOurType->lSampleSize;
288 props.cbAlign=1;
289 props.cbPrefix=0;
290 This->m_pAll->vt->SetProperties(This->m_pAll, &props, &props1);
292 //Notify remote pin about choosed allocator
293 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0);
295 This->m_pOurOutput = COutputPinCreate(This->m_pDestType,DS_Filter_CopySample,pUserData);
297 result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin,
298 (IPin*) This->m_pOurOutput,
299 This->m_pDestType);
300 if (result)
302 em = "could not connect to output pin";
303 break;
306 init++;
307 break;
309 tempAll->vt->Release((IUnknown*)tempAll);
311 if (!init)
313 DS_Filter_Destroy(This);
314 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname);
315 This = 0;
317 return This;