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);
33 static void DS_Filter_Start(DS_Filter
* This
)
37 //Debug printf("DS_Filter_Start(%p)\n", This);
38 hr
= This
->m_pFilter
->vt
->Run(This
->m_pFilter
, (REFERENCE_TIME
)0);
41 Debug
printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr
);
45 static void DS_Filter_Stop(DS_Filter
* This
)
49 //Debug printf("DS_Filter_Stop(%p)\n", This);
50 This
->m_pFilter
->vt
->Stop(This
->m_pFilter
); // causes weird crash ??? FIXME
51 This
->m_pAll
->vt
->Release((IUnknown
*)This
->m_pAll
);
56 void DS_Filter_Destroy(DS_Filter
* This
)
60 if (This
->m_pOurInput
)
61 This
->m_pOurInput
->vt
->Release((IUnknown
*)This
->m_pOurInput
);
62 if (This
->m_pInputPin
)
63 This
->m_pInputPin
->vt
->Disconnect(This
->m_pInputPin
);
64 if (This
->m_pOutputPin
)
65 This
->m_pOutputPin
->vt
->Disconnect(This
->m_pOutputPin
);
67 This
->m_pFilter
->vt
->Release((IUnknown
*)This
->m_pFilter
);
68 if (This
->m_pOutputPin
)
69 This
->m_pOutputPin
->vt
->Release((IUnknown
*)This
->m_pOutputPin
);
70 if (This
->m_pInputPin
)
71 This
->m_pInputPin
->vt
->Release((IUnknown
*)This
->m_pInputPin
);
73 This
->m_pImp
->vt
->Release((IUnknown
*)This
->m_pImp
);
75 if (This
->m_pOurOutput
)
76 This
->m_pOurOutput
->vt
->Release((IUnknown
*)This
->m_pOurOutput
);
77 if (This
->m_pParentFilter
)
78 This
->m_pParentFilter
->vt
->Release((IUnknown
*)This
->m_pParentFilter
);
79 if (This
->m_pSrcFilter
)
80 This
->m_pSrcFilter
->vt
->Release((IUnknown
*)This
->m_pSrcFilter
);
82 // FIXME - we are still leaving few things allocated!
84 FreeLibrary((unsigned)This
->m_iHandle
);
95 static HRESULT STDCALL
DS_Filter_CopySample(void* pUserData
,IMediaSample
* pSample
){
98 SampleProcUserData
* pData
=pUserData
;
99 Debug
printf("CopySample called(%p,%p)\n",pSample
,pUserData
);
100 if (pSample
->vt
->GetPointer(pSample
, &pointer
))
102 len
= pSample
->vt
->GetActualDataLength(pSample
);
104 len
= pSample
->vt
->GetSize(pSample
);//for iv50
106 pData
->frame_pointer
= pointer
;
107 pData
->frame_size
= len
;
109 FILE* file=fopen("./uncompr.bmp", "wb");
110 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
111 *(int*)(&head[2])=len+0x36;
112 fwrite(head, 14, 1, file);
113 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
114 fwrite(pointer, len, 1, file);
120 DS_Filter
* DS_FilterCreate(const char* dllname
, const GUID
* id
,
121 AM_MEDIA_TYPE
* in_fmt
,
122 AM_MEDIA_TYPE
* out_fmt
,SampleProcUserData
* pUserData
)
126 const char* em
= NULL
;
127 MemAllocator
* tempAll
;
128 ALLOCATOR_PROPERTIES props
,props1
;
129 DS_Filter
* This
= malloc(sizeof(DS_Filter
));
140 tempAll is not used anywhere.
141 MemAllocatorCreate() is called to ensure that RegisterComObject for IMemoryAllocator
142 will be called before possible call
143 to CoCreateInstance(...,&IID_IMemoryAllocator,...) from binary codec.
145 tempAll
=MemAllocatorCreate();
146 This
->m_pFilter
= NULL
;
147 This
->m_pInputPin
= NULL
;
148 This
->m_pOutputPin
= NULL
;
149 This
->m_pSrcFilter
= NULL
;
150 This
->m_pParentFilter
= NULL
;
151 This
->m_pOurInput
= NULL
;
152 This
->m_pOurOutput
= NULL
;
156 This
->Start
= DS_Filter_Start
;
157 This
->Stop
= DS_Filter_Stop
;
162 struct IClassFactory
* factory
= NULL
;
163 struct IUnknown
* object
= NULL
;
164 IEnumPins
* enum_pins
= 0;
170 This
->m_iHandle
= LoadLibraryA(dllname
);
171 if (!This
->m_iHandle
)
173 em
= "could not open DirectShow DLL";
176 func
= (GETCLASS
)GetProcAddress((unsigned)This
->m_iHandle
, "DllGetClassObject");
179 em
= "illegal or corrupt DirectShow DLL";
182 result
= func(id
, &IID_IClassFactory
, (void*)&factory
);
183 if (result
|| !factory
)
185 em
= "no such class object";
188 result
= factory
->vt
->CreateInstance(factory
, 0, &IID_IUnknown
, (void*)&object
);
189 factory
->vt
->Release((IUnknown
*)factory
);
190 if (result
|| !object
)
192 em
= "class factory failure";
195 result
= object
->vt
->QueryInterface(object
, &IID_IBaseFilter
, (void*)&This
->m_pFilter
);
196 object
->vt
->Release((IUnknown
*)object
);
197 if (result
|| !This
->m_pFilter
)
199 em
= "object does not provide IBaseFilter interface";
203 result
= This
->m_pFilter
->vt
->EnumPins(This
->m_pFilter
, &enum_pins
);
204 if (result
|| !enum_pins
)
206 em
= "could not enumerate pins";
210 enum_pins
->vt
->Reset(enum_pins
);
211 result
= enum_pins
->vt
->Next(enum_pins
, (ULONG
)256, (IPin
**)array
, &fetched
);
212 Debug
printf("Pins enumeration returned %ld pins, error is %x\n", fetched
, (int)result
);
214 for (i
= 0; i
< fetched
; i
++)
216 PIN_DIRECTION direction
= -1;
217 array
[i
]->vt
->QueryDirection(array
[i
], &direction
);
218 if (!This
->m_pInputPin
&& direction
== PINDIR_INPUT
)
220 This
->m_pInputPin
= array
[i
];
221 This
->m_pInputPin
->vt
->AddRef((IUnknown
*)This
->m_pInputPin
);
223 if (!This
->m_pOutputPin
&& direction
== PINDIR_OUTPUT
)
225 This
->m_pOutputPin
= array
[i
];
226 This
->m_pOutputPin
->vt
->AddRef((IUnknown
*)This
->m_pOutputPin
);
228 array
[i
]->vt
->Release((IUnknown
*)(array
[i
]));
230 if (!This
->m_pInputPin
)
232 em
= "could not find input pin";
235 if (!This
->m_pOutputPin
)
237 em
= "could not find output pin";
240 result
= This
->m_pInputPin
->vt
->QueryInterface((IUnknown
*)This
->m_pInputPin
,
242 (void*)&This
->m_pImp
);
245 em
= "could not get IMemInputPin interface";
249 This
->m_pOurType
= in_fmt
;
250 This
->m_pDestType
= out_fmt
;
251 result
= This
->m_pInputPin
->vt
->QueryAccept(This
->m_pInputPin
, This
->m_pOurType
);
254 em
= "source format is not accepted";
257 This
->m_pParentFilter
= CBaseFilter2Create();
258 This
->m_pSrcFilter
= CBaseFilterCreate(This
->m_pOurType
, This
->m_pParentFilter
);
259 This
->m_pOurInput
= This
->m_pSrcFilter
->GetPin(This
->m_pSrcFilter
);
260 This
->m_pOurInput
->vt
->AddRef((IUnknown
*)This
->m_pOurInput
);
262 result
= This
->m_pInputPin
->vt
->ReceiveConnection(This
->m_pInputPin
,
267 em
= "could not connect to input pin";
270 result
= This
->m_pImp
->vt
->GetAllocator(This
->m_pImp
, &This
->m_pAll
);
271 if (result
|| !This
->m_pAll
)
273 em
="error getting IMemAllocator interface";
277 //Seting allocator property according to our media type
279 props
.cbBuffer
=This
->m_pOurType
->lSampleSize
;
282 This
->m_pAll
->vt
->SetProperties(This
->m_pAll
, &props
, &props1
);
284 //Notify remote pin about choosed allocator
285 This
->m_pImp
->vt
->NotifyAllocator(This
->m_pImp
, This
->m_pAll
, 0);
287 This
->m_pOurOutput
= COutputPinCreate(This
->m_pDestType
,DS_Filter_CopySample
,pUserData
);
289 result
= This
->m_pOutputPin
->vt
->ReceiveConnection(This
->m_pOutputPin
,
290 (IPin
*) This
->m_pOurOutput
,
294 em
= "could not connect to output pin";
301 tempAll
->vt
->Release(tempAll
);
305 DS_Filter_Destroy(This
);
306 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em
, dllname
);