static gboolean gst_gio_base_src_is_seekable (GstBaseSrc * base_src);
static gboolean gst_gio_base_src_unlock (GstBaseSrc * base_src);
static gboolean gst_gio_base_src_unlock_stop (GstBaseSrc * base_src);
-static gboolean gst_gio_base_src_check_get_range (GstBaseSrc * base_src);
static GstFlowReturn gst_gio_base_src_create (GstBaseSrc * base_src,
guint64 offset, guint size, GstBuffer ** buf);
static gboolean gst_gio_base_src_query (GstBaseSrc * base_src,
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_gio_base_src_unlock);
gstbasesrc_class->unlock_stop =
GST_DEBUG_FUNCPTR (gst_gio_base_src_unlock_stop);
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_gio_base_src_check_get_range);
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gio_base_src_create);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_gio_base_src_query);
}
return TRUE;
}
-static gboolean
-gst_gio_base_src_check_get_range (GstBaseSrc * base_src)
-{
- return GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS,
- check_get_range, (base_src), FALSE);
-}
-
static GstFlowReturn
gst_gio_base_src_create (GstBaseSrc * base_src, guint64 offset, guint size,
GstBuffer ** buf_return)
static GInputStream *gst_gio_src_get_stream (GstGioBaseSrc * bsrc);
-static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src);
+static gboolean gst_gio_src_query (GstBaseSrc * base_src, GstQuery * query);
static void
gst_gio_src_class_init (GstGioSrcClass * klass)
"Ren\xc3\xa9 Stadler <mail@renestadler.de>, "
"Sebastian Dröge <sebastian.droege@collabora.co.uk>");
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_gio_src_check_get_range);
+ gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_gio_src_query);
gstgiobasesrc_class->get_stream = GST_DEBUG_FUNCPTR (gst_gio_src_get_stream);
gstgiobasesrc_class->close_on_stop = TRUE;
}
static gboolean
-gst_gio_src_check_get_range (GstBaseSrc * base_src)
+gst_gio_src_query (GstBaseSrc * base_src, GstQuery * query)
{
+ gboolean res;
GstGioSrc *src = GST_GIO_SRC (base_src);
- gchar *scheme;
-
- if (src->file == NULL)
- goto done;
-
- scheme = g_file_get_uri_scheme (src->file);
- if (scheme == NULL)
- goto done;
-
- if (strcmp (scheme, "file") == 0) {
- GST_LOG_OBJECT (src, "local URI, assuming random access is possible");
- g_free (scheme);
- return TRUE;
- } else if (strcmp (scheme, "http") == 0 || strcmp (scheme, "https") == 0) {
- GST_LOG_OBJECT (src, "blacklisted protocol '%s', "
- "no random access possible", scheme);
- g_free (scheme);
- return FALSE;
- }
-
- g_free (scheme);
-done:
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_SCHEDULING:
+ {
+ gchar *scheme;
+ gboolean pull_mode;
+
+ pull_mode = FALSE;
+ if (src->file == NULL)
+ goto forward_parent;
+
+ scheme = g_file_get_uri_scheme (src->file);
+ if (scheme == NULL)
+ goto forward_parent;
+
+ if (strcmp (scheme, "file") == 0) {
+ GST_LOG_OBJECT (src, "local URI, assuming random access is possible");
+ pull_mode = TRUE;
+ } else if (strcmp (scheme, "http") == 0 || strcmp (scheme, "https") == 0) {
+ GST_LOG_OBJECT (src, "blacklisted protocol '%s', "
+ "no random access possible", scheme);
+ } else {
+ GST_LOG_OBJECT (src, "unhandled protocol '%s', asking parent", scheme);
+ goto forward_parent;
+ }
+ g_free (scheme);
- GST_DEBUG_OBJECT (src, "undecided about random access, asking base class");
+ gst_query_set_scheduling (query, pull_mode, pull_mode, FALSE, 1, -1, 1);
+ res = TRUE;
+ break;
+ }
+ default:
+ forward_parent:
+ res = GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS,
+ query, (base_src, query), FALSE);
+ break;
+ }
- return GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS,
- check_get_range, (base_src), FALSE);
+ return res;
}
-
static GInputStream *
gst_gio_src_get_stream (GstGioBaseSrc * bsrc)
{
static gboolean gst_gnome_vfs_src_stop (GstBaseSrc * src);
static gboolean gst_gnome_vfs_src_start (GstBaseSrc * src);
static gboolean gst_gnome_vfs_src_is_seekable (GstBaseSrc * src);
-static gboolean gst_gnome_vfs_src_check_get_range (GstBaseSrc * src);
static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * src, guint64 * size);
static GstFlowReturn gst_gnome_vfs_src_create (GstBaseSrc * basesrc,
guint64 offset, guint size, GstBuffer ** buffer);
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_get_size);
gstbasesrc_class->is_seekable =
GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_is_seekable);
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_check_get_range);
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_create);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_query);
}
}
static gboolean
-gst_gnome_vfs_src_query (GstBaseSrc * basesrc, GstQuery * query)
-{
- gboolean ret = FALSE;
- GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (basesrc);
-
- switch (GST_QUERY_TYPE (query)) {
- case GST_QUERY_URI:
- gst_query_set_uri (query, src->uri_name);
- ret = TRUE;
- break;
- default:
- ret = FALSE;
- break;
- }
-
- if (!ret)
- ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
-
- return ret;
-}
-
-static gboolean
gst_gnome_vfs_src_is_seekable (GstBaseSrc * basesrc)
{
GstGnomeVFSSrc *src;
}
static gboolean
-gst_gnome_vfs_src_check_get_range (GstBaseSrc * basesrc)
+gst_gnome_vfs_src_scheduling (GstBaseSrc * basesrc, GstQuery * query)
{
GstGnomeVFSSrc *src;
const gchar *protocol;
+ gboolean pull_mode;
src = GST_GNOME_VFS_SRC (basesrc);
+ pull_mode = FALSE;
+
if (src->uri == NULL) {
GST_WARNING_OBJECT (src, "no URI set yet");
- return FALSE;
+ goto undecided;
}
if (gnome_vfs_uri_is_local (src->uri)) {
GST_LOG_OBJECT (src, "local URI (%s), assuming random access is possible",
GST_STR_NULL (src->uri_name));
- return TRUE;
- }
-
- /* blacklist certain protocols we know won't work getrange-based */
- protocol = gnome_vfs_uri_get_scheme (src->uri);
- if (protocol == NULL)
+ pull_mode = TRUE;
+ } else {
+ /* blacklist certain protocols we know won't work getrange-based */
+ protocol = gnome_vfs_uri_get_scheme (src->uri);
+ if (protocol == NULL)
+ goto undecided;
+
+ if (strcmp (protocol, "http") == 0 || strcmp (protocol, "https") == 0) {
+ GST_LOG_OBJECT (src,
+ "blacklisted protocol '%s', no random access possible" " (URI=%s)",
+ protocol, GST_STR_NULL (src->uri_name));
+ } else {
+ GST_LOG_OBJECT (src, "undecided about URI '%s', let base class handle it",
+ GST_STR_NULL (src->uri_name));
+ }
goto undecided;
-
- if (strcmp (protocol, "http") == 0 || strcmp (protocol, "https") == 0) {
- GST_LOG_OBJECT (src, "blacklisted protocol '%s', no random access possible"
- " (URI=%s)", protocol, GST_STR_NULL (src->uri_name));
- return FALSE;
}
+ gst_query_set_scheduling (query, pull_mode, pull_mode, FALSE, 1, -1, 1);
- /* fall through to undecided */
+ return TRUE;
+ /* fall through to undecided */
undecided:
{
/* don't know what to do, let the basesrc class decide for us */
- GST_LOG_OBJECT (src, "undecided about URI '%s', let base class handle it",
- GST_STR_NULL (src->uri_name));
+ return GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
+ }
+}
- if (GST_BASE_SRC_CLASS (parent_class)->check_get_range)
- return GST_BASE_SRC_CLASS (parent_class)->check_get_range (basesrc);
+static gboolean
+gst_gnome_vfs_src_query (GstBaseSrc * basesrc, GstQuery * query)
+{
+ gboolean ret = FALSE;
+ GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (basesrc);
- return FALSE;
+ switch (GST_QUERY_TYPE (query)) {
+ case GST_QUERY_URI:
+ gst_query_set_uri (query, src->uri_name);
+ ret = TRUE;
+ break;
+ case GST_QUERY_SCHEDULING:
+ ret = gst_gnome_vfs_src_scheduling (basesrc, query);
+ break;
+ default:
+ ret = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
+ break;
}
+
+ return ret;
}
static gboolean
static gboolean
gst_ogg_demux_sink_activate (GstPad * sinkpad)
{
- if (gst_pad_check_pull_range (sinkpad)) {
- GST_DEBUG_OBJECT (sinkpad, "activating pull");
- return gst_pad_activate_pull (sinkpad, TRUE);
- } else {
+ GstQuery *query;
+ gboolean pull_mode;
+
+ query = gst_query_new_scheduling ();
+
+ if (!gst_pad_peer_query (sinkpad, query)) {
+ gst_query_unref (query);
+ goto activate_push;
+ }
+
+ gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+
+ if (!pull_mode)
+ goto activate_push;
+
+ GST_DEBUG_OBJECT (sinkpad, "activating pull");
+ return gst_pad_activate_pull (sinkpad, TRUE);
+
+activate_push:
+ {
GST_DEBUG_OBJECT (sinkpad, "activating push");
return gst_pad_activate_push (sinkpad, TRUE);
}
static gboolean gst_app_src_unlock_stop (GstBaseSrc * bsrc);
static gboolean gst_app_src_do_seek (GstBaseSrc * src, GstSegment * segment);
static gboolean gst_app_src_is_seekable (GstBaseSrc * src);
-static gboolean gst_app_src_check_get_range (GstBaseSrc * src);
static gboolean gst_app_src_do_get_size (GstBaseSrc * src, guint64 * size);
static gboolean gst_app_src_query (GstBaseSrc * src, GstQuery * query);
basesrc_class->unlock_stop = gst_app_src_unlock_stop;
basesrc_class->do_seek = gst_app_src_do_seek;
basesrc_class->is_seekable = gst_app_src_is_seekable;
- basesrc_class->check_get_range = gst_app_src_check_get_range;
basesrc_class->get_size = gst_app_src_do_get_size;
basesrc_class->get_size = gst_app_src_do_get_size;
basesrc_class->query = gst_app_src_query;
}
static gboolean
-gst_app_src_check_get_range (GstBaseSrc * src)
-{
- GstAppSrc *appsrc = GST_APP_SRC_CAST (src);
- GstAppSrcPrivate *priv = appsrc->priv;
- gboolean res = FALSE;
-
- switch (priv->stream_type) {
- case GST_APP_STREAM_TYPE_STREAM:
- case GST_APP_STREAM_TYPE_SEEKABLE:
- break;
- case GST_APP_STREAM_TYPE_RANDOM_ACCESS:
- res = TRUE;
- break;
- }
- return res;
-}
-
-static gboolean
gst_app_src_do_get_size (GstBaseSrc * src, guint64 * size)
{
GstAppSrc *appsrc = GST_APP_SRC_CAST (src);
gst_query_set_latency (query, live, min, max);
break;
}
+ case GST_QUERY_SCHEDULING:
+ {
+ gboolean pull_mode = FALSE;
+
+ switch (priv->stream_type) {
+ case GST_APP_STREAM_TYPE_STREAM:
+ case GST_APP_STREAM_TYPE_SEEKABLE:
+ break;
+ case GST_APP_STREAM_TYPE_RANDOM_ACCESS:
+ pull_mode = TRUE;
+ break;
+ }
+ gst_query_set_scheduling (query, pull_mode, TRUE, FALSE, 1, -1, 1);
+ res = TRUE;
+ break;
+ }
default:
res = GST_BASE_SRC_CLASS (parent_class)->query (src, query);
break;
static GstFlowReturn gst_base_audio_src_create (GstBaseSrc * bsrc,
guint64 offset, guint length, GstBuffer ** buf);
-static gboolean gst_base_audio_src_check_get_range (GstBaseSrc * bsrc);
static gboolean gst_base_audio_src_event (GstBaseSrc * bsrc, GstEvent * event);
static void gst_base_audio_src_get_times (GstBaseSrc * bsrc,
gstbasesrc_class->get_times =
GST_DEBUG_FUNCPTR (gst_base_audio_src_get_times);
gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_base_audio_src_create);
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_base_audio_src_check_get_range);
gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_base_audio_src_fixate);
/* ref class from a thread-safe context to work around missing bit of
return result;
}
-static gboolean
-gst_base_audio_src_check_get_range (GstBaseSrc * bsrc)
-{
- /* we allow limited pull base operation of which the details
- * will eventually exposed in an as of yet non-existing query.
- * Basically pulling can be done on any number of bytes as long
- * as the offset is -1 or sequentially increasing. */
- return TRUE;
-}
-
/**
* gst_base_audio_src_set_provide_clock:
* @src: a #GstBaseAudioSrc
res = TRUE;
break;
}
+ case GST_QUERY_SCHEDULING:
+ {
+ /* we allow limited pull base operation of which the details
+ * will eventually exposed in an as of yet non-existing query.
+ * Basically pulling can be done on any number of bytes as long
+ * as the offset is -1 or sequentially increasing. */
+ gst_query_set_scheduling (query, TRUE, FALSE, TRUE, 1, -1, 1);
+
+ res = TRUE;
+ break;
+ }
default:
res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query);
break;
static GstFlowReturn gst_tag_demux_read_range (GstTagDemux * tagdemux,
guint64 offset, guint length, GstBuffer ** buffer);
-static gboolean gst_tag_demux_src_checkgetrange (GstPad * srcpad);
static GstFlowReturn gst_tag_demux_src_getrange (GstPad * srcpad,
guint64 offset, guint length, GstBuffer ** buffer);
GST_DEBUG_FUNCPTR (gst_tag_demux_srcpad_event));
gst_pad_set_activatepull_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_activate_pull));
- gst_pad_set_checkgetrange_function (tagdemux->priv->srcpad,
- GST_DEBUG_FUNCPTR (gst_tag_demux_src_checkgetrange));
gst_pad_set_getrange_function (tagdemux->priv->srcpad,
GST_DEBUG_FUNCPTR (gst_tag_demux_src_getrange));
gboolean e_tag_ok, s_tag_ok;
gboolean ret = FALSE;
GstCaps *caps = NULL;
+ GstQuery *query;
+ gboolean pull_mode;
demux = GST_TAG_DEMUX (GST_PAD_PARENT (sinkpad));
klass = GST_TAG_DEMUX_CLASS (G_OBJECT_GET_CLASS (demux));
* collect buffers, read the start tag and output a buffer to end
* preroll.
*/
- if (!gst_pad_check_pull_range (sinkpad) ||
- !gst_pad_activate_pull (sinkpad, TRUE)) {
- GST_DEBUG_OBJECT (demux, "No pull mode. Changing to push, but won't be "
- "able to read end tags");
- demux->priv->state = GST_TAG_DEMUX_READ_START_TAG;
- return gst_pad_activate_push (sinkpad, TRUE);
+ query = gst_query_new_scheduling ();
+
+ if (!gst_pad_peer_query (sinkpad, query)) {
+ gst_query_unref (query);
+ goto activate_push;
}
+ gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+ gst_query_unref (query);
+
+ if (!pull_mode)
+ goto activate_push;
+
+ if (!gst_pad_activate_pull (sinkpad, TRUE))
+ goto activate_push;
+
/* Look for tags at start and end of file */
GST_DEBUG_OBJECT (demux, "Activated pull mode. Looking for tags");
if (!gst_tag_demux_get_upstream_size (demux))
gst_caps_unref (caps);
return ret;
+
+activate_push:
+ {
+ GST_DEBUG_OBJECT (demux, "No pull mode. Changing to push, but won't be "
+ "able to read end tags");
+ demux->priv->state = GST_TAG_DEMUX_READ_START_TAG;
+ return gst_pad_activate_push (sinkpad, TRUE);
+ }
}
static gboolean
return gst_pad_activate_pull (demux->priv->sinkpad, active);
}
-static gboolean
-gst_tag_demux_src_checkgetrange (GstPad * srcpad)
-{
- GstTagDemux *demux = GST_TAG_DEMUX (GST_PAD_PARENT (srcpad));
-
- return gst_pad_check_pull_range (demux->priv->sinkpad);
-}
-
static GstFlowReturn
gst_tag_demux_read_range (GstTagDemux * demux,
guint64 offset, guint length, GstBuffer ** buffer)
static void gst_audio_test_src_src_fixate (GstPad * pad, GstCaps * caps);
static gboolean gst_audio_test_src_is_seekable (GstBaseSrc * basesrc);
-static gboolean gst_audio_test_src_check_get_range (GstBaseSrc * basesrc);
static gboolean gst_audio_test_src_do_seek (GstBaseSrc * basesrc,
GstSegment * segment);
static gboolean gst_audio_test_src_query (GstBaseSrc * basesrc,
gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_test_src_setcaps);
gstbasesrc_class->is_seekable =
GST_DEBUG_FUNCPTR (gst_audio_test_src_is_seekable);
- gstbasesrc_class->check_get_range =
- GST_DEBUG_FUNCPTR (gst_audio_test_src_check_get_range);
gstbasesrc_class->do_seek = GST_DEBUG_FUNCPTR (gst_audio_test_src_do_seek);
gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_audio_test_src_query);
gstbasesrc_class->get_times =
res = TRUE;
break;
}
+ case GST_QUERY_SCHEDULING:
+ {
+ /* if we can operate in pull mode */
+ gst_query_set_scheduling (query, src->can_activate_pull, TRUE, FALSE, 1,
+ -1, 1);
+ res = TRUE;
+ break;
+ }
default:
res = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query);
break;
return TRUE;
}
-static gboolean
-gst_audio_test_src_check_get_range (GstBaseSrc * basesrc)
-{
- GstAudioTestSrc *src;
-
- src = GST_AUDIO_TEST_SRC (basesrc);
-
- /* if we can operate in pull mode */
- return src->can_activate_pull;
-}
-
static GstFlowReturn
gst_audio_test_src_create (GstBaseSrc * basesrc, guint64 offset,
guint length, GstBuffer ** buffer)