mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
amstream: Add the corresponding pin to every media stream added to the media stream filter + add tests.
This commit is contained in:
parent
49762b1679
commit
dec3d50290
@ -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 = {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user