Mercurial > mplayer.hg
annotate loader/dshow/DS_Filter.c @ 6833:a709a7662cd1
Add type= and fix a minor typing difference from ffmpeg
(now encoding (ffmpeg) and playback (mplayer) differ just on one of 1438lines - 0.1error in rounding ;)
author | atmos4 |
---|---|
date | Sun, 28 Jul 2002 21:56:18 +0000 |
parents | 4b0dd1ff6a20 |
children | 174e2a58b4cd |
rev | line source |
---|---|
1545 | 1 #include "DS_Filter.h" |
3056 | 2 #include "driver.h" |
3 #include "com.h" | |
6768
4b0dd1ff6a20
Warnings fix by Sylvain Petreolle <spetreolle@yahoo.fr>, fixed by me.
atmos4
parents:
3467
diff
changeset
|
4 #include "module.h" |
168 | 5 #include <stdio.h> |
6 #include <string.h> | |
1545 | 7 |
168 | 8 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); |
9 | |
1545 | 10 //extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD |
244 | 11 |
3056 | 12 static void DS_Filter_Start(DS_Filter* This) |
168 | 13 { |
3056 | 14 HRESULT hr; |
15 | |
3467 | 16 if (This->m_pAll) |
3056 | 17 return; |
18 | |
19 //Debug printf("DS_Filter_Start(%p)\n", This); | |
20 hr = This->m_pFilter->vt->Run(This->m_pFilter, 0); | |
21 if (hr != 0) | |
22 { | |
23 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); | |
24 } | |
25 hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); | |
26 | |
27 if (hr || !This->m_pAll) | |
28 { | |
29 Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr); | |
30 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); | |
31 return; | |
32 } | |
33 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); | |
168 | 34 } |
35 | |
3056 | 36 static void DS_Filter_Stop(DS_Filter* This) |
713 | 37 { |
3467 | 38 if (This->m_pAll) |
3056 | 39 { |
40 //Debug printf("DS_Filter_Stop(%p)\n", This); | |
3467 | 41 This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME |
3056 | 42 This->m_pAll->vt->Release((IUnknown*)This->m_pAll); |
43 This->m_pAll = 0; | |
44 } | |
1545 | 45 } |
46 | |
3056 | 47 void DS_Filter_Destroy(DS_Filter* This) |
1545 | 48 { |
3056 | 49 This->Stop(This); |
50 | |
51 if (This->m_pOurInput) | |
52 This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); | |
53 if (This->m_pInputPin) | |
54 This->m_pInputPin->vt->Disconnect(This->m_pInputPin); | |
55 if (This->m_pOutputPin) | |
56 This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); | |
57 if (This->m_pFilter) | |
58 This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); | |
59 if (This->m_pOutputPin) | |
60 This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); | |
61 if (This->m_pInputPin) | |
62 This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); | |
63 if (This->m_pImp) | |
64 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); | |
713 | 65 |
3056 | 66 if (This->m_pOurOutput) |
67 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); | |
68 if (This->m_pParentFilter) | |
3130 | 69 This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter); |
3056 | 70 if (This->m_pSrcFilter) |
71 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); | |
713 | 72 |
73 // FIXME - we are still leaving few things allocated! | |
3056 | 74 if (This->m_iHandle) |
75 FreeLibrary(This->m_iHandle); | |
76 | |
77 free(This); | |
78 | |
79 CodecRelease(); | |
713 | 80 } |
81 | |
3056 | 82 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, |
83 AM_MEDIA_TYPE* in_fmt, | |
84 AM_MEDIA_TYPE* out_fmt) | |
168 | 85 { |
3467 | 86 int init = 0; |
87 char eb[250]; | |
88 const char* em = NULL; | |
3056 | 89 DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); |
90 if (!This) | |
91 return NULL; | |
92 | |
93 CodecAlloc(); | |
94 | |
95 This->m_pFilter = NULL; | |
96 This->m_pInputPin = NULL; | |
97 This->m_pOutputPin = NULL; | |
98 This->m_pSrcFilter = NULL; | |
99 This->m_pParentFilter = NULL; | |
100 This->m_pOurInput = NULL; | |
101 This->m_pOurOutput = NULL; | |
102 This->m_pAll = NULL; | |
103 This->m_pImp = NULL; | |
104 | |
105 This->Start = DS_Filter_Start; | |
106 This->Stop = DS_Filter_Stop; | |
107 | |
108 for (;;) | |
168 | 109 { |
3056 | 110 HRESULT result; |
111 GETCLASS func; | |
112 struct IClassFactory* factory = NULL; | |
113 struct IUnknown* object = NULL; | |
114 IEnumPins* enum_pins = 0; | |
115 IPin* array[256]; | |
116 ULONG fetched; | |
117 unsigned int i; | |
118 | |
119 This->m_iHandle = LoadLibraryA(dllname); | |
120 if (!This->m_iHandle) | |
713 | 121 { |
3467 | 122 em = "could not open DirectShow DLL"; |
3056 | 123 break; |
713 | 124 } |
3056 | 125 func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject"); |
713 | 126 if (!func) |
127 { | |
3467 | 128 em = "illegal or corrupt DirectShow DLL"; |
3056 | 129 break; |
713 | 130 } |
1545 | 131 result = func(id, &IID_IClassFactory, (void**)&factory); |
132 if (result || !factory) | |
3056 | 133 { |
3467 | 134 em = "no such class object"; |
3056 | 135 break; |
136 } | |
1545 | 137 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); |
168 | 138 factory->vt->Release((IUnknown*)factory); |
1545 | 139 if (result || !object) |
3056 | 140 { |
3467 | 141 em = "class factory failure"; |
3056 | 142 break; |
143 } | |
144 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); | |
168 | 145 object->vt->Release((IUnknown*)object); |
3056 | 146 if (result || !This->m_pFilter) |
147 { | |
3467 | 148 em = "object does not have IBaseFilter interface"; |
3056 | 149 break; |
150 } | |
151 // enumerate pins | |
152 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); | |
153 if (result || !enum_pins) | |
154 { | |
3467 | 155 em = "could not enumerate pins"; |
3056 | 156 break; |
157 } | |
713 | 158 |
168 | 159 enum_pins->vt->Reset(enum_pins); |
1545 | 160 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); |
713 | 161 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); |
162 | |
3056 | 163 for (i = 0; i < fetched; i++) |
168 | 164 { |
713 | 165 int direction = -1; |
168 | 166 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); |
3056 | 167 if (!This->m_pInputPin && direction == 0) |
168 | 168 { |
3056 | 169 This->m_pInputPin = array[i]; |
170 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); | |
168 | 171 } |
3056 | 172 if (!This->m_pOutputPin && direction == 1) |
168 | 173 { |
3056 | 174 This->m_pOutputPin = array[i]; |
175 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin); | |
168 | 176 } |
177 array[i]->vt->Release((IUnknown*)(array[i])); | |
178 } | |
3056 | 179 if (!This->m_pInputPin) |
180 { | |
3467 | 181 em = "could not find input pin"; |
3056 | 182 break; |
183 } | |
184 if (!This->m_pOutputPin) | |
185 { | |
3467 | 186 em = "could not find output pin"; |
3056 | 187 break; |
188 } | |
189 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, | |
190 &IID_IMemInputPin, | |
191 (void**)&This->m_pImp); | |
713 | 192 if (result) |
3056 | 193 { |
3467 | 194 em = "could not get IMemInputPin interface"; |
3056 | 195 break; |
196 } | |
168 | 197 |
3056 | 198 This->m_pOurType = in_fmt; |
199 This->m_pDestType = out_fmt; | |
200 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); | |
713 | 201 if (result) |
3056 | 202 { |
3467 | 203 em = "source format is not accepted"; |
3056 | 204 break; |
205 } | |
206 This->m_pParentFilter = CBaseFilter2Create(); | |
207 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); | |
208 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); | |
209 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); | |
713 | 210 |
3056 | 211 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, |
212 This->m_pOurInput, | |
213 This->m_pOurType); | |
214 if (result) | |
215 { | |
3467 | 216 em = "could not connect to input pin"; |
3056 | 217 break; |
218 } | |
219 | |
220 This->m_pOurOutput = COutputPinCreate(This->m_pDestType); | |
221 | |
222 result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, | |
223 (IPin*) This->m_pOurOutput, | |
224 This->m_pDestType); | |
713 | 225 if (result) |
1545 | 226 { |
3467 | 227 em = "could not connect to output pin"; |
3056 | 228 break; |
1545 | 229 } |
230 | |
231 printf("Using DirectShow codec: %s\n", dllname); | |
3467 | 232 init++; |
3056 | 233 break; |
168 | 234 } |
3056 | 235 |
3467 | 236 if (!init) |
168 | 237 { |
3056 | 238 DS_Filter_Destroy(This); |
3467 | 239 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em, dllname); |
3056 | 240 This = 0; |
168 | 241 } |
3056 | 242 return This; |
168 | 243 } |