[rhythmbox] add more utility functions for dealing with encoding profiles
- From: Jonathan Matthew <jmatthew src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [rhythmbox] add more utility functions for dealing with encoding profiles
- Date: Sun, 22 Apr 2012 23:01:41 +0000 (UTC)
commit fc8dbef7c33a6f2e338daa09a176583ab1fdc1f6
Author: Jonathan Matthew <jonathan d14n org>
Date: Mon Apr 23 08:37:14 2012 +1000
add more utility functions for dealing with encoding profiles
Also, for some encoders, add a list of properties that could
usefully be exposed to the user as an alternative to selecting a
preset. This is very conservative so far, just exposing quality
settings for a few encoders.
data/rhythmbox.gep | 10 +++
lib/rb-gst-media-types.c | 159 ++++++++++++++++++++++++++++++++++++++++++++--
lib/rb-gst-media-types.h | 6 ++
3 files changed, 170 insertions(+), 5 deletions(-)
---
diff --git a/data/rhythmbox.gep b/data/rhythmbox.gep
index 6383d96..9448922 100644
--- a/data/rhythmbox.gep
+++ b/data/rhythmbox.gep
@@ -15,6 +15,8 @@ type = audio
format = audio/mpeg, mpegversion=1, layer=3
presence = 1
+
+
[profile-oggvorbis]
name = oggvorbis
description = Ogg Vorbis
@@ -27,12 +29,14 @@ type = audio
format = audio/x-vorbis
presence = 1
+
[profile-flac]
name = flac
description = FLAC
format = audio/x-flac
type = audio
+
[profile-m4a]
name = m4a
description = MPEG 4 Audio
@@ -44,3 +48,9 @@ parent = m4a
type = audio
format = audio/mpeg, mpegversion=4, stream-format=raw
presence = 1
+
+[rhythmbox-encoder-settings]
+# maps encoder elements to lists of settings to expose
+lamemp3enc = quality
+faac = quality
+vorbisenc = quality
diff --git a/lib/rb-gst-media-types.c b/lib/rb-gst-media-types.c
index 3a76e1b..97c7881 100644
--- a/lib/rb-gst-media-types.c
+++ b/lib/rb-gst-media-types.c
@@ -50,6 +50,7 @@ static const char *container_formats[] = {
#define ENCODING_TARGET_FILE "rhythmbox.gep"
static GstEncodingTarget *default_target = NULL;
+static GKeyFile *target_keyfile = NULL;
RBGstMediaType
rb_gst_get_missing_plugin_type (const GstStructure *structure)
@@ -253,6 +254,20 @@ rb_gst_encoding_profile_get_media_type (GstEncodingProfile *profile)
}
}
+static char *
+get_encoding_target_file ()
+{
+ char *target_file;
+
+ target_file = rb_find_user_data_file (ENCODING_TARGET_FILE);
+ if (g_file_test (target_file, G_FILE_TEST_EXISTS) == FALSE) {
+ g_free (target_file);
+ target_file = g_strdup (rb_file (ENCODING_TARGET_FILE));
+ }
+
+ return target_file;
+}
+
GstEncodingTarget *
rb_gst_get_default_encoding_target ()
{
@@ -260,17 +275,15 @@ rb_gst_get_default_encoding_target ()
char *target_file;
GError *error = NULL;
- target_file = rb_find_user_data_file (ENCODING_TARGET_FILE);
- if (g_file_test (target_file, G_FILE_TEST_EXISTS) == FALSE) {
- target_file = g_strdup (rb_file (ENCODING_TARGET_FILE));
- }
-
+ target_file = get_encoding_target_file ();
default_target = gst_encoding_target_load_from_file (target_file, &error);
if (default_target == NULL) {
g_warning ("Unable to load encoding profiles from %s: %s", target_file, error ? error->message : "no error");
g_clear_error (&error);
+ g_free (target_file);
return NULL;
}
+ g_free (target_file);
}
return default_target;
@@ -312,3 +325,139 @@ rb_gst_media_type_is_lossless (const char *media_type)
}
return FALSE;
}
+
+static GstEncodingProfile *
+get_audio_encoding_profile (GstEncodingProfile *profile)
+{
+ if (GST_IS_ENCODING_AUDIO_PROFILE (profile)) {
+ return profile;
+ } else if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
+ const GList *l = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile));
+ for (; l != NULL; l = l->next) {
+ GstEncodingProfile *p = get_audio_encoding_profile (l->data);
+ if (p != NULL) {
+ return p;
+ }
+ }
+ }
+
+ g_warning ("no audio encoding profile in profile %s", gst_encoding_profile_get_name (profile));
+ return NULL;
+}
+
+static GstElementFactory *
+get_audio_encoder_factory (GstEncodingProfile *profile)
+{
+ GstEncodingProfile *p = get_audio_encoding_profile (profile);
+ GstElementFactory *f;
+ GList *l;
+ GList *fl;
+
+ if (p == NULL)
+ return NULL;
+
+ l = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER, GST_RANK_MARGINAL);
+ fl = gst_element_factory_list_filter (l, gst_encoding_profile_get_format (p), GST_PAD_SRC, FALSE);
+
+ if (fl != NULL) {
+ f = gst_object_ref (fl->data);
+ } else {
+ g_warning ("no encoder factory for profile %s", gst_encoding_profile_get_name (p));
+ f = NULL;
+ }
+ gst_plugin_feature_list_free (l);
+ gst_plugin_feature_list_free (fl);
+ return f;
+}
+
+/**
+ * rb_gst_encoding_profile_set_preset:
+ * @profile: a #GstEncodingProfile
+ * @preset: preset to apply
+ *
+ * Applies the preset @preset to the audio encoding profile within @profile.
+ */
+void
+rb_gst_encoding_profile_set_preset (GstEncodingProfile *profile, const char *preset)
+{
+ GstEncodingProfile *p;
+
+ p = get_audio_encoding_profile (profile);
+ if (p != NULL) {
+ gst_encoding_profile_set_preset (p, preset);
+ }
+}
+
+/**
+ * rb_gst_encoding_profile_get_settings:
+ * @profile: a #GstEncodingProfile
+ *
+ * Returns a list of settings for the profile @profile that can usefully
+ * be exposed to a user. This usually means just bitrate/quality settings.
+ * This works by finding the name of the encoder element for the profile
+ * and retrieving a list specific to that encoder.
+ *
+ * Return value: (transfer full) (element-type GParamSpec): list of settings
+ */
+char **
+rb_gst_encoding_profile_get_settings (GstEncodingProfile *profile)
+{
+ GstElementFactory *factory;
+ char **setting_names;
+
+ factory = get_audio_encoder_factory (profile);
+ if (factory == NULL) {
+ return NULL;
+ }
+
+ /* look up list of settings;
+ * if we don't have one for the encoder, what do we do? return everything?
+ */
+ if (target_keyfile == NULL) {
+ char *file = get_encoding_target_file ();
+ GError *error = NULL;
+
+ target_keyfile = g_key_file_new ();
+ g_key_file_set_list_separator (target_keyfile, ',');
+ g_key_file_load_from_file (target_keyfile, file, G_KEY_FILE_NONE, &error);
+ if (error != NULL) {
+ g_warning ("Unable to load encoding target keyfile %s: %s", file, error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ setting_names = g_key_file_get_string_list (target_keyfile,
+ "rhythmbox-encoder-settings",
+ gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)),
+ NULL,
+ NULL);
+ return setting_names;
+}
+
+GstElement *
+rb_gst_encoding_profile_get_encoder (GstEncodingProfile *profile)
+{
+ GstElementFactory *factory;
+
+ factory = get_audio_encoder_factory (profile);
+ if (factory == NULL) {
+ return NULL;
+ }
+
+ return gst_element_factory_create (factory, NULL);
+}
+
+char **
+rb_gst_encoding_profile_get_presets (GstEncodingProfile *profile)
+{
+ GstElement *encoder;
+ char **presets = NULL;
+
+ encoder = rb_gst_encoding_profile_get_encoder (profile);
+ if (encoder != NULL && GST_IS_PRESET (encoder)) {
+ presets = gst_preset_get_preset_names (GST_PRESET (encoder));
+ g_object_unref (encoder);
+ }
+ return presets;
+}
+
diff --git a/lib/rb-gst-media-types.h b/lib/rb-gst-media-types.h
index 836a6b3..fd1840e 100644
--- a/lib/rb-gst-media-types.h
+++ b/lib/rb-gst-media-types.h
@@ -70,6 +70,12 @@ char * rb_gst_encoding_profile_get_media_type (GstEncodingProfile *profile);
gboolean rb_gst_media_type_is_lossless (const char *media_type);
+char ** rb_gst_encoding_profile_get_settings (GstEncodingProfile *profile);
+char ** rb_gst_encoding_profile_get_presets (GstEncodingProfile *profile);
+void rb_gst_encoding_profile_set_preset (GstEncodingProfile *profile, const char *preset);
+
+GstElement * rb_gst_encoding_profile_get_encoder (GstEncodingProfile *profile);
+
G_END_DECLS
#endif /* __RB_GST_MEDIA_TYPES_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]