ARG_IRADIO_TITLE
};
-static void gst_gnome_vfs_src_base_init (gpointer g_class);
-static void gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass);
-static void gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc);
static void gst_gnome_vfs_src_finalize (GObject * object);
static void gst_gnome_vfs_src_uri_handler_init (gpointer g_iface,
gpointer iface_data);
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_unlock (GstBaseSrc * basesrc);
static gboolean gst_gnome_vfs_src_unlock_stop (GstBaseSrc * basesrc);
static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * src, guint64 * size);
guint64 offset, guint size, GstBuffer ** buffer);
static gboolean gst_gnome_vfs_src_query (GstBaseSrc * src, GstQuery * query);
-static GstElementClass *parent_class = NULL;
-
-GType
-gst_gnome_vfs_src_get_type (void)
-{
- static GType gnomevfssrc_type = 0;
-
- if (!gnomevfssrc_type) {
- static const GTypeInfo gnomevfssrc_info = {
- sizeof (GstGnomeVFSSrcClass),
- gst_gnome_vfs_src_base_init,
- NULL,
- (GClassInitFunc) gst_gnome_vfs_src_class_init,
- NULL,
- NULL,
- sizeof (GstGnomeVFSSrc),
- 0,
- (GInstanceInitFunc) gst_gnome_vfs_src_init,
- };
- static const GInterfaceInfo urihandler_info = {
- gst_gnome_vfs_src_uri_handler_init,
- NULL,
- NULL
- };
-
- gnomevfssrc_type =
- g_type_register_static (GST_TYPE_BASE_SRC,
- "GstGnomeVFSSrc", &gnomevfssrc_info, 0);
- g_type_add_interface_static (gnomevfssrc_type, GST_TYPE_URI_HANDLER,
- &urihandler_info);
- }
- return gnomevfssrc_type;
-}
-
-static void
-gst_gnome_vfs_src_base_init (gpointer g_class)
-{
- GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
- gst_element_class_add_pad_template (element_class,
- gst_static_pad_template_get (&srctemplate));
- gst_element_class_set_details_simple (element_class,
- "GnomeVFS Source", "Source/File",
- "Read from any GnomeVFS-supported file",
- "Bastien Nocera <hadess@hadess.net>, "
- "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
-
- GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
- "Gnome-VFS Source");
-}
+#define gst_gnome_vfs_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstGnomeVFSSrc, gst_gnome_vfs_src, GST_TYPE_BASE_SRC,
+ G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
+ gst_gnome_vfs_src_uri_handler_init));
static void
gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
{
GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
GstBaseSrcClass *gstbasesrc_class;
gobject_class = G_OBJECT_CLASS (klass);
+ gstelement_class = GST_ELEMENT_CLASS (klass);
gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
- parent_class = g_type_class_peek_parent (klass);
+ GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
+ "Gnome-VFS Source");
gobject_class->finalize = gst_gnome_vfs_src_finalize;
gobject_class->set_property = gst_gnome_vfs_src_set_property;
"Name of currently playing song", NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&srctemplate));
+ gst_element_class_set_details_simple (gstelement_class,
+ "GnomeVFS Source", "Source/File",
+ "Read from any GnomeVFS-supported file",
+ "Bastien Nocera <hadess@hadess.net>, "
+ "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
+
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_start);
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_stop);
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_unlock);
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);
}
GnomeVFSResult res;
GstBuffer *buf;
GnomeVFSFileSize readbytes;
- guint8 *data;
- guint todo;
+ guint8 *data, *ptr;
+ gsize todo;
GstGnomeVFSSrc *src;
gboolean interrupted = FALSE;
}
}
- buf = gst_buffer_try_new_and_alloc (size);
+ buf = gst_buffer_new_and_alloc (size);
if (G_UNLIKELY (buf == NULL)) {
GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
return GST_FLOW_ERROR;
}
- data = GST_BUFFER_DATA (buf);
+ data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+ ptr = data;
todo = size;
while (!src->interrupted && todo > 0) {
/* this can return less that we ask for */
/* Just take what we've so far gotten and return */
size = size - todo;
- GST_BUFFER_SIZE (buf) = size;
todo = 0;
interrupted = TRUE;
break;
goto read_failed;
if (readbytes < todo) {
- data = &data[readbytes];
+ ptr += readbytes;
todo -= readbytes;
} else {
todo = 0;
}
GST_LOG (" got size %" G_GUINT64_FORMAT, readbytes);
}
+ gst_buffer_unmap (buf, data, size);
if (interrupted)
goto interrupted;
}
read_failed:
{
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
("Failed to read data: %s", gnome_vfs_result_to_string (res)));
}
eos:
{
+ gst_buffer_unmap (buf, data, size);
gst_buffer_unref (buf);
GST_DEBUG_OBJECT (src, "Reading data gave EOS");
return GST_FLOW_UNEXPECTED;
}
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;
}
/* Interrupt a blocking request. */