add kega video binary codec for fourcc kgv1
[mplayer/glamo.git] / loader / dshow / DS_Filter.c
blob5fb1ec73dc10817084278067966426749d97c8f3
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 "drv.h"
9 #include "com.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include "win32.h" // printf macro
15 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
17 #ifndef WIN32_LOADER
18 const GUID IID_IUnknown =
20 0x00000000, 0x0000, 0x0000,
21 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
23 const GUID IID_IClassFactory =
25 0x00000001, 0x0000, 0x0000,
26 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
29 HRESULT STDCALL CoInitialize(LPVOID pvReserved);
30 void STDCALL CoUninitialize(void);
31 #endif
33 static void DS_Filter_Start(DS_Filter* This)
35 HRESULT hr;
37 //Debug printf("DS_Filter_Start(%p)\n", This);
38 hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0);
39 if (hr != 0)
41 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr);
45 static void DS_Filter_Stop(DS_Filter* This)
47 if (This->m_pAll)
49 //Debug printf("DS_Filter_Stop(%p)\n", This);
50 This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME
51 This->m_pAll->vt->Release((IUnknown*)This->m_pAll);
52 This->m_pAll = 0;
56 void DS_Filter_Destroy(DS_Filter* This)
58 This->Stop(This);
60 if (This->m_pOurInput)
61 This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput);
62 if (This->m_pInputPin)
63 This->m_pInputPin->vt->Disconnect(This->m_pInputPin);
64 if (This->m_pOutputPin)
65 This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin);
66 if (This->m_pFilter)
67 This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter);
68 if (This->m_pOutputPin)
69 This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin);
70 if (This->m_pInputPin)
71 This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin);
72 if (This->m_pImp)
73 This->m_pImp->vt->Release((IUnknown*)This->m_pImp);
75 if (This->m_pOurOutput)
76 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput);
77 if (This->m_pParentFilter)
78 This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter);
79 if (This->m_pSrcFilter)
80 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter);
82 // FIXME - we are still leaving few things allocated!
83 if (This->m_iHandle)
84 FreeLibrary((unsigned)This->m_iHandle);
86 free(This);
88 #ifdef WIN32_LOADER
89 CodecRelease();
90 #else
91 CoUninitialize();
92 #endif
95 static HRESULT STDCALL DS_Filter_CopySample(void* pUserData,IMediaSample* pSample){
96 BYTE* pointer;
97 int len;
98 SampleProcUserData* pData=pUserData;
99 Debug printf("CopySample called(%p,%p)\n",pSample,pUserData);
100 if (pSample->vt->GetPointer(pSample, &pointer))
101 return 1;
102 len = pSample->vt->GetActualDataLength(pSample);
103 if (len == 0)
104 len = pSample->vt->GetSize(pSample);//for iv50
106 pData->frame_pointer = pointer;
107 pData->frame_size = len;
109 FILE* file=fopen("./uncompr.bmp", "wb");
110 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
111 *(int*)(&head[2])=len+0x36;
112 fwrite(head, 14, 1, file);
113 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
114 fwrite(pointer, len, 1, file);
115 fclose(file);
117 return 0;
120 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
121 AM_MEDIA_TYPE* in_fmt,
122 AM_MEDIA_TYPE* out_fmt,SampleProcUserData* pUserData)
124 int init = 0;
125 // char eb[250];
126 const char* em = NULL;
127 MemAllocator* tempAll;
128 ALLOCATOR_PROPERTIES props,props1;
129 DS_Filter* This = malloc(sizeof(DS_Filter));
130 if (!This)
131 return NULL;
133 #ifdef WIN32_LOADER
134 CodecAlloc();
135 #else
136 CoInitialize(0L);
137 #endif
140 tempAll is not used anywhere.
141 MemAllocatorCreate() is called to ensure that RegisterComObject for IMemoryAllocator
142 will be called before possible call
143 to CoCreateInstance(...,&IID_IMemoryAllocator,...) from binary codec.
145 tempAll=MemAllocatorCreate();
146 This->m_pFilter = NULL;
147 This->m_pInputPin = NULL;
148 This->m_pOutputPin = NULL;
149 This->m_pSrcFilter = NULL;
150 This->m_pParentFilter = NULL;
151 This->m_pOurInput = NULL;
152 This->m_pOurOutput = NULL;
153 This->m_pAll = NULL;
154 This->m_pImp = NULL;
156 This->Start = DS_Filter_Start;
157 This->Stop = DS_Filter_Stop;
159 for (;;)
161 GETCLASS func;
162 struct IClassFactory* factory = NULL;
163 struct IUnknown* object = NULL;
164 IEnumPins* enum_pins = 0;
165 IPin* array[256];
166 ULONG fetched;
167 HRESULT result;
168 unsigned int i;
170 This->m_iHandle = LoadLibraryA(dllname);
171 if (!This->m_iHandle)
173 em = "could not open DirectShow DLL";
174 break;
176 func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject");
177 if (!func)
179 em = "illegal or corrupt DirectShow DLL";
180 break;
182 result = func(id, &IID_IClassFactory, (void*)&factory);
183 if (result || !factory)
185 em = "no such class object";
186 break;
188 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void*)&object);
189 factory->vt->Release((IUnknown*)factory);
190 if (result || !object)
192 em = "class factory failure";
193 break;
195 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void*)&This->m_pFilter);
196 object->vt->Release((IUnknown*)object);
197 if (result || !This->m_pFilter)
199 em = "object does not provide IBaseFilter interface";
200 break;
202 // enumerate pins
203 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
204 if (result || !enum_pins)
206 em = "could not enumerate pins";
207 break;
210 enum_pins->vt->Reset(enum_pins);
211 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
212 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result);
214 for (i = 0; i < fetched; i++)
216 PIN_DIRECTION direction = -1;
217 array[i]->vt->QueryDirection(array[i], &direction);
218 if (!This->m_pInputPin && direction == PINDIR_INPUT)
220 This->m_pInputPin = array[i];
221 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin);
223 if (!This->m_pOutputPin && direction == PINDIR_OUTPUT)
225 This->m_pOutputPin = array[i];
226 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin);
228 array[i]->vt->Release((IUnknown*)(array[i]));
230 if (!This->m_pInputPin)
232 em = "could not find input pin";
233 break;
235 if (!This->m_pOutputPin)
237 em = "could not find output pin";
238 break;
240 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin,
241 &IID_IMemInputPin,
242 (void*)&This->m_pImp);
243 if (result)
245 em = "could not get IMemInputPin interface";
246 break;
249 This->m_pOurType = in_fmt;
250 This->m_pDestType = out_fmt;
251 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType);
252 if (result)
254 em = "source format is not accepted";
255 break;
257 This->m_pParentFilter = CBaseFilter2Create();
258 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter);
259 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter);
260 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput);
262 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin,
263 This->m_pOurInput,
264 This->m_pOurType);
265 if (result)
267 em = "could not connect to input pin";
268 break;
270 result = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll);
271 if (result || !This->m_pAll)
273 em="error getting IMemAllocator interface";
274 break;
277 //Seting allocator property according to our media type
278 props.cBuffers=1;
279 props.cbBuffer=This->m_pOurType->lSampleSize;
280 props.cbAlign=1;
281 props.cbPrefix=0;
282 This->m_pAll->vt->SetProperties(This->m_pAll, &props, &props1);
284 //Notify remote pin about choosed allocator
285 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0);
287 This->m_pOurOutput = COutputPinCreate(This->m_pDestType,DS_Filter_CopySample,pUserData);
289 result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin,
290 (IPin*) This->m_pOurOutput,
291 This->m_pDestType);
292 if (result)
294 em = "could not connect to output pin";
295 break;
298 init++;
299 break;
301 tempAll->vt->Release(tempAll);
303 if (!init)
305 DS_Filter_Destroy(This);
306 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname);
307 This = 0;
309 return This;