amstream: Reimplement IPin::EnumMediaTypes() for the primary audio stream.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d5f1a5c0be
commit
c5651e9409
|
@ -549,6 +549,127 @@ static const struct IAudioMediaStreamVtbl AudioMediaStreamImpl_IAudioMediaStream
|
||||||
AudioMediaStreamImpl_IAudioMediaStream_CreateSample
|
AudioMediaStreamImpl_IAudioMediaStream_CreateSample
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct enum_media_types
|
||||||
|
{
|
||||||
|
IEnumMediaTypes IEnumMediaTypes_iface;
|
||||||
|
LONG refcount;
|
||||||
|
unsigned int index;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const IEnumMediaTypesVtbl enum_media_types_vtbl;
|
||||||
|
|
||||||
|
static struct enum_media_types *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct enum_media_types, IEnumMediaTypes_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_media_types_QueryInterface(IEnumMediaTypes *iface, REFIID iid, void **out)
|
||||||
|
{
|
||||||
|
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
|
||||||
|
|
||||||
|
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumMediaTypes))
|
||||||
|
{
|
||||||
|
IEnumMediaTypes_AddRef(iface);
|
||||||
|
*out = iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
|
||||||
|
*out = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI enum_media_types_AddRef(IEnumMediaTypes *iface)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
ULONG refcount = InterlockedIncrement(&enum_media_types->refcount);
|
||||||
|
TRACE("%p increasing refcount to %u.\n", enum_media_types, refcount);
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI enum_media_types_Release(IEnumMediaTypes *iface)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
ULONG refcount = InterlockedDecrement(&enum_media_types->refcount);
|
||||||
|
TRACE("%p decreasing refcount to %u.\n", enum_media_types, refcount);
|
||||||
|
if (!refcount)
|
||||||
|
heap_free(enum_media_types);
|
||||||
|
return refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_media_types_Next(IEnumMediaTypes *iface, ULONG count, AM_MEDIA_TYPE **mts, ULONG *ret_count)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p, count %u, mts %p, ret_count %p.\n", iface, count, mts, ret_count);
|
||||||
|
|
||||||
|
if (!ret_count)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (count && !enum_media_types->index)
|
||||||
|
{
|
||||||
|
mts[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
|
||||||
|
memset(mts[0], 0, sizeof(AM_MEDIA_TYPE));
|
||||||
|
mts[0]->majortype = MEDIATYPE_Audio;
|
||||||
|
mts[0]->subtype = MEDIASUBTYPE_PCM;
|
||||||
|
++enum_media_types->index;
|
||||||
|
*ret_count = 1;
|
||||||
|
return count == 1 ? S_OK : S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_count = 0;
|
||||||
|
return count ? S_FALSE : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_media_types_Skip(IEnumMediaTypes *iface, ULONG count)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p, count %u.\n", iface, count);
|
||||||
|
|
||||||
|
enum_media_types->index += count;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_media_types_Reset(IEnumMediaTypes *iface)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
|
||||||
|
TRACE("iface %p.\n", iface);
|
||||||
|
|
||||||
|
enum_media_types->index = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI enum_media_types_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **out)
|
||||||
|
{
|
||||||
|
struct enum_media_types *enum_media_types = impl_from_IEnumMediaTypes(iface);
|
||||||
|
struct enum_media_types *object;
|
||||||
|
|
||||||
|
TRACE("iface %p, out %p.\n", iface, out);
|
||||||
|
|
||||||
|
if (!(object = heap_alloc(sizeof(*object))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
object->IEnumMediaTypes_iface.lpVtbl = &enum_media_types_vtbl;
|
||||||
|
object->refcount = 1;
|
||||||
|
object->index = enum_media_types->index;
|
||||||
|
|
||||||
|
*out = &object->IEnumMediaTypes_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IEnumMediaTypesVtbl enum_media_types_vtbl =
|
||||||
|
{
|
||||||
|
enum_media_types_QueryInterface,
|
||||||
|
enum_media_types_AddRef,
|
||||||
|
enum_media_types_Release,
|
||||||
|
enum_media_types_Next,
|
||||||
|
enum_media_types_Skip,
|
||||||
|
enum_media_types_Reset,
|
||||||
|
enum_media_types_Clone,
|
||||||
|
};
|
||||||
|
|
||||||
static inline AudioMediaStreamInputPin *impl_from_AudioMediaStreamInputPin_IPin(IPin *iface)
|
static inline AudioMediaStreamInputPin *impl_from_AudioMediaStreamInputPin_IPin(IPin *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, AudioMediaStreamInputPin, pin.pin.IPin_iface);
|
return CONTAINING_RECORD(iface, AudioMediaStreamInputPin, pin.pin.IPin_iface);
|
||||||
|
@ -576,6 +697,26 @@ static ULONG WINAPI AudioMediaStreamInputPin_IPin_Release(IPin *iface)
|
||||||
return IAMMediaStream_Release(&This->parent->IAMMediaStream_iface);
|
return IAMMediaStream_Release(&This->parent->IAMMediaStream_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI audio_sink_EnumMediaTypes(IPin *iface, IEnumMediaTypes **enum_media_types)
|
||||||
|
{
|
||||||
|
struct enum_media_types *object;
|
||||||
|
|
||||||
|
TRACE("iface %p, enum_media_types %p.\n", iface, enum_media_types);
|
||||||
|
|
||||||
|
if (!enum_media_types)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (!(object = heap_alloc(sizeof(*object))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
object->IEnumMediaTypes_iface.lpVtbl = &enum_media_types_vtbl;
|
||||||
|
object->refcount = 1;
|
||||||
|
object->index = 0;
|
||||||
|
|
||||||
|
*enum_media_types = &object->IEnumMediaTypes_iface;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static const IPinVtbl AudioMediaStreamInputPin_IPin_Vtbl =
|
static const IPinVtbl AudioMediaStreamInputPin_IPin_Vtbl =
|
||||||
{
|
{
|
||||||
AudioMediaStreamInputPin_IPin_QueryInterface,
|
AudioMediaStreamInputPin_IPin_QueryInterface,
|
||||||
|
@ -590,7 +731,7 @@ static const IPinVtbl AudioMediaStreamInputPin_IPin_Vtbl =
|
||||||
BasePinImpl_QueryDirection,
|
BasePinImpl_QueryDirection,
|
||||||
BasePinImpl_QueryId,
|
BasePinImpl_QueryId,
|
||||||
BasePinImpl_QueryAccept,
|
BasePinImpl_QueryAccept,
|
||||||
BasePinImpl_EnumMediaTypes,
|
audio_sink_EnumMediaTypes,
|
||||||
BasePinImpl_QueryInternalConnections,
|
BasePinImpl_QueryInternalConnections,
|
||||||
BaseInputPinImpl_EndOfStream,
|
BaseInputPinImpl_EndOfStream,
|
||||||
BaseInputPinImpl_BeginFlush,
|
BaseInputPinImpl_BeginFlush,
|
||||||
|
|
|
@ -1736,17 +1736,17 @@ static void test_enum_media_types(void)
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
|
hr = IEnumMediaTypes_Next(enum1, 1, mts, NULL);
|
||||||
todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
|
ok(hr == E_POINTER, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
|
hr = IEnumMediaTypes_Next(enum1, 0, mts, &count);
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
ok(!count, "Got count %u.\n", count);
|
ok(!count, "Got count %u.\n", count);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
||||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
todo_wine ok(count == 1, "Got count %u.\n", count);
|
ok(count == 1, "Got count %u.\n", count);
|
||||||
if (hr == S_OK) CoTaskMemFree(mts[0]->pbFormat);
|
CoTaskMemFree(mts[0]->pbFormat);
|
||||||
if (hr == S_OK) CoTaskMemFree(mts[0]);
|
CoTaskMemFree(mts[0]);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
||||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
||||||
|
@ -1768,7 +1768,7 @@ static void test_enum_media_types(void)
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Skip(enum1, 2);
|
hr = IEnumMediaTypes_Skip(enum1, 2);
|
||||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
hr = IEnumMediaTypes_Next(enum1, 1, mts, &count);
|
||||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
||||||
|
@ -1902,12 +1902,10 @@ static void test_media_types(void)
|
||||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
|
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
|
||||||
todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr);
|
ok(hr == E_POINTER, "Got hr %#x.\n", hr);
|
||||||
|
|
||||||
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
|
hr = IEnumMediaTypes_Next(enummt, 1, &pmt, &count);
|
||||||
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
|
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
|
||||||
ok(count == 1, "Got count %u.\n", count);
|
ok(count == 1, "Got count %u.\n", count);
|
||||||
ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
|
ok(IsEqualGUID(&pmt->majortype, &MEDIATYPE_Audio), "Got major type %s\n",
|
||||||
wine_dbgstr_guid(&pmt->majortype));
|
wine_dbgstr_guid(&pmt->majortype));
|
||||||
|
@ -1916,15 +1914,14 @@ static void test_media_types(void)
|
||||||
todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
|
todo_wine ok(pmt->bFixedSizeSamples == TRUE, "Got fixed size %d.\n", pmt->bFixedSizeSamples);
|
||||||
ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
|
ok(!pmt->bTemporalCompression, "Got temporal compression %d.\n", pmt->bTemporalCompression);
|
||||||
todo_wine ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
|
todo_wine ok(pmt->lSampleSize == 2, "Got sample size %u.\n", pmt->lSampleSize);
|
||||||
ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
|
todo_wine ok(IsEqualGUID(&pmt->formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n",
|
||||||
wine_dbgstr_guid(&pmt->formattype));
|
wine_dbgstr_guid(&pmt->formattype));
|
||||||
ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
|
ok(!pmt->pUnk, "Got pUnk %p.\n", pmt->pUnk);
|
||||||
ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
|
todo_wine ok(pmt->cbFormat == sizeof(WAVEFORMATEX), "Got format size %u.\n", pmt->cbFormat);
|
||||||
ok(!memcmp(pmt->pbFormat, &expect_wfx, sizeof(WAVEFORMATEX)), "Format blocks didn't match.\n");
|
ok(!memcmp(pmt->pbFormat, &expect_wfx, pmt->cbFormat), "Format blocks didn't match.\n");
|
||||||
|
|
||||||
hr = IPin_QueryAccept(pin, pmt);
|
hr = IPin_QueryAccept(pin, pmt);
|
||||||
ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
||||||
}
|
|
||||||
|
|
||||||
CoTaskMemFree(pmt);
|
CoTaskMemFree(pmt);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue