diff --git a/gst-libs/gst/audio/gstaudioencoder.c b/gst-libs/gst/audio/gstaudioencoder.c index 17f843aeb1..85eb669f60 100644 --- a/gst-libs/gst/audio/gstaudioencoder.c +++ b/gst-libs/gst/audio/gstaudioencoder.c @@ -880,6 +880,16 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, /* collect output */ if (G_LIKELY (buf)) { gsize size; + GstClockTime timestamp = GST_CLOCK_TIME_NONE; + + if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) { + /* FIXME ? lookahead could lead to weird ts and duration ? + * (particularly if not in perfect mode) */ + /* mind sample rounding and produce perfect output */ + timestamp = priv->base_ts + + gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND, + ctx->info.rate); + } /* Pushing headers first */ if (G_UNLIKELY (priv->ctx.new_headers)) { @@ -893,6 +903,12 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, tmpbuf = gst_buffer_make_writable (tmpbuf); size = gst_buffer_get_size (tmpbuf); + /* we timestamp the headers with the same timestamp as the first + buffer, and set their duration to 0 */ + GST_BUFFER_PTS (tmpbuf) = timestamp; + GST_BUFFER_DTS (tmpbuf) = timestamp; + GST_BUFFER_DURATION (tmpbuf) = 0; + if (G_UNLIKELY (priv->discont)) { GST_LOG_OBJECT (enc, "marking discont"); GST_BUFFER_FLAG_SET (tmpbuf, GST_BUFFER_FLAG_DISCONT); @@ -923,13 +939,8 @@ gst_audio_encoder_finish_frame (GstAudioEncoder * enc, GstBuffer * buf, /* decorate */ if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (priv->base_ts))) { - /* FIXME ? lookahead could lead to weird ts and duration ? - * (particularly if not in perfect mode) */ - /* mind sample rounding and produce perfect output */ - GST_BUFFER_TIMESTAMP (buf) = priv->base_ts + - gst_util_uint64_scale (priv->samples - ctx->lookahead, GST_SECOND, - ctx->info.rate); - GST_BUFFER_DTS (buf) = GST_BUFFER_TIMESTAMP (buf); + GST_BUFFER_PTS (buf) = timestamp; + GST_BUFFER_DTS (buf) = timestamp; GST_DEBUG_OBJECT (enc, "out samples %d", samples); if (G_LIKELY (samples > 0)) { priv->samples += samples; diff --git a/tests/check/libs/audioencoder.c b/tests/check/libs/audioencoder.c index cdcb531910..335e1cd6b0 100644 --- a/tests/check/libs/audioencoder.c +++ b/tests/check/libs/audioencoder.c @@ -398,6 +398,46 @@ GST_START_TEST (audioencoder_events_before_eos) GST_END_TEST; +GST_START_TEST (audioencoder_headers_timestamp) +{ + GstHarness *h = setup_audioencodertester (); + GList *headers = NULL; + GstBuffer *buf; + + /* create and add headers */ + headers = g_list_append (headers, gst_buffer_new ()); + headers = g_list_append (headers, gst_buffer_new ()); + gst_audio_encoder_set_headers (GST_AUDIO_ENCODER (h->element), headers); + + /* push buffer with timestamp 10 seconds*/ + fail_unless (gst_harness_push (h, create_test_buffer (10)) == GST_FLOW_OK); + + /* first header */ + buf = gst_harness_pull (h); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_PTS (buf)); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_DTS (buf)); + fail_unless_equals_uint64 (0, GST_BUFFER_DURATION (buf)); + gst_buffer_unref (buf); + + /* second header */ + buf = gst_harness_pull (h); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_PTS (buf)); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_DTS (buf)); + fail_unless_equals_uint64 (0, GST_BUFFER_DURATION (buf)); + gst_buffer_unref (buf); + + /* buffer */ + buf = gst_harness_pull (h); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_PTS (buf)); + fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_DTS (buf)); + fail_unless_equals_uint64 (1 * GST_SECOND, GST_BUFFER_DURATION (buf)); + gst_buffer_unref (buf); + + gst_harness_teardown (h); +} + +GST_END_TEST; + static Suite * gst_audioencoder_suite (void) { @@ -411,6 +451,8 @@ gst_audioencoder_suite (void) tcase_add_test (tc, audioencoder_events_before_eos); tcase_add_test (tc, audioencoder_flush_events); + tcase_add_test (tc, audioencoder_headers_timestamp); + return s; }