summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2014-06-10 09:33:40 +0100
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2014-10-30 14:41:44 +0000
commitfe6a1d5b8872959bea1295f1e4ad1e3708435eba (patch)
tree83ddb22b7215d1aae955a486b33077bd4177f4e1
parentebe01db234b4f444a5898566fb7b2d8a32783e08 (diff)
downloadgstreamer-plugins-base-fe6a1d5b8872959bea1295f1e4ad1e3708435eba.tar.gz
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.
-rw-r--r--ext/opus/gstopusenc.c27
-rw-r--r--ext/opus/gstopusenc.h1
2 files changed, 28 insertions, 0 deletions
diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c
index f9cf62444..4d118b054 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 64f95e37c..9e1d3600b 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;