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