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); }