[rhythmbox] encoder: on illegal filename errors, retry with a sanitized name
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] encoder: on illegal filename errors, retry with a sanitized name
- Date: Sat, 8 Mar 2014 02:26:45 +0000 (UTC)
commit 0a1ea85ed8415132c9f27b5ed7ad018e3ce89ef2
Author: Jonathan Matthew <jonathan d14n org>
Date: Sat Mar 8 12:25:50 2014 +1000
encoder: on illegal filename errors, retry with a sanitized name
https://bugzilla.gnome.org/show_bug.cgi?id=720217
backends/gstreamer/rb-encoder-gst.c | 196 ++++++++++++++++++-----------------
1 files changed, 101 insertions(+), 95 deletions(-)
---
diff --git a/backends/gstreamer/rb-encoder-gst.c b/backends/gstreamer/rb-encoder-gst.c
index 7a81114..9cdd14a 100644
--- a/backends/gstreamer/rb-encoder-gst.c
+++ b/backends/gstreamer/rb-encoder-gst.c
@@ -440,6 +440,37 @@ add_decoding_pipeline (RBEncoderGst *encoder,
return decodebin;
}
+static GFileOutputStream *
+create_stream (const char *dest, gboolean overwrite, GError **error)
+{
+ GFile *file;
+ GFileOutputStream *stream = NULL;
+ GError *local_error = NULL;
+
+ file = g_file_new_for_uri (dest);
+ stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &local_error);
+
+ if (local_error != NULL) {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ if (overwrite) {
+ g_clear_error (&local_error);
+ stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
+ } else {
+ g_set_error_literal (error,
+ RB_ENCODER_ERROR,
+ RB_ENCODER_ERROR_DEST_EXISTS,
+ local_error->message);
+ g_clear_error (&local_error);
+ }
+ } else {
+ g_propagate_error (error, local_error);
+ }
+ }
+
+ g_object_unref (file);
+ return stream;
+}
+
static gboolean
attach_output_pipeline (RBEncoderGst *encoder,
GstElement *end,
@@ -447,55 +478,28 @@ attach_output_pipeline (RBEncoderGst *encoder,
gboolean overwrite,
GError **error)
{
- GFile *file;
GFileOutputStream *stream;
GstElement *sink;
- GError *local_error = NULL;
/* if we can get to the location with gio, open the file here
* (prompting for overwrite if it already exists) and use giostreamsink.
* otherwise, create whatever sink element we can.
*/
rb_debug ("attempting to open output file %s", dest);
- file = g_file_new_for_uri (dest);
sink = gst_element_factory_make ("giostreamsink", NULL);
if (sink != NULL) {
- stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &local_error);
- if (local_error != NULL) {
- if (g_error_matches (local_error,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED)) {
- rb_debug ("gio can't write to %s, so using whatever sink will work", dest);
- g_object_unref (sink);
- sink = NULL;
- g_error_free (local_error);
- } else if (g_error_matches (local_error,
- G_IO_ERROR,
- G_IO_ERROR_EXISTS)) {
- if (overwrite) {
- g_error_free (local_error);
- stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL,
error);
- if (stream == NULL) {
- return FALSE;
- }
- } else {
- g_set_error_literal (error,
- RB_ENCODER_ERROR,
- RB_ENCODER_ERROR_DEST_EXISTS,
- local_error->message);
- g_error_free (local_error);
- return FALSE;
- }
- } else {
- g_propagate_error (error, local_error);
- return FALSE;
- }
- }
-
+ stream = create_stream (dest, overwrite, error);
if (stream != NULL) {
g_object_set (sink, "stream", stream, NULL);
encoder->priv->outstream = G_OUTPUT_STREAM (stream);
+ } else if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) {
+ rb_debug ("giostreamsink can't write to %s", dest);
+ g_clear_object (&sink);
+ g_clear_error (error);
+ } else {
+ g_object_unref (sink);
+ return FALSE;
}
} else {
rb_debug ("unable to create giostreamsink, falling back to default sink for %s", dest);
@@ -516,7 +520,6 @@ attach_output_pipeline (RBEncoderGst *encoder,
gst_bin_add (GST_BIN (encoder->priv->pipeline), sink);
gst_element_link (end, sink);
-
return TRUE;
}
@@ -556,34 +559,9 @@ create_pipeline_and_source (RBEncoderGst *encoder,
return src;
}
-static gboolean
-copy_track (RBEncoderGst *encoder,
- RhythmDBEntry *entry,
- const char *dest,
- gboolean overwrite,
- GError **error)
-{
- /* source ! sink */
- GstElement *src;
-
- g_assert (encoder->priv->pipeline == NULL);
-
- src = create_pipeline_and_source (encoder, entry, error);
- if (src == NULL)
- return FALSE;
-
- if (!attach_output_pipeline (encoder, src, dest, overwrite, error))
- return FALSE;
-
- start_pipeline (encoder);
- return TRUE;
-}
-
-static gboolean
+static GstElement *
transcode_track (RBEncoderGst *encoder,
RhythmDBEntry *entry,
- const char *dest,
- gboolean overwrite,
GError **error)
{
/* src ! decodebin ! encodebin ! sink */
@@ -593,15 +571,17 @@ transcode_track (RBEncoderGst *encoder,
g_assert (encoder->priv->pipeline == NULL);
g_assert (encoder->priv->profile != NULL);
- rb_debug ("transcoding to %s, profile %s", dest, gst_encoding_profile_get_name
(encoder->priv->profile));
+ rb_debug ("transcoding to profile %s", gst_encoding_profile_get_name (encoder->priv->profile));
src = create_pipeline_and_source (encoder, entry, error);
- if (src == NULL)
- goto error;
+ if (src == NULL) {
+ return NULL;
+ }
decoder = add_decoding_pipeline (encoder, error);
- if (decoder == NULL)
- goto error;
+ if (decoder == NULL) {
+ return NULL;
+ }
if (gst_element_link (src, decoder) == FALSE) {
rb_debug ("unable to link source element to decodebin");
@@ -609,7 +589,7 @@ transcode_track (RBEncoderGst *encoder,
RB_ENCODER_ERROR,
RB_ENCODER_ERROR_INTERNAL,
"Unable to link source element to decodebin");
- goto error;
+ return NULL;
}
encoder->priv->encodebin = gst_element_factory_make ("encodebin", NULL);
@@ -619,7 +599,7 @@ transcode_track (RBEncoderGst *encoder,
RB_ENCODER_ERROR,
RB_ENCODER_ERROR_INTERNAL,
"Could not create encodebin");
- goto error;
+ return NULL;
}
g_object_set (encoder->priv->encodebin,
"profile", encoder->priv->profile,
@@ -629,15 +609,7 @@ transcode_track (RBEncoderGst *encoder,
NULL);
gst_bin_add (GST_BIN (encoder->priv->pipeline), encoder->priv->encodebin);
- if (!attach_output_pipeline (encoder, encoder->priv->encodebin, dest, overwrite, error))
- goto error;
- if (!add_tags_from_entry (encoder, entry, error))
- goto error;
-
- start_pipeline (encoder);
- return TRUE;
-error:
- return FALSE;
+ return encoder->priv->encodebin;
}
static void
@@ -697,25 +669,41 @@ impl_encode (RBEncoder *bencoder,
GstEncodingProfile *profile)
{
RBEncoderGst *encoder = RB_ENCODER_GST (bencoder);
- gboolean result;
GError *error = NULL;
+ char *freedest = NULL;
+ GstElement *end;
g_return_if_fail (encoder->priv->pipeline == NULL);
+ g_free (encoder->priv->dest_media_type);
+ g_free (encoder->priv->dest_uri);
+ encoder->priv->dest_uri = NULL;
+
if (rb_uri_create_parent_dirs (dest, &error) == FALSE) {
- error = g_error_new_literal (RB_ENCODER_ERROR,
- RB_ENCODER_ERROR_FILE_ACCESS,
- error->message); /* I guess */
- set_error (encoder, error);
- g_error_free (error);
- g_idle_add ((GSourceFunc) cancel_idle, g_object_ref (encoder));
- return;
- }
+ /* this might be an msdos filesystem in disguise */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME)) {
+ freedest = rb_sanitize_uri_for_filesystem (dest, "msdos");
+ dest = freedest;
- g_free (encoder->priv->dest_media_type);
- g_free (encoder->priv->dest_uri);
- encoder->priv->dest_uri = g_strdup (dest);
+ g_clear_error (&error);
+ rb_uri_create_parent_dirs (dest, &error);
+ }
+
+ if (error != NULL) {
+ GError *nerror;
+ nerror = g_error_new_literal (RB_ENCODER_ERROR,
+ RB_ENCODER_ERROR_FILE_ACCESS,
+ error->message); /* I guess */
+
+ set_error (encoder, nerror);
+ g_error_free (error);
+ g_error_free (nerror);
+ g_idle_add ((GSourceFunc) cancel_idle, g_object_ref (encoder));
+ g_free (freedest);
+ return;
+ }
+ }
/* keep ourselves alive in case we get cancelled by a signal handler */
g_object_ref (encoder);
@@ -726,7 +714,7 @@ impl_encode (RBEncoder *bencoder,
encoder->priv->position_format = GST_FORMAT_BYTES;
encoder->priv->dest_media_type = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
- result = copy_track (encoder, entry, dest, overwrite, &error);
+ end = create_pipeline_and_source (encoder, entry, &error);
} else {
gst_encoding_profile_ref (profile);
encoder->priv->profile = profile;
@@ -734,19 +722,37 @@ impl_encode (RBEncoder *bencoder,
encoder->priv->position_format = GST_FORMAT_TIME;
encoder->priv->dest_media_type = rb_gst_encoding_profile_get_media_type (profile);
- result = transcode_track (encoder, entry, dest, overwrite, &error);
+ end = transcode_track (encoder, entry, &error);
}
- if (result == FALSE && encoder->priv->cancelled == FALSE) {
- set_error (encoder, error);
- g_idle_add ((GSourceFunc) cancel_idle, g_object_ref (encoder));
+ if (error == NULL) {
+ attach_output_pipeline (encoder, end, dest, overwrite, &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME) && freedest == NULL) {
+ freedest = rb_sanitize_uri_for_filesystem (dest, "msdos");
+ dest = freedest;
+
+ g_clear_error (&error);
+ attach_output_pipeline (encoder, end, dest, overwrite, &error);
+ }
+ }
+
+ if (error == NULL && profile != NULL) {
+ add_tags_from_entry (encoder, entry, &error);
}
if (error != NULL) {
+ if (encoder->priv->cancelled == FALSE) {
+ set_error (encoder, error);
+ g_idle_add ((GSourceFunc) cancel_idle, g_object_ref (encoder));
+ }
g_error_free (error);
+ } else {
+ encoder->priv->dest_uri = g_strdup (dest);
+ start_pipeline (encoder);
}
g_object_unref (encoder);
+ g_free (freedest);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]