2 * Copyright 2013 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "qcap_main.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(qcap
);
37 IPersistPropertyBag IPersistPropertyBag_iface
;
45 VIDEOINFOHEADER
*videoinfo
;
46 size_t videoinfo_size
;
53 static inline AVICompressor
*impl_from_BaseFilter(BaseFilter
*filter
)
55 return CONTAINING_RECORD(filter
, AVICompressor
, filter
);
58 static inline AVICompressor
*impl_from_IBaseFilter(IBaseFilter
*iface
)
60 BaseFilter
*filter
= CONTAINING_RECORD(iface
, BaseFilter
, IBaseFilter_iface
);
61 return impl_from_BaseFilter(filter
);
64 static inline AVICompressor
*impl_from_BasePin(BasePin
*pin
)
66 return impl_from_IBaseFilter(pin
->pinInfo
.pFilter
);
69 static HRESULT
ensure_driver(AVICompressor
*This
)
74 This
->hic
= ICOpen(FCC('v','i','d','c'), This
->fcc_handler
, ICMODE_COMPRESS
);
76 FIXME("ICOpen failed\n");
83 static HRESULT
fill_format_info(AVICompressor
*This
, VIDEOINFOHEADER
*src_videoinfo
)
89 hres
= ensure_driver(This
);
93 size
= ICGetInfo(This
->hic
, &icinfo
, sizeof(icinfo
));
94 if(size
!= sizeof(icinfo
))
97 size
= ICCompressGetFormatSize(This
->hic
, &src_videoinfo
->bmiHeader
);
99 FIXME("ICCompressGetFormatSize failed\n");
103 size
+= FIELD_OFFSET(VIDEOINFOHEADER
, bmiHeader
);
104 This
->videoinfo
= heap_alloc(size
);
106 return E_OUTOFMEMORY
;
108 This
->videoinfo_size
= size
;
109 This
->driver_flags
= icinfo
.dwFlags
;
110 memset(This
->videoinfo
, 0, sizeof(*This
->videoinfo
));
111 ICCompressGetFormat(This
->hic
, &src_videoinfo
->bmiHeader
, &This
->videoinfo
->bmiHeader
);
113 This
->videoinfo
->dwBitRate
= 10000000/src_videoinfo
->AvgTimePerFrame
* This
->videoinfo
->bmiHeader
.biSizeImage
* 8;
114 This
->videoinfo
->AvgTimePerFrame
= src_videoinfo
->AvgTimePerFrame
;
115 This
->max_frame_size
= This
->videoinfo
->bmiHeader
.biSizeImage
;
119 static HRESULT WINAPI
AVICompressor_QueryInterface(IBaseFilter
*iface
, REFIID riid
, void **ppv
)
121 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
123 if(IsEqualIID(riid
, &IID_IUnknown
)) {
124 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
125 *ppv
= &This
->filter
.IBaseFilter_iface
;
126 }else if(IsEqualIID(riid
, &IID_IPersist
)) {
127 TRACE("(%p)->(IID_IPersist %p)\n", This
, ppv
);
128 *ppv
= &This
->filter
.IBaseFilter_iface
;
129 }else if(IsEqualIID(riid
, &IID_IMediaFilter
)) {
130 TRACE("(%p)->(IID_IMediaFilter %p)\n", This
, ppv
);
131 *ppv
= &This
->filter
.IBaseFilter_iface
;
132 }else if(IsEqualIID(riid
, &IID_IBaseFilter
)) {
133 TRACE("(%p)->(IID_IBaseFilter %p)\n", This
, ppv
);
134 *ppv
= &This
->filter
.IBaseFilter_iface
;
135 }else if(IsEqualIID(riid
, &IID_IPersistPropertyBag
)) {
136 TRACE("(%p)->(IID_IPersistPropertyBag %p)\n", This
, ppv
);
137 *ppv
= &This
->IPersistPropertyBag_iface
;
139 FIXME("no interface for %s\n", debugstr_guid(riid
));
141 return E_NOINTERFACE
;
144 IUnknown_AddRef((IUnknown
*)*ppv
);
149 static ULONG WINAPI
AVICompressor_Release(IBaseFilter
*iface
)
151 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
152 ULONG ref
= BaseFilterImpl_Release(&This
->filter
.IBaseFilter_iface
);
154 TRACE("(%p) ref=%d\n", This
, ref
);
159 heap_free(This
->videoinfo
);
161 BaseInputPinImpl_Release(&This
->in
->pin
.IPin_iface
);
163 BaseOutputPinImpl_Release(&This
->out
->pin
.IPin_iface
);
170 static HRESULT WINAPI
AVICompressor_Stop(IBaseFilter
*iface
)
172 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
174 TRACE("(%p)\n", This
);
176 if(This
->filter
.state
== State_Stopped
)
179 ICCompressEnd(This
->hic
);
180 This
->filter
.state
= State_Stopped
;
184 static HRESULT WINAPI
AVICompressor_Pause(IBaseFilter
*iface
)
186 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
187 FIXME("(%p)\n", This
);
191 static HRESULT WINAPI
AVICompressor_Run(IBaseFilter
*iface
, REFERENCE_TIME tStart
)
193 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
196 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_longlong(tStart
));
198 if(This
->filter
.state
== State_Running
)
201 hres
= IMemAllocator_Commit(This
->out
->pAllocator
);
203 FIXME("Commit failed: %08x\n", hres
);
209 This
->filter
.state
= State_Running
;
213 static HRESULT WINAPI
AVICompressor_FindPin(IBaseFilter
*iface
, LPCWSTR Id
, IPin
**ppPin
)
215 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
216 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Id
), ppPin
);
217 return VFW_E_NOT_FOUND
;
220 static HRESULT WINAPI
AVICompressor_QueryFilterInfo(IBaseFilter
*iface
, FILTER_INFO
*pInfo
)
222 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
223 FIXME("(%p)->(%p)\n", This
, pInfo
);
227 static HRESULT WINAPI
AVICompressor_QueryVendorInfo(IBaseFilter
*iface
, LPWSTR
*pVendorInfo
)
229 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
230 FIXME("(%p)->(%p)\n", This
, pVendorInfo
);
234 static const IBaseFilterVtbl AVICompressorVtbl
= {
235 AVICompressor_QueryInterface
,
236 BaseFilterImpl_AddRef
,
237 AVICompressor_Release
,
238 BaseFilterImpl_GetClassID
,
242 BaseFilterImpl_GetState
,
243 BaseFilterImpl_SetSyncSource
,
244 BaseFilterImpl_GetSyncSource
,
245 BaseFilterImpl_EnumPins
,
246 AVICompressor_FindPin
,
247 AVICompressor_QueryFilterInfo
,
248 BaseFilterImpl_JoinFilterGraph
,
249 AVICompressor_QueryVendorInfo
252 static IPin
* WINAPI
AVICompressor_GetPin(BaseFilter
*iface
, int pos
)
254 AVICompressor
*This
= impl_from_BaseFilter(iface
);
257 TRACE("(%p)->(%d)\n", This
, pos
);
261 ret
= &This
->in
->pin
.IPin_iface
;
264 ret
= &This
->out
->pin
.IPin_iface
;
267 TRACE("No pin %d\n", pos
);
275 static LONG WINAPI
AVICompressor_GetPinCount(BaseFilter
*iface
)
280 static const BaseFilterFuncTable filter_func_table
= {
281 AVICompressor_GetPin
,
282 AVICompressor_GetPinCount
285 static AVICompressor
*impl_from_IPersistPropertyBag(IPersistPropertyBag
*iface
)
287 return CONTAINING_RECORD(iface
, AVICompressor
, IPersistPropertyBag_iface
);
290 static HRESULT WINAPI
AVICompressorPropertyBag_QueryInterface(IPersistPropertyBag
*iface
, REFIID riid
, void **ppv
)
292 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
293 return IBaseFilter_QueryInterface(&This
->filter
.IBaseFilter_iface
, riid
, ppv
);
296 static ULONG WINAPI
AVICompressorPropertyBag_AddRef(IPersistPropertyBag
*iface
)
298 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
299 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
302 static ULONG WINAPI
AVICompressorPropertyBag_Release(IPersistPropertyBag
*iface
)
304 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
305 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
308 static HRESULT WINAPI
AVICompressorPropertyBag_GetClassID(IPersistPropertyBag
*iface
, CLSID
*pClassID
)
310 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
311 return IBaseFilter_GetClassID(&This
->filter
.IBaseFilter_iface
, pClassID
);
314 static HRESULT WINAPI
AVICompressorPropertyBag_InitNew(IPersistPropertyBag
*iface
)
316 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
317 FIXME("(%p)->()\n", This
);
321 static HRESULT WINAPI
AVICompressorPropertyBag_Load(IPersistPropertyBag
*iface
, IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
323 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
328 static const WCHAR fcc_handlerW
[] = {'F','c','c','H','a','n','d','l','e','r',0};
330 TRACE("(%p)->(%p %p)\n", This
, pPropBag
, pErrorLog
);
333 hres
= IPropertyBag_Read(pPropBag
, fcc_handlerW
, &v
, NULL
);
335 WARN("Could not read FccHandler: %08x\n", hres
);
339 if(V_VT(&v
) != VT_BSTR
) {
340 FIXME("Got vt %d\n", V_VT(&v
));
346 TRACE("FccHandler = %s\n", debugstr_w(str
));
347 if(SysStringLen(str
) != 4) {
348 FIXME("Invalid FccHandler len\n");
353 This
->fcc_handler
= FCC(str
[0], str
[1], str
[2], str
[3]);
358 static HRESULT WINAPI
AVICompressorPropertyBag_Save(IPersistPropertyBag
*iface
, IPropertyBag
*pPropBag
,
359 BOOL fClearDirty
, BOOL fSaveAllProperties
)
361 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
362 FIXME("(%p)->(%p %x %x)\n", This
, pPropBag
, fClearDirty
, fSaveAllProperties
);
366 static const IPersistPropertyBagVtbl PersistPropertyBagVtbl
= {
367 AVICompressorPropertyBag_QueryInterface
,
368 AVICompressorPropertyBag_AddRef
,
369 AVICompressorPropertyBag_Release
,
370 AVICompressorPropertyBag_GetClassID
,
371 AVICompressorPropertyBag_InitNew
,
372 AVICompressorPropertyBag_Load
,
373 AVICompressorPropertyBag_Save
376 static inline AVICompressor
*impl_from_IPin(IPin
*iface
)
378 BasePin
*bp
= CONTAINING_RECORD(iface
, BasePin
, IPin_iface
);
379 return impl_from_IBaseFilter(bp
->pinInfo
.pFilter
);
382 static HRESULT WINAPI
AVICompressorIn_QueryInterface(IPin
*iface
, REFIID riid
, void **ppv
)
384 return BaseInputPinImpl_QueryInterface(iface
, riid
, ppv
);
387 static ULONG WINAPI
AVICompressorIn_AddRef(IPin
*iface
)
389 AVICompressor
*This
= impl_from_IPin(iface
);
390 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
393 static ULONG WINAPI
AVICompressorIn_Release(IPin
*iface
)
395 AVICompressor
*This
= impl_from_IPin(iface
);
396 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
399 static HRESULT WINAPI
AVICompressorIn_ReceiveConnection(IPin
*iface
,
400 IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
402 AVICompressor
*This
= impl_from_IPin(iface
);
405 TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", This
, pConnector
, pmt
);
406 dump_AM_MEDIA_TYPE(pmt
);
408 hres
= BaseInputPinImpl_ReceiveConnection(iface
, pConnector
, pmt
);
412 hres
= fill_format_info(This
, (VIDEOINFOHEADER
*)pmt
->pbFormat
);
414 BasePinImpl_Disconnect(iface
);
418 static HRESULT WINAPI
AVICompressorIn_Disconnect(IPin
*iface
)
420 AVICompressor
*This
= impl_from_IPin(iface
);
423 TRACE("(%p)\n", This
);
425 hres
= BasePinImpl_Disconnect(iface
);
429 heap_free(This
->videoinfo
);
430 This
->videoinfo
= NULL
;
434 static const IPinVtbl AVICompressorInputPinVtbl
= {
435 AVICompressorIn_QueryInterface
,
436 AVICompressorIn_AddRef
,
437 AVICompressorIn_Release
,
438 BaseInputPinImpl_Connect
,
439 AVICompressorIn_ReceiveConnection
,
440 AVICompressorIn_Disconnect
,
441 BasePinImpl_ConnectedTo
,
442 BasePinImpl_ConnectionMediaType
,
443 BasePinImpl_QueryPinInfo
,
444 BasePinImpl_QueryDirection
,
446 BasePinImpl_QueryAccept
,
447 BasePinImpl_EnumMediaTypes
,
448 BasePinImpl_QueryInternalConnections
,
449 BaseInputPinImpl_EndOfStream
,
450 BaseInputPinImpl_BeginFlush
,
451 BaseInputPinImpl_EndFlush
,
452 BaseInputPinImpl_NewSegment
455 static HRESULT WINAPI
AVICompressorIn_CheckMediaType(BasePin
*base
, const AM_MEDIA_TYPE
*pmt
)
457 AVICompressor
*This
= impl_from_BasePin(base
);
458 VIDEOINFOHEADER
*videoinfo
;
462 TRACE("(%p)->(AM_MEDIA_TYPE(%p))\n", base
, pmt
);
463 dump_AM_MEDIA_TYPE(pmt
);
465 if(!IsEqualIID(&pmt
->majortype
, &MEDIATYPE_Video
))
468 if(!IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
469 FIXME("formattype %s unsupported\n", debugstr_guid(&pmt
->formattype
));
473 hres
= ensure_driver(This
);
477 videoinfo
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
478 res
= ICCompressQuery(This
->hic
, &videoinfo
->bmiHeader
, NULL
);
479 return res
== ICERR_OK
? S_OK
: S_FALSE
;
482 static LONG WINAPI
AVICompressorIn_GetMediaTypeVersion(BasePin
*base
)
487 static HRESULT WINAPI
AVICompressorIn_GetMediaType(BasePin
*base
, int iPosition
, AM_MEDIA_TYPE
*amt
)
489 TRACE("(%p)->(%d %p)\n", base
, iPosition
, amt
);
493 static HRESULT WINAPI
AVICompressorIn_Receive(BaseInputPin
*base
, IMediaSample
*pSample
)
495 AVICompressor
*This
= impl_from_BasePin(&base
->pin
);
496 VIDEOINFOHEADER
*src_videoinfo
;
497 REFERENCE_TIME start
, stop
;
498 IMediaSample
*out_sample
;
500 IMediaSample2
*sample2
;
501 DWORD comp_flags
= 0;
508 TRACE("(%p)->(%p)\n", base
, pSample
);
511 FIXME("Driver not loaded\n");
515 hres
= IMediaSample_QueryInterface(pSample
, &IID_IMediaSample2
, (void**)&sample2
);
516 if(SUCCEEDED(hres
)) {
517 FIXME("Use IMediaSample2\n");
518 IMediaSample2_Release(sample2
);
521 is_preroll
= IMediaSample_IsPreroll(pSample
) == S_OK
;
522 sync_point
= IMediaSample_IsSyncPoint(pSample
) == S_OK
;
524 hres
= IMediaSample_GetTime(pSample
, &start
, &stop
);
526 WARN("GetTime failed: %08x\n", hres
);
530 hres
= IMediaSample_GetMediaType(pSample
, &mt
);
534 hres
= IMediaSample_GetPointer(pSample
, &ptr
);
536 WARN("GetPointer failed: %08x\n", hres
);
540 hres
= BaseOutputPinImpl_GetDeliveryBuffer(This
->out
, &out_sample
, &start
, &stop
, 0);
544 hres
= IMediaSample_GetPointer(out_sample
, &buf
);
548 if((This
->driver_flags
& VIDCF_TEMPORAL
) && !(This
->driver_flags
& VIDCF_FASTTEMPORALC
))
549 FIXME("Unsupported temporal compression\n");
551 src_videoinfo
= (VIDEOINFOHEADER
*)This
->in
->pin
.mtCurrent
.pbFormat
;
552 This
->videoinfo
->bmiHeader
.biSizeImage
= This
->max_frame_size
;
553 res
= ICCompress(This
->hic
, sync_point
? ICCOMPRESS_KEYFRAME
: 0, &This
->videoinfo
->bmiHeader
, buf
,
554 &src_videoinfo
->bmiHeader
, ptr
, 0, &comp_flags
, This
->frame_cnt
, 0, 0, NULL
, NULL
);
555 if(res
!= ICERR_OK
) {
556 WARN("ICCompress failed: %d\n", res
);
557 IMediaSample_Release(out_sample
);
561 IMediaSample_SetActualDataLength(out_sample
, This
->videoinfo
->bmiHeader
.biSizeImage
);
562 IMediaSample_SetPreroll(out_sample
, is_preroll
);
563 IMediaSample_SetSyncPoint(out_sample
, (comp_flags
&AVIIF_KEYFRAME
) != 0);
564 IMediaSample_SetDiscontinuity(out_sample
, (IMediaSample_IsDiscontinuity(pSample
) == S_OK
));
566 if (IMediaSample_GetMediaTime(pSample
, &start
, &stop
) == S_OK
)
567 IMediaSample_SetMediaTime(out_sample
, &start
, &stop
);
569 IMediaSample_SetMediaTime(out_sample
, NULL
, NULL
);
571 hres
= BaseOutputPinImpl_Deliver(This
->out
, out_sample
);
573 WARN("Deliver failed: %08x\n", hres
);
575 IMediaSample_Release(out_sample
);
580 static const BaseInputPinFuncTable AVICompressorBaseInputPinVtbl
= {
582 AVICompressorIn_CheckMediaType
,
584 AVICompressorIn_GetMediaTypeVersion
,
585 AVICompressorIn_GetMediaType
587 AVICompressorIn_Receive
590 static HRESULT WINAPI
AVICompressorOut_QueryInterface(IPin
*iface
, REFIID riid
, void **ppv
)
592 return BaseInputPinImpl_QueryInterface(iface
, riid
, ppv
);
595 static ULONG WINAPI
AVICompressorOut_AddRef(IPin
*iface
)
597 AVICompressor
*This
= impl_from_IPin(iface
);
598 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
601 static ULONG WINAPI
AVICompressorOut_Release(IPin
*iface
)
603 AVICompressor
*This
= impl_from_IPin(iface
);
604 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
607 static const IPinVtbl AVICompressorOutputPinVtbl
= {
608 AVICompressorOut_QueryInterface
,
609 AVICompressorOut_AddRef
,
610 AVICompressorOut_Release
,
611 BaseOutputPinImpl_Connect
,
612 BaseOutputPinImpl_ReceiveConnection
,
613 BaseOutputPinImpl_Disconnect
,
614 BasePinImpl_ConnectedTo
,
615 BasePinImpl_ConnectionMediaType
,
616 BasePinImpl_QueryPinInfo
,
617 BasePinImpl_QueryDirection
,
619 BasePinImpl_QueryAccept
,
620 BasePinImpl_EnumMediaTypes
,
621 BasePinImpl_QueryInternalConnections
,
622 BaseOutputPinImpl_EndOfStream
,
623 BaseOutputPinImpl_BeginFlush
,
624 BaseOutputPinImpl_EndFlush
,
625 BasePinImpl_NewSegment
628 static LONG WINAPI
AVICompressorOut_GetMediaTypeVersion(BasePin
*base
)
630 FIXME("(%p)\n", base
);
634 static HRESULT WINAPI
AVICompressorOut_GetMediaType(BasePin
*base
, int iPosition
, AM_MEDIA_TYPE
*amt
)
636 AVICompressor
*This
= impl_from_IBaseFilter(base
->pinInfo
.pFilter
);
638 TRACE("(%p)->(%d %p)\n", base
, iPosition
, amt
);
640 if(iPosition
|| !This
->videoinfo
)
643 amt
->majortype
= MEDIATYPE_Video
;
644 amt
->subtype
= MEDIASUBTYPE_PCM
;
645 amt
->bFixedSizeSamples
= FALSE
;
646 amt
->bTemporalCompression
= (This
->driver_flags
& VIDCF_TEMPORAL
) != 0;
647 amt
->lSampleSize
= This
->in
->pin
.mtCurrent
.lSampleSize
;
648 amt
->formattype
= FORMAT_VideoInfo
;
650 amt
->cbFormat
= This
->videoinfo_size
;
651 amt
->pbFormat
= (BYTE
*)This
->videoinfo
;
655 static HRESULT WINAPI
AVICompressorOut_DecideBufferSize(BaseOutputPin
*base
, IMemAllocator
*alloc
, ALLOCATOR_PROPERTIES
*ppropInputRequest
)
657 AVICompressor
*This
= impl_from_BasePin(&base
->pin
);
658 ALLOCATOR_PROPERTIES actual
;
660 TRACE("(%p)\n", This
);
662 if (!ppropInputRequest
->cBuffers
)
663 ppropInputRequest
->cBuffers
= 1;
664 if (ppropInputRequest
->cbBuffer
< This
->max_frame_size
)
665 ppropInputRequest
->cbBuffer
= This
->max_frame_size
;
666 if (!ppropInputRequest
->cbAlign
)
667 ppropInputRequest
->cbAlign
= 1;
669 return IMemAllocator_SetProperties(alloc
, ppropInputRequest
, &actual
);
672 static HRESULT WINAPI
AVICompressorOut_DecideAllocator(BaseOutputPin
*base
,
673 IMemInputPin
*pPin
, IMemAllocator
**pAlloc
)
675 TRACE("(%p)->(%p %p)\n", base
, pPin
, pAlloc
);
676 return BaseOutputPinImpl_DecideAllocator(base
, pPin
, pAlloc
);
679 static HRESULT WINAPI
AVICompressorOut_BreakConnect(BaseOutputPin
*base
)
681 FIXME("(%p)\n", base
);
685 static const BaseOutputPinFuncTable AVICompressorBaseOutputPinVtbl
= {
688 BaseOutputPinImpl_AttemptConnection
,
689 AVICompressorOut_GetMediaTypeVersion
,
690 AVICompressorOut_GetMediaType
692 AVICompressorOut_DecideBufferSize
,
693 AVICompressorOut_DecideAllocator
,
694 AVICompressorOut_BreakConnect
697 IUnknown
* WINAPI
QCAP_createAVICompressor(IUnknown
*outer
, HRESULT
*phr
)
699 PIN_INFO in_pin_info
= {NULL
, PINDIR_INPUT
, {'I','n','p','u','t',0}};
700 PIN_INFO out_pin_info
= {NULL
, PINDIR_OUTPUT
, {'O','u','t','p','u','t',0}};
701 AVICompressor
*compressor
;
706 compressor
= heap_alloc_zero(sizeof(*compressor
));
708 *phr
= E_NOINTERFACE
;
712 BaseFilter_Init(&compressor
->filter
, &AVICompressorVtbl
, &CLSID_AVICo
,
713 (DWORD_PTR
)(__FILE__
": AVICompressor.csFilter"), &filter_func_table
);
715 compressor
->IPersistPropertyBag_iface
.lpVtbl
= &PersistPropertyBagVtbl
;
717 in_pin_info
.pFilter
= &compressor
->filter
.IBaseFilter_iface
;
718 hres
= BaseInputPin_Construct(&AVICompressorInputPinVtbl
, sizeof(BaseInputPin
), &in_pin_info
,
719 &AVICompressorBaseInputPinVtbl
, &compressor
->filter
.csFilter
, NULL
, (IPin
**)&compressor
->in
);
721 IBaseFilter_Release(&compressor
->filter
.IBaseFilter_iface
);
726 out_pin_info
.pFilter
= &compressor
->filter
.IBaseFilter_iface
;
727 hres
= BaseOutputPin_Construct(&AVICompressorOutputPinVtbl
, sizeof(BaseOutputPin
), &out_pin_info
,
728 &AVICompressorBaseOutputPinVtbl
, &compressor
->filter
.csFilter
, (IPin
**)&compressor
->out
);
730 IBaseFilter_Release(&compressor
->filter
.IBaseFilter_iface
);
736 return (IUnknown
*)&compressor
->filter
.IBaseFilter_iface
;