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.
This commit is contained in:
Vincent Penquerc'h 2014-06-10 09:33:40 +01:00
parent ebe01db234
commit fe6a1d5b88
2 changed files with 28 additions and 0 deletions

View file

@ -329,6 +329,7 @@ gst_opus_enc_start (GstAudioEncoder * benc)
GST_DEBUG_OBJECT (enc, "start"); GST_DEBUG_OBJECT (enc, "start");
enc->tags = gst_tag_list_new_empty (); enc->tags = gst_tag_list_new_empty ();
enc->header_sent = FALSE; enc->header_sent = FALSE;
enc->encoded_samples = 0;
return TRUE; return TRUE;
} }
@ -704,6 +705,9 @@ gst_opus_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
gst_tag_setter_merge_tags (setter, list, mode); gst_tag_setter_merge_tags (setter, list, mode);
break; break;
} }
case GST_EVENT_SEGMENT:
enc->encoded_samples = 0;
break;
default: default:
break; break;
@ -793,6 +797,8 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
GstMapInfo omap; GstMapInfo omap;
gint outsize; gint outsize;
GstBuffer *outbuf; GstBuffer *outbuf;
GstSegment *segment;
GstClockTime duration;
guint max_payload_size; guint max_payload_size;
gint frame_samples; gint frame_samples;
@ -813,6 +819,26 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
if (G_UNLIKELY (bsize % bytes)) { if (G_UNLIKELY (bsize % bytes)) {
GST_DEBUG_OBJECT (enc, "draining; adding silence samples"); 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; size = ((bsize / bytes) + 1) * bytes;
mdata = g_malloc0 (size); mdata = g_malloc0 (size);
memcpy (mdata, bdata, bsize); memcpy (mdata, bdata, bsize);
@ -864,6 +890,7 @@ gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
ret = ret =
gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf, gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc), outbuf,
frame_samples); frame_samples);
enc->encoded_samples += frame_samples;
done: done:

View file

@ -74,6 +74,7 @@ struct _GstOpusEnc {
gint sample_rate; gint sample_rate;
gboolean header_sent; gboolean header_sent;
guint64 encoded_samples;
GSList *headers; GSList *headers;