From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/transform.c | 1 - dlls/winegstreamer/unixlib.h | 2 +- dlls/winegstreamer/wg_transform.c | 19 ++++++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index b1d72ddddc3..4578dbac591 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -5446,7 +5446,6 @@ static void test_h264_decoder_timestamps(void) { hr = IMFSample_GetSampleTime(output_sample, &time); ok(hr == S_OK, "Got %#lx\n", hr); - todo_wine_if(exp_sample_neg_ts[i].time < 0) ok(time == exp_sample_neg_ts[i].time, "got time %I64d, expected %I64d\n", time, exp_sample_neg_ts[i].time); hr = IMFSample_GetSampleDuration(output_sample, &duration); ok(hr == S_OK, "Got %#lx\n", hr); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index d1a414b6396..83e38849fa9 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -185,7 +185,7 @@ enum wg_sample_flag struct wg_sample { /* timestamp and duration are in 100-nanosecond units. */ - UINT64 pts; + INT64 pts; UINT64 duration; LONG refcount; /* unix refcount */ UINT32 flags; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 01f8a6716da..1e666bd7ff0 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -96,6 +96,7 @@ struct wg_transform GstCaps *input_caps;
bool draining; + INT64 ts_offset; };
static struct wg_transform *get_transform(wg_transform_t trans) @@ -862,7 +863,19 @@ NTSTATUS wg_transform_push_data(void *args) }
if (sample->flags & WG_SAMPLE_FLAG_HAS_PTS) - GST_BUFFER_PTS(buffer) = sample->pts * 100; + { + if (sample->pts < transform->ts_offset) + { + if (transform->ts_offset) + GST_FIXME("ts_offset is already set to %"GST_TIME_FORMAT", overwriting", + GST_TIME_ARGS(-transform->ts_offset)); + + GST_TRACE("Setting ts_offset to %"GST_TIME_FORMAT, GST_TIME_ARGS(-sample->pts)); + transform->ts_offset = sample->pts; + } + + GST_BUFFER_PTS(buffer) = (sample->pts - transform->ts_offset) * 100; + } if (sample->flags & WG_SAMPLE_FLAG_HAS_DURATION) GST_BUFFER_DURATION(buffer) = sample->duration * 100; if (!(sample->flags & WG_SAMPLE_FLAG_SYNC_POINT)) @@ -1196,6 +1209,10 @@ NTSTATUS wg_transform_read_data(void *args) else status = read_transform_output(sample, output_buffer);
+ if ((sample->flags & (WG_SAMPLE_FLAG_PRESERVE_TIMESTAMPS | WG_SAMPLE_FLAG_HAS_PTS)) == + (WG_SAMPLE_FLAG_PRESERVE_TIMESTAMPS | WG_SAMPLE_FLAG_HAS_PTS)) + sample->pts += transform->ts_offset; + if (status) { wg_allocator_release_sample(transform->allocator, sample, false);