diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0bf81e0c878..6755853f995 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -5790,22 +5790,18 @@ static void test_wma_decoder(void) hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "MFCreateMediaType returned %#x\n", hr); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#x.\n", hr); init_media_type(media_type, input_type_desc, 1); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "SetInputType returned %#x.\n", hr); init_media_type(media_type, input_type_desc, 2); for (i = 2; i < ARRAY_SIZE(input_type_desc) - 1; ++i) { hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == MF_E_INVALIDMEDIATYPE, "SetInputType returned %#x.\n", hr); init_media_type(media_type, input_type_desc, i + 1); } hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#x.\n", hr); ret = IMFMediaType_Release(media_type); ok(ret == 0, "Release returned %u\n", ret); @@ -5893,7 +5889,6 @@ static void test_wma_decoder(void) hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 4003); ok(hr == S_OK, "SetUINT32 returned %#x\n", hr); hr = IMFTransform_SetInputType(transform, 0, media_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#x.\n", hr); hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info); diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index f034c34395e..12ac9cee8c3 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -30,6 +30,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmadec); +static const GUID *wma_decoder_input_types[] = +{ + &MEDIASUBTYPE_MSAUDIO1, + &MFAudioFormat_WMAudioV8, + &MFAudioFormat_WMAudioV9, + &MFAudioFormat_WMAudio_Lossless, +}; + struct wma_decoder { IUnknown IUnknown_inner; @@ -38,6 +46,7 @@ struct wma_decoder IPropertyBag IPropertyBag_iface; IUnknown *outer; LONG refcount; + IMFMediaType *input_type; }; static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) @@ -88,7 +97,11 @@ static ULONG WINAPI unknown_Release(IUnknown *iface) TRACE("iface %p decreasing refcount to %u.\n", decoder, refcount); if (!refcount) + { + if (decoder->input_type) + IMFMediaType_Release(decoder->input_type); free(decoder); + } return refcount; } @@ -203,8 +216,50 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) { - FIXME("iface %p, id %u, type %p, flags %#x stub!\n", iface, id, type, flags); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMFTransform(iface); + MF_ATTRIBUTE_TYPE item_type; + GUID major, subtype; + HRESULT hr; + ULONG i; + + TRACE("iface %p, id %u, type %p, flags %#x.\n", iface, id, type, flags); + + if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || + FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) + return hr; + + if (!IsEqualGUID(&major, &MFMediaType_Audio)) + return MF_E_INVALIDMEDIATYPE; + + for (i = 0; i < ARRAY_SIZE(wma_decoder_input_types); ++i) + if (IsEqualGUID(&subtype, wma_decoder_input_types[i])) + break; + if (i == ARRAY_SIZE(wma_decoder_input_types)) + return MF_E_INVALIDMEDIATYPE; + + if (FAILED(IMFMediaType_GetItemType(type, &MF_MT_USER_DATA, &item_type)) || + item_type != MF_ATTRIBUTE_BLOB) + return MF_E_INVALIDMEDIATYPE; + if (FAILED(IMFMediaType_GetItemType(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &item_type)) || + item_type != MF_ATTRIBUTE_UINT32) + return MF_E_INVALIDMEDIATYPE; + if (FAILED(IMFMediaType_GetItemType(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &item_type)) || + item_type != MF_ATTRIBUTE_UINT32) + return MF_E_INVALIDMEDIATYPE; + if (FAILED(IMFMediaType_GetItemType(type, &MF_MT_AUDIO_NUM_CHANNELS, &item_type)) || + item_type != MF_ATTRIBUTE_UINT32) + return MF_E_INVALIDMEDIATYPE; + + if (!decoder->input_type && FAILED(hr = MFCreateMediaType(&decoder->input_type))) + return hr; + + if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->input_type))) + { + IMFMediaType_Release(decoder->input_type); + decoder->input_type = NULL; + } + + return hr; } static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)