scheduling: port to new scheduling query

This commit is contained in:
Wim Taymans 2011-05-24 17:37:45 +02:00
parent 3b35a83688
commit 010add200a
8 changed files with 162 additions and 151 deletions

View file

@ -47,7 +47,6 @@ static gboolean gst_gio_base_src_get_size (GstBaseSrc * base_src,
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,
@ -76,8 +75,6 @@ gst_gio_base_src_class_init (GstGioBaseSrcClass * klass)
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);
}
@ -294,13 +291,6 @@ gst_gio_base_src_unlock_stop (GstBaseSrc * base_src)
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)

View file

@ -96,7 +96,7 @@ static void gst_gio_src_get_property (GObject * object, guint prop_id,
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)
@ -133,8 +133,7 @@ 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;
@ -248,40 +247,51 @@ gst_gio_src_get_property (GObject * object, guint prop_id,
}
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;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_SCHEDULING:
{
gchar *scheme;
gboolean pull_mode;
scheme = g_file_get_uri_scheme (src->file);
if (scheme == NULL)
goto done;
pull_mode = FALSE;
if (src->file == NULL)
goto forward_parent;
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;
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_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;
}
g_free (scheme);
done:
GST_DEBUG_OBJECT (src, "undecided about random access, asking base class");
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)
{

View file

@ -128,7 +128,6 @@ static void gst_gnome_vfs_src_get_property (GObject * object, guint prop_id,
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);
@ -206,8 +205,6 @@ gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
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);
}
@ -656,28 +653,6 @@ eos:
}
}
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)
{
@ -689,50 +664,75 @@ gst_gnome_vfs_src_is_seekable (GstBaseSrc * basesrc)
}
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;
}
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;
/* blacklist certain protocols we know won't work getrange-based */
protocol = gnome_vfs_uri_get_scheme (src->uri);
if (protocol == NULL)
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);
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));
if (GST_BASE_SRC_CLASS (parent_class)->check_get_range)
return GST_BASE_SRC_CLASS (parent_class)->check_get_range (basesrc);
return FALSE;
return GST_BASE_SRC_CLASS (parent_class)->query (basesrc, 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;
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
gst_gnome_vfs_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{

View file

@ -3511,10 +3511,26 @@ gst_ogg_demux_clear_chains (GstOggDemux * ogg)
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);
}

View file

@ -225,7 +225,6 @@ static gboolean gst_app_src_unlock (GstBaseSrc * bsrc);
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);
@ -474,7 +473,6 @@ gst_app_src_class_init (GstAppSrcClass * klass)
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;
@ -749,24 +747,6 @@ gst_app_src_is_seekable (GstBaseSrc * src)
return res;
}
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)
{
@ -804,6 +784,22 @@ gst_app_src_query (GstBaseSrc * src, GstQuery * query)
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;

View file

@ -138,7 +138,6 @@ static GstClockTime gst_base_audio_src_get_time (GstClock * clock,
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,
@ -226,8 +225,6 @@ gst_base_audio_src_class_init (GstBaseAudioSrcClass * klass)
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
@ -348,16 +345,6 @@ gst_base_audio_src_get_time (GstClock * clock, GstBaseAudioSrc * src)
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
@ -658,6 +645,17 @@ gst_base_audio_src_query (GstBaseSrc * bsrc, GstQuery * query)
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;

View file

@ -141,7 +141,6 @@ static gboolean gst_tag_demux_src_activate_pull (GstPad * pad, gboolean active);
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);
@ -344,8 +343,6 @@ gst_tag_demux_add_srcpad (GstTagDemux * tagdemux, GstCaps * new_caps)
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));
@ -1153,6 +1150,8 @@ gst_tag_demux_sink_activate (GstPad * sinkpad)
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));
@ -1163,14 +1162,22 @@ gst_tag_demux_sink_activate (GstPad * sinkpad)
* 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))
@ -1259,6 +1266,14 @@ done_activate:
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
@ -1269,14 +1284,6 @@ gst_tag_demux_src_activate_pull (GstPad * pad, gboolean active)
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)

View file

@ -151,7 +151,6 @@ static gboolean gst_audio_test_src_setcaps (GstBaseSrc * basesrc,
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,
@ -227,8 +226,6 @@ gst_audio_test_src_class_init (GstAudioTestSrcClass * klass)
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 =
@ -405,6 +402,14 @@ gst_audio_test_src_query (GstBaseSrc * basesrc, GstQuery * query)
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;
@ -1006,17 +1011,6 @@ gst_audio_test_src_is_seekable (GstBaseSrc * basesrc)
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)