Along with !4449, this fixes WMV videos in microkiri (https://bugs.winehq.org/show_bug.cgi?id=9127#c102) and Wagamama High Spec Trial Edition (https://wagahigh.com/download_trial.php#normal ; ダウンロード means download).
-- v2: winegstreamer/tests: Test IMediaObject_GetOutputSizeInfo. winegstreamer: Implement DMO interface for WMA decoder. winegstreamer: Switch WMA decoder to use wg_format internally. winegstreamer: Implement WMA <-> AMT conversion. winegstreamer: Add wg_format_from_caps_audio_wma function.
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/wg_format.c | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 7d4bc7a5f8c..018f554dcff 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -201,6 +201,68 @@ static void wg_format_from_caps_audio_mpeg1(struct wg_format *format, const GstC format->u.audio_mpeg1.rate = rate; }
+static void wg_format_from_caps_audio_wma(struct wg_format *format, const GstCaps *caps) +{ + const GstStructure *structure = gst_caps_get_structure(caps, 0); + gint version, bitrate, rate, depth, channels, block_align; + const GValue *codec_data_value; + GstBuffer *codec_data; + GstMapInfo map; + + if (!gst_structure_get_int(structure, "wmaversion", &version)) + { + GST_WARNING("Missing "wmaversion" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!gst_structure_get_int(structure, "bitrate", &bitrate)) + { + GST_WARNING("Missing "bitrate" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!gst_structure_get_int(structure, "rate", &rate)) + { + GST_WARNING("Missing "rate" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!gst_structure_get_int(structure, "depth", &depth)) + { + GST_WARNING("Missing "depth" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!gst_structure_get_int(structure, "channels", &channels)) + { + GST_WARNING("Missing "channels" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!gst_structure_get_int(structure, "block_align", &block_align)) + { + GST_WARNING("Missing "block_align" value in %" GST_PTR_FORMAT ".", caps); + return; + } + if (!(codec_data_value = gst_structure_get_value(structure, "codec_data")) || !(codec_data = gst_value_get_buffer(codec_data_value))) + { + GST_WARNING("Missing "codec_data" value in %" GST_PTR_FORMAT ".", caps); + return; + } + + format->major_type = WG_MAJOR_TYPE_AUDIO_WMA; + format->u.audio_wma.version = version; + format->u.audio_wma.bitrate = bitrate; + format->u.audio_wma.rate = rate; + format->u.audio_wma.depth = depth; + format->u.audio_wma.channels = channels; + format->u.audio_wma.block_align = block_align; + + gst_buffer_map(codec_data, &map, GST_MAP_READ); + if (map.size <= ARRAY_SIZE(format->u.audio_wma.codec_data)) + { + format->u.audio_wma.codec_data_len = map.size; + memcpy(format->u.audio_wma.codec_data, map.data, map.size); + } + else GST_WARNING("Too big codec_data value (%u) in %" GST_PTR_FORMAT ".", (unsigned)map.size, caps); + gst_buffer_unmap(codec_data, &map); +} + static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps) { const GstStructure *structure = gst_caps_get_structure(caps, 0); @@ -336,6 +398,10 @@ void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) { wg_format_from_caps_audio_mpeg1(format, caps); } + else if (!strcmp(name, "audio/x-wma")) + { + wg_format_from_caps_audio_wma(format, caps); + } else if (!strcmp(name, "video/x-cinepak")) { wg_format_from_caps_video_cinepak(format, caps);
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/quartz_parser.c | 130 ++++++++++++++++++++++++++++- dlls/wmvcore/tests/wmvcore.c | 11 ++- 2 files changed, 133 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 0670fbd5181..fdf954ac0bf 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -278,6 +278,71 @@ static bool amt_from_wg_format_audio_mpeg1(AM_MEDIA_TYPE *mt, const struct wg_fo return false; }
+static bool amt_from_wg_format_audio_wma(AM_MEDIA_TYPE *mt, const struct wg_format *format) +{ + WAVEFORMATEX *wave_format; + WORD fmt_tag; + DWORD size; + const GUID *subtype; + + mt->majortype = MEDIATYPE_Audio; + mt->formattype = FORMAT_WaveFormatEx; + + switch (format->u.audio_wma.version) + { + case 1: + subtype = &MEDIASUBTYPE_MSAUDIO1; + size = sizeof(MSAUDIO1WAVEFORMAT); + fmt_tag = WAVE_FORMAT_MSAUDIO1; + break; + case 2: + subtype = &MEDIASUBTYPE_WMAUDIO2; + size = sizeof(WMAUDIO2WAVEFORMAT); + fmt_tag = WAVE_FORMAT_WMAUDIO2; + break; + case 3: + subtype = &MEDIASUBTYPE_WMAUDIO3; + size = sizeof(WMAUDIO3WAVEFORMAT); + fmt_tag = WAVE_FORMAT_WMAUDIO2; + break; + case 4: + subtype = &MEDIASUBTYPE_WMAUDIO_LOSSLESS; + size = sizeof(WAVEFORMATEX) + 18; + fmt_tag = WAVE_FORMAT_WMAUDIO_LOSSLESS; + break; + default: + assert(false); + return false; + } + + if (!(wave_format = CoTaskMemAlloc(size))) + return false; + memset(wave_format, 0, size); + + mt->subtype = *subtype; + mt->bFixedSizeSamples = TRUE; + mt->lSampleSize = format->u.audio_wma.block_align; + mt->cbFormat = size; + mt->pbFormat = (BYTE *)wave_format; + wave_format->wFormatTag = fmt_tag; + wave_format->nChannels = format->u.audio_wma.channels; + wave_format->nSamplesPerSec = format->u.audio_wma.rate; + wave_format->nAvgBytesPerSec = format->u.audio_wma.bitrate / 8; + wave_format->nBlockAlign = format->u.audio_wma.block_align; + wave_format->wBitsPerSample = 0x0010; + wave_format->cbSize = size - sizeof(WAVEFORMATEX); + + if (format->u.audio_wma.version == 1 && format->u.audio_wma.codec_data_len == 4) + memcpy(wave_format+1, format->u.audio_wma.codec_data, 4); + if (format->u.audio_wma.version == 2 && format->u.audio_wma.codec_data_len == 10) + memcpy(wave_format+1, format->u.audio_wma.codec_data, 10); + if (format->u.audio_wma.version == 3 && format->u.audio_wma.codec_data_len == 18) + memcpy(wave_format+1, format->u.audio_wma.codec_data, 18); + if (format->u.audio_wma.version == 4 && format->u.audio_wma.codec_data_len == 18) + memcpy(wave_format+1, format->u.audio_wma.codec_data, 18); + return true; +} + #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1))
static unsigned int wg_format_get_max_size_video_raw(enum wg_video_format format, unsigned int width, unsigned int height) @@ -384,8 +449,13 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) } break;
- case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: + /* Estimated max size of a compressed audio frame. + * There's no way to no way to know the real upper bound, + * so let's just use one second of decompressed size and hope it works. */ + return format->u.audio_wma.rate * format->u.audio_wma.channels * 2; + + case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_VIDEO_H264: case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_INDEO: @@ -643,7 +713,6 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool switch (format->major_type) { case WG_MAJOR_TYPE_AUDIO_MPEG4: - case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: case WG_MAJOR_TYPE_VIDEO_INDEO: FIXME("Format %u not implemented!\n", format->major_type); @@ -657,6 +726,9 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool case WG_MAJOR_TYPE_AUDIO_MPEG1: return amt_from_wg_format_audio_mpeg1(mt, format);
+ case WG_MAJOR_TYPE_AUDIO_WMA: + return amt_from_wg_format_audio_wma(mt, format); + case WG_MAJOR_TYPE_VIDEO: return amt_from_wg_format_video(mt, format, wm);
@@ -787,6 +859,55 @@ static bool amt_to_wg_format_audio_mpeg1_layer3(const AM_MEDIA_TYPE *mt, struct return true; }
+static bool amt_to_wg_format_audio_wma(const AM_MEDIA_TYPE *mt, struct wg_format *format) +{ + const WAVEFORMATEX *audio_format = (const WAVEFORMATEX *)mt->pbFormat; + + if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)) + { + FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype)); + return false; + } + if (mt->cbFormat < sizeof(*audio_format) || !mt->pbFormat) + { + ERR("Unexpected format size %lu.\n", mt->cbFormat); + return false; + } + + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MSAUDIO1)) + format->u.audio_wma.version = 1; + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO2)) + format->u.audio_wma.version = 2; + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO3)) + format->u.audio_wma.version = 3; + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO_LOSSLESS)) + format->u.audio_wma.version = 4; + else + { + ERR("Unexpected subtype %s.\n", debugstr_guid(&mt->subtype)); + return false; + } + format->major_type = WG_MAJOR_TYPE_AUDIO_WMA; + format->u.audio_wma.bitrate = audio_format->nAvgBytesPerSec * 8; + format->u.audio_wma.rate = audio_format->nSamplesPerSec; + format->u.audio_wma.depth = audio_format->wBitsPerSample; + format->u.audio_wma.channels = audio_format->nChannels; + format->u.audio_wma.block_align = audio_format->nBlockAlign; + + format->u.audio_wma.codec_data_len = 0; + if (format->u.audio_wma.version == 1) + format->u.audio_wma.codec_data_len = 4; + if (format->u.audio_wma.version == 2) + format->u.audio_wma.codec_data_len = 10; + if (format->u.audio_wma.version == 3) + format->u.audio_wma.codec_data_len = 18; + if (format->u.audio_wma.version == 4) + format->u.audio_wma.codec_data_len = 18; + memcpy(format->u.audio_wma.codec_data, audio_format+1, format->u.audio_wma.codec_data_len); + + return true; +} + static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *format) { static const struct @@ -932,6 +1053,11 @@ bool amt_to_wg_format(const AM_MEDIA_TYPE *mt, struct wg_format *format) return amt_to_wg_format_audio_mpeg1(mt, format); if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MP3)) return amt_to_wg_format_audio_mpeg1_layer3(mt, format); + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MSAUDIO1) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO2) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO3) + || IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_WMAUDIO_LOSSLESS)) + return amt_to_wg_format_audio_wma(mt, format); return amt_to_wg_format_audio(mt, format); }
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index f40ae37c0ce..1741299e654 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1455,7 +1455,7 @@ static void check_audio_type(const WM_MEDIA_TYPE *mt) }
static void test_stream_media_props(IWMStreamConfig *config, - const GUID *majortype, const GUID *subtype, const GUID *formattype, BOOL todo_subtype) + const GUID *majortype, const GUID *subtype, const GUID *formattype) { char mt_buffer[2000]; WM_MEDIA_TYPE *mt = (WM_MEDIA_TYPE *)mt_buffer; @@ -1484,7 +1484,6 @@ static void test_stream_media_props(IWMStreamConfig *config, ok(size == sizeof(WM_MEDIA_TYPE) + mt->cbFormat, "got %lu.\n", size); ok(IsEqualGUID(&mt->majortype, majortype), "Expected major type %s, got %s.\n", debugstr_guid(majortype), debugstr_guid(&mt->majortype)); - todo_wine_if(todo_subtype) ok(IsEqualGUID(&mt->subtype, subtype), "Expected sub type %s, got %s.\n", debugstr_guid(subtype), debugstr_guid(&mt->subtype)); ok(IsEqualGUID(&mt->formattype, formattype), "Expected format type %s, got %s.\n", @@ -1546,9 +1545,9 @@ static void test_sync_reader_types(void) ok(IsEqualGUID(&majortype, &MEDIATYPE_Audio), "Got major type %s.\n", debugstr_guid(&majortype));
if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) - test_stream_media_props(config, &MEDIATYPE_Audio, &MEDIASUBTYPE_MSAUDIO1, &FORMAT_WaveFormatEx, TRUE); + test_stream_media_props(config, &MEDIATYPE_Audio, &MEDIASUBTYPE_MSAUDIO1, &FORMAT_WaveFormatEx); else - test_stream_media_props(config, &MEDIATYPE_Video, &MEDIASUBTYPE_WMV1, &FORMAT_VideoInfo, FALSE); + test_stream_media_props(config, &MEDIATYPE_Video, &MEDIASUBTYPE_WMV1, &FORMAT_VideoInfo);
ref = IWMStreamConfig_Release(config); ok(!ref, "Got outstanding refcount %ld.\n", ref); @@ -3425,9 +3424,9 @@ static void test_async_reader_types(void) ok(IsEqualGUID(&majortype, &MEDIATYPE_Audio), "Got major type %s.\n", debugstr_guid(&majortype));
if (IsEqualGUID(&majortype, &MEDIATYPE_Audio)) - test_stream_media_props(config, &MEDIATYPE_Audio, &MEDIASUBTYPE_MSAUDIO1, &FORMAT_WaveFormatEx, TRUE); + test_stream_media_props(config, &MEDIATYPE_Audio, &MEDIASUBTYPE_MSAUDIO1, &FORMAT_WaveFormatEx); else - test_stream_media_props(config, &MEDIATYPE_Video, &MEDIASUBTYPE_WMV1, &FORMAT_VideoInfo, FALSE); + test_stream_media_props(config, &MEDIATYPE_Video, &MEDIASUBTYPE_WMV1, &FORMAT_VideoInfo);
ref = IWMStreamConfig_Release(config); ok(!ref, "Got outstanding refcount %ld.\n", ref);
From: Alfred Agrell floating@muncher.se
--- dlls/mf/tests/transform.c | 1 + dlls/winegstreamer/wma_decoder.c | 90 +++++++++++--------------------- 2 files changed, 31 insertions(+), 60 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 3f5524784cc..56103c25d09 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3042,6 +3042,7 @@ static void test_wma_decoder(void) ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050, .required = TRUE), ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS, 2, .required = TRUE), ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 4003), /* not required by SetInputType, but needed for the transform to work */ + ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16), {0}, }; static const struct attribute_desc output_type_desc[] = diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index d1082fe327a..5d63908481e 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -52,10 +52,11 @@ struct wma_decoder IUnknown *outer; LONG refcount;
- IMFMediaType *input_type; - MFT_INPUT_STREAM_INFO input_info; - IMFMediaType *output_type; - MFT_OUTPUT_STREAM_INFO output_info; + struct wg_format input_format; + struct wg_format output_format; + + DWORD input_buf_size; + DWORD output_buf_size;
wg_transform_t wg_transform; struct wg_sample_queue *wg_sample_queue; @@ -68,22 +69,19 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface)
static HRESULT try_create_wg_transform(struct wma_decoder *decoder) { - struct wg_format input_format, output_format; struct wg_transform_attrs attrs = {0};
if (decoder->wg_transform) wg_transform_destroy(decoder->wg_transform); decoder->wg_transform = 0;
- mf_media_type_to_wg_format(decoder->input_type, &input_format); - if (input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) return MF_E_INVALIDMEDIATYPE;
- mf_media_type_to_wg_format(decoder->output_type, &output_format); - if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) + if (decoder->output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) return MF_E_INVALIDMEDIATYPE;
- if (!(decoder->wg_transform = wg_transform_create(&input_format, &output_format, &attrs))) + if (!(decoder->wg_transform = wg_transform_create(&decoder->input_format, &decoder->output_format, &attrs))) return E_FAIL;
return S_OK; @@ -135,10 +133,6 @@ static ULONG WINAPI unknown_Release(IUnknown *iface) { if (decoder->wg_transform) wg_transform_destroy(decoder->wg_transform); - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); - if (decoder->output_type) - IMFMediaType_Release(decoder->output_type);
wg_sample_queue_destroy(decoder->wg_sample_queue); free(decoder); @@ -207,13 +201,17 @@ static HRESULT WINAPI transform_GetInputStreamInfo(IMFTransform *iface, DWORD id
TRACE("iface %p, id %lu, info %p.\n", iface, id, info);
- if (!decoder->input_type || !decoder->output_type) + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN || decoder->output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) { memset(info, 0, sizeof(*info)); return MF_E_TRANSFORM_TYPE_NOT_SET; }
- *info = decoder->input_info; + info->hnsMaxLatency = 0; + info->dwFlags = 0; + info->cbSize = decoder->input_buf_size; + info->cbMaxLookahead = 0; + info->cbAlignment = 1; return S_OK; }
@@ -223,13 +221,13 @@ static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD i
TRACE("iface %p, id %lu, info %p.\n", iface, id, info);
- if (!decoder->input_type || !decoder->output_type) + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN || decoder->output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) { memset(info, 0, sizeof(*info)); return MF_E_TRANSFORM_TYPE_NOT_SET; }
- *info = decoder->output_info; + *info = (MFT_OUTPUT_STREAM_INFO){ 0, decoder->output_buf_size, 1 }; return S_OK; }
@@ -273,7 +271,7 @@ static HRESULT WINAPI transform_GetInputAvailableType(IMFTransform *iface, DWORD static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type) { - UINT32 channel_count, sample_size, sample_rate, block_alignment; + UINT32 sample_size, block_alignment; struct wma_decoder *decoder = impl_from_IMFTransform(iface); IMFMediaType *media_type; const GUID *output_type; @@ -281,7 +279,7 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR
TRACE("iface %p, id %lu, index %lu, type %p.\n", iface, id, index, type);
- if (!decoder->input_type) + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) return MF_E_TRANSFORM_TYPE_NOT_SET;
*type = NULL; @@ -312,20 +310,16 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, sample_size))) goto done;
- if (FAILED(hr = IMFMediaType_GetUINT32(decoder->input_type, &MF_MT_AUDIO_NUM_CHANNELS, &channel_count))) - goto done; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, channel_count))) + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, decoder->input_format.u.audio_wma.channels))) goto done;
- if (FAILED(hr = IMFMediaType_GetUINT32(decoder->input_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &sample_rate))) - goto done; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, sample_rate))) + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, decoder->input_format.u.audio_wma.rate))) goto done;
- block_alignment = sample_size * channel_count / 8; + block_alignment = sample_size * decoder->input_format.u.audio_wma.channels / 8; if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, block_alignment))) goto done; - if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, sample_rate * block_alignment))) + if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, decoder->input_format.u.audio_wma.rate * block_alignment))) goto done;
if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1))) @@ -381,23 +375,9 @@ static HRESULT WINAPI transform_SetInputType(IMFTransform *iface, DWORD id, IMFM if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK;
- if (!decoder->input_type && FAILED(hr = MFCreateMediaType(&decoder->input_type))) - return hr; - - if (decoder->output_type) - { - IMFMediaType_Release(decoder->output_type); - decoder->output_type = NULL; - } - - if (SUCCEEDED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->input_type))) - decoder->input_info.cbSize = block_alignment; - else - { - IMFMediaType_Release(decoder->input_type); - decoder->input_info.cbSize = 0; - decoder->input_type = NULL; - } + mf_media_type_to_wg_format(type, &decoder->input_format); + decoder->input_buf_size = block_alignment; + decoder->output_format.major_type = WG_MAJOR_TYPE_UNKNOWN;
return hr; } @@ -413,7 +393,7 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF
TRACE("iface %p, id %lu, type %p, flags %#lx.\n", iface, id, type, flags);
- if (!decoder->input_type) + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) return MF_E_TRANSFORM_TYPE_NOT_SET;
if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || @@ -456,25 +436,18 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF if (flags & MFT_SET_TYPE_TEST_ONLY) return S_OK;
- if (FAILED(IMFMediaType_SetUINT32(decoder->input_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, sample_size))) - return MF_E_INVALIDMEDIATYPE; - - if (!decoder->output_type && FAILED(hr = MFCreateMediaType(&decoder->output_type))) - return hr; + decoder->input_format.u.audio_wma.depth = sample_size;
- if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->output_type))) - goto failed; + mf_media_type_to_wg_format(type, &decoder->output_format); + decoder->output_buf_size = 1024 * block_alignment * channel_count;
if (FAILED(hr = try_create_wg_transform(decoder))) goto failed;
- decoder->output_info.cbSize = 1024 * block_alignment * channel_count; return S_OK;
failed: - IMFMediaType_Release(decoder->output_type); - decoder->output_info.cbSize = 0; - decoder->output_type = NULL; + decoder->output_format.major_type = WG_MAJOR_TYPE_UNKNOWN; return hr; }
@@ -881,9 +854,6 @@ HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out) decoder->refcount = 1; decoder->outer = outer ? outer : &decoder->IUnknown_inner;
- decoder->input_info.cbAlignment = 1; - decoder->output_info.cbAlignment = 1; - *out = &decoder->IUnknown_inner; TRACE("Created decoder %p\n", *out); return S_OK;
From: Alfred Agrell floating@muncher.se
--- dlls/mf/tests/transform.c | 32 +---- dlls/winegstreamer/wma_decoder.c | 240 ++++++++++++++++++++++++++++--- 2 files changed, 222 insertions(+), 50 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 56103c25d09..a95926d9dc1 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -1384,7 +1384,7 @@ static void check_dmo_media_type_(int line, DMO_MEDIA_TYPE *media_type, const DM "Got unexpected formattype %s.\n", debugstr_guid(&media_type->formattype)); ok_(__FILE__, line)(media_type->pUnk == NULL, "Got unexpected pUnk %p.\n", media_type->pUnk); - todo_wine_if(expected->cbFormat && expected->cbFormat != sizeof(VIDEOINFOHEADER)) + todo_wine_if(expected->cbFormat && expected->cbFormat != sizeof(VIDEOINFOHEADER) && IsEqualGUID(&expected->majortype, &MEDIATYPE_Video)) check_member_(__FILE__, line, *media_type, *expected, "%lu", cbFormat);
if (expected->pbFormat) @@ -3384,8 +3384,6 @@ static void test_wma_decoder_dmo_input_type(void) bad_input_type = (void *)buffer_bad;
/* Test GetInputType. */ - todo_wine - { count = ARRAY_SIZE(expected_input_types); hr = IMediaObject_GetInputType(dmo, 1, 0, NULL); ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetInputType returned %#lx.\n", hr); @@ -3401,7 +3399,6 @@ static void test_wma_decoder_dmo_input_type(void) ok(hr == DMO_E_NO_MORE_ITEMS, "GetInputType returned %#lx.\n", hr); hr = IMediaObject_GetInputType(dmo, 0, count - 1, NULL); ok(hr == S_OK, "GetInputType returned %#lx.\n", hr); - }
i = -1; while (SUCCEEDED(hr = IMediaObject_GetInputType(dmo, 0, ++i, &type))) @@ -3411,17 +3408,13 @@ static void test_wma_decoder_dmo_input_type(void) MoFreeMediaType(&type); winetest_pop_context(); } - todo_wine ok(hr == DMO_E_NO_MORE_ITEMS, "GetInputType returned %#lx.\n", hr); - todo_wine ok(i == count, "%lu types.\n", i);
/* Test SetInputType. */ init_dmo_media_type_audio(good_input_type, &MEDIASUBTYPE_WMAUDIO2, 2, 22050, 32); memset(bad_input_type, 0, sizeof(buffer_bad));
- todo_wine - { hr = IMediaObject_SetInputType(dmo, 1, NULL, 0); ok(hr == DMO_E_INVALIDSTREAMINDEX, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_SetInputType(dmo, 1, bad_input_type, 0); @@ -3477,11 +3470,9 @@ static void test_wma_decoder_dmo_input_type(void) ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_SetInputType(dmo, 0, good_input_type, 0x4); ok(hr == E_INVALIDARG, "SetInputType returned %#lx.\n", hr); - }
/* Test GetInputCurrentType. */ hr = IMediaObject_SetInputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_GetInputCurrentType(dmo, 1, NULL); todo_wine @@ -3497,7 +3488,6 @@ static void test_wma_decoder_dmo_input_type(void) ok(hr == DMO_E_TYPE_NOT_SET, "GetInputCurrentType returned %#lx.\n", hr);
hr = IMediaObject_SetInputType(dmo, 0, good_input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_GetInputCurrentType(dmo, 1, NULL); todo_wine @@ -3567,18 +3557,13 @@ static void test_wma_decoder_dmo_output_type(void)
/* Test GetOutputType. */ hr = IMediaObject_GetOutputType(dmo, 1, 0, NULL); - todo_wine ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetOutputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputType(dmo, 0, 0, NULL); - todo_wine ok(hr == DMO_E_TYPE_NOT_SET, "GetOutputType returned %#lx.\n", hr);
hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr);
- todo_wine - { count = 1; hr = IMediaObject_GetOutputType(dmo, 1, 0, NULL); ok(hr == DMO_E_INVALIDSTREAMINDEX, "GetOutputType returned %#lx.\n", hr); @@ -3594,7 +3579,6 @@ static void test_wma_decoder_dmo_output_type(void) ok(hr == DMO_E_NO_MORE_ITEMS, "GetOutputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputType(dmo, 0, count - 1, NULL); ok(hr == S_OK, "GetOutputType returned %#lx.\n", hr); - }
i = -1; while (SUCCEEDED(hr = IMediaObject_GetOutputType(dmo, 0, ++i, &type))) @@ -3604,17 +3588,12 @@ static void test_wma_decoder_dmo_output_type(void) MoFreeMediaType(&type); winetest_pop_context(); } - todo_wine ok(hr == DMO_E_NO_MORE_ITEMS, "GetInputType returned %#lx.\n", hr); - todo_wine ok(i == count, "%lu types.\n", i);
/* Test SetOutputType. */ hr = IMediaObject_SetInputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); - todo_wine - { hr = IMediaObject_SetOutputType(dmo, 1, NULL, 0); ok(hr == DMO_E_INVALIDSTREAMINDEX, "SetOutputType returned %#lx.\n", hr); hr = IMediaObject_SetOutputType(dmo, 1, good_output_type, 0); @@ -3635,14 +3614,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); - }
hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr);
- todo_wine - { hr = IMediaObject_SetOutputType(dmo, 1, NULL, 0); ok(hr == DMO_E_INVALIDSTREAMINDEX, "SetOutputType returned %#lx.\n", hr); hr = IMediaObject_SetOutputType(dmo, 1, bad_output_type, 0); @@ -3698,11 +3673,9 @@ 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); - }
/* Test GetOutputCurrentType. */ hr = IMediaObject_SetOutputType(dmo, 0, NULL, DMO_SET_TYPEF_CLEAR); - todo_wine ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); todo_wine { @@ -3717,7 +3690,6 @@ static void test_wma_decoder_dmo_output_type(void) }
hr = IMediaObject_SetOutputType(dmo, 0, good_output_type, 0); - todo_wine ok(hr == S_OK, "SetOutputType returned %#lx.\n", hr); todo_wine { @@ -3740,7 +3712,6 @@ static void test_wma_decoder_dmo_output_type(void) todo_wine ok(hr == S_OK, "GetInputCurrentType returned %#lx.\n", hr); hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputCurrentType(dmo, 0, &type); todo_wine @@ -3748,7 +3719,6 @@ static void test_wma_decoder_dmo_output_type(void)
init_dmo_media_type_audio(input_type, input_subtype, channel_count, rate * 2, 32); hr = IMediaObject_SetInputType(dmo, 0, input_type, 0); - todo_wine ok(hr == S_OK, "SetInputType returned %#lx.\n", hr); hr = IMediaObject_GetOutputCurrentType(dmo, 0, &type); todo_wine diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 5d63908481e..085a656c40d 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -24,6 +24,7 @@ #include "mfobjects.h" #include "mftransform.h" #include "wmcodecdsp.h" +#include "mediaerr.h"
#include "wine/debug.h"
@@ -623,29 +624,182 @@ static HRESULT WINAPI media_object_GetOutputStreamInfo(IMediaObject *iface, DWOR static HRESULT WINAPI media_object_GetInputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) { - FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface, index, type_index, type); - return E_NOTIMPL; + TRACE("iface %p, index %lu, type_index %lu, type %p.\n", iface, index, type_index, type); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + if (type_index >= ARRAY_SIZE(wma_decoder_input_types)) + return DMO_E_NO_MORE_ITEMS; + if (!type) + return S_OK; + + memset(type, 0, sizeof(*type)); + type->majortype = MFMediaType_Audio; + type->subtype = *wma_decoder_input_types[type_index]; + type->bFixedSizeSamples = FALSE; + type->bTemporalCompression = TRUE; + type->lSampleSize = 0; + + return S_OK; }
static HRESULT WINAPI media_object_GetOutputType(IMediaObject *iface, DWORD index, DWORD type_index, DMO_MEDIA_TYPE *type) { - FIXME("iface %p, index %lu, type_index %lu, type %p stub!\n", iface, index, type_index, type); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + WAVEFORMATEX *wfx; + + TRACE("iface %p, index %lu, type_index %lu, type %p\n", iface, index, type_index, type); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + if (type_index >= 1) + return DMO_E_NO_MORE_ITEMS; + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) + return DMO_E_TYPE_NOT_SET; + if (!type) + return S_OK; + + memset(type, 0, sizeof(*type)); + type->majortype = MFMediaType_Audio; + type->subtype = MEDIASUBTYPE_PCM; + type->formattype = FORMAT_WaveFormatEx; + type->bFixedSizeSamples = FALSE; + type->bTemporalCompression = TRUE; + type->lSampleSize = 0; + + type->cbFormat = sizeof(WAVEFORMATEX); + type->pbFormat = CoTaskMemAlloc(type->cbFormat); + memset(type->pbFormat, 0, type->cbFormat); + + wfx = (WAVEFORMATEX *)type->pbFormat; + wfx->wFormatTag = WAVE_FORMAT_PCM; + wfx->nChannels = decoder->input_format.u.audio_wma.channels; + wfx->nSamplesPerSec = decoder->input_format.u.audio_wma.rate; + wfx->nAvgBytesPerSec = wfx->nChannels * wfx->nSamplesPerSec * 2; + wfx->nBlockAlign = wfx->nChannels * 2; + wfx->wBitsPerSample = WMAUDIO_BITS_PER_SAMPLE; + + return S_OK; }
static HRESULT WINAPI media_object_SetInputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) { - FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface, index, type, flags); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + struct wg_format wg_format; + unsigned int i; + + TRACE("iface %p, index %lu, type %p, flags %#lx.\n", iface, index, type, flags); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + + if (flags & DMO_SET_TYPEF_CLEAR) + { + if (flags != DMO_SET_TYPEF_CLEAR) + return E_INVALIDARG; + memset(&decoder->input_format, 0, sizeof(decoder->input_format)); + if (decoder->wg_transform) + { + wg_transform_destroy(decoder->wg_transform); + decoder->wg_transform = 0; + } + return S_OK; + } + if (!type) + return E_POINTER; + if (flags & ~DMO_SET_TYPEF_TEST_ONLY) + return E_INVALIDARG; + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) + return DMO_E_TYPE_NOT_ACCEPTED; + + for (i = 0; i < ARRAY_SIZE(wma_decoder_input_types); ++i) + if (IsEqualGUID(&type->subtype, wma_decoder_input_types[i])) + break; + if (i == ARRAY_SIZE(wma_decoder_input_types)) + return DMO_E_TYPE_NOT_ACCEPTED; + + if (!amt_to_wg_format((const AM_MEDIA_TYPE *)type, &wg_format)) + return DMO_E_TYPE_NOT_ACCEPTED; + assert(wg_format.major_type == WG_MAJOR_TYPE_AUDIO_WMA); + + if (flags & DMO_SET_TYPEF_TEST_ONLY) + return S_OK; + + decoder->input_format = wg_format; + if (decoder->wg_transform) + { + wg_transform_destroy(decoder->wg_transform); + decoder->wg_transform = 0; + } + + return S_OK; }
static HRESULT WINAPI media_object_SetOutputType(IMediaObject *iface, DWORD index, const DMO_MEDIA_TYPE *type, DWORD flags) { - FIXME("iface %p, index %lu, type %p, flags %#lx stub!\n", iface, index, type, flags); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + struct wg_transform_attrs attrs = {0}; + struct wg_format wg_format; + unsigned int i; + + TRACE("iface %p, index %lu, type %p, flags %#lx,\n", iface, index, type, flags); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + + if (flags & DMO_SET_TYPEF_CLEAR) + { + if (flags != DMO_SET_TYPEF_CLEAR) + return E_INVALIDARG; + memset(&decoder->output_format, 0, sizeof(decoder->output_format)); + if (decoder->wg_transform) + { + wg_transform_destroy(decoder->wg_transform); + decoder->wg_transform = 0; + } + return S_OK; + } + if (!type) + return E_POINTER; + if (flags & ~DMO_SET_TYPEF_TEST_ONLY) + return E_INVALIDARG; + + if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) + return DMO_E_TYPE_NOT_ACCEPTED; + + for (i = 0; i < ARRAY_SIZE(wma_decoder_output_types); ++i) + if (IsEqualGUID(&type->subtype, wma_decoder_output_types[i])) + break; + if (i == ARRAY_SIZE(wma_decoder_output_types)) + return DMO_E_TYPE_NOT_ACCEPTED; + + + if (!amt_to_wg_format((const AM_MEDIA_TYPE *)type, &wg_format)) + return DMO_E_TYPE_NOT_ACCEPTED; + assert(wg_format.major_type == WG_MAJOR_TYPE_AUDIO); + + if (decoder->input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) + return DMO_E_TYPE_NOT_SET; + + if (flags & DMO_SET_TYPEF_TEST_ONLY) + return S_OK; + + decoder->output_format = wg_format; + + /* Set up wg_transform. */ + if (decoder->wg_transform) + { + wg_transform_destroy(decoder->wg_transform); + decoder->wg_transform = 0; + } + if (!(decoder->wg_transform = wg_transform_create(&decoder->input_format, &decoder->output_format, &attrs))) + return E_FAIL; + + return S_OK; }
static HRESULT WINAPI media_object_GetInputCurrentType(IMediaObject *iface, DWORD index, DMO_MEDIA_TYPE *type) @@ -670,8 +824,21 @@ static HRESULT WINAPI media_object_GetInputSizeInfo(IMediaObject *iface, DWORD i
static HRESULT WINAPI media_object_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment) { - FIXME("iface %p, index %lu, size %p, alignment %p stub!\n", iface, index, size, alignment); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + + TRACE("iface %p, index %lu, size %p, alignment %p.\n", iface, index, size, alignment); + + if (!size || !alignment) + return E_POINTER; + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + if (decoder->output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) + return DMO_E_TYPE_NOT_SET; + + *size = 8192; + *alignment = 1; + + return S_OK; }
static HRESULT WINAPI media_object_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency) @@ -688,14 +855,27 @@ static HRESULT WINAPI media_object_SetInputMaxLatency(IMediaObject *iface, DWORD
static HRESULT WINAPI media_object_Flush(IMediaObject *iface) { - FIXME("iface %p stub!\n", iface); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + HRESULT hr; + + TRACE("iface %p.\n", iface); + + if (FAILED(hr = wg_transform_flush(decoder->wg_transform))) + return hr; + + wg_sample_queue_flush(decoder->wg_sample_queue, TRUE); + + return S_OK; }
static HRESULT WINAPI media_object_Discontinuity(IMediaObject *iface, DWORD index) { - FIXME("iface %p, index %lu stub!\n", iface, index); - return E_NOTIMPL; + TRACE("iface %p, index %lu.\n", iface, index); + + if (index > 0) + return DMO_E_INVALIDSTREAMINDEX; + + return S_OK; }
static HRESULT WINAPI media_object_AllocateStreamingResources(IMediaObject *iface) @@ -719,16 +899,38 @@ static HRESULT WINAPI media_object_GetInputStatus(IMediaObject *iface, DWORD ind static HRESULT WINAPI media_object_ProcessInput(IMediaObject *iface, DWORD index, IMediaBuffer *buffer, DWORD flags, REFERENCE_TIME timestamp, REFERENCE_TIME timelength) { - FIXME("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s stub!\n", iface, - index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(timelength)); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + + TRACE("iface %p, index %lu, buffer %p, flags %#lx, timestamp %s, timelength %s.\n", iface, + index, buffer, flags, wine_dbgstr_longlong(timestamp), wine_dbgstr_longlong(timelength)); + + if (!decoder->wg_transform) + return DMO_E_TYPE_NOT_SET; + + return wg_transform_push_dmo(decoder->wg_transform, buffer, flags, timestamp, timelength, decoder->wg_sample_queue); }
static HRESULT WINAPI media_object_ProcessOutput(IMediaObject *iface, DWORD flags, DWORD count, DMO_OUTPUT_DATA_BUFFER *buffers, DWORD *status) { - FIXME("iface %p, flags %#lx, count %lu, buffers %p, status %p stub!\n", iface, flags, count, buffers, status); - return E_NOTIMPL; + struct wma_decoder *decoder = impl_from_IMediaObject(iface); + HRESULT hr; + + TRACE("iface %p, flags %#lx, count %lu, buffers %p, status %p.\n", iface, flags, count, buffers, status); + + if (!decoder->wg_transform) + return DMO_E_TYPE_NOT_SET; + + hr = wg_transform_read_dmo(decoder->wg_transform, buffers); + + if (SUCCEEDED(hr)) + { + /* WMA Lossless emits anything from 0 to 12 packets of output for each packet of input */ + buffers[0].dwStatus |= DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE; + wg_sample_queue_flush(decoder->wg_sample_queue, false); + } + + return hr; }
static HRESULT WINAPI media_object_Lock(IMediaObject *iface, LONG lock)
From: Alfred Agrell floating@muncher.se
--- dlls/mf/tests/transform.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index a95926d9dc1..51d130a6908 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3531,7 +3531,7 @@ static void test_wma_decoder_dmo_output_type(void)
char buffer_good_output[1024], buffer_bad_output[1024], buffer_input[1024]; DMO_MEDIA_TYPE *good_output_type, *bad_output_type, *input_type, type; - DWORD count, i, ret; + DWORD count, i, ret, size, alignment; IMediaObject *dmo; HRESULT hr;
@@ -3708,6 +3708,20 @@ static void test_wma_decoder_dmo_output_type(void) MoFreeMediaType(&type); }
+ /* Test GetOutputSizeInfo. */ + hr = IMediaObject_GetOutputSizeInfo(dmo, 1, NULL, NULL); + ok(hr == E_POINTER, "GetOutputSizeInfo returned %#lx.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, NULL, NULL); + ok(hr == E_POINTER, "GetOutputSizeInfo returned %#lx.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, &size, NULL); + ok(hr == E_POINTER, "GetOutputSizeInfo returned %#lx.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, NULL, &alignment); + ok(hr == E_POINTER, "GetOutputSizeInfo returned %#lx.\n", hr); + hr = IMediaObject_GetOutputSizeInfo(dmo, 0, &size, &alignment); + ok(hr == S_OK, "GetOutputSizeInfo returned %#lx.\n", hr); + ok(size == 8192, "Unexpected size %lu.\n", size); + ok(alignment == 1, "Unexpected alignment %lu.\n", alignment); + hr = IMediaObject_GetInputCurrentType(dmo, 0, input_type); todo_wine ok(hr == S_OK, "GetInputCurrentType returned %#lx.\n", hr);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=140112
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w7u_adm (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w7u_el (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0. 0a70:transform: unhandled exception c0000005 at 00A945C2
=== w8 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w8adm (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w864 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064v1507 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064v1809 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064_tsign (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64_en_AE_u8 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w11pro64 (32 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w7pro64 (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w864 (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064v1507 (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064v1809 (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064_2qxl (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064_adm (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w1064_tsign (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64 (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64_ar (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64_ja (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w10pro64_zh_CN (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.
=== w11pro64_amd (64 bit report) ===
mf: transform.c:734: Test failed: wmadec: got result 0.