[rhythmbox] track-transfer-batch: use encoding settings
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] track-transfer-batch: use encoding settings
- Date: Thu, 30 Jul 2015 11:40:31 +0000 (UTC)
commit 51d595cac358fefc86554b27f9eb753c7a7a4381
Author: Jonathan Matthew <jonathan d14n org>
Date: Wed Jul 29 22:57:38 2015 +1000
track-transfer-batch: use encoding settings
Encoding profile selection is now pretty complicated. Now we use
the source format if possible, or the preferred format for the target,
or the first available lossy encoding, or any lossless encoding.
If the transcode-lossless setting is enabled, we'll never use a lossless
encoding, even if it's the source format. The setting is not applied
if the preferred format is lossless.
shell/rb-track-transfer-batch.c | 194 ++++++++++++++++++++++-----------------
shell/rb-track-transfer-batch.h | 4 +-
sources/rb-library-source.c | 22 +----
sources/rb-transfer-target.c | 2 +-
4 files changed, 114 insertions(+), 108 deletions(-)
---
diff --git a/shell/rb-track-transfer-batch.c b/shell/rb-track-transfer-batch.c
index 5626015..cfc4f8a 100644
--- a/shell/rb-track-transfer-batch.c
+++ b/shell/rb-track-transfer-batch.c
@@ -52,7 +52,6 @@ enum
TRACK_STARTED,
TRACK_PROGRESS,
TRACK_DONE,
- CONFIGURE_PROFILE,
LAST_SIGNAL
};
@@ -60,6 +59,7 @@ enum
{
PROP_0,
PROP_ENCODING_TARGET,
+ PROP_SETTINGS,
PROP_SOURCE,
PROP_DESTINATION,
PROP_TOTAL_ENTRIES,
@@ -93,6 +93,7 @@ struct _RBTrackTransferBatchPrivate
RBTrackTransferQueue *queue;
GstEncodingTarget *target;
+ GSettings *settings;
GList *missing_plugin_profiles;
RBSource *source;
@@ -148,6 +149,7 @@ G_DEFINE_TYPE_EXTENDED (RBTrackTransferBatch,
*/
RBTrackTransferBatch *
rb_track_transfer_batch_new (GstEncodingTarget *target,
+ GSettings *settings,
GObject *source,
GObject *destination)
{
@@ -155,6 +157,7 @@ rb_track_transfer_batch_new (GstEncodingTarget *target,
obj = g_object_new (RB_TYPE_TRACK_TRANSFER_BATCH,
"encoding-target", target,
+ "settings", settings,
"source", source,
"destination", destination,
NULL);
@@ -174,70 +177,88 @@ rb_track_transfer_batch_add (RBTrackTransferBatch *batch, RhythmDBEntry *entry)
batch->priv->entries = g_list_append (batch->priv->entries, rhythmdb_entry_ref (entry));
}
+static int
+rank_profile (RBTrackTransferBatch *batch, GstEncodingProfile *profile, const char *source_media_type,
gboolean allow_missing)
+{
+ char *profile_media_type;
+ const char *preferred_media_type;
+ gboolean transcode_lossless;
+ gboolean is_preferred;
+ gboolean is_lossless;
+ gboolean is_source;
+ gboolean is_missing;
+ int rank;
+
+ profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
+ if (batch->priv->settings) {
+ preferred_media_type = g_settings_get_string (batch->priv->settings, "media-type");
+ if (rb_gst_media_type_is_lossless (preferred_media_type)) {
+ transcode_lossless = FALSE;
+ } else {
+ transcode_lossless = g_settings_get_boolean (batch->priv->settings,
"transcode-lossless");
+ }
+
+ is_preferred = (rb_gst_media_type_matches_profile (profile, preferred_media_type));
+ } else {
+ preferred_media_type = NULL;
+ transcode_lossless = FALSE;
+ is_preferred = FALSE;
+ }
+
+ is_missing = (g_list_find (batch->priv->missing_plugin_profiles, profile) != NULL);
+ is_lossless = (rb_gst_media_type_is_lossless (profile_media_type));
+ if (g_str_has_prefix (source_media_type, "audio/x-raw") == FALSE) {
+ is_source = rb_gst_media_type_matches_profile (profile, source_media_type);
+ } else {
+ /* always transcode raw audio */
+ is_source = FALSE;
+ }
+
+ if (is_missing && allow_missing == FALSE && is_source == FALSE) {
+ /* this only applies if transcoding would be required */
+ rb_debug ("can't use encoding %s due to missing plugins", profile_media_type);
+ rank = 0;
+ } else if (transcode_lossless && is_lossless) {
+ /* this overrides is_source so all lossless files get transcoded */
+ rb_debug ("don't want lossless encoding %s", profile_media_type);
+ rank = 0;
+ } else if (is_source) {
+ /* this overrides is_preferred so we don't transcode unneccessarily */
+ rb_debug ("can use source encoding %s", profile_media_type);
+ rank = 100;
+ } else if (is_preferred) {
+ /* otherwise, always use the preferred encoding if available */
+ rb_debug ("can use preferred encoding %s", profile_media_type);
+ rank = 50;
+ } else if (is_lossless == FALSE) {
+ /* if we can't use the preferred encoding, we prefer lossy encodings over lossless, for space
reasons */
+ rb_debug ("can use lossy encoding %s", profile_media_type);
+ rank = 25;
+ } else {
+ rb_debug ("can use lossless encoding %s", profile_media_type);
+ rank = 10;
+ }
+
+ g_free (profile_media_type);
+ return rank;
+}
+
static gboolean
select_profile_for_entry (RBTrackTransferBatch *batch, RhythmDBEntry *entry, GstEncodingProfile **rprofile,
gboolean allow_missing)
{
- /* probably want a way to pass in some policy about lossless encoding
- * here. possibilities:
- * - convert everything to lossy
- * - if transcoding is required, use lossy
- * - keep lossless encoded files lossless
- * - if transcoding is required, use lossless
- * - convert everything to lossless
- *
- * of course this only applies to targets that include lossless profiles..
- */
-
const char *media_type = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
- GstEncodingProfile *lossless = NULL;
- gboolean found_lossy = FALSE;
const GList *p;
+ int best = 0;
for (p = gst_encoding_target_get_profiles (batch->priv->target); p != NULL; p = p->next) {
GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
- char *profile_media_type;
- gboolean is_missing;
- gboolean skip;
-
- if (g_str_has_prefix (media_type, "audio/x-raw") == FALSE &&
- rb_gst_media_type_matches_profile (profile, media_type)) {
- /* source file is already in a supported encoding, so just copy it */
- *rprofile = NULL;
- return TRUE;
- }
-
- skip = FALSE;
- is_missing = (g_list_find (batch->priv->missing_plugin_profiles, profile) != NULL);
-
- profile_media_type = rb_gst_encoding_profile_get_media_type (profile);
- if (profile_media_type == NULL) {
- if (g_str_has_prefix (media_type, "audio/x-raw")) {
- skip = TRUE;
- }
- } else if (rb_gst_media_type_is_lossless (profile_media_type)) {
- skip = TRUE;
- if (allow_missing == FALSE && is_missing) {
- /* ignore entirely */
- } else if (lossless == NULL) {
- /* remember the first lossless profile that works */
- lossless = profile;
- }
- } else {
- found_lossy = TRUE;
- if (allow_missing == FALSE && is_missing) {
- skip = TRUE;
- }
- }
+ int rank;
- if (skip == FALSE && *rprofile == NULL) {
+ rank = rank_profile (batch, profile, media_type, allow_missing);
+ if (rank > best) {
*rprofile = profile;
+ best = rank;
}
- g_free (profile_media_type);
- }
-
- /* if we only found a lossless encoding, use it */
- if (*rprofile == NULL && found_lossy == FALSE && lossless != NULL) {
- *rprofile = lossless;
}
return (*rprofile != NULL);
@@ -654,7 +675,21 @@ start_next (RBTrackTransferBatch *batch)
extension = g_strdup (rb_gst_media_type_to_extension (media_type));
rb_gst_encoding_profile_set_preset (profile, NULL);
- g_signal_emit (batch, signals[CONFIGURE_PROFILE], 0, media_type, profile);
+ if (batch->priv->settings != NULL) {
+ GVariant *preset_settings;
+ char *active_preset;
+
+ preset_settings = g_settings_get_value (batch->priv->settings,
+ "media-type-presets");
+ active_preset = NULL;
+ g_variant_lookup (preset_settings, media_type, "s", &active_preset);
+
+ rb_debug ("setting preset %s for media type %s",
+ active_preset, media_type);
+ rb_gst_encoding_profile_set_preset (profile, active_preset);
+
+ g_free (active_preset);
+ }
} else {
media_type = rhythmdb_entry_dup_string (entry, RHYTHMDB_PROP_MEDIA_TYPE);
extension = g_strdup (rb_gst_media_type_to_extension (media_type));
@@ -719,6 +754,9 @@ impl_set_property (GObject *object,
case PROP_ENCODING_TARGET:
batch->priv->target = GST_ENCODING_TARGET (g_value_dup_object (value));
break;
+ case PROP_SETTINGS:
+ batch->priv->settings = g_value_dup_object (value);
+ break;
case PROP_SOURCE:
batch->priv->source = g_value_dup_object (value);
break;
@@ -760,6 +798,9 @@ impl_get_property (GObject *object,
case PROP_ENCODING_TARGET:
g_value_set_object (value, batch->priv->target);
break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, batch->priv->settings);
+ break;
case PROP_SOURCE:
g_value_set_object (value, batch->priv->source);
break;
@@ -846,15 +887,9 @@ impl_dispose (GObject *object)
{
RBTrackTransferBatch *batch = RB_TRACK_TRANSFER_BATCH (object);
- if (batch->priv->source != NULL) {
- g_object_unref (batch->priv->source);
- batch->priv->source = NULL;
- }
-
- if (batch->priv->destination != NULL) {
- g_object_unref (batch->priv->destination);
- batch->priv->destination = NULL;
- }
+ g_clear_object (&batch->priv->source);
+ g_clear_object (&batch->priv->destination);
+ g_clear_object (&batch->priv->settings);
if (batch->priv->target != NULL) {
gst_encoding_target_unref (batch->priv->target);
@@ -909,6 +944,18 @@ rb_track_transfer_batch_class_init (RBTrackTransferBatchClass *klass)
GST_TYPE_ENCODING_TARGET,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
/**
+ * RBTrackTransferBatch:settings
+ *
+ * GSettings instance holding profile preferences
+ */
+ g_object_class_install_property (object_class,
+ PROP_SETTINGS,
+ g_param_spec_object ("settings",
+ "profile settings",
+ "GSettings instance holding profile settings",
+ G_TYPE_SETTINGS,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ /**
* RBTrackTransferBatch:source:
*
* The RBSource from which the tracks are being transferred.
@@ -1149,24 +1196,5 @@ rb_track_transfer_batch_class_init (RBTrackTransferBatchClass *klass)
G_TYPE_NONE,
5, RHYTHMDB_TYPE_ENTRY, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_STRING,
G_TYPE_POINTER);
- /**
- * RBTrackTransferBatch::configure-profile:
- * @batch: the #RBTrackTransferBatch
- * @mediatype: the target media type
- * @profile: the #GstEncodingProfile
- *
- * Emitted to allow configuration of encoding profile settings
- * (mostly by setting presets on sub-profiles).
- */
- signals [CONFIGURE_PROFILE] =
- g_signal_new ("configure-profile",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (RBTrackTransferBatchClass, configure_profile),
- NULL, NULL,
- rb_marshal_VOID__STRING_POINTER,
- G_TYPE_NONE,
- 2, G_TYPE_STRING, GST_TYPE_ENCODING_PROFILE);
-
g_type_class_add_private (klass, sizeof (RBTrackTransferBatchPrivate));
}
diff --git a/shell/rb-track-transfer-batch.h b/shell/rb-track-transfer-batch.h
index b661c73..cc15868 100644
--- a/shell/rb-track-transfer-batch.h
+++ b/shell/rb-track-transfer-batch.h
@@ -60,9 +60,6 @@ struct _RBTrackTransferBatchClass
void (*cancelled) (RBTrackTransferBatch *batch);
void (*complete) (RBTrackTransferBatch *batch);
- char * (*configure_profile) (RBTrackTransferBatch *batch,
- const char *mediatype,
- GstEncodingProfile *profile);
char * (*get_dest_uri) (RBTrackTransferBatch *batch,
RhythmDBEntry *entry,
const char *mediatype,
@@ -89,6 +86,7 @@ struct _RBTrackTransferBatchClass
GType rb_track_transfer_batch_get_type (void);
RBTrackTransferBatch * rb_track_transfer_batch_new (GstEncodingTarget *target,
+ GSettings *settings,
GObject *source,
GObject *destination);
void rb_track_transfer_batch_add (RBTrackTransferBatch *batch,
diff --git a/sources/rb-library-source.c b/sources/rb-library-source.c
index fe656b6..69b023e 100644
--- a/sources/rb-library-source.c
+++ b/sources/rb-library-source.c
@@ -1640,25 +1640,6 @@ get_dest_uri_cb (RBTrackTransferBatch *batch,
}
static void
-configure_profile_cb (RBTrackTransferBatch *batch,
- const char *media_type,
- GstEncodingProfile *profile,
- RBLibrarySource *source)
-{
- GVariant *preset_settings;
- char *active_preset;
-
- preset_settings = g_settings_get_value (source->priv->encoding_settings, "media-type-presets");
- active_preset = NULL;
- g_variant_lookup (preset_settings, media_type, "s", &active_preset);
-
- rb_debug ("setting preset %s for media type %s", active_preset, media_type);
- rb_gst_encoding_profile_set_preset (profile, active_preset);
-
- g_free (active_preset);
-}
-
-static void
track_done_cb (RBTrackTransferBatch *batch,
RhythmDBEntry *entry,
const char *dest,
@@ -1736,10 +1717,9 @@ impl_paste (RBSource *asource, GList *entries)
gst_encoding_profile_set_name (profile, "copy");
gst_encoding_target_add_profile (target, profile);
- batch = rb_track_transfer_batch_new (target, NULL, G_OBJECT (source));
+ batch = rb_track_transfer_batch_new (target, source->priv->encoding_settings, NULL, G_OBJECT
(source));
g_signal_connect_object (batch, "get-dest-uri", G_CALLBACK (get_dest_uri_cb), source, 0);
g_signal_connect_object (batch, "track-done", G_CALLBACK (track_done_cb), source, 0);
- g_signal_connect_object (batch, "configure-profile", G_CALLBACK (configure_profile_cb), source, 0);
for (l = entries; l != NULL; l = g_list_next (l)) {
RhythmDBEntry *entry = (RhythmDBEntry *)l->data;
diff --git a/sources/rb-transfer-target.c b/sources/rb-transfer-target.c
index 17eeb99..b9f8077 100644
--- a/sources/rb-transfer-target.c
+++ b/sources/rb-transfer-target.c
@@ -410,7 +410,7 @@ rb_transfer_target_transfer (RBTransferTarget *target, GSettings *settings, GLis
batch = g_object_steal_data (G_OBJECT (target), "transfer-target-batch");
if (batch == NULL) {
- batch = rb_track_transfer_batch_new (NULL, NULL, G_OBJECT (target));
+ batch = rb_track_transfer_batch_new (NULL, settings, NULL, G_OBJECT (target));
g_signal_connect_object (batch, "get-dest-uri", G_CALLBACK (get_dest_uri_cb), target, 0);
g_signal_connect_object (batch, "track-done", G_CALLBACK (track_done_cb), target, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]