Mercurial > mplayer.hg
annotate loader/dshow/DS_Filter.c @ 16647:e26e80f3031c
synced with 1.30
author | gabrov |
---|---|
date | Mon, 03 Oct 2005 12:00:28 +0000 |
parents | f5537cc95b02 |
children | 0783dd397f74 |
rev | line source |
---|---|
15166
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
1 /* |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
2 * Modified for use with MPlayer, detailed CVS changelog at |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
3 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
4 * $Id$ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
5 */ |
f5537cc95b02
Mark modified imported files as such to comply with GPL ¡ø2a.
diego
parents:
9967
diff
changeset
|
6 |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
7 #include "config.h" |
1545 | 8 #include "DS_Filter.h" |
3056 | 9 #include "driver.h" |
10 #include "com.h" | |
168 | 11 #include <stdio.h> |
12 #include <string.h> | |
7386 | 13 #include <stdlib.h> |
14 #include "win32.h" // printf macro | |
1545 | 15 |
168 | 16 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); |
17 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
18 #ifndef WIN32_LOADER |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
19 const GUID IID_IUnknown = |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
20 { |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
21 0x00000000, 0x0000, 0x0000, |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
22 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
23 }; |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
24 const GUID IID_IClassFactory = |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
25 { |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
26 0x00000001, 0x0000, 0x0000, |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
27 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
28 }; |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
29 |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
30 HRESULT STDCALL CoInitialize(LPVOID pvReserved); |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
31 void STDCALL CoUninitialize(void); |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
32 #endif |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
33 |
8292 | 34 //void trapbug(); |
244 | 35 |
3056 | 36 static void DS_Filter_Start(DS_Filter* This) |
168 | 37 { |
3056 | 38 HRESULT hr; |
39 | |
3467 | 40 if (This->m_pAll) |
3056 | 41 return; |
42 | |
43 //Debug printf("DS_Filter_Start(%p)\n", This); | |
8292 | 44 hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0); |
3056 | 45 if (hr != 0) |
46 { | |
47 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); | |
48 } | |
49 hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); | |
50 | |
51 if (hr || !This->m_pAll) | |
52 { | |
53 Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr); | |
54 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); | |
55 return; | |
56 } | |
57 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); | |
168 | 58 } |
59 | |
3056 | 60 static void DS_Filter_Stop(DS_Filter* This) |
713 | 61 { |
3467 | 62 if (This->m_pAll) |
3056 | 63 { |
64 //Debug printf("DS_Filter_Stop(%p)\n", This); | |
3467 | 65 This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME |
3056 | 66 This->m_pAll->vt->Release((IUnknown*)This->m_pAll); |
67 This->m_pAll = 0; | |
68 } | |
1545 | 69 } |
70 | |
3056 | 71 void DS_Filter_Destroy(DS_Filter* This) |
1545 | 72 { |
3056 | 73 This->Stop(This); |
74 | |
75 if (This->m_pOurInput) | |
76 This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); | |
77 if (This->m_pInputPin) | |
78 This->m_pInputPin->vt->Disconnect(This->m_pInputPin); | |
79 if (This->m_pOutputPin) | |
80 This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); | |
81 if (This->m_pFilter) | |
82 This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); | |
83 if (This->m_pOutputPin) | |
84 This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); | |
85 if (This->m_pInputPin) | |
86 This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); | |
87 if (This->m_pImp) | |
88 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); | |
713 | 89 |
3056 | 90 if (This->m_pOurOutput) |
91 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); | |
92 if (This->m_pParentFilter) | |
3130 | 93 This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter); |
3056 | 94 if (This->m_pSrcFilter) |
95 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); | |
713 | 96 |
97 // FIXME - we are still leaving few things allocated! | |
3056 | 98 if (This->m_iHandle) |
8292 | 99 FreeLibrary((unsigned)This->m_iHandle); |
3056 | 100 |
101 free(This); | |
102 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
103 #ifdef WIN32_LOADER |
3056 | 104 CodecRelease(); |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
105 #else |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
106 CoUninitialize(); |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
107 #endif |
713 | 108 } |
109 | |
3056 | 110 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, |
111 AM_MEDIA_TYPE* in_fmt, | |
112 AM_MEDIA_TYPE* out_fmt) | |
168 | 113 { |
3467 | 114 int init = 0; |
7472
c4434bdf6e51
tons of warning fixes, also some 10l bugfixes, including Dominik's PVA bug
arpi
parents:
7386
diff
changeset
|
115 // char eb[250]; |
3467 | 116 const char* em = NULL; |
8292 | 117 HRESULT result; |
3056 | 118 DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); |
119 if (!This) | |
120 return NULL; | |
121 | |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
122 #ifdef WIN32_LOADER |
3056 | 123 CodecAlloc(); |
9967
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
124 #else |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
125 CoInitialize(0L); |
b0d1b415320c
cygwin support patch by Sascha Sommer and some fixes by me
alex
parents:
8292
diff
changeset
|
126 #endif |
3056 | 127 |
128 This->m_pFilter = NULL; | |
129 This->m_pInputPin = NULL; | |
130 This->m_pOutputPin = NULL; | |
131 This->m_pSrcFilter = NULL; | |
132 This->m_pParentFilter = NULL; | |
133 This->m_pOurInput = NULL; | |
134 This->m_pOurOutput = NULL; | |
135 This->m_pAll = NULL; | |
136 This->m_pImp = NULL; | |
137 | |
138 This->Start = DS_Filter_Start; | |
139 This->Stop = DS_Filter_Stop; | |
140 | |
141 for (;;) | |
168 | 142 { |
3056 | 143 GETCLASS func; |
144 struct IClassFactory* factory = NULL; | |
145 struct IUnknown* object = NULL; | |
146 IEnumPins* enum_pins = 0; | |
147 IPin* array[256]; | |
148 ULONG fetched; | |
149 unsigned int i; | |
150 | |
151 This->m_iHandle = LoadLibraryA(dllname); | |
152 if (!This->m_iHandle) | |
713 | 153 { |
3467 | 154 em = "could not open DirectShow DLL"; |
3056 | 155 break; |
713 | 156 } |
8292 | 157 func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); |
713 | 158 if (!func) |
159 { | |
3467 | 160 em = "illegal or corrupt DirectShow DLL"; |
3056 | 161 break; |
713 | 162 } |
1545 | 163 result = func(id, &IID_IClassFactory, (void**)&factory); |
164 if (result || !factory) | |
3056 | 165 { |
3467 | 166 em = "no such class object"; |
3056 | 167 break; |
168 } | |
1545 | 169 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); |
168 | 170 factory->vt->Release((IUnknown*)factory); |
1545 | 171 if (result || !object) |
3056 | 172 { |
3467 | 173 em = "class factory failure"; |
3056 | 174 break; |
175 } | |
176 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); | |
168 | 177 object->vt->Release((IUnknown*)object); |
3056 | 178 if (result || !This->m_pFilter) |
179 { | |
7386 | 180 em = "object does not provide IBaseFilter interface"; |
3056 | 181 break; |
182 } | |
183 // enumerate pins | |
184 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); | |
185 if (result || !enum_pins) | |
186 { | |
3467 | 187 em = "could not enumerate pins"; |
3056 | 188 break; |
189 } | |
713 | 190 |
168 | 191 enum_pins->vt->Reset(enum_pins); |
1545 | 192 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); |
8292 | 193 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); |
713 | 194 |
3056 | 195 for (i = 0; i < fetched; i++) |
168 | 196 { |
713 | 197 int direction = -1; |
168 | 198 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); |
3056 | 199 if (!This->m_pInputPin && direction == 0) |
168 | 200 { |
3056 | 201 This->m_pInputPin = array[i]; |
202 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); | |
168 | 203 } |
3056 | 204 if (!This->m_pOutputPin && direction == 1) |
168 | 205 { |
3056 | 206 This->m_pOutputPin = array[i]; |
207 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin); | |
168 | 208 } |
209 array[i]->vt->Release((IUnknown*)(array[i])); | |
210 } | |
3056 | 211 if (!This->m_pInputPin) |
212 { | |
3467 | 213 em = "could not find input pin"; |
3056 | 214 break; |
215 } | |
216 if (!This->m_pOutputPin) | |
217 { | |
3467 | 218 em = "could not find output pin"; |
3056 | 219 break; |
220 } | |
221 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, | |
222 &IID_IMemInputPin, | |
223 (void**)&This->m_pImp); | |
713 | 224 if (result) |
3056 | 225 { |
3467 | 226 em = "could not get IMemInputPin interface"; |
3056 | 227 break; |
228 } | |
168 | 229 |
3056 | 230 This->m_pOurType = in_fmt; |
231 This->m_pDestType = out_fmt; | |
232 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); | |
713 | 233 if (result) |
3056 | 234 { |
3467 | 235 em = "source format is not accepted"; |
3056 | 236 break; |
237 } | |
238 This->m_pParentFilter = CBaseFilter2Create(); | |
239 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); | |
240 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); | |
241 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); | |
713 | 242 |
3056 | 243 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, |
244 This->m_pOurInput, | |
245 This->m_pOurType); | |
246 if (result) | |
247 { | |
3467 | 248 em = "could not connect to input pin"; |
3056 | 249 break; |
250 } | |
251 | |
252 This->m_pOurOutput = COutputPinCreate(This->m_pDestType); | |
253 | |
254 result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, | |
255 (IPin*) This->m_pOurOutput, | |
256 This->m_pDestType); | |
713 | 257 if (result) |
1545 | 258 { |
3467 | 259 em = "could not connect to output pin"; |
3056 | 260 break; |
1545 | 261 } |
262 | |
3467 | 263 init++; |
3056 | 264 break; |
168 | 265 } |
3056 | 266 |
3467 | 267 if (!init) |
168 | 268 { |
3056 | 269 DS_Filter_Destroy(This); |
8292 | 270 printf("Warning: DS_Filter() %s. (DLL=%.200s, r=0x%x)\n", em, dllname, result); |
3056 | 271 This = 0; |
168 | 272 } |
3056 | 273 return This; |
168 | 274 } |