diff options
author | Seungha Yang <sh.yang@lge.com> | 2016-01-28 21:36:54 +0900 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-01-29 10:53:39 +0100 |
commit | d8bb6687ea251570c331038279a43d448167d6ad (patch) | |
tree | 1b8916b5a4fb204547a9ed9473df0120d7d155b1 | |
parent | 3edf0737d69a58beecb977817c897e4b718e1f04 (diff) | |
download | gstreamer-plugins-good-d8bb6687ea251570c331038279a43d448167d6ad.tar.gz |
qtdemux: expose streams with first moof for fragmented format
In case of push mode, qtdemux expose streams after got moov box.
We can not guarantee that a moov box has sample data such as sample duration
and the number of sample in stbl box for fragmented format case.
So, if a moov has no sample data, streams will not be exposed until get the first moof.
https://bugzilla.gnome.org/show_bug.cgi?id=760779
-rw-r--r-- | gst/isomp4/qtdemux.c | 54 | ||||
-rw-r--r-- | gst/isomp4/qtdemux.h | 1 |
2 files changed, 39 insertions, 16 deletions
diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c index 1aaafa861..cbba39bc8 100644 --- a/gst/isomp4/qtdemux.c +++ b/gst/isomp4/qtdemux.c @@ -583,6 +583,7 @@ gst_qtdemux_init (GstQTDemux * qtdemux) qtdemux->state = QTDEMUX_STATE_INITIAL; qtdemux->pullbased = FALSE; qtdemux->posted_redirect = FALSE; + qtdemux->pending_configure = FALSE; qtdemux->neededbytes = 16; qtdemux->todrop = 0; qtdemux->adapter = gst_adapter_new (); @@ -1983,6 +1984,7 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard) gst_caps_replace (&qtdemux->media_caps, NULL); qtdemux->timescale = 0; qtdemux->got_moov = FALSE; + qtdemux->pending_configure = FALSE; } else if (qtdemux->mss_mode) { gst_flow_combiner_reset (qtdemux->flowcombiner); for (n = 0; n < qtdemux->n_streams; n++) @@ -5778,6 +5780,7 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) &fourcc); if (fourcc == FOURCC_moov) { gint n; + gboolean got_samples = FALSE; /* in usual fragmented setup we could try to scan for more * and end up at the the moov (after mdat) again */ @@ -5809,19 +5812,27 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) qtdemux_node_dump (demux, demux->moov_node); qtdemux_parse_tree (demux); qtdemux_prepare_streams (demux); - if (!demux->got_moov) - qtdemux_expose_streams (demux); - else { - for (n = 0; n < demux->n_streams; n++) { - QtDemuxStream *stream = demux->streams[n]; - - gst_qtdemux_configure_stream (demux, stream); + for (n = 0; n < demux->n_streams; n++) { + QtDemuxStream *stream = demux->streams[n]; + got_samples |= stream->stbl_index >= 0; + } + if (!demux->fragmented || got_samples) { + if (!demux->got_moov) { + qtdemux_expose_streams (demux); + } else { + for (n = 0; n < demux->n_streams; n++) { + QtDemuxStream *stream = demux->streams[n]; + gst_qtdemux_configure_stream (demux, stream); + } } + gst_qtdemux_check_send_pending_segment (demux); + demux->pending_configure = FALSE; + } else { + demux->pending_configure = TRUE; } demux->got_moov = TRUE; - gst_qtdemux_check_send_pending_segment (demux); /* fragmented streams headers shouldn't contain edts atoms */ if (!demux->fragmented) { @@ -5840,6 +5851,7 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) guint64 dist = 0; GstClockTime prev_pts; guint64 prev_offset; + gint n; GST_DEBUG_OBJECT (demux, "Parsing [moof]"); @@ -5873,15 +5885,25 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force) ret = GST_FLOW_ERROR; goto done; } - /* in MSS we need to expose the pads after the first moof as we won't get a moov */ - if (demux->mss_mode && !demux->exposed) { - if (!demux->pending_newsegment) { - GstSegment segment; - gst_segment_init (&segment, GST_FORMAT_TIME); - GST_DEBUG_OBJECT (demux, "new pending_newsegment"); - demux->pending_newsegment = gst_event_new_segment (&segment); + /* in MSS we need to expose the pads after the first moof as we won't get a moov + * Also, fragmented format need to be exposed if a moov have no valid sample data */ + if (demux->mss_mode || demux->pending_configure) { + if (!demux->exposed) { + if (!demux->pending_newsegment) { + GstSegment segment; + gst_segment_init (&segment, GST_FORMAT_TIME); + GST_DEBUG_OBJECT (demux, "new pending_newsegment"); + demux->pending_newsegment = gst_event_new_segment (&segment); + } + qtdemux_expose_streams (demux); + } else { + for (n = 0; n < demux->n_streams; n++) { + QtDemuxStream *stream = demux->streams[n]; + gst_qtdemux_configure_stream (demux, stream); + } } - qtdemux_expose_streams (demux); + gst_qtdemux_check_send_pending_segment (demux); + demux->pending_configure = FALSE; } } else { GST_DEBUG_OBJECT (demux, "Discarding [moof]"); diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h index 53bd071c3..165435cea 100644 --- a/gst/isomp4/qtdemux.h +++ b/gst/isomp4/qtdemux.h @@ -89,6 +89,7 @@ struct _GstQTDemux { gboolean posted_redirect; /* push based variables */ + gboolean pending_configure; guint neededbytes; guint todrop; GstAdapter *adapter; |