static gboolean gst_gio_src_check_get_range (GstBaseSrc * base_src) { 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: 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); }
static void gst_gio_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { case PROP_LOCATION:{ gchar *uri; GST_OBJECT_LOCK (GST_OBJECT (src)); if (src->file) { uri = g_file_get_uri (src->file); g_value_set_string (value, uri); g_free (uri); } else { g_value_set_string (value, NULL); } GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; } case PROP_FILE: GST_OBJECT_LOCK (GST_OBJECT (src)); g_value_set_object (value, src->file); GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_gio_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { case PROP_LOCATION:{ const gchar *uri = NULL; if (GST_STATE (src) == GST_STATE_PLAYING || GST_STATE (src) == GST_STATE_PAUSED) { GST_WARNING ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); break; } GST_OBJECT_LOCK (GST_OBJECT (src)); if (src->file) g_object_unref (src->file); uri = g_value_get_string (value); if (uri) { src->file = g_file_new_for_uri (uri); if (!src->file) { GST_ERROR ("Could not create GFile for URI '%s'", uri); } } else { src->file = NULL; } GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; } case PROP_FILE: if (GST_STATE (src) == GST_STATE_PLAYING || GST_STATE (src) == GST_STATE_PAUSED) { GST_WARNING ("Setting a new location or GFile not supported in PLAYING or PAUSED state"); break; } GST_OBJECT_LOCK (GST_OBJECT (src)); if (src->file) g_object_unref (src->file); src->file = g_value_dup_object (value); GST_OBJECT_UNLOCK (GST_OBJECT (src)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_gio_src_finalize (GObject * object) { GstGioSrc *src = GST_GIO_SRC (object); if (src->file) { g_object_unref (src->file); src->file = NULL; } GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); }
static void gst_gio_src_finalize (GObject * object) { GstGioSrc *src = GST_GIO_SRC (object); if (src->location) { g_free (src->location); src->location = NULL; } GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); }
static GInputStream * gst_gio_src_get_stream (GstGioBaseSrc * bsrc) { GstGioSrc *src = GST_GIO_SRC (bsrc); GError *err = NULL; GInputStream *stream; GCancellable *cancel = bsrc->cancel; gchar *uri = NULL; if (src->file == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location or GFile given")); return NULL; } uri = g_file_get_uri (src->file); if (!uri) uri = g_strdup ("(null)"); stream = G_INPUT_STREAM (g_file_read (src->file, cancel, &err)); if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("Could not open location %s for reading: %s", uri, err->message)); } else if (GST_GIO_ERROR_MATCHES (err, NOT_MOUNTED)) { gst_element_post_message (GST_ELEMENT_CAST (src), gst_message_new_element (GST_OBJECT_CAST (src), gst_structure_new ("not-mounted", "file", G_TYPE_FILE, src->file, "uri", G_TYPE_STRING, uri, NULL))); GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Location %s not mounted: %s", uri, err->message)); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Could not open location %s for reading: %s", uri, err->message)); } g_free (uri); g_clear_error (&err); return NULL; } else if (stream == NULL) { g_free (uri); return NULL; } GST_DEBUG_OBJECT (src, "opened location %s", uri); g_free (uri); return stream; }
static gboolean gst_gio_src_start (GstBaseSrc * base_src) { GstGioSrc *src = GST_GIO_SRC (base_src); GFile *file; GError *err = NULL; GInputStream *stream; GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel; if (src->location == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location given")); return FALSE; } file = g_file_new_for_uri (src->location); if (file == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Malformed URI or protocol not supported (%s)", src->location)); return FALSE; } stream = G_INPUT_STREAM (g_file_read (file, cancel, &err)); g_object_unref (file); if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("Could not open location %s for reading: %s", src->location, err->message)); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Could not open location %s for reading: %s", src->location, err->message)); } g_clear_error (&err); return FALSE; } else if (stream == NULL) { return FALSE; } gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream); GST_DEBUG_OBJECT (src, "opened location %s", src->location); return GST_BASE_SRC_CLASS (parent_class)->start (base_src); }
static gboolean gst_gio_src_query (GstBaseSrc * base_src, GstQuery * query) { gboolean res; GstGioSrc *src = GST_GIO_SRC (base_src); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_SCHEDULING: { gchar *scheme; GstSchedulingFlags flags; flags = 0; 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"); flags |= GST_SCHEDULING_FLAG_SEEKABLE; } 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, flags, 1, -1, 0); gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH); if (flags & GST_SCHEDULING_FLAG_SEEKABLE) gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL); res = TRUE; break; } default: forward_parent: res = GST_CALL_PARENT_WITH_DEFAULT (GST_BASE_SRC_CLASS, query, (base_src, query), FALSE); break; } return res; }
static gboolean gst_gio_src_start (GstBaseSrc * base_src) { GstGioSrc *src = GST_GIO_SRC (base_src); GError *err = NULL; GInputStream *stream; GCancellable *cancel = GST_GIO_BASE_SRC (src)->cancel; gchar *uri = NULL; if (src->file == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No location or GFile given")); return FALSE; } uri = g_file_get_uri (src->file); if (!uri) uri = g_strdup ("(null)"); stream = G_INPUT_STREAM (g_file_read (src->file, cancel, &err)); if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) { if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("Could not open location %s for reading: %s", uri, err->message)); } else { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("Could not open location %s for reading: %s", uri, err->message)); } g_free (uri); g_clear_error (&err); return FALSE; } else if (stream == NULL) { g_free (uri); return FALSE; } gst_gio_base_src_set_stream (GST_GIO_BASE_SRC (src), stream); GST_DEBUG_OBJECT (src, "opened location %s", uri); g_free (uri); return GST_BASE_SRC_CLASS (parent_class)->start (base_src); }
static void gst_gio_src_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { case ARG_LOCATION: g_value_set_string (value, src->location); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void gst_gio_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstGioSrc *src = GST_GIO_SRC (object); switch (prop_id) { case ARG_LOCATION: if (GST_STATE (src) == GST_STATE_PLAYING || GST_STATE (src) == GST_STATE_PAUSED) break; g_free (src->location); src->location = g_strdup (g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }