matroskamux: For audio tracks, take the default duration from the first buffer

... if we don't have any better idea from the caps. This allows writing
SimpleBlocks for a majority of audio streams where the duration of
frames is usually fixed. And as a side effect, allows VLC to play
streams with Opus as it only works with SimpleBlocks currently:
  https://trac.videolan.org/vlc/ticket/18545

https://bugzilla.gnome.org/show_bug.cgi?id=784969
This commit is contained in:
Sebastian Dröge 2017-07-18 10:41:40 +03:00
parent 5a6fe4ed29
commit 317d3380bb

View file

@ -2723,7 +2723,8 @@ gst_matroska_mux_write_chapter_edition (GstMatroskaMux * mux,
* Start a new matroska file (write headers etc...)
*/
static void
gst_matroska_mux_start (GstMatroskaMux * mux)
gst_matroska_mux_start (GstMatroskaMux * mux, GstMatroskaPad * first_pad,
GstBuffer * first_pad_buf)
{
GstEbmlWrite *ebml = mux->ebml_write;
const gchar *doctype;
@ -2893,6 +2894,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
for (collected = mux->collect->data; collected;
collected = g_slist_next (collected)) {
GstMatroskaPad *collect_pad;
GstBuffer *buf;
collect_pad = (GstMatroskaPad *) collected->data;
@ -2900,6 +2902,23 @@ gst_matroska_mux_start (GstMatroskaMux * mux)
if (collect_pad->track->codec_id == NULL)
continue;
/* For audio tracks, use the first buffers duration as the default
* duration if we didn't get any better idea from the caps event already
*/
if (collect_pad->track->type == GST_MATROSKA_TRACK_TYPE_AUDIO &&
collect_pad->track->default_duration == 0) {
if (collect_pad == first_pad)
buf = first_pad_buf ? gst_buffer_ref (first_pad_buf) : NULL;
else
buf = gst_collect_pads_peek (mux->collect, collected->data);
if (buf && GST_BUFFER_DURATION_IS_VALID (buf))
collect_pad->track->default_duration =
GST_BUFFER_DURATION (buf) + collect_pad->track->codec_delay;
if (buf)
gst_buffer_unref (buf);
}
collect_pad->track->num = tracknum++;
child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKENTRY);
gst_matroska_mux_track_header (mux, collect_pad->track);
@ -3814,7 +3833,7 @@ gst_matroska_mux_handle_buffer (GstCollectPads * pads, GstCollectData * data,
GstClockTime buffer_timestamp;
GstMatroskaMux *mux = GST_MATROSKA_MUX (user_data);
GstEbmlWrite *ebml = mux->ebml_write;
GstMatroskaPad *best;
GstMatroskaPad *best = (GstMatroskaPad *) data;
GstFlowReturn ret = GST_FLOW_OK;
GST_DEBUG_OBJECT (mux, "Collected pads");
@ -3827,14 +3846,11 @@ gst_matroska_mux_handle_buffer (GstCollectPads * pads, GstCollectData * data,
}
mux->state = GST_MATROSKA_MUX_STATE_HEADER;
gst_ebml_start_streamheader (ebml);
gst_matroska_mux_start (mux);
gst_matroska_mux_start (mux, best, buf);
gst_matroska_mux_stop_streamheader (mux);
mux->state = GST_MATROSKA_MUX_STATE_DATA;
}
/* provided with stream to write from */
best = (GstMatroskaPad *) data;
/* if there is no best pad, we have reached EOS */
if (best == NULL) {
GST_DEBUG_OBJECT (mux, "No best pad. Finishing...");