[PATCH] queue2: Process SEEKING query
Jan Alexander Steffens (heftig)
jan.steffens at gmail.com
Fri Jul 18 04:32:06 PDT 2014
In order to seek FLV streams, flvdemux creates a seek index;
however, this index is not created if upstream is not seekable.
gst_flv_demux_check_seekability was copied nearly verbatim from
GstBaseParse.
This commit adds QUERY_SEEKING handling to queue2, so RTMP live
streams become seekable when a queue2 in download or ringbuffer
mode is inserted:
rtmpsrc ! queue2 ! flvdemux
Alternatively, flvdemux could be altered to not require
seekability. I am unsure what is the best approach.
---
plugins/elements/gstqueue2.c | 52 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/plugins/elements/gstqueue2.c b/plugins/elements/gstqueue2.c
index 144c684..fcc3cdc 100644
--- a/plugins/elements/gstqueue2.c
+++ b/plugins/elements/gstqueue2.c
@@ -3000,6 +3000,58 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
break;
}
+ case GST_QUERY_SEEKING:
+ {
+ GstFormat format;
+ gboolean peer_success, upstream_seekable, queue_seekable;
+ gint64 segment_start, segment_end;
+
+ peer_success = gst_pad_peer_query (queue->sinkpad, query);
+
+ gst_query_parse_seeking (query,
+ &format, &upstream_seekable, &segment_start, &segment_end);
+
+ queue_seekable =
+ (format == GST_FORMAT_BYTES && !QUEUE_IS_USING_QUEUE (queue));
+
+ if (peer_success) {
+ if (upstream_seekable) {
+ GST_DEBUG_OBJECT (queue, "upstream seekable (%s)"
+ " from %" G_GINT64_FORMAT " to %" G_GINT64_FORMAT,
+ gst_format_get_name (format), segment_start, segment_end);
+ break;
+ }
+
+ if (!queue_seekable) {
+ GST_DEBUG_OBJECT (queue, "both upstream and queue unseekable");
+ break;
+ }
+ } else {
+ if (!queue_seekable) {
+ GST_DEBUG_OBJECT (queue,
+ "upstream query failed and queue unseekable");
+ goto peer_failed;
+ }
+
+ upstream_seekable = FALSE;
+ segment_start = 0;
+ segment_end = -1;
+
+ GST_DEBUG_OBJECT (queue, "doing duration query to discover seek end");
+ gst_pad_peer_query_duration (queue->sinkpad, format, &segment_end);
+
+ if (segment_end < 0) {
+ GST_DEBUG_OBJECT (queue, "fixing seekable segment to maximum");
+ segment_end = G_MAXINT64;
+ }
+ }
+
+ GST_DEBUG_OBJECT (queue, "queue seekable from %" G_GINT64_FORMAT
+ " to %" G_GINT64_FORMAT, segment_start, segment_end);
+
+ gst_query_set_seeking (query, format, TRUE, segment_start, segment_end);
+ break;
+ }
default:
/* peer handled other queries */
if (!gst_pad_query_default (pad, parent, query))
--
2.0.1
More information about the gstreamer-devel
mailing list