Mercurial > mplayer.hg
comparison loader/dshow/DS_Filter.c @ 3056:213b35f84cf3
C++ -> C (import from avifile cvs)
author | arpi |
---|---|
date | Wed, 21 Nov 2001 19:12:39 +0000 |
parents | b95069f5ed07 |
children | 623cdb771e97 |
comparison
equal
deleted
inserted
replaced
3055:38df49b91824 | 3056:213b35f84cf3 |
---|---|
1 #include "DS_Filter.h" | 1 #include "DS_Filter.h" |
2 //#include "../loader/loader.h" | 2 #include "driver.h" |
3 #include "libwin32.h" | 3 #include "com.h" |
4 //#include <string> | |
5 #include <stdio.h> | 4 #include <stdio.h> |
6 #include <string.h> | 5 #include <string.h> |
7 | 6 |
8 #define __MODULE__ "DirectShow generic filter" | |
9 | |
10 using namespace std; | |
11 | |
12 extern "C" int STDCALL expLoadLibraryA(const char*); | |
13 | |
14 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); | 7 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); |
15 | 8 |
16 //extern "C" int STDCALL LoadLibraryA(const char*); | |
17 //extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD | 9 //extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD |
18 //extern "C" int STDCALL FreeLibrary(int); | 10 |
19 | 11 static void DS_Filter_Start(DS_Filter* This) |
20 DS_Filter::DS_Filter() | 12 { |
21 { | 13 HRESULT hr; |
22 m_iHandle = 0; | 14 |
23 m_pFilter = 0; | 15 if (This->m_iState != 1) |
24 m_pInputPin = 0; | |
25 m_pOutputPin = 0; | |
26 m_pSrcFilter = 0; | |
27 m_pParentFilter = 0; | |
28 m_pOurInput = 0; | |
29 m_pOurOutput = 0; | |
30 m_pAll = 0; | |
31 m_pImp = 0; | |
32 m_iState = 0; | |
33 } | |
34 | |
35 DS_Filter::~DS_Filter() | |
36 { | |
37 //cout << "Destruction of DS_FILTER" << endl; | |
38 Stop(); | |
39 destroy(); | |
40 //cout << "Destruction of DS_FILTER done" << endl; | |
41 } | |
42 | |
43 void DS_Filter::destroy() | |
44 { | |
45 if (m_iState == 0) | |
46 return; | 16 return; |
47 m_iState = 0; | 17 |
48 | 18 //Debug printf("DS_Filter_Start(%p)\n", This); |
49 if (m_pOurInput) | 19 hr = This->m_pFilter->vt->Run(This->m_pFilter, 0); |
50 m_pOurInput->vt->Release((IUnknown*)m_pOurInput); | 20 if (hr != 0) |
51 if (m_pInputPin) | 21 { |
52 m_pInputPin->vt->Disconnect(m_pInputPin); | 22 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); |
53 if (m_pOutputPin) | 23 } |
54 m_pOutputPin->vt->Disconnect(m_pOutputPin); | 24 hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); |
55 if (m_pFilter) | 25 |
56 m_pFilter->vt->Release((IUnknown*)m_pFilter); | 26 if (hr || !This->m_pAll) |
57 if (m_pOutputPin) | 27 { |
58 m_pOutputPin->vt->Release((IUnknown*)m_pOutputPin); | 28 Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr); |
59 if (m_pInputPin) | 29 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); |
60 m_pInputPin->vt->Release((IUnknown*)m_pInputPin); | 30 return; |
61 if (m_pImp) | 31 } |
62 m_pImp->vt->Release((IUnknown*)m_pImp); | 32 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); |
63 | 33 This->m_iState = 2; |
64 delete m_pOurOutput; | 34 } |
65 delete m_pParentFilter; | 35 |
66 delete m_pSrcFilter; | 36 static void DS_Filter_Stop(DS_Filter* This) |
37 { | |
38 if (This->m_iState == 2) | |
39 { | |
40 This->m_iState = 1; | |
41 //Debug printf("DS_Filter_Stop(%p)\n", This); | |
42 if (This->m_pFilter) | |
43 { | |
44 //printf("vt: %p\n", m_pFilter->vt); | |
45 //printf("vtstop %p\n", m_pFilter->vt->Stop); | |
46 This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME | |
47 } | |
48 else | |
49 printf("WARNING: DS_Filter::Stop() m_pFilter is NULL!\n"); | |
50 This->m_pAll->vt->Release((IUnknown*)This->m_pAll); | |
51 This->m_pAll = 0; | |
52 } | |
53 } | |
54 | |
55 void DS_Filter_Destroy(DS_Filter* This) | |
56 { | |
57 This->Stop(This); | |
58 | |
59 This->m_iState = 0; | |
60 | |
61 if (This->m_pOurInput) | |
62 This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); | |
63 if (This->m_pInputPin) | |
64 This->m_pInputPin->vt->Disconnect(This->m_pInputPin); | |
65 if (This->m_pOutputPin) | |
66 This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); | |
67 if (This->m_pFilter) | |
68 This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); | |
69 if (This->m_pOutputPin) | |
70 This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); | |
71 if (This->m_pInputPin) | |
72 This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); | |
73 if (This->m_pImp) | |
74 This->m_pImp->vt->Release((IUnknown*)This->m_pImp); | |
75 | |
76 if (This->m_pOurOutput) | |
77 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); | |
78 if (This->m_pParentFilter) | |
79 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pParentFilter); | |
80 if (This->m_pSrcFilter) | |
81 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); | |
67 | 82 |
68 // FIXME - we are still leaving few things allocated! | 83 // FIXME - we are still leaving few things allocated! |
69 if (m_iHandle) | 84 if (This->m_iHandle) |
70 FreeLibrary(m_iHandle); | 85 FreeLibrary(This->m_iHandle); |
71 } | 86 |
72 | 87 free(This); |
73 void DS_Filter::Create(const char* dllname, const GUID* id, | 88 |
74 AM_MEDIA_TYPE* in_fmt, | 89 CodecRelease(); |
75 AM_MEDIA_TYPE* out_fmt) | 90 } |
76 { | 91 |
77 try | 92 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, |
78 { | 93 AM_MEDIA_TYPE* in_fmt, |
79 m_iHandle = expLoadLibraryA(dllname); | 94 AM_MEDIA_TYPE* out_fmt) |
80 if (!m_iHandle) | 95 { |
81 { | 96 DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); |
82 char e[256]; | 97 if (!This) |
83 snprintf((char *)&e[0], 256, "Could not open DirectShow DLL: %.200s", dllname); | 98 return NULL; |
84 throw FATAL(e); | 99 |
85 } | 100 CodecAlloc(); |
86 GETCLASS func = (GETCLASS)GetProcAddress(m_iHandle, "DllGetClassObject"); | 101 |
102 This->m_pFilter = NULL; | |
103 This->m_pInputPin = NULL; | |
104 This->m_pOutputPin = NULL; | |
105 This->m_pSrcFilter = NULL; | |
106 This->m_pParentFilter = NULL; | |
107 This->m_pOurInput = NULL; | |
108 This->m_pOurOutput = NULL; | |
109 This->m_pAll = NULL; | |
110 This->m_pImp = NULL; | |
111 This->m_iState = 0; | |
112 | |
113 This->Start = DS_Filter_Start; | |
114 This->Stop = DS_Filter_Stop; | |
115 | |
116 for (;;) | |
117 { | |
118 HRESULT result; | |
119 GETCLASS func; | |
120 struct IClassFactory* factory = NULL; | |
121 struct IUnknown* object = NULL; | |
122 IEnumPins* enum_pins = 0; | |
123 IPin* array[256]; | |
124 ULONG fetched; | |
125 unsigned int i; | |
126 | |
127 This->m_iHandle = LoadLibraryA(dllname); | |
128 if (!This->m_iHandle) | |
129 { | |
130 printf("Could not open DirectShow DLL: %.200s\n", dllname); | |
131 break; | |
132 } | |
133 func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject"); | |
87 if (!func) | 134 if (!func) |
88 { | 135 { |
89 char e[256]; | 136 printf("Illegal or corrupt DirectShow DLL: %.200s\n", dllname); |
90 snprintf((char *)&e[0], 256, "Illegal or corrupt DirectShow DLL: %.200s", dllname); | 137 break; |
91 throw FATAL(e); | 138 } |
92 } | |
93 | |
94 HRESULT result; | |
95 IClassFactory* factory = 0; | |
96 result = func(id, &IID_IClassFactory, (void**)&factory); | 139 result = func(id, &IID_IClassFactory, (void**)&factory); |
97 if (result || !factory) | 140 if (result || !factory) |
98 throw FATAL("No such class object");; | 141 { |
99 | 142 printf("No such class object\n"); |
100 IUnknown* object = 0; | 143 break; |
144 } | |
101 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); | 145 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); |
102 factory->vt->Release((IUnknown*)factory); | 146 factory->vt->Release((IUnknown*)factory); |
103 if (result || !object) | 147 if (result || !object) |
104 throw FATAL("Class factory failure"); | 148 { |
105 | 149 printf("Class factory failure\n"); |
106 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&m_pFilter); | 150 break; |
151 } | |
152 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); | |
107 object->vt->Release((IUnknown*)object); | 153 object->vt->Release((IUnknown*)object); |
108 if (result || !m_pFilter) | 154 if (result || !This->m_pFilter) |
109 throw FATAL("Object does not have IBaseFilter interface"); | 155 { |
110 | 156 printf("Object does not have IBaseFilter interface\n"); |
111 IEnumPins* enum_pins = 0; | 157 break; |
158 } | |
112 // enumerate pins | 159 // enumerate pins |
113 result = m_pFilter->vt->EnumPins(m_pFilter, &enum_pins); | 160 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); |
114 if (result || !enum_pins) | 161 if (result || !enum_pins) |
115 throw FATAL("Could not enumerate pins"); | 162 { |
116 | 163 printf("Could not enumerate pins\n"); |
117 IPin* array[256]; | 164 break; |
118 ULONG fetched; | 165 } |
166 | |
119 enum_pins->vt->Reset(enum_pins); | 167 enum_pins->vt->Reset(enum_pins); |
120 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); | 168 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); |
121 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); | 169 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); |
122 | 170 |
123 for (unsigned i = 0; i < fetched; i++) | 171 for (i = 0; i < fetched; i++) |
124 { | 172 { |
125 int direction = -1; | 173 int direction = -1; |
126 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); | 174 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); |
127 if (!m_pInputPin && direction == 0) | 175 if (!This->m_pInputPin && direction == 0) |
128 { | 176 { |
129 m_pInputPin = array[i]; | 177 This->m_pInputPin = array[i]; |
130 m_pInputPin->vt->AddRef((IUnknown*)m_pInputPin); | 178 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); |
131 } | 179 } |
132 if (!m_pOutputPin && direction == 1) | 180 if (!This->m_pOutputPin && direction == 1) |
133 { | 181 { |
134 m_pOutputPin = array[i]; | 182 This->m_pOutputPin = array[i]; |
135 m_pOutputPin->vt->AddRef((IUnknown*)m_pOutputPin); | 183 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin); |
136 } | 184 } |
137 array[i]->vt->Release((IUnknown*)(array[i])); | 185 array[i]->vt->Release((IUnknown*)(array[i])); |
138 } | 186 } |
139 if (!m_pInputPin) | 187 if (!This->m_pInputPin) |
140 throw FATAL("Input pin not found"); | 188 { |
141 if (!m_pOutputPin) | 189 printf("Input pin not found\n"); |
142 throw FATAL("Output pin not found"); | 190 break; |
143 | 191 } |
144 result = m_pInputPin->vt->QueryInterface((IUnknown*)m_pInputPin, | 192 if (!This->m_pOutputPin) |
145 &IID_IMemInputPin, | 193 { |
146 (void**)&m_pImp); | 194 printf("Output pin not found\n"); |
147 if (result) | 195 break; |
148 throw FATAL("Error getting IMemInputPin interface"); | 196 } |
149 m_pOurType = in_fmt; | 197 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, |
150 m_pDestType = out_fmt; | 198 &IID_IMemInputPin, |
151 result = m_pInputPin->vt->QueryAccept(m_pInputPin, m_pOurType); | 199 (void**)&This->m_pImp); |
152 if (result) | 200 if (result) |
153 throw FATAL("Source format is not accepted"); | 201 { |
154 | 202 printf("Error getting IMemInputPin interface\n"); |
155 m_pParentFilter = new CBaseFilter2; | 203 break; |
156 m_pSrcFilter = new CBaseFilter(*m_pOurType, m_pParentFilter); | 204 } |
157 m_pOurInput = m_pSrcFilter->GetPin(); | 205 |
158 m_pOurInput->vt->AddRef((IUnknown*)m_pOurInput); | 206 This->m_pOurType = in_fmt; |
159 | 207 This->m_pDestType = out_fmt; |
160 result = m_pInputPin->vt->ReceiveConnection(m_pInputPin, | 208 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); |
161 m_pOurInput, | 209 if (result) |
162 m_pOurType); | 210 { |
163 if (result) | 211 printf("Source format is not accepted\n"); |
164 throw FATAL("Error connecting to input pin"); | 212 break; |
165 | 213 } |
166 m_pOurOutput = new COutputPin(*m_pDestType); | 214 This->m_pParentFilter = CBaseFilter2Create(); |
167 | 215 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); |
168 //extern void trapbug(); | 216 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); |
169 //trapbug(); | 217 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); |
170 result = m_pOutputPin->vt->ReceiveConnection(m_pOutputPin, | 218 |
171 m_pOurOutput, | 219 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, |
172 m_pDestType); | 220 This->m_pOurInput, |
221 This->m_pOurType); | |
222 if (result) | |
223 { | |
224 printf("Error connecting to input pin\n"); | |
225 break; | |
226 } | |
227 | |
228 This->m_pOurOutput = COutputPinCreate(This->m_pDestType); | |
229 | |
230 result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, | |
231 (IPin*) This->m_pOurOutput, | |
232 This->m_pDestType); | |
173 if (result) | 233 if (result) |
174 { | 234 { |
175 //printf("Tracking ACELP %d 0%x\n", result); | 235 //printf("Tracking ACELP %d 0%x\n", result); |
176 throw FATAL("Error connecting to output pin"); | 236 printf("Error connecting to output pin\n"); |
237 break; | |
177 } | 238 } |
178 | 239 |
179 printf("Using DirectShow codec: %s\n", dllname); | 240 printf("Using DirectShow codec: %s\n", dllname); |
180 m_iState = 1; | 241 This->m_iState = 1; |
181 } | 242 break; |
182 catch (FatalError e) | 243 } |
183 { | 244 |
184 //e.PrintAll(); | 245 if (This->m_iState != 1) |
185 destroy(); | 246 { |
186 throw; | 247 DS_Filter_Destroy(This); |
187 } | 248 This = 0; |
188 } | 249 } |
189 | 250 return This; |
190 void DS_Filter::Start() | 251 } |
191 { | |
192 if (m_iState != 1) | |
193 return; | |
194 | |
195 HRESULT hr=m_pFilter->vt->Run(m_pFilter, 0); | |
196 if (hr != 0) | |
197 { | |
198 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); | |
199 } | |
200 hr = m_pImp->vt->GetAllocator(m_pImp, &m_pAll); | |
201 if (hr) | |
202 { | |
203 Debug printf("Error getting IMemAllocator interface %x\n", (int)hr); | |
204 m_pImp->vt->Release((IUnknown*)m_pImp); | |
205 return; | |
206 } | |
207 m_pImp->vt->NotifyAllocator(m_pImp, m_pAll, 0); | |
208 m_iState = 2; | |
209 } | |
210 | |
211 void DS_Filter::Stop() | |
212 { | |
213 if (m_iState == 2) | |
214 { | |
215 m_pAll->vt->Release((IUnknown*)m_pAll); | |
216 if (m_pFilter) | |
217 m_pFilter->vt->Stop(m_pFilter); // causes weird crash ??? FIXME | |
218 else | |
219 printf("m_pFilter is NULL!\n"); | |
220 m_pAll = 0; | |
221 m_iState = 1; | |
222 } | |
223 } |