+2008-02-15 Sebastian Dröge <slomo@circular-chaos.org>
+
+ * ext/gio/gstgiobasesink.c: (close_stream_cb):
+ * ext/gio/gstgiobasesrc.c: (close_stream_cb):
+ Improve debugging a bit.
+
+ * ext/gio/gstgiosink.c: (mount_cb), (gst_gio_sink_start):
+ * ext/gio/gstgiosink.h:
+ * ext/gio/gstgiosrc.c: (mount_cb), (gst_gio_src_start):
+ * ext/gio/gstgiosrc.h:
+ Try to mount the enclosing volume of a GFile if it isn't mounted
+ yet. This requires us to wait for an async operation to finish, done
+ with an nested GMainLoop. Authentication is not supported yet, will
+ come later.
+
2008-02-14 Wim Taymans <wim.taymans@collabora.co.uk>
* gst/playback/gstplaybin2.c: (gst_play_bin_class_init),
if (!success
&& !gst_gio_error (sink, "g_output_stream_close_async", &err, NULL)) {
- GST_ELEMENT_ERROR (sink, RESOURCE, CLOSE, (NULL),
+ GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
("g_output_stream_close_async failed: %s", err->message));
g_clear_error (&err);
+ } else if (!success) {
+ GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
+ ("g_output_stream_close_async failed"));
+ } else {
+ GST_DEBUG_OBJECT (sink, "g_output_stream_close_async succeeded");
}
- GST_DEBUG_OBJECT (sink, "closed stream");
-
g_object_unref (sink);
}
if (!success
&& !gst_gio_error (src, "g_input_stream_close_async", &err, NULL)) {
- GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL),
+ GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
("g_input_stream_close_async failed: %s", err->message));
g_clear_error (&err);
+ } else if (!success) {
+ GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
+ ("g_input_stream_close_async failed"));
+ } else {
+ GST_DEBUG_OBJECT (src, "g_input_stream_close_async succeeded");
}
- GST_DEBUG_OBJECT (src, "closed stream");
-
g_object_unref (src);
}
}
}
+static void
+mount_cb (GObject * source, GAsyncResult * res, gpointer user_data)
+{
+ gboolean success;
+ GError *err = NULL;
+ GstGioSink *sink = GST_GIO_SINK (user_data);
+
+ success = g_file_mount_enclosing_volume_finish (G_FILE (source), res, &err);
+
+ if (!success
+ && !gst_gio_error (sink, "g_file_mount_enclosing_volume", &err, NULL)) {
+ GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
+ ("g_file_mount_enclosing_volume failed: %s", err->message));
+ g_clear_error (&err);
+ } else if (!success) {
+ GST_ELEMENT_WARNING (sink, RESOURCE, CLOSE, (NULL),
+ ("g_file_mount_enclosing_volume failed"));
+ } else {
+ GST_DEBUG ("g_file_mount_enclosing_volume failed succeeded");
+ }
+
+ sink->mount_successful = success;
+
+ g_main_loop_quit (sink->loop);
+
+ g_object_unref (sink);
+}
+
static gboolean
gst_gio_sink_start (GstBaseSink * base_sink)
{
stream =
G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel, &err));
+
+ if (stream == NULL && !gst_gio_error (sink, "g_file_read", &err, NULL) &&
+ GST_GIO_ERROR_MATCHES (err, NOT_MOUNTED)) {
+
+ GST_DEBUG ("Trying to mount enclosing volume for %s\n", sink->location);
+ g_clear_error (&err);
+ err = NULL;
+
+ sink->loop = g_main_loop_new (NULL, TRUE);
+ if (!sink->loop) {
+ GST_ELEMENT_ERROR (sink, LIBRARY, INIT,
+ (NULL), ("Failed to start GMainLoop"));
+ } else {
+ sink->mount_successful = FALSE;
+ /* TODO: authentication: a GMountOperation property that apps can set
+ * and properties for user/password/etc that can be used more easily
+ */
+ g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, NULL, cancel,
+ mount_cb, g_object_ref (sink));
+ g_main_loop_run (sink->loop);
+
+ g_main_loop_unref (sink->loop);
+ sink->loop = NULL;
+
+ if (!sink->mount_successful) {
+ GST_DEBUG ("Mounting the enclosing volume failed for some reason");
+ } else {
+ stream =
+ G_OUTPUT_STREAM (g_file_create (file, G_FILE_CREATE_NONE, cancel,
+ &err));
+ }
+ }
+ }
+
success = (stream != NULL);
g_object_unref (file);
/*< private >*/
gchar *location;
+
+ GMainLoop *loop;
+ gboolean mount_successful;
};
struct _GstGioSinkClass
}
}
+static void
+mount_cb (GObject * source, GAsyncResult * res, gpointer user_data)
+{
+ gboolean success;
+ GError *err = NULL;
+ GstGioSrc *src = GST_GIO_SRC (user_data);
+
+ success = g_file_mount_enclosing_volume_finish (G_FILE (source), res, &err);
+
+ if (!success
+ && !gst_gio_error (src, "g_file_mount_enclosing_volume", &err, NULL)) {
+ GST_ELEMENT_ERROR (src, RESOURCE, CLOSE, (NULL),
+ ("g_file_mount_enclosing_volume failed: %s", err->message));
+ g_clear_error (&err);
+ } else if (!success) {
+ GST_ELEMENT_WARNING (src, RESOURCE, CLOSE, (NULL),
+ ("g_file_mount_enclosing_volume failed"));
+ } else {
+ GST_DEBUG ("g_file_mount_enclosing_volume failed succeeded");
+ }
+
+ src->mount_successful = success;
+
+ g_main_loop_quit (src->loop);
+
+ g_object_unref (src);
+}
+
static gboolean
gst_gio_src_start (GstBaseSrc * base_src)
{
stream = G_INPUT_STREAM (g_file_read (file, cancel, &err));
+ if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL) &&
+ GST_GIO_ERROR_MATCHES (err, NOT_MOUNTED)) {
+
+
+ GST_DEBUG ("Trying to mount enclosing volume for %s\n", src->location);
+ g_clear_error (&err);
+ err = NULL;
+
+ src->loop = g_main_loop_new (NULL, TRUE);
+ if (!src->loop) {
+ GST_ELEMENT_ERROR (src, LIBRARY, INIT,
+ (NULL), ("Failed to start GMainLoop"));
+ } else {
+ src->mount_successful = FALSE;
+ /* TODO: authentication: a GMountOperation property that apps can set
+ * and properties for user/password/etc that can be used more easily
+ */
+ g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, NULL, cancel,
+ mount_cb, g_object_ref (src));
+ g_main_loop_run (src->loop);
+
+ g_main_loop_unref (src->loop);
+ src->loop = NULL;
+
+ if (!src->mount_successful) {
+ GST_ERROR ("Mounting the enclosing volume failed for some reason");
+ } else {
+ stream = G_INPUT_STREAM (g_file_read (file, cancel, &err));
+ }
+ }
+ }
+
+ src->mount_successful = FALSE;
+
g_object_unref (file);
if (stream == NULL && !gst_gio_error (src, "g_file_read", &err, NULL)) {
- if (GST_GIO_ERROR_MATCHES (err, NOT_FOUND))
+ 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
+ } 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;
}
/*< private >*/
gchar *location;
+
+ GMainLoop *loop;
+ gboolean mount_successful;
};
struct _GstGioSrcClass