Commit 7c7e5589 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winegstreamer: Append an optional parser before decoders.

parent 8ae80637
...@@ -905,6 +905,7 @@ struct testfilter ...@@ -905,6 +905,7 @@ struct testfilter
unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush; unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush;
REFERENCE_TIME expected_start_time; REFERENCE_TIME expected_start_time;
REFERENCE_TIME expected_stop_time; REFERENCE_TIME expected_stop_time;
BOOL todo_time;
}; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) 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 ...@@ -1012,7 +1013,9 @@ static HRESULT WINAPI testsink_Receive(struct strmbase_sink *iface, IMediaSample
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
if (filter->got_sample == 1) 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)); 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)); 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, ...@@ -1510,6 +1513,7 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_start_time = 0;
testsink->expected_stop_time = 120000; testsink->expected_stop_time = 120000;
testsink->todo_time = TRUE;
hr = IMemInputPin_Receive(input, sample); hr = IMemInputPin_Receive(input, sample);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
hr = IMemInputPin_Receive(input, sample); hr = IMemInputPin_Receive(input, sample);
......
...@@ -834,7 +834,6 @@ struct testfilter ...@@ -834,7 +834,6 @@ struct testfilter
unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush; unsigned int got_sample, got_new_segment, got_eos, got_begin_flush, got_end_flush;
REFERENCE_TIME expected_start_time; REFERENCE_TIME expected_start_time;
REFERENCE_TIME expected_stop_time; REFERENCE_TIME expected_stop_time;
BOOL todo_stop_time;
}; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) 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 ...@@ -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", ok(start == filter->expected_start_time, "Got start time %s, expected %s.\n",
wine_dbgstr_longlong(start), wine_dbgstr_longlong(filter->expected_start_time)); 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", ok(stop == filter->expected_stop_time, "Got stop time %s, expected %s.\n",
wine_dbgstr_longlong(stop), wine_dbgstr_longlong(filter->expected_stop_time)); wine_dbgstr_longlong(stop), wine_dbgstr_longlong(filter->expected_stop_time));
} }
...@@ -1226,7 +1225,7 @@ static void test_send_video(IMemInputPin *input, IMediaSample *sample) ...@@ -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 */ /* 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 */ /* 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 */ /* 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, 0xb3, 0x02, 0x00, 0x18, 0x15, 0x02, 0xbf, 0x60, 0x9c,
0x00, 0x00, 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x01, 0xb8, 0x00, 0x08, 0x00, 0x40,
0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x00, 0x01, 0x00, 0x00, 0x0f, 0xff, 0xf8,
...@@ -1235,27 +1234,22 @@ static void test_send_video(IMemInputPin *input, IMediaSample *sample) ...@@ -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, 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, 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, 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, 0x00, 0x00, 0x57, 0xff, 0xf9, 0x80,
0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0,
0x00, 0x00, 0x01, 0x02, 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, 0x00, 0x00, 0x97, 0xff, 0xf9, 0x80,
0x00, 0x00, 0x01, 0x01, 0x0a, 0x79, 0xc0, 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; HRESULT hr;
IPin *pin; IPin *pin;
/* frame 1 - it's a complete frame, but due to how MPEG framing works, the decoder doesn't know that */ /* native won't emit anything until an unknown-sized internal buffer is filled, or EOS is announced */
/* frame 2 - new frame starts, frame 1 can be emitted - but Wine gets confused by colorimetry and returns an error */ test_send_sample(input, sample, empty_mpg_frames, ARRAY_SIZE(empty_mpg_frames), TRUE);
/* frame 3 - Wine emits frames 1 and 2 */ test_send_sample(input, sample, empty_mpg_eos, ARRAY_SIZE(empty_mpg_eos), FALSE);
/* 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);
hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin); hr = IMemInputPin_QueryInterface(input, &IID_IPin, (void **)&pin);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
...@@ -1304,7 +1298,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input, ...@@ -1304,7 +1298,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
sink->expected_start_time = 0; sink->expected_start_time = 0;
sink->expected_stop_time = 0; sink->expected_stop_time = 0;
sink->todo_stop_time = FALSE;
hr = IMediaSample_SetTime(sample, &sink->expected_start_time, &sink->expected_stop_time); hr = IMediaSample_SetTime(sample, &sink->expected_start_time, &sink->expected_stop_time);
ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(hr == S_OK, "Got hr %#lx.\n", hr);
...@@ -1342,7 +1335,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input, ...@@ -1342,7 +1335,6 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
sink->expected_start_time = 22222; sink->expected_start_time = 22222;
sink->expected_stop_time = 22222; sink->expected_stop_time = 22222;
sink->todo_stop_time = TRUE;
test_send_video(input, sample); test_send_video(input, sample);
ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_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); 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, ...@@ -1412,7 +1404,6 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_start_time = 0;
testsink->expected_stop_time = 0; testsink->expected_stop_time = 0;
testsink->todo_stop_time = TRUE;
test_send_video(input, sample); test_send_video(input, sample);
ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample); ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample);
testsink->got_sample = 0; testsink->got_sample = 0;
...@@ -1440,7 +1431,6 @@ static void test_streaming_events(IMediaControl *control, IPin *sink, ...@@ -1440,7 +1431,6 @@ static void test_streaming_events(IMediaControl *control, IPin *sink,
testsink->expected_start_time = 0; testsink->expected_start_time = 0;
testsink->expected_stop_time = 0; testsink->expected_stop_time = 0;
testsink->todo_stop_time = TRUE;
test_send_video(input, sample); test_send_video(input, sample);
ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample); ok(testsink->got_sample >= 1, "Got %u calls to Receive().\n", testsink->got_sample);
testsink->got_sample = 0; testsink->got_sample = 0;
......
...@@ -338,7 +338,7 @@ NTSTATUS wg_transform_create(void *args) ...@@ -338,7 +338,7 @@ NTSTATUS wg_transform_create(void *args)
struct wg_format output_format = *params->output_format; struct wg_format output_format = *params->output_format;
struct wg_format input_format = *params->input_format; struct wg_format input_format = *params->input_format;
GstElement *first = NULL, *last = NULL, *element; 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; NTSTATUS status = STATUS_UNSUCCESSFUL;
GstPadTemplate *template = NULL; GstPadTemplate *template = NULL;
struct wg_transform *transform; struct wg_transform *transform;
...@@ -390,6 +390,10 @@ NTSTATUS wg_transform_create(void *args) ...@@ -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_query_function(transform->my_sink, transform_sink_query_cb);
gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_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 /* Since we append conversion elements, we don't want to filter decoders
* based on the actual output caps now. Matching decoders with the * based on the actual output caps now. Matching decoders with the
* raw output media type should be enough. * raw output media type should be enough.
...@@ -408,7 +412,16 @@ NTSTATUS wg_transform_create(void *args) ...@@ -408,7 +412,16 @@ NTSTATUS wg_transform_create(void *args)
case WG_MAJOR_TYPE_VIDEO_INDEO: case WG_MAJOR_TYPE_VIDEO_INDEO:
case WG_MAJOR_TYPE_VIDEO_WMV: case WG_MAJOR_TYPE_VIDEO_WMV:
case WG_MAJOR_TYPE_VIDEO_MPEG1: 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)) || !append_element(transform->container, element, &first, &last))
goto out; goto out;
break; break;
...@@ -500,6 +513,7 @@ NTSTATUS wg_transform_create(void *args) ...@@ -500,6 +513,7 @@ NTSTATUS wg_transform_create(void *args)
|| !push_event(transform->my_src, event)) || !push_event(transform->my_src, event))
goto out; goto out;
gst_caps_unref(parsed_caps);
gst_caps_unref(src_caps); gst_caps_unref(src_caps);
gst_caps_unref(sink_caps); gst_caps_unref(sink_caps);
...@@ -516,6 +530,8 @@ out: ...@@ -516,6 +530,8 @@ out:
gst_object_unref(transform->my_src); gst_object_unref(transform->my_src);
if (src_caps) if (src_caps)
gst_caps_unref(src_caps); gst_caps_unref(src_caps);
if (parsed_caps)
gst_caps_unref(parsed_caps);
if (sink_caps) if (sink_caps)
gst_caps_unref(sink_caps); gst_caps_unref(sink_caps);
if (transform->allocator) if (transform->allocator)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment