amstream: Use streams as pins in MediaStreamFilter.

Signed-off-by: Anton Baskanov <baskanov@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Anton Baskanov 2018-02-16 23:43:43 +07:00 committed by Alexandre Julliard
parent 193e56ce2c
commit 2622690534
2 changed files with 10 additions and 179 deletions

View file

@ -34,38 +34,10 @@
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;
IAMMediaStream** streams;
IPin** pins;
} IMediaStreamFilterImpl;
static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
@ -73,133 +45,6 @@ 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)
{
IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter((IMediaStreamFilter*)This->pinInfo.pFilter);
MSPID purpose_id;
ULONG i;
TRACE("Checking media type %s - %s\n", debugstr_guid(&pmt->majortype), debugstr_guid(&pmt->subtype));
/* Find which stream is associated with the pin */
for (i = 0; i < filter->nb_streams; i++)
if (&This->IPin_iface == filter->pins[i])
break;
if (i == filter->nb_streams)
return S_FALSE;
if (FAILED(IAMMediaStream_GetInformation(filter->streams[i], &purpose_id, NULL)))
return S_FALSE;
TRACE("Checking stream with purpose id %s\n", debugstr_guid(&purpose_id));
if (IsEqualGUID(&purpose_id, &MSPID_PrimaryVideo) && IsEqualGUID(&pmt->majortype, &MEDIATYPE_Video))
{
if (IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB1) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB4) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB8) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB565) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB555) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB24) ||
IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB32))
{
TRACE("Video sub-type %s matches\n", debugstr_guid(&pmt->subtype));
return S_OK;
}
}
else if (IsEqualGUID(&purpose_id, &MSPID_PrimaryAudio) && IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio))
{
if (IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_PCM))
{
TRACE("Audio sub-type %s matches\n", debugstr_guid(&pmt->subtype));
return S_OK;
}
}
return S_FALSE;
}
static LONG WINAPI BasePinImp_GetMediaTypeVersion(BasePin *This)
{
return 0;
}
static HRESULT WINAPI BasePinImp_GetMediaType(BasePin *This, int index, AM_MEDIA_TYPE *amt)
{
IMediaStreamFilterImpl *filter = (IMediaStreamFilterImpl*)This->pinInfo.pFilter;
MSPID purpose_id;
ULONG i;
/* FIXME: Reset structure as we only fill majortype and minortype for now */
ZeroMemory(amt, sizeof(*amt));
/* Find which stream is associated with the pin */
for (i = 0; i < filter->nb_streams; i++)
if (&This->IPin_iface == filter->pins[i])
break;
if (i == filter->nb_streams)
return S_FALSE;
if (FAILED(IAMMediaStream_GetInformation(filter->streams[i], &purpose_id, NULL)))
return S_FALSE;
TRACE("Processing stream with purpose id %s\n", debugstr_guid(&purpose_id));
if (IsEqualGUID(&purpose_id, &MSPID_PrimaryVideo))
{
amt->majortype = MEDIATYPE_Video;
switch (index)
{
case 0:
amt->subtype = MEDIASUBTYPE_RGB1;
break;
case 1:
amt->subtype = MEDIASUBTYPE_RGB4;
break;
case 2:
amt->subtype = MEDIASUBTYPE_RGB8;
break;
case 3:
amt->subtype = MEDIASUBTYPE_RGB565;
break;
case 4:
amt->subtype = MEDIASUBTYPE_RGB555;
break;
case 5:
amt->subtype = MEDIASUBTYPE_RGB24;
break;
case 6:
amt->subtype = MEDIASUBTYPE_RGB32;
break;
default:
return S_FALSE;
}
}
else if (IsEqualGUID(&purpose_id, &MSPID_PrimaryAudio))
{
if (index)
return S_FALSE;
amt->majortype = MEDIATYPE_Audio;
amt->subtype = MEDIASUBTYPE_PCM;
}
return S_OK;
}
static const BaseInputPinFuncTable input_BaseInputFuncTable = {
{
BasePinImpl_CheckMediaType,
NULL,
BasePinImp_GetMediaTypeVersion,
BasePinImp_GetMediaType
},
NULL
};
/*** IUnknown methods ***/
static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid, void **ret_iface)
@ -246,11 +91,10 @@ static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface)
ULONG i;
for (i = 0; i < This->nb_streams; i++)
{
IAMMediaStream_JoinFilter(This->streams[i], NULL);
IAMMediaStream_Release(This->streams[i]);
IPin_Release(This->pins[i]);
}
CoTaskMemFree(This->streams);
CoTaskMemFree(This->pins);
BaseFilter_Destroy(&This->filter);
HeapFree(GetProcessHeap(), 0, This);
}
@ -344,11 +188,7 @@ static HRESULT WINAPI MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter* i
{
IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
IAMMediaStream** streams;
IPin** pins;
MediaStreamFilter_InputPin* pin;
HRESULT hr;
PIN_INFO info;
MSPID purpose_id;
TRACE("(%p)->(%p)\n", iface, pAMMediaStream);
@ -356,25 +196,11 @@ 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 = &This->filter.IBaseFilter_iface;
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, sizeof(BaseInputPin), &info,
&input_BaseInputFuncTable, &This->filter.csFilter, NULL, &This->pins[This->nb_streams]);
hr = IAMMediaStream_JoinFilter(pAMMediaStream, iface);
if (FAILED(hr))
return hr;
pin = (MediaStreamFilter_InputPin*)This->pins[This->nb_streams];
pin->pin.pin.pinInfo.pFilter = &This->filter.IBaseFilter_iface;
This->streams[This->nb_streams] = pAMMediaStream;
This->nb_streams++;
@ -488,8 +314,9 @@ static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos)
if (pos < This->nb_streams)
{
IPin_AddRef(This->pins[pos]);
return This->pins[pos];
IPin *pin = NULL;
IAMMediaStream_QueryInterface(This->streams[pos], &IID_IPin, (void **)&pin);
return pin;
}
return NULL;

View file

@ -483,6 +483,10 @@ static void test_media_streams(void)
ok(SUCCEEDED(hr), "IEnumMediaTypes_Next returned: %x\n", hr);
ok(nb_media_types > 0, "nb_media_types should be >0\n");
IEnumMediaTypes_Release(enum_media_types);
hr = IMediaStream_QueryInterface(i ? audio_stream : video_stream, &IID_IPin, (void **)&pin);
ok(hr == S_OK, "IMediaStream_QueryInterface returned: %x\n", hr);
ok(pin == pins[i], "Pin is %p instead of %p\n", pins[i], pin);
IPin_Release(pin);
IPin_Release(pins[i]);
}
IEnumPins_Release(enum_pins);