mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-28 20:05:38 +00:00
qtdemux: fix reverse playback of fragmented media
qtdemux creates a samples array and gets the timestamps for buffers by accumulating their durations. When doing reverse playback of fragments, accumulating samples will lead to wrong timestamps as the timestamps should go decreasing from fragment to fragment and the accumulation will produce wrong results. In this case, when receiving a discont for fragmented reverse playback, the previous samples information should be flushed before new data is processed.
This commit is contained in:
parent
d3997773fc
commit
fc0a184592
1 changed files with 37 additions and 16 deletions
|
@ -2149,6 +2149,28 @@ gst_qtdemux_stbl_free (QtDemuxStream * stream)
|
|||
stream->ctts.data = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_qtdemux_stream_flush_samples_data (GstQTDemux * qtdemux,
|
||||
QtDemuxStream * stream)
|
||||
{
|
||||
g_free (stream->samples);
|
||||
stream->samples = NULL;
|
||||
g_free (stream->segments);
|
||||
stream->segments = NULL;
|
||||
gst_qtdemux_stbl_free (stream);
|
||||
|
||||
/* fragments */
|
||||
g_free (stream->ra_entries);
|
||||
stream->ra_entries = NULL;
|
||||
stream->n_ra_entries = 0;
|
||||
|
||||
stream->sample_index = -1;
|
||||
stream->stbl_index = -1;
|
||||
stream->n_samples = 0;
|
||||
stream->time_position = 0;
|
||||
stream->segment_index = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_qtdemux_stream_clear (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
||||
{
|
||||
|
@ -2162,29 +2184,16 @@ gst_qtdemux_stream_clear (GstQTDemux * qtdemux, QtDemuxStream * stream)
|
|||
gst_memory_unref (stream->rgb8_palette);
|
||||
stream->rgb8_palette = NULL;
|
||||
}
|
||||
g_free (stream->samples);
|
||||
stream->samples = NULL;
|
||||
g_free (stream->segments);
|
||||
stream->segments = NULL;
|
||||
|
||||
if (stream->pending_tags)
|
||||
gst_tag_list_unref (stream->pending_tags);
|
||||
stream->pending_tags = NULL;
|
||||
g_free (stream->redirect_uri);
|
||||
stream->redirect_uri = NULL;
|
||||
/* free stbl sub-atoms */
|
||||
gst_qtdemux_stbl_free (stream);
|
||||
/* fragments */
|
||||
g_free (stream->ra_entries);
|
||||
stream->ra_entries = NULL;
|
||||
stream->n_ra_entries = 0;
|
||||
|
||||
stream->sent_eos = FALSE;
|
||||
stream->segment_index = -1;
|
||||
stream->time_position = 0;
|
||||
stream->sample_index = -1;
|
||||
stream->stbl_index = -1;
|
||||
stream->n_samples = 0;
|
||||
stream->sparse = FALSE;
|
||||
|
||||
gst_qtdemux_stream_flush_samples_data (qtdemux, stream);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5010,6 +5019,18 @@ gst_qtdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * inbuf)
|
|||
for (i = 0; i < demux->n_streams; i++) {
|
||||
demux->streams[i]->discont = TRUE;
|
||||
}
|
||||
|
||||
/* Reverse fragmented playback, need to flush all we have before
|
||||
* consuming a new fragment.
|
||||
* The samples array have the timestamps calculated by accumulating the
|
||||
* durations but this won't work for reverse playback of fragments as
|
||||
* the timestamps of a subsequent fragment should be smaller than the
|
||||
* previously received one. */
|
||||
if (demux->fragmented && demux->segment.rate < 0) {
|
||||
gst_qtdemux_process_adapter (demux, TRUE);
|
||||
for (i = 0; i < demux->n_streams; i++)
|
||||
gst_qtdemux_stream_flush_samples_data (demux, demux->streams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
gst_adapter_push (demux->adapter, inbuf);
|
||||
|
|
Loading…
Reference in a new issue