-- v3: winegstreamer: Reject SetOutput with a different number of channels. winegstreamer: Reject setting WMA DMO with an output type with a wrong formattype. mf/tests: Test if WMV decoder DMO accepts output type with a different size. mf/tests: Test SetOutputType with a wrong formattype on WMA decoder. mf/tests: Test if WMA decoder DMO accept output type with a different num of channels.
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mf/tests/transform.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index e5c65ace228..c357731b4c5 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4079,6 +4079,24 @@ static void test_wma_decoder_dmo_output_type(void) MoFreeMediaType(input_type); MoFreeMediaType(&type);
+ /* Test setting output type to a type with less channels. */ + init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, 1, rate, bits_per_sample); + hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); + todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + + /* Test setting output type to a type with more channels. */ + init_dmo_media_type_audio(input_type, input_subtype, 1, rate, 16); + ((WAVEFORMATEX *)(input_type + 1))->nBlockAlign = 640; + ((WAVEFORMATEX *)(input_type + 1))->nAvgBytesPerSec = 2000; + init_dmo_media_type_audio(good_output_type, &MEDIASUBTYPE_PCM, 1, rate, bits_per_sample); + hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); + ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); + hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); + ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); + init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, 2, rate, bits_per_sample); + hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); + todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + init_dmo_media_type_audio(input_type, input_subtype, channel_count, rate * 2, 32); hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); ok(hr == S_OK, "SetInputType returned %#lx.\n", hr);
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mf/tests/transform.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index c357731b4c5..4f7a7c8503f 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4021,6 +4021,10 @@ static void test_wma_decoder_dmo_output_type(void) ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0x4); ok(hr == E_INVALIDARG, "SetOutputType returned %#lx.\n", hr); + init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, channel_count, rate, bits_per_sample); + bad_output_type->formattype = FORMAT_VideoInfo; /* What if formattype is wrong? */ + hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); + todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr);
hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr);
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mf/tests/transform.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 4f7a7c8503f..f2ed6c55894 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -7991,6 +7991,7 @@ static void test_wmv_decoder_dmo_output_type(void) const GUID* input_subtype = &MEDIASUBTYPE_WMV1; REFERENCE_TIME time_per_frame = 10000000; LONG width = 16, height = 16; + VIDEOINFOHEADER *vih; DWORD count, i, ret; IMediaObject *dmo; HRESULT hr; @@ -8150,6 +8151,17 @@ static void test_wmv_decoder_dmo_output_type(void) hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0x4); ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr);
+ /* Does DMO accept a format with a different size? */ + vih = (VIDEOINFOHEADER *)good_output_type->pbFormat; + vih->bmiHeader.biHeight += 10; + vih->bmiHeader.biWidth += 10; + vih->rcSource.bottom += 10; + vih->rcSource.right += 10; + vih->rcTarget.bottom += 10; + vih->rcTarget.right += 10; + hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); + ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); + /* Release. */ ret = IMediaObject_Release(dmo); ok(ret == 0, "Release returned %lu\n", ret);
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mf/tests/transform.c | 2 +- dlls/winegstreamer/wma_decoder.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index f2ed6c55894..87df9adf4dd 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4024,7 +4024,7 @@ static void test_wma_decoder_dmo_output_type(void) init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, channel_count, rate, bits_per_sample); bad_output_type->formattype = FORMAT_VideoInfo; /* What if formattype is wrong? */ hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr);
hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 951a50f7164..fd046a6ef01 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -798,6 +798,9 @@ static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD inde if (IsEqualGUID(&decoder->input_type.majortype, &GUID_NULL)) return DMO_E_TYPE_NOT_SET;
+ if (!IsEqualGUID(&decoder->input_type.formattype, &type->formattype)) + return DMO_E_TYPE_NOT_ACCEPTED; + if (FAILED(hr = wg_transform_create_quartz(&decoder->input_type, &decoder->output_type, &attrs, &new_transform))) return hr;
From: Yuxuan Shui yshui@codeweavers.com
--- dlls/mf/tests/transform.c | 4 ++-- dlls/winegstreamer/wma_decoder.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 87df9adf4dd..3defdb7fa64 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4086,7 +4086,7 @@ static void test_wma_decoder_dmo_output_type(void) /* Test setting output type to a type with less channels. */ init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, 1, rate, bits_per_sample); hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr);
/* Test setting output type to a type with more channels. */ init_dmo_media_type_audio(input_type, input_subtype, 1, rate, 16); @@ -4099,7 +4099,7 @@ static void test_wma_decoder_dmo_output_type(void) ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); init_dmo_media_type_audio(bad_output_type, &MEDIASUBTYPE_PCM, 2, rate, bits_per_sample); hr = IMediaObject_SetOutputType(dmo, 0, bad_output_type, 0); - todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr);
init_dmo_media_type_audio(input_type, input_subtype, channel_count, rate * 2, 32); hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index fd046a6ef01..329e07d9831 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -801,6 +801,14 @@ static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD inde if (!IsEqualGUID(&decoder->input_type.formattype, &type->formattype)) return DMO_E_TYPE_NOT_ACCEPTED;
+ if (IsEqualGUID(&decoder->input_type.formattype, &FORMAT_WaveFormatEx)) + { + WORD current_nchannels = ((WAVEFORMATEX *)decoder->input_type.pbFormat)->nChannels; + WORD incomming_nchannels = ((WAVEFORMATEX *)type->pbFormat)->nChannels; + if (current_nchannels != incomming_nchannels) + return DMO_E_TYPE_NOT_ACCEPTED; + } + if (FAILED(hr = wg_transform_create_quartz(&decoder->input_type, &decoder->output_type, &attrs, &new_transform))) return hr;
On Thu Nov 27 15:55:51 2025 +0000, Elizabeth Figura wrote:
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index e5c65ace228..d2fb18afdf1 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4030,6 +4030,10 @@ static void test_wma_decoder_dmo_output_type(void) ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0x4); ok(hr == E_INVALIDARG, "SetOutputType returned %#lx.\n", hr); + ((WAVEFORMATEX *)good_output_type->pbFormat)->nChannels += 1; + hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); + todo_wine ok(hr == DMO_E_TYPE_NOT_ACCEPTED, "SetOutputType returned %#lx.\n", hr); + ((WAVEFORMATEX *)good_output_type->pbFormat)->nChannels -= 1; /* Test GetOutputCurrentType. */ hr = IMediaObject_SetOutputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR);I don't think that's a valid media type as written, though, which kind of weakens the test. It's 3 channels, which I think you need EXTENSIBLE for, and the bit rate and block align are wrong.
updated to use `init_dmo_media_type_audio` now, as well as changed to mono/stereo instead of stereo/3-channels.
On Thu Nov 27 15:56:07 2025 +0000, Elizabeth Figura wrote:
+ if (IsEqualGUID(&decoder->input_type.formattype, &FORMAT_WaveFormatEx) && + IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) + { + WORD current_nchannels = ((WAVEFORMATEX *)decoder->input_type.pbFormat)->nChannels; + WORD incomming_nchannels = ((WAVEFORMATEX *)type->pbFormat)->nChannels; + if (current_nchannels != incomming_nchannels) + return DMO_E_TYPE_NOT_ACCEPTED; + }That's a bit of an odd test, because as written it implies that using a different formattype is legal, which I would be surprised to find that it is.
added a test case for mismatching `formattype`