From 23029acf4617b432cd4cca2abd621c5e52cda2e9 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 10 Jun 2014 09:33:40 +0100 Subject: [PATCH] opusenc: update output segment stop time to match clipped samples This will let oggmux generate a granpos on the last page that properly represents the clipped samples at the end of the stream. --- ext/opus/gstopusenc.c | 27 +++++++++++++++++++++++++++ ext/opus/gstopusenc.h | 1 + 2 files changed, 28 insertions(+) diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c index f9cf624448..4d118b054c 100644 --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@ -329,6 +329,7 @@ gst_opus_enc_start (GstAudioEncoder * benc) GST_DEBUG_OBJECT (enc, "start"); enc->tags = gst_tag_list_new_empty (); enc->header_sent = FALSE; + enc->encoded_samples = 0; return TRUE; } @@ -704,6 +705,9 @@ gst_opus_enc_sink_event (GstAudioEncoder * benc, GstEvent * event) gst_tag_setter_merge_tags (setter, list, mode); break; } + case GST_EVENT_SEGMENT: + enc->encoded_samples = 0; + break; default: break; @@ -793,6 +797,8 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf) GstMapInfo omap; gint outsize; GstBuffer *outbuf; + GstSegment *segment; + GstClockTime duration; guint max_payload_size; gint frame_samples; @@ -813,6 +819,26 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf) if (G_UNLIKELY (bsize % bytes)) { GST_DEBUG_OBJECT (enc, "draining; adding silence samples"); + /* If encoding part of a frame, and we have no set stop time on + * the output segment, we update the segment stop time to reflect + * the last sample. This will let oggmux set the last page's + * granpos to tell a decoder the dummy samples should be clipped. + */ + segment = &GST_AUDIO_ENCODER_OUTPUT_SEGMENT (enc); + if (!GST_CLOCK_TIME_IS_VALID (segment->stop)) { + int input_samples = bsize / (enc->n_channels * 2); + GST_DEBUG_OBJECT (enc, + "No stop time and partial frame, updating segment"); + duration = + gst_util_uint64_scale (enc->encoded_samples + input_samples, + GST_SECOND, enc->sample_rate); + segment->stop = segment->start + duration; + GST_DEBUG_OBJECT (enc, "new output segment %" GST_SEGMENT_FORMAT, + segment); + gst_pad_push_event (GST_AUDIO_ENCODER_SRC_PAD (enc), + gst_event_new_segment (segment)); + } + size = ((bsize / bytes) + 1) * bytes; mdata = g_malloc0 (size); memcpy (mdata, bdata, bsize); @@ -864,6 +890,7 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf) ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf, frame_samples); + enc->encoded_samples += frame_samples; done: diff --git a/ext/opus/gstopusenc.h b/ext/opus/gstopusenc.h index 64f95e37c0..9e1d3600b2 100644 --- a/ext/opus/gstopusenc.h +++ b/ext/opus/gstopusenc.h @@ -74,6 +74,7 @@ struct _GstOpusEnc { gint sample_rate; gboolean header_sent; + guint64 encoded_samples; GSList *headers;