2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
9 #include "loader/drv.h"
10 #include "loader/com.h"
14 #include "loader/win32.h" // printf macro
16 typedef long STDCALL (*GETCLASS
) (const GUID
*, const GUID
*, void**);
19 const GUID IID_IUnknown
=
21 0x00000000, 0x0000, 0x0000,
22 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
24 const GUID IID_IClassFactory
=
26 0x00000001, 0x0000, 0x0000,
27 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
30 HRESULT STDCALL
CoInitialize(LPVOID pvReserved
);
31 void STDCALL
CoUninitialize(void);
34 static void DS_Filter_Start(DS_Filter
* This
)
38 //Debug printf("DS_Filter_Start(%p)\n", This);
39 hr
= This
->m_pFilter
->vt
->Run(This
->m_pFilter
, (REFERENCE_TIME
)0);
42 Debug
printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr
);
46 static void DS_Filter_Stop(DS_Filter
* This
)
50 //Debug printf("DS_Filter_Stop(%p)\n", This);
51 This
->m_pFilter
->vt
->Stop(This
->m_pFilter
); // causes weird crash ??? FIXME
52 This
->m_pAll
->vt
->Release((IUnknown
*)This
->m_pAll
);
57 void DS_Filter_Destroy(DS_Filter
* This
)
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
);
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
);
74 This
->m_pImp
->vt
->Release((IUnknown
*)This
->m_pImp
);
76 if (This
->m_pOurOutput
)
77 This
->m_pOurOutput
->vt
->Release((IUnknown
*)This
->m_pOurOutput
);
78 if (This
->m_pParentFilter
)
79 This
->m_pParentFilter
->vt
->Release((IUnknown
*)This
->m_pParentFilter
);
80 if (This
->m_pSrcFilter
)
81 This
->m_pSrcFilter
->vt
->Release((IUnknown
*)This
->m_pSrcFilter
);
83 // FIXME - we are still leaving few things allocated!
85 FreeLibrary((unsigned)This
->m_iHandle
);
96 static HRESULT STDCALL
DS_Filter_CopySample(void* pUserData
,IMediaSample
* pSample
){
99 SampleProcUserData
* pData
=pUserData
;
100 Debug
printf("CopySample called(%p,%p)\n",pSample
,pUserData
);
101 if (pSample
->vt
->GetPointer(pSample
, &pointer
))
103 len
= pSample
->vt
->GetActualDataLength(pSample
);
105 len
= pSample
->vt
->GetSize(pSample
);//for iv50
107 pData
->frame_pointer
= pointer
;
108 pData
->frame_size
= len
;
110 FILE* file=fopen("./uncompr.bmp", "wb");
111 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
112 *(int*)(&head[2])=len+0x36;
113 fwrite(head, 14, 1, file);
114 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
115 fwrite(pointer, len, 1, file);
121 DS_Filter
* DS_FilterCreate(const char* dllname
, const GUID
* id
,
122 AM_MEDIA_TYPE
* in_fmt
,
123 AM_MEDIA_TYPE
* out_fmt
,SampleProcUserData
* pUserData
)
127 const char* em
= NULL
;
128 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;
171 static const uint16_t filter_name
[] = { 'F', 'i', 'l', 't', 'e', 'r', 0 };
173 This
->m_iHandle
= LoadLibraryA(dllname
);
174 if (!This
->m_iHandle
)
176 em
= "could not open DirectShow DLL";
179 func
= (GETCLASS
)GetProcAddress((unsigned)This
->m_iHandle
, "DllGetClassObject");
182 em
= "illegal or corrupt DirectShow DLL";
185 result
= func(id
, &IID_IClassFactory
, (void*)&factory
);
186 if (result
|| !factory
)
188 em
= "no such class object";
191 result
= factory
->vt
->CreateInstance(factory
, 0, &IID_IUnknown
, (void*)&object
);
192 factory
->vt
->Release((IUnknown
*)factory
);
193 if (result
|| !object
)
195 em
= "class factory failure";
198 result
= object
->vt
->QueryInterface(object
, &IID_IBaseFilter
, (void*)&This
->m_pFilter
);
199 object
->vt
->Release((IUnknown
*)object
);
200 if (result
|| !This
->m_pFilter
)
202 em
= "object does not provide IBaseFilter interface";
206 graph
= FilterGraphCreate();
207 result
= This
->m_pFilter
->vt
->JoinFilterGraph(This
->m_pFilter
, (IFilterGraph
*)graph
, filter_name
);
210 result
= This
->m_pFilter
->vt
->EnumPins(This
->m_pFilter
, &enum_pins
);
211 if (result
|| !enum_pins
)
213 em
= "could not enumerate pins";
217 enum_pins
->vt
->Reset(enum_pins
);
218 result
= enum_pins
->vt
->Next(enum_pins
, (ULONG
)256, (IPin
**)array
, &fetched
);
219 enum_pins
->vt
->Release(enum_pins
);
220 Debug
printf("Pins enumeration returned %ld pins, error is %x\n", fetched
, (int)result
);
222 for (i
= 0; i
< fetched
; i
++)
224 PIN_DIRECTION direction
= -1;
225 array
[i
]->vt
->QueryDirection(array
[i
], &direction
);
226 if (!This
->m_pInputPin
&& direction
== PINDIR_INPUT
)
228 This
->m_pInputPin
= array
[i
];
229 This
->m_pInputPin
->vt
->AddRef((IUnknown
*)This
->m_pInputPin
);
231 if (!This
->m_pOutputPin
&& direction
== PINDIR_OUTPUT
)
233 This
->m_pOutputPin
= array
[i
];
234 This
->m_pOutputPin
->vt
->AddRef((IUnknown
*)This
->m_pOutputPin
);
236 array
[i
]->vt
->Release((IUnknown
*)(array
[i
]));
238 if (!This
->m_pInputPin
)
240 em
= "could not find input pin";
243 if (!This
->m_pOutputPin
)
245 em
= "could not find output pin";
248 result
= This
->m_pInputPin
->vt
->QueryInterface((IUnknown
*)This
->m_pInputPin
,
250 (void*)&This
->m_pImp
);
253 em
= "could not get IMemInputPin interface";
257 This
->m_pOurType
= in_fmt
;
258 This
->m_pDestType
= out_fmt
;
259 result
= This
->m_pInputPin
->vt
->QueryAccept(This
->m_pInputPin
, This
->m_pOurType
);
262 em
= "source format is not accepted";
265 This
->m_pParentFilter
= CBaseFilter2Create();
266 This
->m_pSrcFilter
= CBaseFilterCreate(This
->m_pOurType
, This
->m_pParentFilter
);
267 This
->m_pOurInput
= This
->m_pSrcFilter
->GetPin(This
->m_pSrcFilter
);
268 This
->m_pOurInput
->vt
->AddRef((IUnknown
*)This
->m_pOurInput
);
270 result
= This
->m_pInputPin
->vt
->ReceiveConnection(This
->m_pInputPin
,
275 em
= "could not connect to input pin";
278 result
= This
->m_pImp
->vt
->GetAllocator(This
->m_pImp
, &This
->m_pAll
);
279 if (result
|| !This
->m_pAll
)
281 em
="error getting IMemAllocator interface";
285 //Seting allocator property according to our media type
287 props
.cbBuffer
=This
->m_pOurType
->lSampleSize
;
290 This
->m_pAll
->vt
->SetProperties(This
->m_pAll
, &props
, &props1
);
292 //Notify remote pin about choosed allocator
293 This
->m_pImp
->vt
->NotifyAllocator(This
->m_pImp
, This
->m_pAll
, 0);
295 This
->m_pOurOutput
= COutputPinCreate(This
->m_pDestType
,DS_Filter_CopySample
,pUserData
);
297 result
= This
->m_pOutputPin
->vt
->ReceiveConnection(This
->m_pOutputPin
,
298 (IPin
*) This
->m_pOurOutput
,
302 em
= "could not connect to output pin";
309 tempAll
->vt
->Release(tempAll
);
313 DS_Filter_Destroy(This
);
314 printf("Warning: DS_Filter() %s. (DLL=%.200s)\n", em
, dllname
);