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"
32 #include "wine/heap.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(qcap
);
38 IPersistPropertyBag IPersistPropertyBag_iface
;
46 VIDEOINFOHEADER
*videoinfo
;
47 size_t videoinfo_size
;
54 static inline AVICompressor
*impl_from_BaseFilter(BaseFilter
*filter
)
56 return CONTAINING_RECORD(filter
, AVICompressor
, filter
);
59 static inline AVICompressor
*impl_from_IBaseFilter(IBaseFilter
*iface
)
61 BaseFilter
*filter
= CONTAINING_RECORD(iface
, BaseFilter
, IBaseFilter_iface
);
62 return impl_from_BaseFilter(filter
);
65 static inline AVICompressor
*impl_from_BasePin(BasePin
*pin
)
67 return impl_from_IBaseFilter(pin
->pinInfo
.pFilter
);
70 static HRESULT
ensure_driver(AVICompressor
*This
)
75 This
->hic
= ICOpen(FCC('v','i','d','c'), This
->fcc_handler
, ICMODE_COMPRESS
);
77 FIXME("ICOpen failed\n");
84 static HRESULT
fill_format_info(AVICompressor
*This
, VIDEOINFOHEADER
*src_videoinfo
)
90 hres
= ensure_driver(This
);
94 size
= ICGetInfo(This
->hic
, &icinfo
, sizeof(icinfo
));
95 if(size
!= sizeof(icinfo
))
98 size
= ICCompressGetFormatSize(This
->hic
, &src_videoinfo
->bmiHeader
);
100 FIXME("ICCompressGetFormatSize failed\n");
104 size
+= FIELD_OFFSET(VIDEOINFOHEADER
, bmiHeader
);
105 This
->videoinfo
= heap_alloc(size
);
107 return E_OUTOFMEMORY
;
109 This
->videoinfo_size
= size
;
110 This
->driver_flags
= icinfo
.dwFlags
;
111 memset(This
->videoinfo
, 0, sizeof(*This
->videoinfo
));
112 ICCompressGetFormat(This
->hic
, &src_videoinfo
->bmiHeader
, &This
->videoinfo
->bmiHeader
);
114 This
->videoinfo
->dwBitRate
= 10000000/src_videoinfo
->AvgTimePerFrame
* This
->videoinfo
->bmiHeader
.biSizeImage
* 8;
115 This
->videoinfo
->AvgTimePerFrame
= src_videoinfo
->AvgTimePerFrame
;
116 This
->max_frame_size
= This
->videoinfo
->bmiHeader
.biSizeImage
;
120 static HRESULT WINAPI
AVICompressor_QueryInterface(IBaseFilter
*iface
, REFIID riid
, void **ppv
)
122 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
124 if(IsEqualIID(riid
, &IID_IUnknown
)) {
125 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
126 *ppv
= &This
->filter
.IBaseFilter_iface
;
127 }else if(IsEqualIID(riid
, &IID_IPersist
)) {
128 TRACE("(%p)->(IID_IPersist %p)\n", This
, ppv
);
129 *ppv
= &This
->filter
.IBaseFilter_iface
;
130 }else if(IsEqualIID(riid
, &IID_IMediaFilter
)) {
131 TRACE("(%p)->(IID_IMediaFilter %p)\n", This
, ppv
);
132 *ppv
= &This
->filter
.IBaseFilter_iface
;
133 }else if(IsEqualIID(riid
, &IID_IBaseFilter
)) {
134 TRACE("(%p)->(IID_IBaseFilter %p)\n", This
, ppv
);
135 *ppv
= &This
->filter
.IBaseFilter_iface
;
136 }else if(IsEqualIID(riid
, &IID_IPersistPropertyBag
)) {
137 TRACE("(%p)->(IID_IPersistPropertyBag %p)\n", This
, ppv
);
138 *ppv
= &This
->IPersistPropertyBag_iface
;
140 FIXME("no interface for %s\n", debugstr_guid(riid
));
142 return E_NOINTERFACE
;
145 IUnknown_AddRef((IUnknown
*)*ppv
);
150 static ULONG WINAPI
AVICompressor_Release(IBaseFilter
*iface
)
152 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
153 ULONG ref
= BaseFilterImpl_Release(&This
->filter
.IBaseFilter_iface
);
155 TRACE("(%p) ref=%d\n", This
, ref
);
160 heap_free(This
->videoinfo
);
162 BaseInputPinImpl_Release(&This
->in
->pin
.IPin_iface
);
164 BaseOutputPinImpl_Release(&This
->out
->pin
.IPin_iface
);
171 static HRESULT WINAPI
AVICompressor_Stop(IBaseFilter
*iface
)
173 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
175 TRACE("(%p)\n", This
);
177 if(This
->filter
.state
== State_Stopped
)
180 ICCompressEnd(This
->hic
);
181 This
->filter
.state
= State_Stopped
;
185 static HRESULT WINAPI
AVICompressor_Pause(IBaseFilter
*iface
)
187 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
188 FIXME("(%p)\n", This
);
192 static HRESULT WINAPI
AVICompressor_Run(IBaseFilter
*iface
, REFERENCE_TIME tStart
)
194 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
197 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_longlong(tStart
));
199 if(This
->filter
.state
== State_Running
)
202 hres
= IMemAllocator_Commit(This
->out
->pAllocator
);
204 FIXME("Commit failed: %08x\n", hres
);
210 This
->filter
.state
= State_Running
;
214 static HRESULT WINAPI
AVICompressor_FindPin(IBaseFilter
*iface
, LPCWSTR Id
, IPin
**ppPin
)
216 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
217 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Id
), ppPin
);
218 return VFW_E_NOT_FOUND
;
221 static HRESULT WINAPI
AVICompressor_QueryFilterInfo(IBaseFilter
*iface
, FILTER_INFO
*pInfo
)
223 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
224 FIXME("(%p)->(%p)\n", This
, pInfo
);
228 static HRESULT WINAPI
AVICompressor_QueryVendorInfo(IBaseFilter
*iface
, LPWSTR
*pVendorInfo
)
230 AVICompressor
*This
= impl_from_IBaseFilter(iface
);
231 FIXME("(%p)->(%p)\n", This
, pVendorInfo
);
235 static const IBaseFilterVtbl AVICompressorVtbl
= {
236 AVICompressor_QueryInterface
,
237 BaseFilterImpl_AddRef
,
238 AVICompressor_Release
,
239 BaseFilterImpl_GetClassID
,
243 BaseFilterImpl_GetState
,
244 BaseFilterImpl_SetSyncSource
,
245 BaseFilterImpl_GetSyncSource
,
246 BaseFilterImpl_EnumPins
,
247 AVICompressor_FindPin
,
248 AVICompressor_QueryFilterInfo
,
249 BaseFilterImpl_JoinFilterGraph
,
250 AVICompressor_QueryVendorInfo
253 static IPin
* WINAPI
AVICompressor_GetPin(BaseFilter
*iface
, int pos
)
255 AVICompressor
*This
= impl_from_BaseFilter(iface
);
258 TRACE("(%p)->(%d)\n", This
, pos
);
262 ret
= &This
->in
->pin
.IPin_iface
;
265 ret
= &This
->out
->pin
.IPin_iface
;
268 TRACE("No pin %d\n", pos
);
276 static LONG WINAPI
AVICompressor_GetPinCount(BaseFilter
*iface
)
281 static const BaseFilterFuncTable filter_func_table
= {
282 AVICompressor_GetPin
,
283 AVICompressor_GetPinCount
286 static AVICompressor
*impl_from_IPersistPropertyBag(IPersistPropertyBag
*iface
)
288 return CONTAINING_RECORD(iface
, AVICompressor
, IPersistPropertyBag_iface
);
291 static HRESULT WINAPI
AVICompressorPropertyBag_QueryInterface(IPersistPropertyBag
*iface
, REFIID riid
, void **ppv
)
293 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
294 return IBaseFilter_QueryInterface(&This
->filter
.IBaseFilter_iface
, riid
, ppv
);
297 static ULONG WINAPI
AVICompressorPropertyBag_AddRef(IPersistPropertyBag
*iface
)
299 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
300 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
303 static ULONG WINAPI
AVICompressorPropertyBag_Release(IPersistPropertyBag
*iface
)
305 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
306 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
309 static HRESULT WINAPI
AVICompressorPropertyBag_GetClassID(IPersistPropertyBag
*iface
, CLSID
*pClassID
)
311 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
312 return IBaseFilter_GetClassID(&This
->filter
.IBaseFilter_iface
, pClassID
);
315 static HRESULT WINAPI
AVICompressorPropertyBag_InitNew(IPersistPropertyBag
*iface
)
317 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
318 FIXME("(%p)->()\n", This
);
322 static HRESULT WINAPI
AVICompressorPropertyBag_Load(IPersistPropertyBag
*iface
, IPropertyBag
*pPropBag
, IErrorLog
*pErrorLog
)
324 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
329 static const WCHAR fcc_handlerW
[] = {'F','c','c','H','a','n','d','l','e','r',0};
331 TRACE("(%p)->(%p %p)\n", This
, pPropBag
, pErrorLog
);
334 hres
= IPropertyBag_Read(pPropBag
, fcc_handlerW
, &v
, NULL
);
336 WARN("Could not read FccHandler: %08x\n", hres
);
340 if(V_VT(&v
) != VT_BSTR
) {
341 FIXME("Got vt %d\n", V_VT(&v
));
347 TRACE("FccHandler = %s\n", debugstr_w(str
));
348 if(SysStringLen(str
) != 4) {
349 FIXME("Invalid FccHandler len\n");
354 This
->fcc_handler
= FCC(str
[0], str
[1], str
[2], str
[3]);
359 static HRESULT WINAPI
AVICompressorPropertyBag_Save(IPersistPropertyBag
*iface
, IPropertyBag
*pPropBag
,
360 BOOL fClearDirty
, BOOL fSaveAllProperties
)
362 AVICompressor
*This
= impl_from_IPersistPropertyBag(iface
);
363 FIXME("(%p)->(%p %x %x)\n", This
, pPropBag
, fClearDirty
, fSaveAllProperties
);
367 static const IPersistPropertyBagVtbl PersistPropertyBagVtbl
= {
368 AVICompressorPropertyBag_QueryInterface
,
369 AVICompressorPropertyBag_AddRef
,
370 AVICompressorPropertyBag_Release
,
371 AVICompressorPropertyBag_GetClassID
,
372 AVICompressorPropertyBag_InitNew
,
373 AVICompressorPropertyBag_Load
,
374 AVICompressorPropertyBag_Save
377 static inline AVICompressor
*impl_from_IPin(IPin
*iface
)
379 BasePin
*bp
= CONTAINING_RECORD(iface
, BasePin
, IPin_iface
);
380 return impl_from_IBaseFilter(bp
->pinInfo
.pFilter
);
383 static HRESULT WINAPI
AVICompressorIn_QueryInterface(IPin
*iface
, REFIID riid
, void **ppv
)
385 return BaseInputPinImpl_QueryInterface(iface
, riid
, ppv
);
388 static ULONG WINAPI
AVICompressorIn_AddRef(IPin
*iface
)
390 AVICompressor
*This
= impl_from_IPin(iface
);
391 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
394 static ULONG WINAPI
AVICompressorIn_Release(IPin
*iface
)
396 AVICompressor
*This
= impl_from_IPin(iface
);
397 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
400 static HRESULT WINAPI
AVICompressorIn_ReceiveConnection(IPin
*iface
,
401 IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
403 AVICompressor
*This
= impl_from_IPin(iface
);
406 TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", This
, pConnector
, pmt
);
407 dump_AM_MEDIA_TYPE(pmt
);
409 hres
= BaseInputPinImpl_ReceiveConnection(iface
, pConnector
, pmt
);
413 hres
= fill_format_info(This
, (VIDEOINFOHEADER
*)pmt
->pbFormat
);
415 BasePinImpl_Disconnect(iface
);
419 static HRESULT WINAPI
AVICompressorIn_Disconnect(IPin
*iface
)
421 AVICompressor
*This
= impl_from_IPin(iface
);
424 TRACE("(%p)\n", This
);
426 hres
= BasePinImpl_Disconnect(iface
);
430 heap_free(This
->videoinfo
);
431 This
->videoinfo
= NULL
;
435 static const IPinVtbl AVICompressorInputPinVtbl
= {
436 AVICompressorIn_QueryInterface
,
437 AVICompressorIn_AddRef
,
438 AVICompressorIn_Release
,
439 BaseInputPinImpl_Connect
,
440 AVICompressorIn_ReceiveConnection
,
441 AVICompressorIn_Disconnect
,
442 BasePinImpl_ConnectedTo
,
443 BasePinImpl_ConnectionMediaType
,
444 BasePinImpl_QueryPinInfo
,
445 BasePinImpl_QueryDirection
,
447 BasePinImpl_QueryAccept
,
448 BasePinImpl_EnumMediaTypes
,
449 BasePinImpl_QueryInternalConnections
,
450 BaseInputPinImpl_EndOfStream
,
451 BaseInputPinImpl_BeginFlush
,
452 BaseInputPinImpl_EndFlush
,
453 BaseInputPinImpl_NewSegment
456 static HRESULT WINAPI
AVICompressorIn_CheckMediaType(BasePin
*base
, const AM_MEDIA_TYPE
*pmt
)
458 AVICompressor
*This
= impl_from_BasePin(base
);
459 VIDEOINFOHEADER
*videoinfo
;
463 TRACE("(%p)->(AM_MEDIA_TYPE(%p))\n", base
, pmt
);
464 dump_AM_MEDIA_TYPE(pmt
);
466 if(!IsEqualIID(&pmt
->majortype
, &MEDIATYPE_Video
))
469 if(!IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
470 FIXME("formattype %s unsupported\n", debugstr_guid(&pmt
->formattype
));
474 hres
= ensure_driver(This
);
478 videoinfo
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
479 res
= ICCompressQuery(This
->hic
, &videoinfo
->bmiHeader
, NULL
);
480 return res
== ICERR_OK
? S_OK
: S_FALSE
;
483 static LONG WINAPI
AVICompressorIn_GetMediaTypeVersion(BasePin
*base
)
488 static HRESULT WINAPI
AVICompressorIn_GetMediaType(BasePin
*base
, int iPosition
, AM_MEDIA_TYPE
*amt
)
490 TRACE("(%p)->(%d %p)\n", base
, iPosition
, amt
);
494 static HRESULT WINAPI
AVICompressorIn_Receive(BaseInputPin
*base
, IMediaSample
*pSample
)
496 AVICompressor
*This
= impl_from_BasePin(&base
->pin
);
497 VIDEOINFOHEADER
*src_videoinfo
;
498 REFERENCE_TIME start
, stop
;
499 IMediaSample
*out_sample
;
501 IMediaSample2
*sample2
;
502 DWORD comp_flags
= 0;
509 TRACE("(%p)->(%p)\n", base
, pSample
);
512 FIXME("Driver not loaded\n");
516 hres
= IMediaSample_QueryInterface(pSample
, &IID_IMediaSample2
, (void**)&sample2
);
517 if(SUCCEEDED(hres
)) {
518 FIXME("Use IMediaSample2\n");
519 IMediaSample2_Release(sample2
);
522 is_preroll
= IMediaSample_IsPreroll(pSample
) == S_OK
;
523 sync_point
= IMediaSample_IsSyncPoint(pSample
) == S_OK
;
525 hres
= IMediaSample_GetTime(pSample
, &start
, &stop
);
527 WARN("GetTime failed: %08x\n", hres
);
531 hres
= IMediaSample_GetMediaType(pSample
, &mt
);
535 hres
= IMediaSample_GetPointer(pSample
, &ptr
);
537 WARN("GetPointer failed: %08x\n", hres
);
541 hres
= BaseOutputPinImpl_GetDeliveryBuffer(This
->out
, &out_sample
, &start
, &stop
, 0);
545 hres
= IMediaSample_GetPointer(out_sample
, &buf
);
549 if((This
->driver_flags
& VIDCF_TEMPORAL
) && !(This
->driver_flags
& VIDCF_FASTTEMPORALC
))
550 FIXME("Unsupported temporal compression\n");
552 src_videoinfo
= (VIDEOINFOHEADER
*)This
->in
->pin
.mtCurrent
.pbFormat
;
553 This
->videoinfo
->bmiHeader
.biSizeImage
= This
->max_frame_size
;
554 res
= ICCompress(This
->hic
, sync_point
? ICCOMPRESS_KEYFRAME
: 0, &This
->videoinfo
->bmiHeader
, buf
,
555 &src_videoinfo
->bmiHeader
, ptr
, 0, &comp_flags
, This
->frame_cnt
, 0, 0, NULL
, NULL
);
556 if(res
!= ICERR_OK
) {
557 WARN("ICCompress failed: %d\n", res
);
558 IMediaSample_Release(out_sample
);
562 IMediaSample_SetActualDataLength(out_sample
, This
->videoinfo
->bmiHeader
.biSizeImage
);
563 IMediaSample_SetPreroll(out_sample
, is_preroll
);
564 IMediaSample_SetSyncPoint(out_sample
, (comp_flags
&AVIIF_KEYFRAME
) != 0);
565 IMediaSample_SetDiscontinuity(out_sample
, (IMediaSample_IsDiscontinuity(pSample
) == S_OK
));
567 if (IMediaSample_GetMediaTime(pSample
, &start
, &stop
) == S_OK
)
568 IMediaSample_SetMediaTime(out_sample
, &start
, &stop
);
570 IMediaSample_SetMediaTime(out_sample
, NULL
, NULL
);
572 hres
= BaseOutputPinImpl_Deliver(This
->out
, out_sample
);
574 WARN("Deliver failed: %08x\n", hres
);
576 IMediaSample_Release(out_sample
);
581 static const BaseInputPinFuncTable AVICompressorBaseInputPinVtbl
= {
583 AVICompressorIn_CheckMediaType
,
585 AVICompressorIn_GetMediaTypeVersion
,
586 AVICompressorIn_GetMediaType
588 AVICompressorIn_Receive
591 static HRESULT WINAPI
AVICompressorOut_QueryInterface(IPin
*iface
, REFIID riid
, void **ppv
)
593 return BaseInputPinImpl_QueryInterface(iface
, riid
, ppv
);
596 static ULONG WINAPI
AVICompressorOut_AddRef(IPin
*iface
)
598 AVICompressor
*This
= impl_from_IPin(iface
);
599 return IBaseFilter_AddRef(&This
->filter
.IBaseFilter_iface
);
602 static ULONG WINAPI
AVICompressorOut_Release(IPin
*iface
)
604 AVICompressor
*This
= impl_from_IPin(iface
);
605 return IBaseFilter_Release(&This
->filter
.IBaseFilter_iface
);
608 static const IPinVtbl AVICompressorOutputPinVtbl
= {
609 AVICompressorOut_QueryInterface
,
610 AVICompressorOut_AddRef
,
611 AVICompressorOut_Release
,
612 BaseOutputPinImpl_Connect
,
613 BaseOutputPinImpl_ReceiveConnection
,
614 BaseOutputPinImpl_Disconnect
,
615 BasePinImpl_ConnectedTo
,
616 BasePinImpl_ConnectionMediaType
,
617 BasePinImpl_QueryPinInfo
,
618 BasePinImpl_QueryDirection
,
620 BasePinImpl_QueryAccept
,
621 BasePinImpl_EnumMediaTypes
,
622 BasePinImpl_QueryInternalConnections
,
623 BaseOutputPinImpl_EndOfStream
,
624 BaseOutputPinImpl_BeginFlush
,
625 BaseOutputPinImpl_EndFlush
,
626 BasePinImpl_NewSegment
629 static LONG WINAPI
AVICompressorOut_GetMediaTypeVersion(BasePin
*base
)
631 FIXME("(%p)\n", base
);
635 static HRESULT WINAPI
AVICompressorOut_GetMediaType(BasePin
*base
, int iPosition
, AM_MEDIA_TYPE
*amt
)
637 AVICompressor
*This
= impl_from_IBaseFilter(base
->pinInfo
.pFilter
);
639 TRACE("(%p)->(%d %p)\n", base
, iPosition
, amt
);
641 if(iPosition
|| !This
->videoinfo
)
644 amt
->majortype
= MEDIATYPE_Video
;
645 amt
->subtype
= MEDIASUBTYPE_PCM
;
646 amt
->bFixedSizeSamples
= FALSE
;
647 amt
->bTemporalCompression
= (This
->driver_flags
& VIDCF_TEMPORAL
) != 0;
648 amt
->lSampleSize
= This
->in
->pin
.mtCurrent
.lSampleSize
;
649 amt
->formattype
= FORMAT_VideoInfo
;
651 amt
->cbFormat
= This
->videoinfo_size
;
652 amt
->pbFormat
= (BYTE
*)This
->videoinfo
;
656 static HRESULT WINAPI
AVICompressorOut_DecideBufferSize(BaseOutputPin
*base
, IMemAllocator
*alloc
, ALLOCATOR_PROPERTIES
*ppropInputRequest
)
658 AVICompressor
*This
= impl_from_BasePin(&base
->pin
);
659 ALLOCATOR_PROPERTIES actual
;
661 TRACE("(%p)\n", This
);
663 if (!ppropInputRequest
->cBuffers
)
664 ppropInputRequest
->cBuffers
= 1;
665 if (ppropInputRequest
->cbBuffer
< This
->max_frame_size
)
666 ppropInputRequest
->cbBuffer
= This
->max_frame_size
;
667 if (!ppropInputRequest
->cbAlign
)
668 ppropInputRequest
->cbAlign
= 1;
670 return IMemAllocator_SetProperties(alloc
, ppropInputRequest
, &actual
);
673 static HRESULT WINAPI
AVICompressorOut_DecideAllocator(BaseOutputPin
*base
,
674 IMemInputPin
*pPin
, IMemAllocator
**pAlloc
)
676 TRACE("(%p)->(%p %p)\n", base
, pPin
, pAlloc
);
677 return BaseOutputPinImpl_DecideAllocator(base
, pPin
, pAlloc
);
680 static HRESULT WINAPI
AVICompressorOut_BreakConnect(BaseOutputPin
*base
)
682 FIXME("(%p)\n", base
);
686 static const BaseOutputPinFuncTable AVICompressorBaseOutputPinVtbl
= {
689 BaseOutputPinImpl_AttemptConnection
,
690 AVICompressorOut_GetMediaTypeVersion
,
691 AVICompressorOut_GetMediaType
693 AVICompressorOut_DecideBufferSize
,
694 AVICompressorOut_DecideAllocator
,
695 AVICompressorOut_BreakConnect
698 IUnknown
* WINAPI
QCAP_createAVICompressor(IUnknown
*outer
, HRESULT
*phr
)
700 PIN_INFO in_pin_info
= {NULL
, PINDIR_INPUT
, {'I','n','p','u','t',0}};
701 PIN_INFO out_pin_info
= {NULL
, PINDIR_OUTPUT
, {'O','u','t','p','u','t',0}};
702 AVICompressor
*compressor
;
707 compressor
= heap_alloc_zero(sizeof(*compressor
));
709 *phr
= E_NOINTERFACE
;
713 BaseFilter_Init(&compressor
->filter
, &AVICompressorVtbl
, &CLSID_AVICo
,
714 (DWORD_PTR
)(__FILE__
": AVICompressor.csFilter"), &filter_func_table
);
716 compressor
->IPersistPropertyBag_iface
.lpVtbl
= &PersistPropertyBagVtbl
;
718 in_pin_info
.pFilter
= &compressor
->filter
.IBaseFilter_iface
;
719 hres
= BaseInputPin_Construct(&AVICompressorInputPinVtbl
, sizeof(BaseInputPin
), &in_pin_info
,
720 &AVICompressorBaseInputPinVtbl
, &compressor
->filter
.csFilter
, NULL
, (IPin
**)&compressor
->in
);
722 IBaseFilter_Release(&compressor
->filter
.IBaseFilter_iface
);
727 out_pin_info
.pFilter
= &compressor
->filter
.IBaseFilter_iface
;
728 hres
= BaseOutputPin_Construct(&AVICompressorOutputPinVtbl
, sizeof(BaseOutputPin
), &out_pin_info
,
729 &AVICompressorBaseOutputPinVtbl
, &compressor
->filter
.csFilter
, (IPin
**)&compressor
->out
);
731 IBaseFilter_Release(&compressor
->filter
.IBaseFilter_iface
);
737 return (IUnknown
*)&compressor
->filter
.IBaseFilter_iface
;