Along with !4450, 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: tests/wmvcore: Add tests for compressed output. winegstreamer: Implement compressed output support in WMSyncReader. winegstreamer: Fill in a few more pieces of WMV format handling. winegstreamer: Add codec_data to WMVs. winegstreamer: Don't use VIDEOINFO for non-RGB data.
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/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 381b2837214..b56e56c0483 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -558,7 +558,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) @@ -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(*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)); @@ -602,6 +602,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; } @@ -879,6 +880,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 7d4bc7a5f8c..a48de3160ed 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -236,6 +236,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)) { @@ -280,6 +283,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) @@ -665,6 +680,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"))) @@ -712,6 +728,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 b56e56c0483..483b9c610ea 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -338,6 +338,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; @@ -387,7 +391,6 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) 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: FIXME("Format %u not implemented!\n", format->major_type); return 0; @@ -602,6 +605,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 a48de3160ed..30e816add28 100644 --- a/dlls/winegstreamer/wg_format.c +++ b/dlls/winegstreamer/wg_format.c @@ -824,7 +824,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); @@ -848,6 +847,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/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/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 f40ae37c0ce..76ad6a57718 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1820,6 +1820,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; @@ -3957,6 +4140,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=140093
Your paranoid android.
=== 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:1843: Test failed: Media types didn't match. wmvcore.c:1843: Test failed: Media types didn't match. wmvcore.c:1988: Test succeeded inside todo block: 0: Got 3 wmvcore.c:1991: Test failed: 0: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 1: Got 1 wmvcore.c:1991: Test failed: 1: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 2: Got 1 wmvcore.c:1991: Test failed: 2: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 3: Got 1 wmvcore.c:1991: Test failed: 3: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 4: Got 1 wmvcore.c:1991: Test failed: 4: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 5: Got 1 wmvcore.c:1991: Test failed: 5: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 6: Got 1 wmvcore.c:1991: Test failed: 6: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 7: Got 1 wmvcore.c:1991: Test failed: 7: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 8: Got 1 wmvcore.c:1991: Test failed: 8: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 9: Got 1 wmvcore.c:1991: Test failed: 9: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 10: Got 1 wmvcore.c:1991: Test failed: 10: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 11: Got 1 wmvcore.c:1991: Test failed: 11: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 12: Got 1 wmvcore.c:1991: Test failed: 12: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 13: Got 1 wmvcore.c:1991: Test failed: 13: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 14: Got 1 wmvcore.c:1991: Test failed: 14: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 15: Got 1 wmvcore.c:1991: Test failed: 15: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 16: Got 1 wmvcore.c:1991: Test failed: 16: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 17: Got 1 wmvcore.c:1991: Test failed: 17: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 18: Got 1 wmvcore.c:1991: Test failed: 18: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 19: Got 1 wmvcore.c:1991: Test failed: 19: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 20: Got 1 wmvcore.c:1991: Test failed: 20: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 21: Got 1 wmvcore.c:1991: Test failed: 21: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 22: Got 1 wmvcore.c:1991: Test failed: 22: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 23: Got 1 wmvcore.c:1991: Test failed: 23: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 24: Got 1 wmvcore.c:1991: Test failed: 24: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 25: Got 1 wmvcore.c:1991: Test failed: 25: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 26: Got 1 wmvcore.c:1991: Test failed: 26: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 27: Got 1 wmvcore.c:1991: Test failed: 27: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 28: Got 1 wmvcore.c:1991: Test failed: 28: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 29: Got 1 wmvcore.c:1991: Test failed: 29: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 30: Got 1 wmvcore.c:1991: Test failed: 30: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 31: Got 1 wmvcore.c:1991: Test failed: 31: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 32: Got 1 wmvcore.c:1991: Test failed: 32: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 33: Got 1 wmvcore.c:1991: Test failed: 33: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 34: Got 1 wmvcore.c:1991: Test failed: 34: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 35: Got 1 wmvcore.c:1991: Test failed: 35: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 36: Got 1 wmvcore.c:1991: Test failed: 36: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 37: Got 1 wmvcore.c:1991: Test failed: 37: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 38: Got 1 wmvcore.c:1991: Test failed: 38: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 39: Got 1 wmvcore.c:1991: Test failed: 39: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 40: Got 1 wmvcore.c:1991: Test failed: 40: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 41: Got 1 wmvcore.c:1991: Test failed: 41: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 42: Got 1 wmvcore.c:1991: Test failed: 42: Got 4096 wmvcore.c:1990: Test succeeded inside todo block: 43: Got 1 wmvcore.c:1991: Test failed: 43: Got 4096 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2333: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2333: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2333: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000 wmvcore.c:2240: Test failed: got time 0 wmvcore.c:2240: Test failed: got time 460000 wmvcore.c:2321: Test failed: got pts 0 wmvcore.c:2321: Test failed: got pts 460000
wmvcore:wmvcore is failing; I'm investigating, but it's not entirely clear to me what exactly it's trying to test for, and I think there's a tiny threading issue in current master (I don't think it's causing any actual trouble, but it still makes me nervous), so it's taking a while to figure out.
Wise choice to focus on the WMA DMO first, reviewers.
On Thu Nov 23 01:30:54 2023 +0000, Alfred Agrell wrote:
wmvcore:wmvcore is failing; I'm investigating, but it's not entirely clear to me what exactly it's trying to test for, and I think there's a tiny threading issue in current master (I don't think it's causing any actual trouble, but it still makes me nervous), so it's taking a while to figure out. Wise choice to focus on the WMA DMO first, reviewers.
Solved it; had to switch a few tests to todo, hopefully nothing relies on SetReadStreamSamples() not seeking to the start (considering it previously didn't return the expected compressed data, and changing stream format outside stream start being quite implausible, probably a safe assumption).
Also applied all relevant code review remarks I could find in 4450. (Probably plenty of remark-worthy stuff I didn't find, though. Especially the art of commit size eludes me, I'm just guessing.)