From: Akihiro Sagawa <sagawa.aki@gmail.com> mpegpsdemux uses raw PTS values from the stream, which often start at a non-zero timestamp. To avoid an initial delay, we normalize the PTS by subtracting the first raw value so that the buffer timeline begins at zero. Without this adjustment, the first sample would not be presented until its original (non-zero) timestamp. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=59565 --- dlls/quartz/tests/mpegsplit.c | 2 +- dlls/winegstreamer/wg_parser.c | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/dlls/quartz/tests/mpegsplit.c b/dlls/quartz/tests/mpegsplit.c index 9fd94f84b90..913c19a4f63 100644 --- a/dlls/quartz/tests/mpegsplit.c +++ b/dlls/quartz/tests/mpegsplit.c @@ -2110,7 +2110,7 @@ static void test_video_file(void) ok(testsink_audio.byte_count == 8777, "Audio sink got %u bytes.\n", testsink_audio.byte_count); /* Native uses 55 for the first sample timestamp, but there's no need to copy the exact value. */ - todo_wine ok(min(testsink_video.sample_start, testsink_audio.sample_start) < 100, + ok(min(testsink_video.sample_start, testsink_audio.sample_start) < 100, "The first sample timestamp is off by more 100, video %I64d and audio %I64d.\n", testsink_video.sample_start, testsink_audio.sample_start); diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index da414af6134..6f13047a4a6 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -68,6 +68,7 @@ struct wg_parser GstPad *my_src; guint64 file_size, start_offset, next_offset, stop_offset; + GstClockTime base_pts; guint64 next_pull_offset; gchar *uri; @@ -366,8 +367,17 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) * that this will need modification to wg_parser_stream_notify_qos() as * well. */ + /* Because mpegpsdemux reports a non-zero PTS for the earliest buffer among + * all streams, we normalize the PTS by subtracting base_pts so that our + * stream starts at zero. */ + if ((wg_buffer->has_pts = GST_BUFFER_PTS_IS_VALID(buffer))) - wg_buffer->pts = GST_BUFFER_PTS(buffer) / 100; + { + if (GST_CLOCK_TIME_IS_VALID(parser->base_pts)) + wg_buffer->pts = (GST_BUFFER_PTS(buffer) - parser->base_pts) / 100; + else + wg_buffer->pts = GST_BUFFER_PTS(buffer) / 100; + } if ((wg_buffer->has_duration = GST_BUFFER_DURATION_IS_VALID(buffer))) wg_buffer->duration = GST_BUFFER_DURATION(buffer) / 100; wg_buffer->discontinuity = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); @@ -725,6 +735,16 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu if (!stream->has_buffer) { stream->has_buffer = true; + + /* Keep the earliest PTS for adjusting. */ + if (GST_BUFFER_PTS_IS_VALID(buffer) && + (GST_BUFFER_PTS(buffer) < parser->base_pts)) + { + parser->base_pts = GST_BUFFER_PTS(buffer); + GST_LOG("Updated base PTS to %" GST_TIME_FORMAT ".", + GST_TIME_ARGS(parser->base_pts)); + } + pthread_cond_signal(&parser->init_cond); } @@ -1883,6 +1903,7 @@ static NTSTATUS wg_parser_create(void *args) parser->output_compressed = params->output_compressed; parser->err_on = params->err_on; parser->warn_on = params->warn_on; + parser->base_pts = GST_CLOCK_TIME_NONE; GST_DEBUG("Created winegstreamer parser %p.", parser); params->parser = (wg_parser_t)(ULONG_PTR)parser; return S_OK; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10864