2 * Implementation of MediaStream Filter
4 * Copyright 2008, 2012 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/debug.h"
29 #include "wine/strmbase.h"
31 #include "amstream_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(amstream
);
38 typedef struct MediaStreamFilter_InputPin
41 } MediaStreamFilter_InputPin
;
43 static const IPinVtbl MediaStreamFilter_InputPin_Vtbl
=
45 BaseInputPinImpl_QueryInterface
,
47 BaseInputPinImpl_Release
,
48 BaseInputPinImpl_Connect
,
49 BaseInputPinImpl_ReceiveConnection
,
50 BasePinImpl_Disconnect
,
51 BasePinImpl_ConnectedTo
,
52 BasePinImpl_ConnectionMediaType
,
53 BasePinImpl_QueryPinInfo
,
54 BasePinImpl_QueryDirection
,
56 BasePinImpl_QueryAccept
,
57 BasePinImpl_EnumMediaTypes
,
58 BasePinImpl_QueryInternalConnections
,
59 BaseInputPinImpl_EndOfStream
,
60 BaseInputPinImpl_BeginFlush
,
61 BaseInputPinImpl_EndFlush
,
62 BasePinImpl_NewSegment
68 IMediaStream
** streams
;
70 } IMediaStreamFilterImpl
;
72 static inline IMediaStreamFilterImpl
*impl_from_IMediaStreamFilter(IMediaStreamFilter
*iface
)
74 return CONTAINING_RECORD(iface
, IMediaStreamFilterImpl
, filter
);
77 static HRESULT WINAPI
BasePinImpl_CheckMediaType(BasePin
*This
, const AM_MEDIA_TYPE
*pmt
)
82 static LONG WINAPI
BasePinImp_GetMediaTypeVersion(BasePin
*This
)
87 static HRESULT WINAPI
BasePinImp_GetMediaType(BasePin
*This
, int iPosition
, AM_MEDIA_TYPE
*amt
)
92 static const BasePinFuncTable input_BaseFuncTable
= {
93 BasePinImpl_CheckMediaType
,
95 BasePinImp_GetMediaTypeVersion
,
96 BasePinImp_GetMediaType
99 static const BaseInputPinFuncTable input_BaseInputFuncTable
= {
103 /*** IUnknown methods ***/
105 static HRESULT WINAPI
MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter
*iface
, REFIID riid
,
108 IMediaStreamFilterImpl
*This
= impl_from_IMediaStreamFilter(iface
);
110 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
114 if (IsEqualIID(riid
, &IID_IUnknown
))
116 else if (IsEqualIID(riid
, &IID_IPersist
))
118 else if (IsEqualIID(riid
, &IID_IMediaFilter
))
120 else if (IsEqualIID(riid
, &IID_IBaseFilter
))
122 else if (IsEqualIID(riid
, &IID_IMediaStreamFilter
))
127 IUnknown_AddRef((IUnknown
*)(*ppv
));
131 return E_NOINTERFACE
;
134 static ULONG WINAPI
MediaStreamFilterImpl_AddRef(IMediaStreamFilter
*iface
)
136 return BaseFilterImpl_AddRef((IBaseFilter
*)iface
);
139 static ULONG WINAPI
MediaStreamFilterImpl_Release(IMediaStreamFilter
*iface
)
141 IMediaStreamFilterImpl
*This
= impl_from_IMediaStreamFilter(iface
);
142 ULONG refCount
= BaseFilterImpl_Release((IBaseFilter
*)iface
);
144 TRACE("(%p)->() Release from %d\n", iface
, refCount
+ 1);
149 for (i
= 0; i
< This
->nb_streams
; i
++)
151 IMediaStream_Release(This
->streams
[i
]);
152 IPin_Release(This
->pins
[i
]);
154 HeapFree(GetProcessHeap(), 0, This
);
160 /*** IPersist methods ***/
162 static HRESULT WINAPI
MediaStreamFilterImpl_GetClassID(IMediaStreamFilter
* iface
, CLSID
* pClsid
)
164 return BaseFilterImpl_GetClassID((IBaseFilter
*)iface
, pClsid
);
167 /*** IBaseFilter methods ***/
169 static HRESULT WINAPI
MediaStreamFilterImpl_Stop(IMediaStreamFilter
* iface
)
171 FIXME("(%p)->(): Stub!\n", iface
);
176 static HRESULT WINAPI
MediaStreamFilterImpl_Pause(IMediaStreamFilter
* iface
)
178 FIXME("(%p)->(): Stub!\n", iface
);
183 static HRESULT WINAPI
MediaStreamFilterImpl_Run(IMediaStreamFilter
* iface
, REFERENCE_TIME tStart
)
185 FIXME("(%p)->(%s): Stub!\n", iface
, wine_dbgstr_longlong(tStart
));
190 static HRESULT WINAPI
MediaStreamFilterImpl_GetState(IMediaStreamFilter
* iface
, DWORD dwMilliSecsTimeout
, FILTER_STATE
*pState
)
192 return BaseFilterImpl_GetState((IBaseFilter
*)iface
, dwMilliSecsTimeout
, pState
);
195 static HRESULT WINAPI
MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter
* iface
, IReferenceClock
*pClock
)
197 return BaseFilterImpl_SetSyncSource((IBaseFilter
*)iface
, pClock
);
200 static HRESULT WINAPI
MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter
* iface
, IReferenceClock
**ppClock
)
202 return BaseFilterImpl_GetSyncSource((IBaseFilter
*)iface
, ppClock
);
205 static HRESULT WINAPI
MediaStreamFilterImpl_EnumPins(IMediaStreamFilter
* iface
, IEnumPins
**ppEnum
)
207 return BaseFilterImpl_EnumPins((IBaseFilter
*)iface
, ppEnum
);
210 static HRESULT WINAPI
MediaStreamFilterImpl_FindPin(IMediaStreamFilter
* iface
, LPCWSTR Id
, IPin
**ppPin
)
212 FIXME("(%p)->(%s,%p): Stub!\n", iface
, debugstr_w(Id
), ppPin
);
217 static HRESULT WINAPI
MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter
* iface
, FILTER_INFO
*pInfo
)
219 return BaseFilterImpl_QueryFilterInfo((IBaseFilter
*)iface
, pInfo
);
222 static HRESULT WINAPI
MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter
* iface
, IFilterGraph
*pGraph
, LPCWSTR pName
)
224 return BaseFilterImpl_JoinFilterGraph((IBaseFilter
*)iface
, pGraph
, pName
);
227 static HRESULT WINAPI
MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter
* iface
, LPWSTR
*pVendorInfo
)
229 return BaseFilterImpl_QueryVendorInfo((IBaseFilter
*)iface
, pVendorInfo
);
232 /*** IMediaStreamFilter methods ***/
234 static HRESULT WINAPI
MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter
* iface
, IAMMediaStream
*pAMMediaStream
)
236 IMediaStreamFilterImpl
*This
= impl_from_IMediaStreamFilter(iface
);
237 IMediaStream
** streams
;
239 MediaStreamFilter_InputPin
* pin
;
244 TRACE("(%p)->(%p)\n", iface
, pAMMediaStream
);
246 streams
= CoTaskMemRealloc(This
->streams
, (This
->nb_streams
+ 1) * sizeof(IMediaStream
*));
248 return E_OUTOFMEMORY
;
249 This
->streams
= streams
;
250 pins
= CoTaskMemRealloc(This
->pins
, (This
->nb_streams
+ 1) * sizeof(IPin
*));
252 return E_OUTOFMEMORY
;
254 info
.pFilter
= (IBaseFilter
*)&This
->filter
;
255 info
.dir
= PINDIR_INPUT
;
256 hr
= IAMMediaStream_GetInformation(pAMMediaStream
, &purpose_id
, NULL
);
259 /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
260 info
.achName
[0] = 'I';
261 StringFromGUID2(&purpose_id
, info
.achName
+ 1, 40);
262 hr
= BaseInputPin_Construct(&MediaStreamFilter_InputPin_Vtbl
, &info
, &input_BaseFuncTable
, &input_BaseInputFuncTable
, &This
->filter
.csFilter
, NULL
, &This
->pins
[This
->nb_streams
]);
266 pin
= (MediaStreamFilter_InputPin
*)This
->pins
[This
->nb_streams
];
267 pin
->pin
.pin
.pinInfo
.pFilter
= (LPVOID
)This
;
268 This
->streams
[This
->nb_streams
] = (IMediaStream
*)pAMMediaStream
;
271 IMediaStream_AddRef((IMediaStream
*)pAMMediaStream
);
276 static HRESULT WINAPI
MediaStreamFilterImpl_GetMediaStream(IMediaStreamFilter
* iface
, REFMSPID idPurpose
, IMediaStream
**ppMediaStream
)
278 IMediaStreamFilterImpl
*This
= impl_from_IMediaStreamFilter(iface
);
282 TRACE("(%p)->(%s,%p)\n", iface
, debugstr_guid(idPurpose
), ppMediaStream
);
284 for (i
= 0; i
< This
->nb_streams
; i
++)
286 IMediaStream_GetInformation(This
->streams
[i
], &purpose_id
, NULL
);
287 if (IsEqualIID(&purpose_id
, idPurpose
))
289 *ppMediaStream
= This
->streams
[i
];
290 IMediaStream_AddRef(*ppMediaStream
);
295 return MS_E_NOSTREAM
;
298 static HRESULT WINAPI
MediaStreamFilterImpl_EnumMediaStreams(IMediaStreamFilter
* iface
, LONG Index
, IMediaStream
**ppMediaStream
)
300 FIXME("(%p)->(%d,%p): Stub!\n", iface
, Index
, ppMediaStream
);
305 static HRESULT WINAPI
MediaStreamFilterImpl_SupportSeeking(IMediaStreamFilter
* iface
, BOOL bRenderer
)
307 FIXME("(%p)->(%d): Stub!\n", iface
, bRenderer
);
312 static HRESULT WINAPI
MediaStreamFilterImpl_ReferenceTimeToStreamTime(IMediaStreamFilter
* iface
, REFERENCE_TIME
*pTime
)
314 FIXME("(%p)->(%p): Stub!\n", iface
, pTime
);
319 static HRESULT WINAPI
MediaStreamFilterImpl_GetCurrentStreamTime(IMediaStreamFilter
* iface
, REFERENCE_TIME
*pCurrentStreamTime
)
321 FIXME("(%p)->(%p): Stub!\n", iface
, pCurrentStreamTime
);
326 static HRESULT WINAPI
MediaStreamFilterImpl_WaitUntil(IMediaStreamFilter
* iface
, REFERENCE_TIME WaitStreamTime
)
328 FIXME("(%p)->(%s): Stub!\n", iface
, wine_dbgstr_longlong(WaitStreamTime
));
333 static HRESULT WINAPI
MediaStreamFilterImpl_Flush(IMediaStreamFilter
* iface
, BOOL bCancelEOS
)
335 FIXME("(%p)->(%d): Stub!\n", iface
, bCancelEOS
);
340 static HRESULT WINAPI
MediaStreamFilterImpl_EndOfStream(IMediaStreamFilter
* iface
)
342 FIXME("(%p)->(): Stub!\n", iface
);
347 static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl
=
349 MediaStreamFilterImpl_QueryInterface
,
350 MediaStreamFilterImpl_AddRef
,
351 MediaStreamFilterImpl_Release
,
352 MediaStreamFilterImpl_GetClassID
,
353 MediaStreamFilterImpl_Stop
,
354 MediaStreamFilterImpl_Pause
,
355 MediaStreamFilterImpl_Run
,
356 MediaStreamFilterImpl_GetState
,
357 MediaStreamFilterImpl_SetSyncSource
,
358 MediaStreamFilterImpl_GetSyncSource
,
359 MediaStreamFilterImpl_EnumPins
,
360 MediaStreamFilterImpl_FindPin
,
361 MediaStreamFilterImpl_QueryFilterInfo
,
362 MediaStreamFilterImpl_JoinFilterGraph
,
363 MediaStreamFilterImpl_QueryVendorInfo
,
364 MediaStreamFilterImpl_AddMediaStream
,
365 MediaStreamFilterImpl_GetMediaStream
,
366 MediaStreamFilterImpl_EnumMediaStreams
,
367 MediaStreamFilterImpl_SupportSeeking
,
368 MediaStreamFilterImpl_ReferenceTimeToStreamTime
,
369 MediaStreamFilterImpl_GetCurrentStreamTime
,
370 MediaStreamFilterImpl_WaitUntil
,
371 MediaStreamFilterImpl_Flush
,
372 MediaStreamFilterImpl_EndOfStream
375 static IPin
* WINAPI
MediaStreamFilterImpl_GetPin(BaseFilter
*iface
, int pos
)
377 IMediaStreamFilterImpl
* This
= (IMediaStreamFilterImpl
*)iface
;
379 if (pos
< This
->nb_streams
)
381 IPin_AddRef(This
->pins
[pos
]);
382 return This
->pins
[pos
];
388 static LONG WINAPI
MediaStreamFilterImpl_GetPinCount(BaseFilter
*iface
)
390 IMediaStreamFilterImpl
* This
= (IMediaStreamFilterImpl
*)iface
;
392 return This
->nb_streams
;
395 static const BaseFilterFuncTable BaseFuncTable
= {
396 MediaStreamFilterImpl_GetPin
,
397 MediaStreamFilterImpl_GetPinCount
400 HRESULT
MediaStreamFilter_create(IUnknown
*pUnkOuter
, void **ppObj
)
402 IMediaStreamFilterImpl
* object
;
404 TRACE("(%p,%p)\n", pUnkOuter
, ppObj
);
407 return CLASS_E_NOAGGREGATION
;
409 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IMediaStreamFilterImpl
));
412 ERR("Out of memory\n");
413 return E_OUTOFMEMORY
;
416 BaseFilter_Init(&object
->filter
, (IBaseFilterVtbl
*)&MediaStreamFilter_Vtbl
, &CLSID_MediaStreamFilter
, (DWORD_PTR
)(__FILE__
": MediaStreamFilterImpl.csFilter"), &BaseFuncTable
);