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)
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/wg_sample.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/wg_sample.c b/dlls/winegstreamer/wg_sample.c index 4b02252174b..31281066957 100644 --- a/dlls/winegstreamer/wg_sample.c +++ b/dlls/winegstreamer/wg_sample.c @@ -484,7 +484,7 @@ HRESULT wg_transform_push_dmo(wg_transform_t transform, IMediaBuffer *media_buff if (flags & DMO_INPUT_DATA_BUFFERF_TIMELENGTH) { wg_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION; - wg_sample->pts = time_length; + wg_sample->duration = time_length; }
wg_sample_queue_begin_append(queue, wg_sample);
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/quartz_parser.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 0670fbd5181..381b2837214 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -524,7 +524,7 @@ static bool amt_from_wg_format_video(AM_MEDIA_TYPE *mt, const struct wg_format *
static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_format *format) { - VIDEOINFO *video_format; + VIDEOINFOHEADER *video_format; uint32_t frame_time;
if (!(video_format = CoTaskMemAlloc(sizeof(*video_format)))) @@ -535,7 +535,7 @@ static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_ mt->bTemporalCompression = TRUE; mt->lSampleSize = 1; mt->formattype = FORMAT_VideoInfo; - mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->cbFormat = sizeof(*video_format); mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); @@ -554,7 +554,7 @@ static bool amt_from_wg_format_video_cinepak(AM_MEDIA_TYPE *mt, const struct wg_
static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_format *format) { - VIDEOINFO *video_format; + VIDEOINFOHEADER *video_format; uint32_t frame_time; const GUID *subtype;
@@ -589,7 +589,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form mt->bTemporalCompression = TRUE; mt->lSampleSize = 0; mt->formattype = FORMAT_VideoInfo; - mt->cbFormat = sizeof(VIDEOINFOHEADER); + mt->cbFormat = sizeof(*video_format); mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format));
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/mfplat.c | 2 +- dlls/winegstreamer/wg_format.c | 66 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index 0e1d489d8e5..d1e8812adb6 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -765,7 +765,7 @@ static void mf_media_type_to_wg_format_audio_wma(IMFMediaType *type, const GUID if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth))) { FIXME("Depth is not set.\n"); - return; + depth = 0; } if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len))) { diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 7d4bc7a5f8c..9f2a2ea8515 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 <= 64) + { + 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 ++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 381b2837214..e458ee59553 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); }
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/quartz_parser.c | 12 ++++++++++-- dlls/winegstreamer/unixlib.h | 2 ++ dlls/winegstreamer/wg_format.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index e458ee59553..f4895fabc2c 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -628,7 +628,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form uint32_t frame_time; const GUID *subtype;
- if (!(video_format = CoTaskMemAlloc(sizeof(*video_format)))) + if (!(video_format = CoTaskMemAlloc(sizeof(*video_format) + format->u.video_wmv.codec_data_len))) return false;
switch (format->u.video_wmv.format) @@ -659,7 +659,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form mt->bTemporalCompression = TRUE; mt->lSampleSize = 0; mt->formattype = FORMAT_VideoInfo; - mt->cbFormat = sizeof(*video_format); + mt->cbFormat = sizeof(*video_format) + format->u.video_wmv.codec_data_len; mt->pbFormat = (BYTE *)video_format;
memset(video_format, 0, sizeof(*video_format)); @@ -672,6 +672,7 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form video_format->bmiHeader.biHeight = format->u.video_wmv.height; video_format->bmiHeader.biPlanes = 1; video_format->bmiHeader.biCompression = mt->subtype.Data1; + memcpy(video_format+1, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len);
return true; } @@ -1000,6 +1001,13 @@ static bool amt_to_wg_format_video_wmv(const AM_MEDIA_TYPE *mt, struct wg_format else format->u.video_wmv.format = WG_WMV_VIDEO_FORMAT_UNKNOWN;
+ format->u.video_wmv.codec_data_len = mt->cbFormat - sizeof(VIDEOINFOHEADER); + if (format->u.video_wmv.codec_data_len > 64) + { + WARN("Too big codec_data value (%u).\n", (unsigned)format->u.video_wmv.codec_data_len); + format->u.video_wmv.codec_data_len = 0; + } + memcpy(format->u.video_wmv.codec_data, video_format+1, format->u.video_wmv.codec_data_len); return true; }
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 6c0c61f76bb..42cc853c4d0 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -157,6 +157,8 @@ struct wg_format wg_wmv_video_format format; int32_t width, height; uint32_t fps_n, fps_d; + uint32_t codec_data_len; + unsigned char codec_data[64]; } video_wmv; struct { diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 9f2a2ea8515..2dcc08bb7e4 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -298,6 +298,9 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap gchar format_buffer[5] = {'W','M','V','0',0}; enum wg_wmv_video_format wmv_format; const gchar *wmv_format_str = NULL; + const GValue *codec_data_value; + GstBuffer *codec_data; + GstMapInfo map;
if (!gst_structure_get_int(structure, "width", &width)) { @@ -342,6 +345,18 @@ static void wg_format_from_caps_video_wmv(struct wg_format *format, const GstCap format->u.video_wmv.format = wmv_format; format->u.video_wmv.fps_n = fps_n; format->u.video_wmv.fps_d = fps_d; + + if ((codec_data_value = gst_structure_get_value(structure, "codec_data")) && (codec_data = gst_value_get_buffer(codec_data_value))) + { + gst_buffer_map(codec_data, &map, GST_MAP_READ); + if (map.size <= 64) + { + format->u.video_wmv.codec_data_len = map.size; + memcpy(format->u.video_wmv.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_mpeg1(struct wg_format *format, const GstCaps *caps) @@ -731,6 +746,7 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) { unsigned int wmv_version; const char *wmv_format; + GstBuffer *buffer; GstCaps *caps;
if (!(caps = gst_caps_new_empty_simple("video/x-wmv"))) @@ -778,6 +794,19 @@ static GstCaps *wg_format_to_caps_video_wmv(const struct wg_format *format) if (format->u.video_wmv.fps_d || format->u.video_wmv.fps_n) gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video_wmv.fps_n, format->u.video_wmv.fps_d, NULL);
+ if (format->u.video_wmv.codec_data_len) + { + if (!(buffer = gst_buffer_new_and_alloc(format->u.video_h264.codec_data_len))) + { + gst_caps_unref(caps); + return NULL; + } + + gst_buffer_fill(buffer, 0, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len); + gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); + gst_buffer_unref(buffer); + } + return caps; }
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/quartz_parser.c | 7 ++++++- dlls/winegstreamer/wg_format.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index f4895fabc2c..8a740f80483 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -403,6 +403,10 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) return wg_format_get_max_size_video_raw(WG_VIDEO_FORMAT_YV12, format->u.video_mpeg1.width, format->u.video_mpeg1.height);
+ case WG_MAJOR_TYPE_VIDEO_WMV: + return wg_format_get_max_size_video_raw(WG_VIDEO_FORMAT_YV12, + format->u.video_wmv.width, format->u.video_wmv.height); + case WG_MAJOR_TYPE_AUDIO: { unsigned int rate = format->u.audio.rate, channels = format->u.audio.channels; @@ -457,7 +461,6 @@ unsigned int wg_format_get_max_size(const struct wg_format *format)
case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_INDEO: FIXME("Format %u not implemented!\n", format->major_type); return 0; @@ -672,6 +675,8 @@ static bool amt_from_wg_format_video_wmv(AM_MEDIA_TYPE *mt, const struct wg_form video_format->bmiHeader.biHeight = format->u.video_wmv.height; video_format->bmiHeader.biPlanes = 1; video_format->bmiHeader.biCompression = mt->subtype.Data1; + video_format->bmiHeader.biBitCount = 24; + video_format->dwBitRate = 0; memcpy(video_format+1, format->u.video_wmv.codec_data, format->u.video_wmv.codec_data_len);
return true; diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c index 2dcc08bb7e4..b22eef013f7 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -890,7 +890,6 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) case WG_MAJOR_TYPE_AUDIO_MPEG4: case WG_MAJOR_TYPE_AUDIO_WMA: case WG_MAJOR_TYPE_VIDEO_H264: - case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_INDEO: case WG_MAJOR_TYPE_VIDEO_MPEG1: GST_FIXME("Format %u not implemented!", a->major_type); @@ -914,6 +913,12 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) /* Do not compare FPS. */ return a->u.video_cinepak.width == b->u.video_cinepak.width && a->u.video_cinepak.height == b->u.video_cinepak.height; + + case WG_MAJOR_TYPE_VIDEO_WMV: + /* Do not compare FPS. */ + return a->u.video_wmv.format == b->u.video_wmv.format + && a->u.video_wmv.width == b->u.video_wmv.width + && a->u.video_wmv.height == b->u.video_wmv.height; }
assert(0);
From: Alfred Agrell floating@muncher.se
--- dlls/winegstreamer/wma_decoder.c | 86 ++++++++++---------------------- 1 file changed, 26 insertions(+), 60 deletions(-)
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index d1082fe327a..8889f6eeb2d 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,13 @@ 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 = (MFT_INPUT_STREAM_INFO){ 0, 0, decoder->input_buf_size, 0, 1 }; return S_OK; }
@@ -223,13 +217,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 +267,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 +275,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 +306,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 +371,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 +389,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 +432,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 +850,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/winegstreamer/wma_decoder.c | 241 ++++++++++++++++++++++++++++--- 1 file changed, 222 insertions(+), 19 deletions(-)
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 8889f6eeb2d..b03dc3f587c 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"
@@ -619,29 +620,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 = 16; + + 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) @@ -666,8 +820,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) @@ -684,14 +851,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) @@ -715,16 +895,39 @@ 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; + + if ((hr = wg_transform_read_dmo(decoder->wg_transform, buffers)) == MF_E_TRANSFORM_STREAM_CHANGE) + 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/winegstreamer/wm_reader.c | 45 ++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 882b6df1bbb..857d40855b4 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -30,10 +30,6 @@ struct wm_stream WMT_STREAM_SELECTION selection; WORD index; bool eos; - /* Note that we only pretend to read compressed samples, and instead output - * uncompressed samples regardless of whether we are configured to read - * compressed samples. Rather, the behaviour of the reader objects differs - * in nontrivial ways depending on this field. */ bool read_compressed;
IWMReaderAllocatorEx *output_allocator; @@ -55,6 +51,7 @@ struct wm_reader
CRITICAL_SECTION cs; QWORD start_time; + QWORD file_size;
IStream *source_stream; HANDLE file; @@ -567,6 +564,7 @@ static HRESULT WINAPI stream_props_GetMediaType(IWMMediaProps *iface, WM_MEDIA_T memcpy(mt, &stream_mt, sizeof(*mt)); memcpy(mt + 1, stream_mt.pbFormat, stream_mt.cbFormat); mt->pbFormat = (BYTE *)(mt + 1); + FreeMediaType(&stream_mt); return S_OK; }
@@ -1453,13 +1451,15 @@ static const IWMReaderTimecodeVtbl timecode_vtbl = timecode_GetTimecodeRangeBounds, };
-static HRESULT init_stream(struct wm_reader *reader, QWORD file_size) +static HRESULT init_stream(struct wm_reader *reader, bool read_compressed) { wg_parser_t wg_parser; HRESULT hr; WORD i;
- if (!(wg_parser = wg_parser_create(WG_PARSER_DECODEBIN, FALSE))) + EnterCriticalSection(&reader->cs); + + if (!(wg_parser = wg_parser_create(WG_PARSER_DECODEBIN, read_compressed))) return E_OUTOFMEMORY;
reader->wg_parser = wg_parser; @@ -1470,20 +1470,26 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size) goto out_destroy_parser; }
- if (FAILED(hr = wg_parser_connect(reader->wg_parser, file_size))) + if (FAILED(hr = wg_parser_connect(reader->wg_parser, reader->file_size))) { ERR("Failed to connect parser, hr %#lx.\n", hr); goto out_shutdown_thread; }
- reader->stream_count = wg_parser_get_stream_count(reader->wg_parser); - - if (!(reader->streams = calloc(reader->stream_count, sizeof(*reader->streams)))) + if (!reader->streams) { - hr = E_OUTOFMEMORY; - goto out_disconnect_parser; + reader->stream_count = wg_parser_get_stream_count(reader->wg_parser); + if (!(reader->streams = calloc(reader->stream_count, sizeof(*reader->streams)))) + { + hr = E_OUTOFMEMORY; + goto out_disconnect_parser; + } + for (i = 0; i < reader->stream_count; ++i) + reader->streams[i].selection = WMT_ON; }
+ assert(reader->stream_count == wg_parser_get_stream_count(reader->wg_parser)); + for (i = 0; i < reader->stream_count; ++i) { struct wm_stream *stream = &reader->streams[i]; @@ -1491,7 +1497,6 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size) stream->wg_stream = wg_parser_get_stream(reader->wg_parser, i); stream->reader = reader; stream->index = i; - stream->selection = WMT_ON; wg_parser_stream_get_preferred_format(stream->wg_stream, &stream->format); if (stream->format.major_type == WG_MAJOR_TYPE_AUDIO) { @@ -1517,13 +1522,15 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size) if (stream->format.u.video.height > 0) stream->format.u.video.height = -stream->format.u.video.height; } - wg_parser_stream_enable(stream->wg_stream, &stream->format); + if (stream->selection == WMT_ON) + wg_parser_stream_enable(stream->wg_stream, &stream->format); }
/* We probably discarded events because streams weren't enabled yet. * Now that they're all enabled seek back to the start again. */ wg_parser_stream_seek(reader->streams[0].wg_stream, 1.0, 0, 0, AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning); + LeaveCriticalSection(&reader->cs);
return S_OK;
@@ -1540,6 +1547,8 @@ out_destroy_parser: wg_parser_destroy(reader->wg_parser); reader->wg_parser = 0;
+ LeaveCriticalSection(&reader->cs); + return hr; }
@@ -2134,8 +2143,9 @@ static HRESULT WINAPI reader_Open(IWMSyncReader2 *iface, const WCHAR *filename) }
reader->file = file; + reader->file_size = size.QuadPart;
- if (FAILED(hr = init_stream(reader, size.QuadPart))) + if (FAILED(hr = init_stream(reader, false))) reader->file = NULL;
LeaveCriticalSection(&reader->cs); @@ -2166,7 +2176,9 @@ static HRESULT WINAPI reader_OpenStream(IWMSyncReader2 *iface, IStream *stream) }
IStream_AddRef(reader->source_stream = stream); - if (FAILED(hr = init_stream(reader, stat.cbSize.QuadPart))) + reader->file_size = stat.cbSize.QuadPart; + + if (FAILED(hr = init_stream(reader, false))) { IStream_Release(stream); reader->source_stream = NULL; @@ -2340,6 +2352,7 @@ static HRESULT WINAPI reader_SetReadStreamSamples(IWMSyncReader2 *iface, WORD st }
stream->read_compressed = compressed; + init_stream(reader, compressed);
LeaveCriticalSection(&reader->cs); return S_OK;
From: Alfred Agrell floating@muncher.se
--- dlls/mf/tests/transform.c | 48 +++++++++++++-------------------------- 1 file changed, 16 insertions(+), 32 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 3f5524784cc..956c2d66e2a 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) @@ -3383,8 +3383,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); @@ -3400,7 +3398,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))) @@ -3410,17 +3407,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); @@ -3476,11 +3469,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 @@ -3496,7 +3487,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 @@ -3540,7 +3530,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;
@@ -3566,18 +3556,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); @@ -3593,7 +3578,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))) @@ -3603,17 +3587,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); @@ -3634,14 +3613,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); @@ -3697,11 +3672,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 { @@ -3716,7 +3689,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 { @@ -3735,11 +3707,24 @@ 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); 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 @@ -3747,7 +3732,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
From: Alfred Agrell floating@muncher.se
--- dlls/wmvcore/tests/wmvcore.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
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/wmvcore/tests/wmvcore.c | 184 +++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+)
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 1741299e654..86502336508 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1819,6 +1819,189 @@ static void test_sync_reader_file(void) ok(ret, "Failed to delete %s, error %lu.\n", debugstr_w(filename), GetLastError()); }
+static void test_stream_output_type(IWMProfile *profile, WORD stream_num, const WM_MEDIA_TYPE *expected) +{ + IWMStreamConfig *stream_config; + IWMMediaProps *media_props; + char mt_buffer[2000]; + WM_MEDIA_TYPE *mt; + DWORD ret_size; + HRESULT hr; + + hr = IWMProfile_GetStreamByNumber(profile, stream_num, &stream_config); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IWMStreamConfig_QueryInterface(stream_config, &IID_IWMMediaProps, (void**)&media_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + mt = (WM_MEDIA_TYPE *)mt_buffer; + memset(mt_buffer, 0xcc, sizeof(mt_buffer)); + ret_size = sizeof(mt_buffer); + hr = IWMMediaProps_GetMediaType(media_props, mt, &ret_size); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(compare_media_types(mt, expected), "Media types didn't match.\n"); + + IWMStreamConfig_Release(stream_config); + IWMMediaProps_Release(media_props); +} + +static const VIDEOINFOHEADER vih_wmv1 = { + .rcSource = { 0, 0, 64, 48 }, + .rcTarget = { 0, 0, 64, 48 }, + .dwBitRate = 0x0002e418, + .dwBitErrorRate = 0, + .AvgTimePerFrame = 0, + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 64, + .bmiHeader.biHeight = 48, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 0x18, + .bmiHeader.biCompression = MAKEFOURCC('W','M','V','1'), + .bmiHeader.biSizeImage = 0, + .bmiHeader.biXPelsPerMeter = 0, + .bmiHeader.biYPelsPerMeter = 0, +}; +static const WM_MEDIA_TYPE mt_wmv1 = { + /* MEDIATYPE_Video, MEDIASUBTYPE_WMV1, FORMAT_VideoInfo */ + .majortype = {0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0x31564d57, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .bTemporalCompression = TRUE, + .formattype = {0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(VIDEOINFOHEADER), + .pbFormat = (BYTE *)&vih_wmv1, +}; + +static const MSAUDIO1WAVEFORMAT wfx_msaudio1 = { + .wfx.wFormatTag = WAVE_FORMAT_MSAUDIO1, + .wfx.nChannels = 1, + .wfx.nSamplesPerSec = 44100, + .wfx.nAvgBytesPerSec = 16000, + .wfx.nBlockAlign = 0x02e7, + .wfx.wBitsPerSample = 0x0010, + .wfx.cbSize = MSAUDIO1_WFX_EXTRA_BYTES, + .wSamplesPerBlock = 0, + .wEncodeOptions = 1, +}; +static const WM_MEDIA_TYPE mt_msaudio1 = { + /* MEDIATYPE_Audio, MEDIASUBTYPE_MSAUDIO1, FORMAT_WaveFormatEx */ + .majortype = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .subtype = {0x00000160, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}, + .bFixedSizeSamples = TRUE, + .lSampleSize = 0x02e7, + .formattype = {0x05589f81, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}, + .cbFormat = sizeof(MSAUDIO1WAVEFORMAT), + .pbFormat = (BYTE *)&wfx_msaudio1, +}; + +static void test_sync_reader_compressed_output(void) +{ + static const DWORD audio_sample_times[] = { + 0, 460000, 920000, 1390000, 1850000, 2320000, 2780000, 3250000, 3710000, 4180000, 4640000, 5100000, + 5570000, 6030000, 6500000, 6960000, 7430000, 7890000, 8350000, 8820000, 9280000, 9750000, 10210000, + 10680000, 11140000, 11610000, 12070000, 12530000, 13000000, 13460000, 13930000, 14390000, 14860000, + 15320000, 15790000, 16250000, 16710000, 17180000, 17640000, 18110000, 18570000, 19040000, 19500000, 19960000, + 99999999 + }; + static const DWORD video_sample_sizes[] = { + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1117, 8 + }; + + const WCHAR *filename = load_resource(L"test.wmv"); + DWORD flags, bytes_count; + QWORD sample_time, sample_duration; + IWMSyncReader *reader; + IWMProfile *profile; + INSSBuffer *sample; + WORD stream_num; + HRESULT hr; + BYTE *data; + + DWORD audio_idx = 0; + DWORD video_idx = 0; + + VIDEOINFOHEADER vih = vih_wmv1; + WM_MEDIA_TYPE mt = mt_wmv1; + mt.pbFormat = (BYTE *)&vih; + + hr = WMCreateSyncReader(NULL, 0, &reader); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IWMSyncReader_QueryInterface(reader, &IID_IWMProfile, (void **)&profile); + + hr = IWMSyncReader_Open(reader, filename); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + if (winetest_platform_is_wine) + { + todo_wine ok(0, "dwBitRate is not implemented\n"); + vih.dwBitRate = 0; + } + test_stream_output_type(profile, 1, &mt); + test_stream_output_type(profile, 2, &mt_msaudio1); + + hr = IWMSyncReader_SetReadStreamSamples(reader, 1, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IWMSyncReader_SetReadStreamSamples(reader, 2, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + test_stream_output_type(profile, 1, &mt); + test_stream_output_type(profile, 2, &mt_msaudio1); + + while (video_idx < 50 || audio_idx < 44) + { + DWORD next_video_time = 460000 + video_idx * 400000; + DWORD next_audio_time = audio_sample_times[audio_idx]; + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &sample_time, &sample_duration, &flags, NULL, &stream_num); + ok(hr == S_OK, "%lu/%lu: Got hr %#lx.\n", video_idx, audio_idx, hr); + /* we don't care about the buffer, but GetLength is unimplemented in Wine */ + hr = INSSBuffer_GetBufferAndLength(sample, &data, &bytes_count); + ok(hr == S_OK, "%lu/%lu: Got hr %#lx.\n", video_idx, audio_idx, hr); + + if (next_video_time <= next_audio_time) + { + ok(stream_num == 1, "%lu: Got %lu\n", video_idx, (DWORD)stream_num); + ok(sample_time == next_video_time, "%lu: Expected %lu, got %lu\n", video_idx, next_video_time, (DWORD)sample_time); + todo_wine ok(sample_duration == 10000, "%lu: Got %lu\n", video_idx, (DWORD)sample_duration); + + if (video_idx == 0) + ok(flags == (WM_SF_CLEANPOINT|WM_SF_DISCONTINUITY), "%lu: Got %lu\n", audio_idx, flags); + else if (video_sample_sizes[video_idx] == 1117) + ok(flags == WM_SF_CLEANPOINT, "%lu: Got %lu\n", audio_idx, flags); + else + ok(flags == 0, "%lu: Got %lu\n", audio_idx, flags); + ok(bytes_count == video_sample_sizes[video_idx], + "%lu: Expected %lu, got %lu\n", video_idx, video_sample_sizes[video_idx], bytes_count); + video_idx++; + } + else + { + ok(stream_num == 2, "%lu: Got %lu\n", audio_idx, (DWORD)stream_num); + ok(sample_time == next_audio_time, "%lu: Expected %lu, got %lu\n", audio_idx, next_audio_time, (DWORD)sample_time); + todo_wine ok(sample_duration == 460000, "%lu: Got %lu\n", audio_idx, (DWORD)sample_duration); + + if (audio_idx == 0) + todo_wine ok(flags == (WM_SF_CLEANPOINT|WM_SF_DISCONTINUITY), "%lu: Got %lu\n", audio_idx, flags); + else + todo_wine ok(flags == WM_SF_CLEANPOINT, "%lu: Got %lu\n", audio_idx, flags); + ok(bytes_count == 743, "%lu: Got %lu\n", audio_idx, bytes_count); + + audio_idx++; + } + + INSSBuffer_Release(sample); + } + + hr = IWMSyncReader_GetNextSample(reader, 0, &sample, &sample_time, &sample_duration, &flags, NULL, &stream_num); + ok(hr == NS_E_NO_MORE_SAMPLES, "Got hr %#lx.\n", hr); + + IWMSyncReader_Release(reader); + IWMProfile_Release(profile); +} + struct callback { IWMReaderCallback IWMReaderCallback_iface; @@ -3956,6 +4139,7 @@ START_TEST(wmvcore) test_sync_reader_streaming(); test_sync_reader_types(); test_sync_reader_file(); + test_sync_reader_compressed_output(); test_async_reader_settings(); test_async_reader_streaming(); test_async_reader_types();
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=140082
Your paranoid android.
=== w7u_el (32 bit report) ===
mf: 0a6c:transform: unhandled exception c0000005 at 013045C2
=== debian11 (32 bit report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit ar:MA report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit de report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit fr report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit he:IL report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit hi:IN report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit ja:JP report) ===
wmvcore: wmvcore: Timeout
=== debian11 (32 bit zh:CN report) ===
wmvcore: wmvcore: Timeout
=== debian11b (32 bit WoW report) ===
wmvcore: wmvcore: Timeout
=== debian11b (64 bit WoW report) ===
wmvcore: wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2332: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000 wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2332: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000 wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2332: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000 wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000 wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000 wmvcore.c:2239: Test failed: got time 0 wmvcore.c:2239: Test failed: got time 460000 wmvcore.c:2320: Test failed: got pts 0 wmvcore.c:2320: Test failed: got pts 460000
12 patches is quite a lot for a series, could you please try to limit it to 5 or so at a time?
On Tue Nov 21 00:56:05 2023 +0000, Zebediah Figura wrote:
12 patches is quite a lot for a series, could you please try to limit it to 5 or so at a time?
I felt that these patches don't make much sense without each other (no program I'm aware of is improved by merging only parts of it), so keeping them together makes it easier to review the context.
But if you feel otherwise, then split it is.