Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/Makefile.in | 2 +- dlls/mp3dmod/mp3dmod.c | 32 +++++++++++++++- dlls/mp3dmod/tests/Makefile.in | 2 +- dlls/mp3dmod/tests/mp3dmod.c | 69 +++++++++++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 5 deletions(-)
diff --git a/dlls/mp3dmod/Makefile.in b/dlls/mp3dmod/Makefile.in index 0ac6d9680bc..56a5ef38eb5 100644 --- a/dlls/mp3dmod/Makefile.in +++ b/dlls/mp3dmod/Makefile.in @@ -1,5 +1,5 @@ MODULE = mp3dmod.dll -IMPORTS = dmoguids msdmo uuid wmcodecdspuuid +IMPORTS = dmoguids msdmo ole32 uuid wmcodecdspuuid EXTRAINCL = $(MPG123_CFLAGS) EXTRALIBS = $(MPG123_LIBS)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 50b6803ff81..c89f32e9ed6 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -187,9 +187,37 @@ static HRESULT WINAPI MediaObject_GetInputType(IMediaObject *iface, DWORD index,
static HRESULT WINAPI MediaObject_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) { - FIXME("(%p)->(%d, %d, %p) stub!\n", iface, index, type_index, type); + struct mp3_decoder *dmo = impl_from_IMediaObject(iface); + const WAVEFORMATEX *input_format; + WAVEFORMATEX *format;
- return E_NOTIMPL; + TRACE("iface %p, index %u, type_index %u, type %p.\n", iface, index, type_index, type); + + if (!dmo->intype_set) + return DMO_E_TYPE_NOT_SET; + + input_format = (WAVEFORMATEX *)dmo->intype.pbFormat; + + if (type_index >= (2 * input_format->nChannels)) + return DMO_E_NO_MORE_ITEMS; + + type->majortype = WMMEDIATYPE_Audio; + type->subtype = WMMEDIASUBTYPE_PCM; + type->formattype = WMFORMAT_WaveFormatEx; + type->pUnk = NULL; + type->cbFormat = sizeof(WAVEFORMATEX); + if (!(type->pbFormat = CoTaskMemAlloc(sizeof(WAVEFORMATEX)))) + return E_OUTOFMEMORY; + format = (WAVEFORMATEX *)type->pbFormat; + format->wFormatTag = WAVE_FORMAT_PCM; + format->nSamplesPerSec = input_format->nSamplesPerSec; + format->nChannels = (type_index / 2) ? 1 : input_format->nChannels; + format->wBitsPerSample = (type_index % 2) ? 8 : 16; + format->nBlockAlign = format->nChannels * format->wBitsPerSample / 8; + format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; + format->cbSize = 0; + + return S_OK; }
static HRESULT WINAPI MediaObject_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) diff --git a/dlls/mp3dmod/tests/Makefile.in b/dlls/mp3dmod/tests/Makefile.in index 3cbe4feb018..f5d54e48533 100644 --- a/dlls/mp3dmod/tests/Makefile.in +++ b/dlls/mp3dmod/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mp3dmod.dll -IMPORTS = dmoguids ole32 strmiids uuid wmcodecdspuuid +IMPORTS = dmoguids msdmo ole32 strmiids uuid wmcodecdspuuid
C_SRCS = \ mp3dmod.c diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index dcf0820afb1..1e410861eed 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -21,7 +21,7 @@ #include "wingdi.h" #include "mmreg.h" #include "mmsystem.h" -#include "mediaerr.h" +#include "dmo.h" #include "wmcodecdsp.h" #include "uuids.h" #include "wine/test.h" @@ -330,9 +330,16 @@ static void test_media_types(void) .pbFormat = (BYTE *)&mp3fmt, };
+ WAVEFORMATEX expect_wfx = + { + .wFormatTag = WAVE_FORMAT_PCM, + .nSamplesPerSec = 48000, + }; + DMO_MEDIA_TYPE mt; IMediaObject *dmo; HRESULT hr; + DWORD i;
hr = CoCreateInstance(&CLSID_CMP3DecMediaObject, NULL, CLSCTX_INPROC_SERVER, &IID_IMediaObject, (void **)&dmo); @@ -355,6 +362,10 @@ static void test_media_types(void) hr = IMediaObject_GetInputType(dmo, 0, 1, &mt); ok(hr == DMO_E_NO_MORE_ITEMS, "Got hr %#x.\n", hr);
+ memset(&mt, 0xcc, sizeof(DMO_MEDIA_TYPE)); + hr = IMediaObject_GetOutputType(dmo, 0, 0, &mt); + ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr); + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -385,10 +396,66 @@ static void test_media_types(void) hr = IMediaObject_SetInputType(dmo, 0, &input_mt, 0); ok(hr == S_OK, "Got hr %#x.\n", hr);
+ for (i = 0; i < 4; ++i) + { + memset(&mt, 0xcc, sizeof(DMO_MEDIA_TYPE)); + hr = IMediaObject_GetOutputType(dmo, 0, i, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Audio), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype)); + ok(IsEqualGUID(&mt.subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype)); + ok(mt.bFixedSizeSamples == 0xcccccccc, "Got fixed size %d.\n", mt.bFixedSizeSamples); + ok(mt.bTemporalCompression == 0xcccccccc, "Got temporal compression %d.\n", mt.bTemporalCompression); + ok(mt.lSampleSize == 0xcccccccc, "Got sample size %u.\n", mt.lSampleSize); + ok(IsEqualGUID(&mt.formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", + wine_dbgstr_guid(&mt.formattype)); + ok(!mt.pUnk, "Got pUnk %p.\n", mt.pUnk); + ok(mt.cbFormat >= sizeof(WAVEFORMATEX), "Got format size %u.\n", mt.cbFormat); + ok(!!mt.pbFormat, "Got format block %p.\n", mt.pbFormat); + + expect_wfx.nChannels = (i / 2) ? 1 : 2; + expect_wfx.wBitsPerSample = (i % 2) ? 8 : 16; + expect_wfx.nBlockAlign = expect_wfx.nChannels * expect_wfx.wBitsPerSample / 8; + expect_wfx.nAvgBytesPerSec = 48000 * expect_wfx.nBlockAlign; + ok(!memcmp(mt.pbFormat, &expect_wfx, sizeof(WAVEFORMATEX)), "Format blocks didn't match.\n"); + + MoFreeMediaType(&mt); + } + + hr = IMediaObject_GetOutputType(dmo, 0, 4, &mt); + ok(hr == DMO_E_NO_MORE_ITEMS, "Got hr %#x.\n", hr); + mp3fmt.wfx.nChannels = 1; hr = IMediaObject_SetInputType(dmo, 0, &input_mt, 0); ok(hr == S_OK, "Got hr %#x.\n", hr);
+ for (i = 0; i < 2; ++i) + { + memset(&mt, 0xcc, sizeof(DMO_MEDIA_TYPE)); + hr = IMediaObject_GetOutputType(dmo, 0, i, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(IsEqualGUID(&mt.majortype, &MEDIATYPE_Audio), "Got major type %s.\n", wine_dbgstr_guid(&mt.majortype)); + ok(IsEqualGUID(&mt.subtype, &MEDIASUBTYPE_PCM), "Got subtype %s.\n", wine_dbgstr_guid(&mt.subtype)); + ok(mt.bFixedSizeSamples == 0xcccccccc, "Got fixed size %d.\n", mt.bFixedSizeSamples); + ok(mt.bTemporalCompression == 0xcccccccc, "Got temporal compression %d.\n", mt.bTemporalCompression); + ok(mt.lSampleSize == 0xcccccccc, "Got sample size %u.\n", mt.lSampleSize); + ok(IsEqualGUID(&mt.formattype, &FORMAT_WaveFormatEx), "Got format type %s.\n", + wine_dbgstr_guid(&mt.formattype)); + ok(!mt.pUnk, "Got pUnk %p.\n", mt.pUnk); + ok(mt.cbFormat >= sizeof(WAVEFORMATEX), "Got format size %u.\n", mt.cbFormat); + ok(!!mt.pbFormat, "Got format block %p.\n", mt.pbFormat); + + expect_wfx.nChannels = 1; + expect_wfx.wBitsPerSample = (i % 2) ? 8 : 16; + expect_wfx.nBlockAlign = expect_wfx.nChannels * expect_wfx.wBitsPerSample / 8; + expect_wfx.nAvgBytesPerSec = 48000 * expect_wfx.nBlockAlign; + ok(!memcmp(mt.pbFormat, &expect_wfx, sizeof(WAVEFORMATEX)), "Format blocks didn't match.\n"); + + MoFreeMediaType(&mt); + } + + hr = IMediaObject_GetOutputType(dmo, 0, 2, &mt); + ok(hr == DMO_E_NO_MORE_ITEMS, "Got hr %#x.\n", hr); + IMediaObject_Release(dmo); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 18 ++++++++++--- dlls/mp3dmod/tests/mp3dmod.c | 50 +++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index c89f32e9ed6..5e232f0443f 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -52,7 +52,7 @@ struct mp3_decoder mpg123_handle *mh;
DMO_MEDIA_TYPE intype, outtype; - BOOL intype_set; + BOOL intype_set, outtype_set;
IMediaBuffer *buffer; REFERENCE_TIME timestamp; @@ -262,6 +262,7 @@ static HRESULT WINAPI MediaObject_SetOutputType(IMediaObject *iface, DWORD index if (flags & DMO_SET_TYPEF_CLEAR) { MoFreeMediaType(&This->outtype); + This->outtype_set = FALSE; return S_OK; }
@@ -287,6 +288,7 @@ static HRESULT WINAPI MediaObject_SetOutputType(IMediaObject *iface, DWORD index return DMO_E_TYPE_NOT_ACCEPTED; } MoCopyMediaType(&This->outtype, type); + This->outtype_set = TRUE; }
return S_OK; @@ -306,11 +308,19 @@ static HRESULT WINAPI MediaObject_GetOutputCurrentType(IMediaObject *iface, DWOR return E_NOTIMPL; }
-static HRESULT WINAPI MediaObject_GetInputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *max_lookahead, DWORD *alignment) +static HRESULT WINAPI MediaObject_GetInputSizeInfo(IMediaObject *iface, + DWORD index, DWORD *size, DWORD *lookahead, DWORD *alignment) { - FIXME("(%p)->(%d, %p, %p, %p) stub!\n", iface, index, size, max_lookahead, alignment); + struct mp3_decoder *dmo = impl_from_IMediaObject(iface);
- return E_NOTIMPL; + TRACE("iface %p, index %u, size %p, lookahead %p, alignment %p.\n", iface, index, size, lookahead, alignment); + + if (!dmo->intype_set || !dmo->outtype_set) + return DMO_E_TYPE_NOT_SET; + + *size = 0; + *alignment = 1; + return S_OK; }
static HRESULT WINAPI MediaObject_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 1e410861eed..78471c42bcb 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -288,7 +288,36 @@ static void test_aggregation(void)
static void test_stream_info(void) { - DWORD input_count, output_count, flags; + static const MPEGLAYER3WAVEFORMAT input_format = + { + .wfx.nChannels = 2, + .wfx.nSamplesPerSec = 48000, + }; + DMO_MEDIA_TYPE input_mt = + { + .majortype = MEDIATYPE_Audio, + .subtype = WMMEDIASUBTYPE_MP3, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(input_format), + .pbFormat = (BYTE *)&input_format, + }; + + static const WAVEFORMATEX output_format = + { + .nChannels = 1, + .nSamplesPerSec = 48000, + .nAvgBytesPerSec = 2 * 48000, + .nBlockAlign = 2, + .wBitsPerSample = 16, + }; + DMO_MEDIA_TYPE output_mt = + { + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(output_format), + .pbFormat = (BYTE *)&output_format, + }; + + DWORD input_count, output_count, flags, size, lookahead, alignment; IMediaObject *dmo; HRESULT hr;
@@ -311,6 +340,25 @@ static void test_stream_info(void) ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!flags, "Got flags %#x.\n", flags);
+ hr = IMediaObject_GetInputSizeInfo(dmo, 0, &size, &lookahead, &alignment); + ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr); + + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaObject_GetInputSizeInfo(dmo, 0, &size, &lookahead, &alignment); + ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr); + + hr = IMediaObject_SetOutputType(dmo, 0, &output_mt, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + size = lookahead = alignment = 0xdeadbeef; + hr = IMediaObject_GetInputSizeInfo(dmo, 0, &size, &lookahead, &alignment); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!size, "Got size %u.\n", size); + ok(lookahead == 0xdeadbeef, "Got lookahead %u.\n", lookahead); + ok(alignment == 1, "Got alignment %u.\n", alignment); + IMediaObject_Release(dmo); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 11 +++++++++-- dlls/mp3dmod/tests/mp3dmod.c | 10 ++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 5e232f0443f..6a904716bc1 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -325,9 +325,16 @@ static HRESULT WINAPI MediaObject_GetInputSizeInfo(IMediaObject *iface,
static HRESULT WINAPI MediaObject_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) { - FIXME("(%p)->(%d, %p, %p) stub!\n", iface, index, size, alignment); + struct mp3_decoder *dmo = impl_from_IMediaObject(iface);
- return E_NOTIMPL; + TRACE("iface %p, index %u, size %p, alignment %p.\n", iface, index, size, alignment); + + if (!dmo->intype_set || !dmo->outtype_set) + return DMO_E_TYPE_NOT_SET; + + *size = 2 * 1152 * ((WAVEFORMATEX *)dmo->outtype.pbFormat)->wBitsPerSample / 8; + *alignment = 1; + return S_OK; }
static HRESULT WINAPI MediaObject_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 78471c42bcb..285b76023b0 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -342,12 +342,16 @@ static void test_stream_info(void)
hr = IMediaObject_GetInputSizeInfo(dmo, 0, &size, &lookahead, &alignment); ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, &size, &alignment); + ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr);
hr = IMediaObject_SetInputType(dmo, 0, &input_mt, 0); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaObject_GetInputSizeInfo(dmo, 0, &size, &lookahead, &alignment); ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, &size, &alignment); + ok(hr == DMO_E_TYPE_NOT_SET, "Got hr %#x.\n", hr);
hr = IMediaObject_SetOutputType(dmo, 0, &output_mt, 0); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -359,6 +363,12 @@ static void test_stream_info(void) ok(lookahead == 0xdeadbeef, "Got lookahead %u.\n", lookahead); ok(alignment == 1, "Got alignment %u.\n", alignment);
+ size = alignment = 0xdeadbeef; + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, &size, &alignment); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(size == 1152 * 4, "Got size %u.\n", size); + ok(alignment == 1, "Got alignment %u.\n", alignment); + IMediaObject_Release(dmo); }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/mp3dmod/mp3dmod.c | 3 +++ dlls/mp3dmod/tests/mp3dmod.c | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 6a904716bc1..592ee5482a1 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -266,6 +266,9 @@ static HRESULT WINAPI MediaObject_SetOutputType(IMediaObject *iface, DWORD index return S_OK; }
+ if (!IsEqualGUID(&type->formattype, &WMFORMAT_WaveFormatEx)) + return DMO_E_TYPE_NOT_ACCEPTED; + format = (WAVEFORMATEX *)type->pbFormat;
if (format->wBitsPerSample == 8) diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index 285b76023b0..99d52e6fd77 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -394,6 +394,21 @@ static void test_media_types(void) .nSamplesPerSec = 48000, };
+ WAVEFORMATEX output_format = + { + .nChannels = 1, + .nSamplesPerSec = 48000, + .nAvgBytesPerSec = 48000, + .nBlockAlign = 1, + .wBitsPerSample = 8, + }; + DMO_MEDIA_TYPE output_mt = + { + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(output_format), + .pbFormat = (BYTE *)&output_format, + }; + DMO_MEDIA_TYPE mt; IMediaObject *dmo; HRESULT hr; @@ -514,6 +529,17 @@ static void test_media_types(void) hr = IMediaObject_GetOutputType(dmo, 0, 2, &mt); ok(hr == DMO_E_NO_MORE_ITEMS, "Got hr %#x.\n", hr);
+ hr = IMediaObject_SetOutputType(dmo, 0, &output_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + output_mt.formattype = GUID_NULL; + hr = IMediaObject_SetOutputType(dmo, 0, &output_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + output_mt.formattype = FORMAT_None; + hr = IMediaObject_SetOutputType(dmo, 0, &output_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + output_mt.formattype = FORMAT_WaveFormatEx; + IMediaObject_Release(dmo); }