Supersedes https://gitlab.winehq.org/wine/wine/-/merge_requests/5090
-- v5: winegstreamer: Append an optional parser before decoders. winegstreamer: Release sink caps in the error path.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/wg_transform.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 516b28e82e2..c252142d13d 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -338,7 +338,7 @@ NTSTATUS wg_transform_create(void *args) struct wg_format output_format = *params->output_format; struct wg_format input_format = *params->input_format; GstElement *first = NULL, *last = NULL, *element; - GstCaps *raw_caps = NULL, *src_caps = NULL; + GstCaps *sink_caps = NULL, *src_caps = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; GstPadTemplate *template = NULL; struct wg_transform *transform; @@ -395,7 +395,7 @@ NTSTATUS wg_transform_create(void *args) * raw output media type should be enough. */ media_type = gst_structure_get_name(gst_caps_get_structure(transform->output_caps, 0)); - if (!(raw_caps = gst_caps_new_empty_simple(media_type))) + if (!(sink_caps = gst_caps_new_empty_simple(media_type))) goto out;
switch (input_format.major_type) @@ -408,12 +408,9 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_VIDEO_INDEO: case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_MPEG1: - if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, src_caps, raw_caps)) + if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, src_caps, sink_caps)) || !append_element(transform->container, element, &first, &last)) - { - gst_caps_unref(raw_caps); goto out; - } break;
case WG_MAJOR_TYPE_AUDIO: @@ -421,12 +418,9 @@ NTSTATUS wg_transform_create(void *args) break; case WG_MAJOR_TYPE_UNKNOWN: GST_FIXME("Format %u not implemented!", input_format.major_type); - gst_caps_unref(raw_caps); goto out; }
- gst_caps_unref(raw_caps); - switch (output_format.major_type) { case WG_MAJOR_TYPE_AUDIO: @@ -507,6 +501,7 @@ NTSTATUS wg_transform_create(void *args) goto out;
gst_caps_unref(src_caps); + gst_caps_unref(sink_caps);
GST_INFO("Created winegstreamer transform %p.", transform); params->transform = (wg_transform_t)(ULONG_PTR)transform; @@ -521,6 +516,8 @@ out: gst_object_unref(transform->my_src); if (src_caps) gst_caps_unref(src_caps); + if (sink_caps) + gst_caps_unref(sink_caps); if (transform->allocator) wg_allocator_destroy(transform->allocator); if (transform->drain_query)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/quartz/tests/mpegaudio.c | 4 ++++ dlls/quartz/tests/mpegvideo.c | 28 +++++++++------------------- dlls/winegstreamer/wg_transform.c | 21 +++++++++++++++++++-- 3 files changed, 32 insertions(+), 21 deletions(-)
diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c index 804cbbcc3d1..9fa6796e096 100644 --- a/dlls/quartz/tests/mpegaudio.c +++ b/dlls/quartz/tests/mpegaudio.c @@ -905,6 +905,7 @@ struct testfilter unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush; REFERENCE_TIME expected_start_time; REFERENCE_TIME expected_stop_time; + BOOL todo_time; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -1012,7 +1013,9 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample ok(hr == S_OK, "Got hr %#lx.\n", hr); if (filter->got_sample == 1) { + todo_wine_if(filter->todo_time) ok(start == filter->expected_start_time, "Got start time %s.\n", wine_dbgstr_longlong(start)); + todo_wine_if(filter->todo_time) ok(stop == filter->expected_stop_time, "Got stop time %s.\n", wine_dbgstr_longlong(stop)); }
@@ -1510,6 +1513,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_stop_time = 120000; + testsink->todo_time = TRUE; hr = IMemInputPin_Receive(input, sample); ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IMemInputPin_Receive(input, sample); diff --git a/dlls/quartz/tests/mpegvideo.c b/dlls/quartz/tests/mpegvideo.c index 1f17ddbe636..433436bd954 100644 --- a/dlls/quartz/tests/mpegvideo.c +++ b/dlls/quartz/tests/mpegvideo.c @@ -834,7 +834,6 @@ struct testfilter unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush; REFERENCE_TIME expected_start_time; REFERENCE_TIME expected_stop_time; - BOOL todo_stop_time; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -942,7 +941,7 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample { ok(start == filter->expected_start_time, "Got start time %s, expected %s.\n", wine_dbgstr_longlong(start), wine_dbgstr_longlong(filter->expected_start_time)); - todo_wine_if(filter->todo_stop_time) + todo_wine ok(stop == filter->expected_stop_time, "Got stop time %s, expected %s.\n", wine_dbgstr_longlong(stop), wine_dbgstr_longlong(filter->expected_stop_time)); } @@ -1226,7 +1225,7 @@ static void test_send_video(IMemInputPin *input, IMediaSample *sample) /* gst-launch-1.0 -v videotestsrc pattern=black num-buffers=10 ! video/x-raw,width=32,height=24 ! mpeg2enc ! filesink location=empty-es2.mpg */ /* then truncate to taste */ /* each 00 00 01 b3 or 00 00 01 00 starts a new frame, except the first 00 00 01 00 after a 00 00 01 b3 */ - static const BYTE empty_mpg_frame1[] = { + static const BYTE empty_mpg_frames[] = { 0x00, 0x00, 0x01, 0xb3, 0x02, 0x00, 0x18, 0x15, 0x02, 0xbf, 0x60, 0x9c, 0x00, 0x00, 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xff, 0xf8, @@ -1235,27 +1234,22 @@ static void test_send_video(IMemInputPin *input, IMediaSample *sample) 0x41, 0x28, 0x88, 0x13, 0xb9, 0x6f, 0xcf, 0xc1, 0x04, 0x03, 0xa0, 0x11, 0xb1, 0x41, 0x28, 0x88, 0x13, 0xb9, 0x6f, 0xa1, 0x4b, 0x9f, 0x48, 0x04, 0x10, 0x0e, 0x80, 0x46, 0xc5, 0x04, 0xa2, 0x20, 0x4e, 0xe5, 0x80, 0x41, 0x00, 0xe8, 0x04, 0x6c, 0x50, 0x4a, 0x22, 0x04, 0xee, 0x58, - }; - static const BYTE empty_mpg_frame2[] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x57, 0xff, 0xf9, 0x80, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0, 0x00, 0x00, 0x01, 0x02, 0x0a, 0x79, 0xc0, - }; - static const BYTE empty_mpg_frame3[] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x97, 0xff, 0xf9, 0x80, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0, - 0x00, 0x00, 0x01, 0x02, 0x0a, 0x79, 0xc0, 0x00, 0x00, 0x01, 0xb7, + 0x00, 0x00, 0x01, 0x02, 0x0a, 0x79, 0xc0, + }; + static const BYTE empty_mpg_eos[] = { + 0x00, 0x00, 0x01, 0xb7, }; HRESULT hr; IPin *pin;
- /* frame 1 - it's a complete frame, but due to how MPEG framing works, the decoder doesn't know that */ - /* frame 2 - new frame starts, frame 1 can be emitted - but Wine gets confused by colorimetry and returns an error */ - /* frame 3 - Wine emits frames 1 and 2 */ - /* meanwhile, native won't emit anything until an unknown-sized internal buffer is filled, or EOS is announced */ - test_send_sample(input, sample, empty_mpg_frame1, ARRAY_SIZE(empty_mpg_frame1), FALSE); - test_send_sample(input, sample, empty_mpg_frame2, ARRAY_SIZE(empty_mpg_frame2), TRUE); - test_send_sample(input, sample, empty_mpg_frame3, ARRAY_SIZE(empty_mpg_frame3), FALSE); + /* native won't emit anything until an unknown-sized internal buffer is filled, or EOS is announced */ + test_send_sample(input, sample, empty_mpg_frames, ARRAY_SIZE(empty_mpg_frames), TRUE); + test_send_sample(input, sample, empty_mpg_eos, ARRAY_SIZE(empty_mpg_eos), FALSE);
hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -1304,7 +1298,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
sink->expected_start_time = 0; sink->expected_stop_time = 0; - sink->todo_stop_time = FALSE; hr = IMediaSample_SetTime(sample, &sink->expected_start_time, &sink->expected_stop_time); ok(hr == S_OK, "Got hr %#lx.\n", hr);
@@ -1342,7 +1335,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
sink->expected_start_time = 22222; sink->expected_stop_time = 22222; - sink->todo_stop_time = TRUE; test_send_video(input, sample); ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample); ok(sink->got_eos == 1, "Got %u calls to EndOfStream().\n", sink->got_eos); @@ -1412,7 +1404,6 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_stop_time = 0; - testsink->todo_stop_time = TRUE; test_send_video(input, sample); ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample); testsink->got_sample = 0; @@ -1440,7 +1431,6 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_stop_time = 0; - testsink->todo_stop_time = TRUE; test_send_video(input, sample); ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample); testsink->got_sample = 0; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index c252142d13d..72b2ed7cfce 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -338,7 +338,7 @@ NTSTATUS wg_transform_create(void *args) struct wg_format output_format = *params->output_format; struct wg_format input_format = *params->input_format; GstElement *first = NULL, *last = NULL, *element; - GstCaps *sink_caps = NULL, *src_caps = NULL; + GstCaps *sink_caps = NULL, *src_caps = NULL, *parsed_caps = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; GstPadTemplate *template = NULL; struct wg_transform *transform; @@ -390,6 +390,11 @@ NTSTATUS wg_transform_create(void *args) gst_pad_set_query_function(transform->my_sink, transform_sink_query_cb); gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb);
+ media_type = gst_structure_get_name(gst_caps_get_structure(src_caps, 0)); + if (!(parsed_caps = gst_caps_new_empty_simple(media_type))) + goto out; + gst_caps_set_simple(parsed_caps, "parsed", G_TYPE_BOOLEAN, true, NULL); + /* Since we append conversion elements, we don't want to filter decoders * based on the actual output caps now. Matching decoders with the * raw output media type should be enough. @@ -408,7 +413,16 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_VIDEO_INDEO: case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_MPEG1: - if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, src_caps, sink_caps)) + if ((element = find_element(GST_ELEMENT_FACTORY_TYPE_PARSER, src_caps, parsed_caps)) + && !append_element(transform->container, element, &first, &last)) + goto out; + else + { + gst_caps_unref(parsed_caps); + parsed_caps = gst_caps_ref(src_caps); + } + + if (!(element = find_element(GST_ELEMENT_FACTORY_TYPE_DECODER, parsed_caps, sink_caps)) || !append_element(transform->container, element, &first, &last)) goto out; break; @@ -500,6 +514,7 @@ NTSTATUS wg_transform_create(void *args) || !push_event(transform->my_src, event)) goto out;
+ gst_caps_unref(parsed_caps); gst_caps_unref(src_caps); gst_caps_unref(sink_caps);
@@ -516,6 +531,8 @@ out: gst_object_unref(transform->my_src); if (src_caps) gst_caps_unref(src_caps); + if (parsed_caps) + gst_caps_unref(parsed_caps); if (sink_caps) gst_caps_unref(sink_caps); if (transform->allocator)
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=144035
Your paranoid android.
=== debian11b (64 bit WoW report) ===
d3dx10_34: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239650. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239650. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001194A80. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011C3550.
d3dx10_35: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011A4690. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011A4690. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011A4B40. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011C1820. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D56B0.
d3dx10_36: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239D30. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239F00. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001239F00. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001194A80. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E34B0.
d3dx10_37: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239710. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011E2E90. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011E3060. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011E2E90. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001194770.
d3dx10_38: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239DC0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B4D80. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B5AE0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B5CB0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B5E80.
d3dx10_39: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011D5B20. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D1AF0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B6030. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001195800. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011BCAB0.
d3dx10_40: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BB900. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B5D20. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011BB6A0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D1820. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D19F0.
d3dx10_41: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011A4690. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011A4860. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D18E0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D1AB0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D55F0.
d3dx10_42: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239DA0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001195940. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B5AE0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B5CB0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B5E80.
d3dx10_43: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239E40. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011D5830. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011E3580. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001239D40. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001239D40.