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