2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
13 #include "win32.h" // printf macro
15 typedef long STDCALL (*GETCLASS
) (const GUID
*, const GUID
*, void**);
18 const GUID IID_IUnknown
=
20 0x00000000, 0x0000, 0x0000,
21 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
23 const GUID IID_IClassFactory
=
25 0x00000001, 0x0000, 0x0000,
26 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
29 HRESULT STDCALL
CoInitialize(LPVOID pvReserved
);
30 void STDCALL
CoUninitialize(void);
35 static void DS_Filter_Start(DS_Filter
* This
)
39 //Debug printf("DS_Filter_Start(%p)\n", This);
40 hr
= This
->m_pFilter
->vt
->Run(This
->m_pFilter
, (REFERENCE_TIME
)0);
43 Debug
printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr
);
47 static void DS_Filter_Stop(DS_Filter
* This
)
51 //Debug printf("DS_Filter_Stop(%p)\n", This);
52 This
->m_pFilter
->vt
->Stop(This
->m_pFilter
); // causes weird crash ??? FIXME
53 This
->m_pAll
->vt
->Release((IUnknown
*)This
->m_pAll
);
58 void DS_Filter_Destroy(DS_Filter
* This
)
62 if (This
->m_pOurInput
)
63 This
->m_pOurInput
->vt
->Release((IUnknown
*)This
->m_pOurInput
);
64 if (This
->m_pInputPin
)
65 This
->m_pInputPin
->vt
->Disconnect(This
->m_pInputPin
);
66 if (This
->m_pOutputPin
)
67 This
->m_pOutputPin
->vt
->Disconnect(This
->m_pOutputPin
);
69 This
->m_pFilter
->vt
->Release((IUnknown
*)This
->m_pFilter
);
70 if (This
->m_pOutputPin
)
71 This
->m_pOutputPin
->vt
->Release((IUnknown
*)This
->m_pOutputPin
);
72 if (This
->m_pInputPin
)
73 This
->m_pInputPin
->vt
->Release((IUnknown
*)This
->m_pInputPin
);
75 This
->m_pImp
->vt
->Release((IUnknown
*)This
->m_pImp
);
77 if (This
->m_pOurOutput
)
78 This
->m_pOurOutput
->vt
->Release((IUnknown
*)This
->m_pOurOutput
);
79 if (This
->m_pParentFilter
)
80 This
->m_pParentFilter
->vt
->Release((IUnknown
*)This
->m_pParentFilter
);
81 if (This
->m_pSrcFilter
)
82 This
->m_pSrcFilter
->vt
->Release((IUnknown
*)This
->m_pSrcFilter
);
84 // FIXME - we are still leaving few things allocated!
86 FreeLibrary((unsigned)This
->m_iHandle
);
97 static HRESULT STDCALL
DS_Filter_CopySample(void* pUserData
,IMediaSample
* pSample
){
100 SampleProcUserData
* pData
=pUserData
;
101 Debug
printf("CopySample called(%p,%p)\n",pSample
,pUserData
);
102 if (pSample
->vt
->GetPointer(pSample
, &pointer
))
104 len
= pSample
->vt
->GetActualDataLength(pSample
);
106 len
= pSample
->vt
->GetSize(pSample
);//for iv50
108 pData
->frame_pointer
= pointer
;
109 pData
->frame_size
= len
;
111 FILE* file=fopen("./uncompr.bmp", "wb");
112 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
113 *(int*)(&head[2])=len+0x36;
114 fwrite(head, 14, 1, file);
115 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
116 fwrite(pointer, len, 1, file);
122 DS_Filter
* DS_FilterCreate(const char* dllname
, const GUID
* id
,
123 AM_MEDIA_TYPE
* in_fmt
,
124 AM_MEDIA_TYPE
* out_fmt
,SampleProcUserData
* pUserData
)
128 const char* em
= NULL
;
129 MemAllocator
* tempAll
;
130 ALLOCATOR_PROPERTIES props
,props1
;
131 DS_Filter
* This
= malloc(sizeof(DS_Filter
));
142 tempAll is not used anywhere.
143 MemAllocatorCreate() is called to ensure that RegisterComObject for IMemoryAllocator
144 will be called before possible call
145 to CoCreateInstance(...,&IID_IMemoryAllocator,...) from binary codec.
147 tempAll
=MemAllocatorCreate();
148 This
->m_pFilter
= NULL
;
149 This
->m_pInputPin
= NULL
;
150 This
->m_pOutputPin
= NULL
;
151 This
->m_pSrcFilter
= NULL
;
152 This
->m_pParentFilter
= NULL
;
153 This
->m_pOurInput
= NULL
;
154 This
->m_pOurOutput
= NULL
;
158 This
->Start
= DS_Filter_Start
;
159 This
->Stop
= DS_Filter_Stop
;
164 struct IClassFactory
* factory
= NULL
;
165 struct IUnknown
* object
= NULL
;
166 IEnumPins
* enum_pins
= 0;
172 This
->m_iHandle
= LoadLibraryA(dllname
);
173 if (!This
->m_iHandle
)
175 em
= "could not open DirectShow DLL";
178 func
= (GETCLASS
)GetProcAddress((unsigned)This
->m_iHandle
, "DllGetClassObject");
181 em
= "illegal or corrupt DirectShow DLL";
184 result
= func(id
, &IID_IClassFactory
, (void*)&factory
);
185 if (result
|| !factory
)
187 em
= "no such class object";
190 result
= factory
->vt
->CreateInstance(factory
, 0, &IID_IUnknown
, (void*)&object
);
191 factory
->vt
->Release((IUnknown
*)factory
);
192 if (result
|| !object
)
194 em
= "class factory failure";
197 result
= object
->vt
->QueryInterface(object
, &IID_IBaseFilter
, (void*)&This
->m_pFilter
);
198 object
->vt
->Release((IUnknown
*)object
);
199 if (result
|| !This
->m_pFilter
)
201 em
= "object does not provide IBaseFilter interface";
205 result
= This
->m_pFilter
->vt
->EnumPins(This
->m_pFilter
, &enum_pins
);
206 if (result
|| !enum_pins
)
208 em
= "could not enumerate pins";
212 enum_pins
->vt
->Reset(enum_pins
);
213 result
= enum_pins
->vt
->Next(enum_pins
, (ULONG
)256, (IPin
**)array
, &fetched
);
214 Debug
printf("Pins enumeration returned %ld pins, error is %x\n", fetched
, (int)result
);
216 for (i
= 0; i
< fetched
; i
++)
218 PIN_DIRECTION direction
= -1;
219 array
[i
]->vt
->QueryDirection(array
[i
], &direction
);
220 if (!This
->m_pInputPin
&& direction
== PINDIR_INPUT
)
222 This
->m_pInputPin
= array
[i
];
223 This
->m_pInputPin
->vt
->AddRef((IUnknown
*)This
->m_pInputPin
);
225 if (!This
->m_pOutputPin
&& direction
== PINDIR_OUTPUT
)
227 This
->m_pOutputPin
= array
[i
];
228 This
->m_pOutputPin
->vt
->AddRef((IUnknown
*)This
->m_pOutputPin
);
230 array
[i
]->vt
->Release((IUnknown
*)(array
[i
]));
232 if (!This
->m_pInputPin
)
234 em
= "could not find input pin";
237 if (!This
->m_pOutputPin
)
239 em
= "could not find output pin";
242 result
= This
->m_pInputPin
->vt
->QueryInterface((IUnknown
*)This
->m_pInputPin
,
244 (void*)&This
->m_pImp
);
247 em
= "could not get IMemInputPin interface";
251 This
->m_pOurType
= in_fmt
;
252 This
->m_pDestType
= out_fmt
;
253 result
= This
->m_pInputPin
->vt
->QueryAccept(This
->m_pInputPin
, This
->m_pOurType
);
256 em
= "source format is not accepted";
259 This
->m_pParentFilter
= CBaseFilter2Create();
260 This
->m_pSrcFilter
= CBaseFilterCreate(This
->m_pOurType
, This
->m_pParentFilter
);
261 This
->m_pOurInput
= This
->m_pSrcFilter
->GetPin(This
->m_pSrcFilter
);
262 This
->m_pOurInput
->vt
->AddRef((IUnknown
*)This
->m_pOurInput
);
264 result
= This
->m_pInputPin
->vt
->ReceiveConnection(This
->m_pInputPin
,
269 em
= "could not connect to input pin";
272 result
= This
->m_pImp
->vt
->GetAllocator(This
->m_pImp
, &This
->m_pAll
);
273 if (result
|| !This
->m_pAll
)
275 em
="error getting IMemAllocator interface";
279 //Seting allocator property according to our media type
281 props
.cbBuffer
=This
->m_pOurType
->lSampleSize
;
284 This
->m_pAll
->vt
->SetProperties(This
->m_pAll
, &props
, &props1
);
286 //Notify remote pin about choosed allocator
287 This
->m_pImp
->vt
->NotifyAllocator(This
->m_pImp
, This
->m_pAll
, 0);
289 This
->m_pOurOutput
= COutputPinCreate(This
->m_pDestType
,DS_Filter_CopySample
,pUserData
);
291 result
= This
->m_pOutputPin
->vt
->ReceiveConnection(This
->m_pOutputPin
,
292 (IPin
*) This
->m_pOurOutput
,
296 em
= "could not connect to output pin";
303 tempAll
->vt
->Release(tempAll
);
307 DS_Filter_Destroy(This
);
308 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em
, dllname
);