Set AVFMT_FLAG_GENPTS if -correct-pts is used.
[mplayer.git] / loader / dshow / outputpin.c
blob3ab6221eab67d91605b00d0187ba1f10a6763382
1 /*
2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
4 * $Id$
5 */
7 #include "wine/winerror.h"
8 #include "wine/windef.h"
9 #include "outputpin.h"
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
15 An object beyond interface IEnumMediaTypes.
16 Returned by COutputPin through call IPin::EnumMediaTypes().
19 static inline int output_unimplemented(const char* s, void* p)
21 Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p);
22 return E_NOTIMPL;
25 typedef struct CEnumMediaTypes
27 IEnumMediaTypes_vt* vt;
28 DECLARE_IUNKNOWN();
29 AM_MEDIA_TYPE type;
30 GUID interfaces[2];
31 } CEnumMediaTypes;
33 struct _COutputMemPin
35 IMemInputPin_vt* vt;
36 DECLARE_IUNKNOWN();
37 char** frame_pointer;
38 long* frame_size_pointer;
39 MemAllocator* pAllocator;
40 COutputPin* parent;
43 static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This,
44 /* [in] */ ULONG cMediaTypes,
45 /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes,
46 /* [out] */ ULONG *pcFetched)
48 AM_MEDIA_TYPE* type = &((CEnumMediaTypes*)This)->type;
49 Debug printf("CEnumMediaTypes::Next(%p) called\n", This);
50 if (!ppMediaTypes)
51 return E_INVALIDARG;
52 if (!pcFetched && (cMediaTypes!=1))
53 return E_INVALIDARG;
54 if (cMediaTypes <= 0)
55 return 0;
57 if (pcFetched)
58 *pcFetched=1;
59 ppMediaTypes[0] = malloc(sizeof(AM_MEDIA_TYPE));
60 // copy structures - C can handle this...
61 **ppMediaTypes = *type;
62 if (ppMediaTypes[0]->pbFormat)
64 ppMediaTypes[0]->pbFormat=malloc(ppMediaTypes[0]->cbFormat);
65 memcpy(ppMediaTypes[0]->pbFormat, type->pbFormat, ppMediaTypes[0]->cbFormat);
67 if (cMediaTypes == 1)
68 return 0;
69 return 1;
72 /* I expect that these methods are unused. */
73 static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This,
74 /* [in] */ ULONG cMediaTypes)
76 return output_unimplemented("CEnumMediaTypes::Skip", This);
79 static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This)
81 Debug printf("CEnumMediaTypes::Reset(%p) called\n", This);
82 return 0;
85 static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This,
86 /* [out] */ IEnumMediaTypes **ppEnum)
88 Debug printf("CEnumMediaTypes::Clone(%p) called\n", This);
89 return E_NOTIMPL;
92 static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This)
94 free(This->vt);
95 free(This);
98 // IPin->IUnknown methods
99 IMPLEMENT_IUNKNOWN(CEnumMediaTypes)
101 static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt)
103 CEnumMediaTypes *This = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ;
105 if (!This)
106 return NULL;
108 This->vt = (IEnumMediaTypes_vt*) malloc(sizeof(IEnumMediaTypes_vt));
109 if (!This->vt)
111 free(This);
112 return NULL;
115 This->refcount = 1;
116 This->type = *amt;
118 This->vt->QueryInterface = CEnumMediaTypes_QueryInterface;
119 This->vt->AddRef = CEnumMediaTypes_AddRef;
120 This->vt->Release = CEnumMediaTypes_Release;
121 This->vt->Next = CEnumMediaTypes_Next;
122 This->vt->Skip = CEnumMediaTypes_Skip;
123 This->vt->Reset = CEnumMediaTypes_Reset;
124 This->vt->Clone = CEnumMediaTypes_Clone;
126 This->interfaces[0] = IID_IUnknown;
127 This->interfaces[1] = IID_IEnumMediaTypes;
129 return This;
133 /*************
134 * COutputPin
135 *************/
138 static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv)
140 COutputPin* p = (COutputPin*) This;
142 Debug printf("COutputPin_QueryInterface(%p) called\n", This);
143 if (!ppv)
144 return E_INVALIDARG;
146 if (memcmp(iid, &IID_IUnknown, 16) == 0)
148 *ppv = p;
149 p->vt->AddRef(This);
150 return 0;
152 if (memcmp(iid, &IID_IMemInputPin, 16) == 0)
154 *ppv = p->mempin;
155 p->mempin->vt->AddRef((IUnknown*)*ppv);
156 return 0;
159 Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-"
160 "%02x%02x%02x%02x%02x%02x\n",
161 iid->f1, iid->f2, iid->f3,
162 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
163 (unsigned char)iid->f4[2], (unsigned char)iid->f4[3],
164 (unsigned char)iid->f4[4], (unsigned char)iid->f4[5],
165 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]);
166 return E_NOINTERFACE;
169 // IPin methods
170 static HRESULT STDCALL COutputPin_Connect(IPin * This,
171 /* [in] */ IPin *pReceivePin,
172 /* [in] */ /* const */ AM_MEDIA_TYPE *pmt)
174 Debug printf("COutputPin_Connect() called\n");
176 *pmt=((COutputPin*)This)->type;
177 if(pmt->cbFormat>0)
179 pmt->pbFormat=malloc(pmt->cbFormat);
180 memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
183 //return E_NOTIMPL;
184 return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX
185 // if I put return 0; here, it crashes
188 static HRESULT STDCALL COutputPin_ReceiveConnection(IPin * This,
189 /* [in] */ IPin *pConnector,
190 /* [in] */ const AM_MEDIA_TYPE *pmt)
192 Debug printf("COutputPin_ReceiveConnection(%p) called\n", This);
193 ((COutputPin*)This)->remote = pConnector;
194 return 0;
197 static HRESULT STDCALL COutputPin_Disconnect(IPin * This)
199 Debug printf("COutputPin_Disconnect(%p) called\n", This);
200 return 1;
203 static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This,
204 /* [out] */ IPin **pPin)
206 Debug printf("COutputPin_ConnectedTo(%p) called\n", This);
207 if (!pPin)
208 return E_INVALIDARG;
209 *pPin = ((COutputPin*)This)->remote;
210 return 0;
213 static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This,
214 /* [out] */ AM_MEDIA_TYPE *pmt)
216 Debug printf("CInputPin::ConnectionMediaType() called\n");
217 if (!pmt)
218 return E_INVALIDARG;
219 *pmt = ((COutputPin*)This)->type;
220 if (pmt->cbFormat>0)
222 pmt->pbFormat=malloc(pmt->cbFormat);
223 memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat);
225 return 0;
228 static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This,
229 /* [out] */ PIN_INFO *pInfo)
231 return output_unimplemented("COutputPin_QueryPinInfo", This);
234 static HRESULT STDCALL COutputPin_QueryDirection(IPin * This,
235 /* [out] */ PIN_DIRECTION *pPinDir)
237 Debug printf("COutputPin_QueryDirection(%p) called\n", This);
238 if (!pPinDir)
239 return E_INVALIDARG;
240 *pPinDir = PINDIR_INPUT;
241 return 0;
244 static HRESULT STDCALL COutputPin_QueryId(IPin * This,
245 /* [out] */ LPWSTR *Id)
247 return output_unimplemented("COutputPin_QueryId", This);
250 static HRESULT STDCALL COutputPin_QueryAccept(IPin * This,
251 /* [in] */ const AM_MEDIA_TYPE *pmt)
253 return output_unimplemented("COutputPin_QueryAccept", This);
256 static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This,
257 /* [out] */ IEnumMediaTypes **ppEnum)
259 Debug printf("COutputPin_EnumMediaTypes() called\n");
260 if (!ppEnum)
261 return E_INVALIDARG;
262 *ppEnum = (IEnumMediaTypes*) CEnumMediaTypesCreate(&((COutputPin*)This)->type);
263 return 0;
266 static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This,
267 /* [out] */ IPin **apPin,
268 /* [out][in] */ ULONG *nPin)
270 return output_unimplemented("COutputPin_QueryInternalConnections", This);
273 static HRESULT STDCALL COutputPin_EndOfStream(IPin * This)
275 return output_unimplemented("COutputPin_EndOfStream", This);
278 static HRESULT STDCALL COutputPin_BeginFlush(IPin * This)
280 return output_unimplemented("COutputPin_BeginFlush", This);
283 static HRESULT STDCALL COutputPin_EndFlush(IPin * This)
285 return output_unimplemented("COutputPin_EndFlush", This);
288 static HRESULT STDCALL COutputPin_NewSegment(IPin * This,
289 /* [in] */ REFERENCE_TIME tStart,
290 /* [in] */ REFERENCE_TIME tStop,
291 /* [in] */ double dRate)
293 Debug printf("COutputPin_NewSegment(%Ld,%Ld,%f) called\n",
294 tStart, tStop, dRate);
295 return 0;
300 // IMemInputPin->IUnknown methods
302 static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, const GUID* iid, void** ppv)
304 COutputPin* p = (COutputPin*)This;
306 Debug printf("COutputPin_M_QueryInterface(%p) called\n", This);
307 if (!ppv)
308 return E_INVALIDARG;
310 if(!memcmp(iid, &IID_IUnknown, 16))
312 *ppv = p;
313 p->vt->AddRef(This);
314 return 0;
316 /*if(!memcmp(iid, &IID_IPin, 16))
318 COutputPin* ptr=(COutputPin*)(This-1);
319 *ppv=(void*)ptr;
320 AddRef((IUnknown*)ptr);
321 return 0;
323 if(!memcmp(iid, &IID_IMemInputPin, 16))
325 *ppv = p->mempin;
326 p->mempin->vt->AddRef(This);
327 return 0;
329 Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" \
330 "%02x%02x%02x%02x%02x%02x\n",
331 iid->f1, iid->f2, iid->f3,
332 (unsigned char)iid->f4[1], (unsigned char)iid->f4[0],
333 (unsigned char)iid->f4[2], (unsigned char)iid->f4[3],
334 (unsigned char)iid->f4[4], (unsigned char)iid->f4[5],
335 (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]);
336 return E_NOINTERFACE;
339 // IMemInputPin methods
341 static HRESULT STDCALL COutputPin_GetAllocator(IMemInputPin* This,
342 /* [out] */ IMemAllocator** ppAllocator)
344 Debug printf("COutputPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator);
345 *ppAllocator = (IMemAllocator*) MemAllocatorCreate();
346 return 0;
349 static HRESULT STDCALL COutputPin_NotifyAllocator(IMemInputPin* This,
350 /* [in] */ IMemAllocator* pAllocator,
351 /* [in] */ int bReadOnly)
353 Debug printf("COutputPin_NotifyAllocator(%p, %p) called\n", This, pAllocator);
354 ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator;
355 return 0;
358 static HRESULT STDCALL COutputPin_GetAllocatorRequirements(IMemInputPin* This,
359 /* [out] */ ALLOCATOR_PROPERTIES* pProps)
361 return output_unimplemented("COutputPin_GetAllocatorRequirements", This);
364 static HRESULT STDCALL COutputPin_Receive(IMemInputPin* This,
365 /* [in] */ IMediaSample* pSample)
367 COutputMemPin* mp = (COutputMemPin*)This;
368 char* pointer;
369 int len;
371 Debug printf("COutputPin_Receive(%p) called\n", This);
372 if (!pSample)
373 return E_INVALIDARG;
374 if (pSample->vt->GetPointer(pSample, (BYTE**) &pointer))
375 return -1;
376 len = pSample->vt->GetActualDataLength(pSample);
377 if (len == 0)
378 len = pSample->vt->GetSize(pSample);//for iv50
379 //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len);
381 if (mp->frame_pointer)
382 *(mp->frame_pointer) = pointer;
383 if (mp->frame_size_pointer)
384 *(mp->frame_size_pointer) = len;
386 FILE* file=fopen("./uncompr.bmp", "wb");
387 char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00};
388 *(int*)(&head[2])=len+0x36;
389 fwrite(head, 14, 1, file);
390 fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file);
391 fwrite(pointer, len, 1, file);
392 fclose(file);
394 // pSample->vt->Release((IUnknown*)pSample);
396 return 0;
399 static HRESULT STDCALL COutputPin_ReceiveMultiple(IMemInputPin * This,
400 /* [size_is][in] */ IMediaSample **pSamples,
401 /* [in] */ long nSamples,
402 /* [out] */ long *nSamplesProcessed)
404 return output_unimplemented("COutputPin_ReceiveMultiple", This);
407 static HRESULT STDCALL COutputPin_ReceiveCanBlock(IMemInputPin * This)
409 return output_unimplemented("COutputPin_ReceiveCanBlock", This);
412 static void COutputPin_SetFramePointer(COutputPin* This, char** z)
414 This->mempin->frame_pointer = z;
417 static void COutputPin_SetPointer2(COutputPin* This, char* p)
419 if (This->mempin->pAllocator)
420 // fixme
421 This->mempin->pAllocator->SetPointer(This->mempin->pAllocator, p);
424 static void COutputPin_SetFrameSizePointer(COutputPin* This, long* z)
426 This->mempin->frame_size_pointer = z;
429 static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt)
431 This->type = *amt;
434 static void COutputPin_Destroy(COutputPin* This)
436 if (This->mempin->vt)
437 free(This->mempin->vt);
438 if (This->mempin)
439 free(This->mempin);
440 if (This->vt)
441 free(This->vt);
442 free(This);
445 static HRESULT STDCALL COutputPin_AddRef(IUnknown* This)
447 Debug printf("COutputPin_AddRef(%p) called (%d)\n", This, ((COutputPin*)This)->refcount);
448 ((COutputPin*)This)->refcount++;
449 return 0;
452 static HRESULT STDCALL COutputPin_Release(IUnknown* This)
454 Debug printf("COutputPin_Release(%p) called (%d)\n", This, ((COutputPin*)This)->refcount);
455 if (--((COutputPin*)This)->refcount <= 0)
456 COutputPin_Destroy((COutputPin*)This);
458 return 0;
461 static HRESULT STDCALL COutputPin_M_AddRef(IUnknown* This)
463 COutputMemPin* p = (COutputMemPin*) This;
464 Debug printf("COutputPin_MAddRef(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount);
465 p->parent->refcount++;
466 return 0;
469 static HRESULT STDCALL COutputPin_M_Release(IUnknown* This)
471 COutputMemPin* p = (COutputMemPin*) This;
472 Debug printf("COutputPin_MRelease(%p) called (%p, %d)\n",
473 p, p->parent, p->parent->refcount);
474 if (--p->parent->refcount <= 0)
475 COutputPin_Destroy(p->parent);
476 return 0;
479 COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt)
481 COutputPin* This = (COutputPin*) malloc(sizeof(COutputPin));
482 IMemInputPin_vt* ivt;
484 if (!This)
485 return NULL;
487 This->vt = (IPin_vt*) malloc(sizeof(IPin_vt));
488 This->mempin = (COutputMemPin*) malloc(sizeof(COutputMemPin));
489 ivt = (IMemInputPin_vt*) malloc(sizeof(IMemInputPin_vt));
491 if (!This->vt || !This->mempin || !ivt)
493 COutputPin_Destroy(This);
494 return NULL;
497 This->mempin->vt = ivt;
499 This->refcount = 1;
500 This->remote = 0;
501 This->type = *amt;
503 This->vt->QueryInterface = COutputPin_QueryInterface;
504 This->vt->AddRef = COutputPin_AddRef;
505 This->vt->Release = COutputPin_Release;
506 This->vt->Connect = COutputPin_Connect;
507 This->vt->ReceiveConnection = COutputPin_ReceiveConnection;
508 This->vt->Disconnect = COutputPin_Disconnect;
509 This->vt->ConnectedTo = COutputPin_ConnectedTo;
510 This->vt->ConnectionMediaType = COutputPin_ConnectionMediaType;
511 This->vt->QueryPinInfo = COutputPin_QueryPinInfo;
512 This->vt->QueryDirection = COutputPin_QueryDirection;
513 This->vt->QueryId = COutputPin_QueryId;
514 This->vt->QueryAccept = COutputPin_QueryAccept;
515 This->vt->EnumMediaTypes = COutputPin_EnumMediaTypes;
516 This->vt->QueryInternalConnections = COutputPin_QueryInternalConnections;
517 This->vt->EndOfStream = COutputPin_EndOfStream;
518 This->vt->BeginFlush = COutputPin_BeginFlush;
519 This->vt->EndFlush = COutputPin_EndFlush;
520 This->vt->NewSegment = COutputPin_NewSegment;
522 This->mempin->vt->QueryInterface = COutputPin_M_QueryInterface;
523 This->mempin->vt->AddRef = COutputPin_M_AddRef;
524 This->mempin->vt->Release = COutputPin_M_Release;
525 This->mempin->vt->GetAllocator = COutputPin_GetAllocator;
526 This->mempin->vt->NotifyAllocator = COutputPin_NotifyAllocator;
527 This->mempin->vt->GetAllocatorRequirements = COutputPin_GetAllocatorRequirements;
528 This->mempin->vt->Receive = COutputPin_Receive;
529 This->mempin->vt->ReceiveMultiple = COutputPin_ReceiveMultiple;
530 This->mempin->vt->ReceiveCanBlock = COutputPin_ReceiveCanBlock;
532 This->mempin->frame_size_pointer = 0;
533 This->mempin->frame_pointer = 0;
534 This->mempin->pAllocator = 0;
535 This->mempin->refcount = 1;
536 This->mempin->parent = This;
538 This->SetPointer2 = COutputPin_SetPointer2;
539 This->SetFramePointer = COutputPin_SetFramePointer;
540 This->SetFrameSizePointer = COutputPin_SetFrameSizePointer;
541 This->SetNewFormat = COutputPin_SetNewFormat;
543 return This;