Commit 45c16599 authored by Thiago Santos's avatar Thiago Santos

qtdemux: avoid re-reading the same moov and entering into loop

In the scenario of "mdat | moov (with fragmented artifacts)" qtdemux
could read the moov again after the mdat because it was considering the
media as a fragmented one.

To avoid this loop this patch makes it store
the last processed moov_offset to avoid parsing it again.
And it also checks if there are any samples to play before
resturning to the mdat, so that it knows there is new data to be played.

https://bugzilla.gnome.org/show_bug.cgi?id=691570
parent fcc78aa3
......@@ -1819,6 +1819,7 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
if (qtdemux->comp_brands)
gst_buffer_unref (qtdemux->comp_brands);
qtdemux->comp_brands = NULL;
qtdemux->last_moov_offset = -1;
if (qtdemux->moov_node)
g_node_destroy (qtdemux->moov_node);
qtdemux->moov_node = NULL;
......@@ -4412,6 +4413,39 @@ pause:
}
}
/*
* has_next_entry
*
* Returns if there are samples to be played.
*/
static gboolean
has_next_entry (GstQTDemux * demux)
{
QtDemuxStream *stream;
int i;
GST_DEBUG_OBJECT (demux, "Checking if there are samples not played yet");
for (i = 0; i < demux->n_streams; i++) {
stream = demux->streams[i];
if (stream->sample_index == -1) {
stream->sample_index = 0;
stream->offset_in_sample = 0;
}
if (stream->sample_index >= stream->n_samples) {
GST_LOG_OBJECT (demux, "stream %d samples exhausted", i);
continue;
}
GST_DEBUG_OBJECT (demux, "Found a sample");
return TRUE;
}
GST_DEBUG_OBJECT (demux, "There wasn't any next sample");
return FALSE;
}
/*
* next_entry_size
*
......@@ -4704,9 +4738,11 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
if (fourcc == FOURCC_moov) {
/* in usual fragmented setup we could try to scan for more
* and end up at the the moov (after mdat) again */
if (demux->got_moov && demux->n_streams > 0 && !demux->fragmented) {
if (demux->got_moov && demux->n_streams > 0 &&
(!demux->fragmented
|| demux->last_moov_offset == demux->offset)) {
GST_DEBUG_OBJECT (demux,
"Skipping moov atom as we have one already");
"Skipping moov atom as we have (this) one already");
} else {
GST_DEBUG_OBJECT (demux, "Parsing [moov]");
......@@ -4724,6 +4760,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
gst_event_new_segment (&demux->segment);
}
demux->last_moov_offset = demux->offset;
qtdemux_parse_moov (demux, data, demux->neededbytes);
qtdemux_node_dump (demux, demux->moov_node);
qtdemux_parse_tree (demux);
......@@ -4817,7 +4855,9 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
GST_DEBUG_OBJECT (demux, "Carrying on normally");
gst_adapter_flush (demux->adapter, demux->neededbytes);
if (demux->got_moov && demux->first_mdat != -1) {
/* only go back to the mdat if there are samples to play */
if (demux->got_moov && demux->first_mdat != -1
&& has_next_entry (demux)) {
gboolean res;
/* we need to seek back */
......
......@@ -106,6 +106,7 @@ struct _GstQTDemux {
guint64 mdatoffset;
guint64 first_mdat;
gboolean got_moov;
guint64 last_moov_offset;
guint header_size;
GstTagList *tag_list;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment