1545
|
1 #include "DS_Filter.h"
|
3056
|
2 #include "driver.h"
|
|
3 #include "com.h"
|
168
|
4 #include <stdio.h>
|
|
5 #include <string.h>
|
1545
|
6
|
168
|
7 typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**);
|
|
8
|
1545
|
9 //extern "C" STDCALL void* GetProcAddress(int, const char*); // STDCALL has to be first NetBSD
|
244
|
10
|
3056
|
11 static void DS_Filter_Start(DS_Filter* This)
|
168
|
12 {
|
3056
|
13 HRESULT hr;
|
|
14
|
|
15 if (This->m_iState != 1)
|
|
16 return;
|
|
17
|
|
18 //Debug printf("DS_Filter_Start(%p)\n", This);
|
|
19 hr = This->m_pFilter->vt->Run(This->m_pFilter, 0);
|
|
20 if (hr != 0)
|
|
21 {
|
|
22 Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr);
|
|
23 }
|
|
24 hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll);
|
|
25
|
|
26 if (hr || !This->m_pAll)
|
|
27 {
|
|
28 Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr);
|
|
29 This->m_pImp->vt->Release((IUnknown*)This->m_pImp);
|
|
30 return;
|
|
31 }
|
|
32 This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0);
|
|
33 This->m_iState = 2;
|
168
|
34 }
|
|
35
|
3056
|
36 static void DS_Filter_Stop(DS_Filter* This)
|
713
|
37 {
|
3056
|
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 }
|
1545
|
53 }
|
|
54
|
3056
|
55 void DS_Filter_Destroy(DS_Filter* This)
|
1545
|
56 {
|
3056
|
57 This->Stop(This);
|
|
58
|
|
59 This->m_iState = 0;
|
713
|
60
|
3056
|
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);
|
713
|
75
|
3056
|
76 if (This->m_pOurOutput)
|
|
77 This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput);
|
|
78 if (This->m_pParentFilter)
|
3130
|
79 This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter);
|
3056
|
80 if (This->m_pSrcFilter)
|
|
81 This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter);
|
713
|
82
|
|
83 // FIXME - we are still leaving few things allocated!
|
3056
|
84 if (This->m_iHandle)
|
|
85 FreeLibrary(This->m_iHandle);
|
|
86
|
|
87 free(This);
|
|
88
|
|
89 CodecRelease();
|
713
|
90 }
|
|
91
|
3056
|
92 DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id,
|
|
93 AM_MEDIA_TYPE* in_fmt,
|
|
94 AM_MEDIA_TYPE* out_fmt)
|
168
|
95 {
|
3056
|
96 DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter));
|
|
97 if (!This)
|
|
98 return NULL;
|
|
99
|
|
100 CodecAlloc();
|
|
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 (;;)
|
168
|
117 {
|
3056
|
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)
|
713
|
129 {
|
3056
|
130 printf("Could not open DirectShow DLL: %.200s\n", dllname);
|
|
131 break;
|
713
|
132 }
|
3056
|
133 func = (GETCLASS)GetProcAddress(This->m_iHandle, "DllGetClassObject");
|
713
|
134 if (!func)
|
|
135 {
|
3056
|
136 printf("Illegal or corrupt DirectShow DLL: %.200s\n", dllname);
|
|
137 break;
|
713
|
138 }
|
1545
|
139 result = func(id, &IID_IClassFactory, (void**)&factory);
|
|
140 if (result || !factory)
|
3056
|
141 {
|
|
142 printf("No such class object\n");
|
|
143 break;
|
|
144 }
|
1545
|
145 result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object);
|
168
|
146 factory->vt->Release((IUnknown*)factory);
|
1545
|
147 if (result || !object)
|
3056
|
148 {
|
|
149 printf("Class factory failure\n");
|
|
150 break;
|
|
151 }
|
|
152 result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter);
|
168
|
153 object->vt->Release((IUnknown*)object);
|
3056
|
154 if (result || !This->m_pFilter)
|
|
155 {
|
|
156 printf("Object does not have IBaseFilter interface\n");
|
|
157 break;
|
|
158 }
|
|
159 // enumerate pins
|
|
160 result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins);
|
|
161 if (result || !enum_pins)
|
|
162 {
|
|
163 printf("Could not enumerate pins\n");
|
|
164 break;
|
|
165 }
|
713
|
166
|
168
|
167 enum_pins->vt->Reset(enum_pins);
|
1545
|
168 result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched);
|
713
|
169 Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result);
|
|
170
|
3056
|
171 for (i = 0; i < fetched; i++)
|
168
|
172 {
|
713
|
173 int direction = -1;
|
168
|
174 array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction);
|
3056
|
175 if (!This->m_pInputPin && direction == 0)
|
168
|
176 {
|
3056
|
177 This->m_pInputPin = array[i];
|
|
178 This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin);
|
168
|
179 }
|
3056
|
180 if (!This->m_pOutputPin && direction == 1)
|
168
|
181 {
|
3056
|
182 This->m_pOutputPin = array[i];
|
|
183 This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin);
|
168
|
184 }
|
|
185 array[i]->vt->Release((IUnknown*)(array[i]));
|
|
186 }
|
3056
|
187 if (!This->m_pInputPin)
|
|
188 {
|
|
189 printf("Input pin not found\n");
|
|
190 break;
|
|
191 }
|
|
192 if (!This->m_pOutputPin)
|
|
193 {
|
|
194 printf("Output pin not found\n");
|
|
195 break;
|
|
196 }
|
|
197 result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin,
|
|
198 &IID_IMemInputPin,
|
|
199 (void**)&This->m_pImp);
|
713
|
200 if (result)
|
3056
|
201 {
|
|
202 printf("Error getting IMemInputPin interface\n");
|
|
203 break;
|
|
204 }
|
168
|
205
|
3056
|
206 This->m_pOurType = in_fmt;
|
|
207 This->m_pDestType = out_fmt;
|
|
208 result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType);
|
713
|
209 if (result)
|
3056
|
210 {
|
|
211 printf("Source format is not accepted\n");
|
|
212 break;
|
|
213 }
|
|
214 This->m_pParentFilter = CBaseFilter2Create();
|
|
215 This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter);
|
|
216 This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter);
|
|
217 This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput);
|
713
|
218
|
3056
|
219 result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin,
|
|
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);
|
713
|
233 if (result)
|
1545
|
234 {
|
|
235 //printf("Tracking ACELP %d 0%x\n", result);
|
3056
|
236 printf("Error connecting to output pin\n");
|
|
237 break;
|
1545
|
238 }
|
|
239
|
|
240 printf("Using DirectShow codec: %s\n", dllname);
|
3056
|
241 This->m_iState = 1;
|
|
242 break;
|
168
|
243 }
|
3056
|
244
|
|
245 if (This->m_iState != 1)
|
168
|
246 {
|
3056
|
247 DS_Filter_Destroy(This);
|
|
248 This = 0;
|
168
|
249 }
|
3056
|
250 return This;
|
168
|
251 }
|