mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
qtdemux: push mode; perform some extra checks prior to upstream seeking
This commit is contained in:
parent
9de9d7e4d4
commit
e15d29ffe4
2 changed files with 60 additions and 2 deletions
|
@ -1862,6 +1862,8 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
|
||||||
gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
|
gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
|
||||||
qtdemux->requested_seek_time = GST_CLOCK_TIME_NONE;
|
qtdemux->requested_seek_time = GST_CLOCK_TIME_NONE;
|
||||||
qtdemux->seek_offset = 0;
|
qtdemux->seek_offset = 0;
|
||||||
|
qtdemux->upstream_seekable = FALSE;
|
||||||
|
qtdemux->upstream_size = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -3973,6 +3975,49 @@ qtdemux_seek_offset (GstQTDemux * demux, guint64 offset)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check for seekable upstream, above and beyond a mere query */
|
||||||
|
static void
|
||||||
|
gst_qtdemux_check_seekability (GstQTDemux * demux)
|
||||||
|
{
|
||||||
|
GstQuery *query;
|
||||||
|
gboolean seekable = FALSE;
|
||||||
|
gint64 start = -1, stop = -1;
|
||||||
|
|
||||||
|
if (demux->upstream_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
query = gst_query_new_seeking (GST_FORMAT_BYTES);
|
||||||
|
if (!gst_pad_peer_query (demux->sinkpad, query)) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "seeking query failed");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
|
||||||
|
|
||||||
|
/* try harder to query upstream size if we didn't get it the first time */
|
||||||
|
if (seekable && stop == -1) {
|
||||||
|
GstFormat fmt = GST_FORMAT_BYTES;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "doing duration query to fix up unset stop");
|
||||||
|
gst_pad_query_peer_duration (demux->sinkpad, &fmt, &stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if upstream doesn't know the size, it's likely that it's not seekable in
|
||||||
|
* practice even if it technically may be seekable */
|
||||||
|
if (seekable && (start != 0 || stop <= start)) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "seekable but unknown start/stop -> disable");
|
||||||
|
seekable = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
gst_query_unref (query);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "seekable: %d (%" G_GUINT64_FORMAT " - %"
|
||||||
|
G_GUINT64_FORMAT ")", seekable, start, stop);
|
||||||
|
demux->upstream_seekable = seekable;
|
||||||
|
demux->upstream_size = seekable ? stop : -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME, unverified after edit list updates */
|
/* FIXME, unverified after edit list updates */
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
|
@ -4004,6 +4049,8 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
guint32 fourcc;
|
guint32 fourcc;
|
||||||
guint64 size;
|
guint64 size;
|
||||||
|
|
||||||
|
gst_qtdemux_check_seekability (demux);
|
||||||
|
|
||||||
data = gst_adapter_peek (demux->adapter, demux->neededbytes);
|
data = gst_adapter_peek (demux->adapter, demux->neededbytes);
|
||||||
|
|
||||||
/* get fourcc/length, set neededbytes */
|
/* get fourcc/length, set neededbytes */
|
||||||
|
@ -4040,7 +4087,15 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
target = old + size;
|
target = old + size;
|
||||||
|
|
||||||
/* try to jump over the atom with a seek */
|
/* try to jump over the atom with a seek */
|
||||||
res = qtdemux_seek_offset (demux, target);
|
/* only bother if it seems worth doing so,
|
||||||
|
* and avoids possible upstream/server problems */
|
||||||
|
if (demux->upstream_seekable &&
|
||||||
|
demux->upstream_size > 4 * (1 << 20)) {
|
||||||
|
res = qtdemux_seek_offset (demux, target);
|
||||||
|
} else {
|
||||||
|
GST_DEBUG_OBJECT (demux, "skipping seek");
|
||||||
|
res = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
GST_DEBUG_OBJECT (demux, "seek success");
|
GST_DEBUG_OBJECT (demux, "seek success");
|
||||||
|
@ -4058,7 +4113,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
|
||||||
} else {
|
} else {
|
||||||
/* seek failed, need to buffer */
|
/* seek failed, need to buffer */
|
||||||
demux->offset = old;
|
demux->offset = old;
|
||||||
GST_DEBUG_OBJECT (demux, "seek failed");
|
GST_DEBUG_OBJECT (demux, "seek failed/skipped");
|
||||||
/* there may be multiple mdat (or alike) buffers */
|
/* there may be multiple mdat (or alike) buffers */
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (demux->mdatbuffer)
|
if (demux->mdatbuffer)
|
||||||
|
|
|
@ -109,6 +109,9 @@ struct _GstQTDemux {
|
||||||
|
|
||||||
gint64 requested_seek_time;
|
gint64 requested_seek_time;
|
||||||
guint64 seek_offset;
|
guint64 seek_offset;
|
||||||
|
|
||||||
|
gboolean upstream_seekable;
|
||||||
|
gboolean upstream_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstQTDemuxClass {
|
struct _GstQTDemuxClass {
|
||||||
|
|
Loading…
Reference in a new issue