Christian Costa : amstream: Add the corresponding pin to every media stream added to the media stream filter + add tests .
Alexandre Julliard
julliard at winehq.org
Fri May 4 12:01:21 CDT 2012
Module: wine
Branch: master
Commit: dec3d502901d56839ee5240c1ee68158efdcfac1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dec3d502901d56839ee5240c1ee68158efdcfac1
Author: Christian Costa <titan.costa at gmail.com>
Date: Tue May 1 10:21:28 2012 +0200
amstream: Add the corresponding pin to every media stream added to the media stream filter + add tests.
---
dlls/amstream/mediastreamfilter.c | 96 +++++++++++++++++++++++++++++++++++--
dlls/amstream/tests/amstream.c | 48 ++++++++++++++++++
2 files changed, 140 insertions(+), 4 deletions(-)
diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c
index cd08490..ee9d970 100644
--- a/dlls/amstream/mediastreamfilter.c
+++ b/dlls/amstream/mediastreamfilter.c
@@ -1,7 +1,7 @@
/*
* Implementation of MediaStream Filter
*
- * Copyright 2008 Christian Costa
+ * Copyright 2008, 2012 Christian Costa
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,10 +35,38 @@
WINE_DEFAULT_DEBUG_CHANNEL(amstream);
+typedef struct MediaStreamFilter_InputPin
+{
+ BaseInputPin pin;
+} MediaStreamFilter_InputPin;
+
+static const IPinVtbl MediaStreamFilter_InputPin_Vtbl =
+{
+ BaseInputPinImpl_QueryInterface,
+ BasePinImpl_AddRef,
+ BaseInputPinImpl_Release,
+ BaseInputPinImpl_Connect,
+ BaseInputPinImpl_ReceiveConnection,
+ BasePinImpl_Disconnect,
+ BasePinImpl_ConnectedTo,
+ BasePinImpl_ConnectionMediaType,
+ BasePinImpl_QueryPinInfo,
+ BasePinImpl_QueryDirection,
+ BasePinImpl_QueryId,
+ BasePinImpl_QueryAccept,
+ BasePinImpl_EnumMediaTypes,
+ BasePinImpl_QueryInternalConnections,
+ BaseInputPinImpl_EndOfStream,
+ BaseInputPinImpl_BeginFlush,
+ BaseInputPinImpl_EndFlush,
+ BasePinImpl_NewSegment
+};
+
typedef struct {
BaseFilter filter;
ULONG nb_streams;
IMediaStream** streams;
+ IPin** pins;
} IMediaStreamFilterImpl;
static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
@@ -46,6 +74,32 @@ static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamF
return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter);
}
+static HRESULT WINAPI BasePinImpl_CheckMediaType(BasePin *This, const AM_MEDIA_TYPE *pmt)
+{
+ return S_FALSE;
+}
+
+static LONG WINAPI BasePinImp_GetMediaTypeVersion(BasePin *This)
+{
+ return 0;
+}
+
+static HRESULT WINAPI BasePinImp_GetMediaType(BasePin *This, int iPosition, AM_MEDIA_TYPE *amt)
+{
+ return S_FALSE;
+}
+
+static const BasePinFuncTable input_BaseFuncTable = {
+ BasePinImpl_CheckMediaType,
+ NULL,
+ BasePinImp_GetMediaTypeVersion,
+ BasePinImp_GetMediaType
+};
+
+static const BaseInputPinFuncTable input_BaseInputFuncTable = {
+ NULL
+};
+
/*** IUnknown methods ***/
static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid,
@@ -93,7 +147,10 @@ static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface)
{
int i;
for (i = 0; i < This->nb_streams; i++)
+ {
IMediaStream_Release(This->streams[i]);
+ IPin_Release(This->pins[i]);
+ }
HeapFree(GetProcessHeap(), 0, This);
}
@@ -178,6 +235,11 @@ static HRESULT WINAPI MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter* i
{
IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
IMediaStream** streams;
+ IPin** pins;
+ MediaStreamFilter_InputPin* pin;
+ HRESULT hr;
+ PIN_INFO info;
+ MSPID purpose_id;
TRACE("(%p)->(%p)\n", iface, pAMMediaStream);
@@ -185,6 +247,24 @@ static HRESULT WINAPI MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter* i
if (!streams)
return E_OUTOFMEMORY;
This->streams = streams;
+ pins = CoTaskMemRealloc(This->pins, (This->nb_streams + 1) * sizeof(IPin*));
+ if (!pins)
+ return E_OUTOFMEMORY;
+ This->pins = pins;
+ info.pFilter = (IBaseFilter*)&This->filter;
+ info.dir = PINDIR_INPUT;
+ hr = IAMMediaStream_GetInformation(pAMMediaStream, &purpose_id, NULL);
+ if (FAILED(hr))
+ return hr;
+ /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
+ info.achName[0] = 'I';
+ StringFromGUID2(&purpose_id, info.achName + 1, 40);
+ hr = BaseInputPin_Construct(&MediaStreamFilter_InputPin_Vtbl, &info, &input_BaseFuncTable, &input_BaseInputFuncTable, &This->filter.csFilter, NULL, &This->pins[This->nb_streams]);
+ if (FAILED(hr))
+ return hr;
+
+ pin = (MediaStreamFilter_InputPin*)This->pins[This->nb_streams];
+ pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
This->streams[This->nb_streams] = (IMediaStream*)pAMMediaStream;
This->nb_streams++;
@@ -294,14 +374,22 @@ static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl =
static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos)
{
- /* No pins */
+ IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface;
+
+ if (pos < This->nb_streams)
+ {
+ IPin_AddRef(This->pins[pos]);
+ return This->pins[pos];
+ }
+
return NULL;
}
static LONG WINAPI MediaStreamFilterImpl_GetPinCount(BaseFilter *iface)
{
- /* No pins */
- return 0;
+ IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface;
+
+ return This->nb_streams;
}
static const BaseFilterFuncTable BaseFuncTable = {
diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c
index c62e83d..36c97b9 100644
--- a/dlls/amstream/tests/amstream.c
+++ b/dlls/amstream/tests/amstream.c
@@ -364,6 +364,54 @@ static void test_media_streams(void)
}
}
+ if (media_stream_filter)
+ {
+ IEnumPins *enum_pins;
+
+ hr = IMediaStreamFilter_EnumPins(media_stream_filter, &enum_pins);
+ ok(hr == S_OK, "IBaseFilter_EnumPins returned: %x\n", hr);
+ if (hr == S_OK)
+ {
+ IPin* pins[3] = { NULL, NULL, NULL };
+ ULONG nb_pins;
+ ULONG expected_nb_pins = audio_stream ? 2 : 1;
+ int i;
+
+ hr = IEnumPins_Next(enum_pins, 3, pins, &nb_pins);
+ ok(SUCCEEDED(hr), "IEnumPins_Next returned: %x\n", hr);
+ ok(nb_pins == expected_nb_pins, "Number of pins is %u instead of %u\n", nb_pins, expected_nb_pins);
+ for (i = 0; i < min(nb_pins, expected_nb_pins); i++)
+ {
+ IEnumMediaTypes* enum_media_types;
+ AM_MEDIA_TYPE* media_types[10];
+ ULONG nb_media_types;
+ IPin* pin;
+ PIN_INFO info;
+ WCHAR id[40];
+
+ /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
+ id[0] = 'I';
+ StringFromGUID2(i ? &MSPID_PrimaryAudio : &MSPID_PrimaryVideo, id + 1, 40);
+
+ hr = IPin_ConnectedTo(pins[i], &pin);
+ ok(hr == VFW_E_NOT_CONNECTED, "IPin_ConnectedTo returned: %x\n", hr);
+ hr = IPin_QueryPinInfo(pins[i], &info);
+ ok(hr == S_OK, "IPin_QueryPinInfo returned: %x\n", hr);
+ IBaseFilter_Release(info.pFilter);
+ ok(info.dir == PINDIR_INPUT, "Pin direction is %u instead of %u\n", info.dir, PINDIR_INPUT);
+ ok(!lstrcmpW(info.achName, id), "Pin name is %s instead of %s\n", wine_dbgstr_w(info.achName), wine_dbgstr_w(id));
+ hr = IPin_EnumMediaTypes(pins[i], &enum_media_types);
+ ok(hr == S_OK, "IPin_EnumMediaTypes returned: %x\n", hr);
+ hr = IEnumMediaTypes_Next(enum_media_types, sizeof(media_types) / sizeof(AM_MEDIA_TYPE), media_types, &nb_media_types);
+ ok(SUCCEEDED(hr), "IEnumMediaTypes_Next returned: %x\n", hr);
+ ok(nb_media_types == 0, "nb_media_types should be 0 instead of %u\n", nb_media_types);
+ IEnumMediaTypes_Release(enum_media_types);
+ IPin_Release(pins[i]);
+ }
+ IEnumPins_Release(enum_pins);
+ }
+ }
+
if (video_stream)
IMediaStream_Release(video_stream);
if (audio_stream)
More information about the wine-cvs
mailing list