mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-09 17:44:14 +00:00
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
This commit is contained in:
parent
fcc78aa3bd
commit
45c16599ff
2 changed files with 44 additions and 3 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue