Mercurial > mplayer.hg
annotate loader/dshow/DS_Filter.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +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 } |