diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c index 4df74fc0375..50b6803ff81 100644 --- a/dlls/mp3dmod/mp3dmod.c +++ b/dlls/mp3dmod/mp3dmod.c @@ -37,18 +37,23 @@ DEFINE_GUID(WMMEDIATYPE_Audio, 0x73647561,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); DEFINE_GUID(WMMEDIASUBTYPE_MP3,0x00000055,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); DEFINE_GUID(WMMEDIASUBTYPE_PCM,0x00000001,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71); +DEFINE_GUID(WMFORMAT_WaveFormatEx, 0x05589f81,0xc356,0x11ce,0xbf,0x01,0x00,0xaa,0x00,0x55,0x59,0x5a); WINE_DEFAULT_DEBUG_CHANNEL(mp3dmod); static HINSTANCE mp3dmod_instance; -struct mp3_decoder { +struct mp3_decoder +{ IUnknown IUnknown_inner; IMediaObject IMediaObject_iface; IUnknown *outer; LONG ref; mpg123_handle *mh; - DMO_MEDIA_TYPE outtype; + + DMO_MEDIA_TYPE intype, outtype; + BOOL intype_set; + IMediaBuffer *buffer; REFERENCE_TIME timestamp; }; @@ -98,6 +103,8 @@ static ULONG WINAPI Unknown_Release(IUnknown *iface) if (!refcount) { + if (This->intype_set) + MoFreeMediaType(&This->intype); MoFreeMediaType(&This->outtype); mpg123_delete(This->mh); heap_free(This); @@ -187,7 +194,30 @@ static HRESULT WINAPI MediaObject_GetOutputType(IMediaObject *iface, DWORD index static HRESULT WINAPI MediaObject_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) { - FIXME("(%p)->(%d, %p, %#x) stub!\n", iface, index, type, flags); + struct mp3_decoder *dmo = impl_from_IMediaObject(iface); + + TRACE("iface %p, index %u, type %p, flags %#x.\n", iface, index, type, flags); + + if (flags & DMO_SET_TYPEF_CLEAR) + { + if (dmo->intype_set) + MoFreeMediaType(&dmo->intype); + dmo->intype_set = FALSE; + return S_OK; + } + + if (!IsEqualGUID(&type->majortype, &WMMEDIATYPE_Audio) + || !IsEqualGUID(&type->subtype, &WMMEDIASUBTYPE_MP3) + || !IsEqualGUID(&type->formattype, &WMFORMAT_WaveFormatEx)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!(flags & DMO_SET_TYPEF_TEST_ONLY)) + { + if (dmo->intype_set) + MoFreeMediaType(&dmo->intype); + MoCopyMediaType(&dmo->intype, type); + dmo->intype_set = TRUE; + } return S_OK; } diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c index da785479990..dcf0820afb1 100644 --- a/dlls/mp3dmod/tests/mp3dmod.c +++ b/dlls/mp3dmod/tests/mp3dmod.c @@ -316,6 +316,20 @@ static void test_stream_info(void) static void test_media_types(void) { + MPEGLAYER3WAVEFORMAT mp3fmt = + { + .wfx.nChannels = 2, + .wfx.nSamplesPerSec = 48000, + }; + DMO_MEDIA_TYPE input_mt = + { + .majortype = MEDIATYPE_Audio, + .subtype = WMMEDIASUBTYPE_MP3, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(mp3fmt), + .pbFormat = (BYTE *)&mp3fmt, + }; + DMO_MEDIA_TYPE mt; IMediaObject *dmo; HRESULT hr; @@ -341,6 +355,40 @@ 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); + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + input_mt.majortype = GUID_NULL; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.majortype = MEDIATYPE_Stream; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.majortype = MEDIATYPE_Audio; + + input_mt.subtype = GUID_NULL; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.subtype = MEDIASUBTYPE_PCM; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.subtype = WMMEDIASUBTYPE_MP3; + + input_mt.formattype = GUID_NULL; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.formattype = FORMAT_None; + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, DMO_SET_TYPEF_TEST_ONLY); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr); + input_mt.formattype = FORMAT_WaveFormatEx; + + hr = IMediaObject_SetInputType(dmo, 0, &input_mt, 0); + ok(hr == S_OK, "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); + IMediaObject_Release(dmo); }