Supersedes https://gitlab.winehq.org/wine/wine/-/merge_requests/5090
-- v6: 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 | 20 ++++++++++++++++++-- 3 files changed, 31 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..71ea8cd263c 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,10 @@ 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; + /* 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 +412,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 +513,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 +530,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=144036
Your paranoid android.
=== w11pro64_amd (64 bit report) ===
quartz: mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11cca6e, expected 56ce. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0. mpegvideo.c:945: Test failed: Got stop time 11c73a0, expected 0.
=== debian11b (64 bit WoW report) ===
d3dx10_34: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239DE0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011A4A60. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D5720. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011BB560. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B6050.
d3dx10_35: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BBA60. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011BB950. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011E3990. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D5600. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D57D0.
d3dx10_36: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001195C50. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011C3380. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001195B50. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011C3550. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011C3380.
d3dx10_37: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239C00. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239DD0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001239DD0. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001195B50. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011D3B60.
d3dx10_38: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 0000000001239D50. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239F20. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 0000000001239F20. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001194B40. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001239F20.
d3dx10_39: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011B6030. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011BCAB0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011A4690. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011A4B40. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011958C0.
d3dx10_40: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011E3910. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011BB9B0. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011D3F40. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 0000000001195BC0. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011E3AE0.
d3dx10_41: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BB6A0. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011B6010. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011BB870. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011D5660. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 0000000001195A50.
d3dx10_42: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011A4A60. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 00000000011A4A60. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011A4A60. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B5E50. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011C34D0.
d3dx10_43: d3dx10.c:4380: Test succeeded inside todo block: Got unexpected effect 00000000011BBE20. d3dx10.c:4470: Test succeeded inside todo block: Got unexpected effect 0000000001239D80. d3dx10.c:4480: Test succeeded inside todo block: Got unexpected effect 00000000011B6120. d3dx10.c:4589: Test succeeded inside todo block: Got unexpected effect 00000000011B1F50. d3dx10.c:4599: Test succeeded inside todo block: Got unexpected effect 00000000011B6120.
v5: Updated with test results tweaked instead.
And, like I said in 5255, I don't see how restricting the caps is necessary. What parser are you imagining would parse to the wrong format?
I don't understand what you mean by that. The caps isn't restricted anymore.
And, like I said in 5255, I don't see how restricting the caps is necessary. What parser are you imagining would parse to the wrong format?
I don't understand what you mean by that. The caps isn't restricted anymore.
Well, it's restricted relative to 5255.
Anyway, I'm not sure any of this is an improvement over that patch set, but it's not really worse either, so approving.
This merge request was approved by Zebediah Figura.