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 }