[nautilus-sound-converter/gst-1-0] Add files to get audio media types support



commit ab3ed022d80b736f4f362b5e7668056c8cdd586f
Author: Brian Pepple <bpepple fedoraproject org>
Date:   Thu Aug 9 11:19:25 2012 -0700

    Add files to get audio media types support

 data/Makefile.am         |    5 +-
 data/rhythmbox.gep       |   46 +++++++
 src/Makefile.am          |    3 +-
 src/rb-gst-media-types.c |  338 ++++++++++++++++++++++++++++++++++++++++++++++
 src/rb-gst-media-types.h |   76 +++++++++++
 5 files changed, 466 insertions(+), 2 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 3b5a7d2..d1d5816 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -7,7 +7,10 @@ builderdir = $(datadir)/nautilus-sound-converter
 builder_DATA =		\
 	main.ui		\
 	progress.ui
-	
+
+profilesdir = $(datadir)/nautilus-sound-converter
+dist_profiles_DATA = rhythmbox.gep
+
 EXTRA_DIST =			\
 	$(builder_DATA)		\
 	$(schemas_in_files)
diff --git a/data/rhythmbox.gep b/data/rhythmbox.gep
new file mode 100644
index 0000000..6383d96
--- /dev/null
+++ b/data/rhythmbox.gep
@@ -0,0 +1,46 @@
+[GStreamer Encoding Target]
+name = rhythmbox
+category = muh
+description = Common encoding profiles for Rhythmbox
+
+[profile-mp3]
+name = mp3
+description = MPEG Layer 3 Audio
+format = application/x-id3
+type = container
+
+[streamprofile-mp3-1]
+parent = mp3
+type = audio
+format = audio/mpeg, mpegversion=1, layer=3
+presence = 1
+
+[profile-oggvorbis]
+name = oggvorbis
+description = Ogg Vorbis
+format = application/ogg
+type = container
+
+[streamprofile-oggvorbis-1]
+parent = oggvorbis
+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
+format = video/quicktime, variant=iso
+type = container
+
+[streamprofile-m4a-1]
+parent = m4a
+type = audio
+format = audio/mpeg, mpegversion=4, stream-format=raw
+presence = 1
diff --git a/src/Makefile.am b/src/Makefile.am
index ff98a8c..5d4ea9d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,7 +16,8 @@ libnautilus_sound_converter_la_SOURCES =		\
 	nsc-extension.c		nsc-extension.h		\
 	nsc-converter.c		nsc-converter.h		\
 	nsc-gstreamer.c		nsc-gstreamer.h		\
-	nsc-xml.c		nsc-xml.h
+	nsc-xml.c		nsc-xml.h		\
+	rb-gst-media-types.c	rb-gst-media-types.h
 
 libnautilus_sound_converter_la_LDFLAGS = -module -avoid-version
 libnautilus_sound_converter_la_LIBADD  = $(NSC_LIBS)
diff --git a/src/rb-gst-media-types.c b/src/rb-gst-media-types.c
new file mode 100644
index 0000000..8e21f00
--- /dev/null
+++ b/src/rb-gst-media-types.c
@@ -0,0 +1,338 @@
+/*
+ *  Copyright (C) 2010  Jonathan Matthew  <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#include "config.h"
+
+#define GST_USE_UNSTABLE_API
+
+#include <memory.h>
+
+#include <gst/pbutils/encoding-target.h>
+#include <gst/pbutils/missing-plugins.h>
+
+#include "rb-gst-media-types.h"
+
+#define SOURCE_ENCODING_TARGET_FILE "../data/rhythmbox.gep"
+#define INSTALLED_ENCODING_TARGET_FILE DATADIR"/nautilus-sound-converter/rhythmbox.gep"
+static GstEncodingTarget *default_target = NULL;
+
+char *
+rb_gst_caps_to_media_type (const GstCaps *caps)
+{
+	GstStructure *s;
+	const char *media_type;
+
+	/* the aim here is to reduce the caps to a single mimetype-like
+	 * string, describing the audio encoding (for audio files) or the
+	 * file type (for everything else).  raw media types are ignored.
+	 *
+	 * there are only a couple of special cases.
+	 */
+
+	if (gst_caps_get_size (caps) == 0)
+		return NULL;
+
+	s = gst_caps_get_structure (caps, 0);
+	media_type = gst_structure_get_name (s);
+	if (media_type == NULL) {
+		return NULL;
+	} else if (g_str_has_prefix (media_type, "audio/x-raw-") ||
+	    g_str_has_prefix (media_type, "video/x-raw-")) {
+		/* ignore raw types */
+		return NULL;
+	} else if (g_str_equal (media_type, "audio/mpeg")) {
+		/* need to distinguish between mpeg 1 layer 3 and
+		 * mpeg 2 or 4 here.
+		 */
+		int mpegversion = 0;
+		gst_structure_get_int (s, "mpegversion", &mpegversion);
+		switch (mpegversion) {
+		case 2:
+		case 4:
+			return g_strdup ("audio/x-aac");		/* hmm. */
+
+		case 1:
+		default:
+			return g_strdup ("audio/mpeg");
+		}
+	} else {
+		/* everything else is fine as-is */
+		return g_strdup (media_type);
+	}
+}
+
+GstCaps *
+rb_gst_media_type_to_caps (const char *media_type)
+{
+	/* special cases: */
+	if (strcmp (media_type, "audio/mpeg") == 0) {
+		return gst_caps_from_string ("audio/mpeg, mpegversion=(int)1");
+	} else if (strcmp (media_type, "audio/x-aac") == 0) {
+		return gst_caps_from_string ("audio/mpeg, mpegversion=(int){ 2, 4 }");
+	} else {
+		/* otherwise, the media type is enough */
+		return gst_caps_from_string (media_type);
+	}
+}
+
+const char *
+rb_gst_media_type_to_extension (const char *media_type)
+{
+	if (media_type == NULL) {
+		return NULL;
+	} else if (!strcmp (media_type, "audio/mpeg")) {
+		return "mp3";
+	} else if (!strcmp (media_type, "audio/x-vorbis") || !strcmp (media_type, "application/ogg")) {
+		return "ogg";
+	} else if (!strcmp (media_type, "audio/x-flac") || !strcmp (media_type, "audio/flac")) {
+		return "flac";
+	} else if (!strcmp (media_type, "audio/x-aac") || !strcmp (media_type, "audio/aac") || !strcmp (media_type, "audio/x-alac")) {
+		return "m4a";
+	} else if (!strcmp (media_type, "audio/x-wavpack")) {
+		return "wv";
+	} else {
+		return NULL;
+	}
+}
+
+const char *
+rb_gst_mime_type_to_media_type (const char *mime_type)
+{
+	if (!strcmp (mime_type, "application/x-id3") || !strcmp (mime_type, "audio/mpeg")) {
+		return "audio/mpeg";
+	} else if (!strcmp (mime_type, "application/ogg") || !strcmp (mime_type, "audio/x-vorbis")) {
+		return "audio/x-vorbis";
+	} else if (!strcmp (mime_type, "audio/flac")) {
+		return "audio/x-flac";
+	} else if (!strcmp (mime_type, "audio/aac") || !strcmp (mime_type, "audio/mp4") || !strcmp (mime_type, "audio/m4a")) {
+		return "audio/x-aac";
+	}
+	return mime_type;
+}
+
+const char *
+rb_gst_media_type_to_mime_type (const char *media_type)
+{
+	if (!strcmp (media_type, "audio/x-vorbis")) {
+		return "application/ogg";
+	} else if (!strcmp (media_type, "audio/x-flac")) {
+		return "audio/flac";
+	} else if (!strcmp (media_type, "audio/x-aac")) {
+		return "audio/mp4";	/* probably */
+	} else {
+		return media_type;
+	}
+}
+
+gboolean
+rb_gst_media_type_matches_profile (GstEncodingProfile *profile, const char *media_type)
+{
+	const GstCaps *pcaps;
+	const GList *cl;
+	GstCaps *caps;
+	gboolean matches = FALSE;
+
+	caps = rb_gst_media_type_to_caps (media_type);
+	if (caps == NULL) {
+		return FALSE;
+	}
+
+	pcaps = gst_encoding_profile_get_format (profile);
+	if (gst_caps_can_intersect (caps, pcaps)) {
+		matches = TRUE;
+	}
+
+	if (matches == FALSE && GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
+		for (cl = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile)); cl != NULL; cl = cl->next) {
+			GstEncodingProfile *cp = cl->data;
+			pcaps = gst_encoding_profile_get_format (cp);
+			if (gst_caps_can_intersect (caps, pcaps)) {
+				matches = TRUE;
+				break;
+			}
+		}
+	}
+	return matches;
+}
+
+char *
+rb_gst_encoding_profile_get_media_type (GstEncodingProfile *profile)
+{
+	if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
+		const GList *cl = gst_encoding_container_profile_get_profiles (GST_ENCODING_CONTAINER_PROFILE (profile));
+		for (; cl != NULL; cl = cl->next) {
+			GstEncodingProfile *p = cl->data;
+			if (GST_IS_ENCODING_AUDIO_PROFILE (p)) {
+				return rb_gst_caps_to_media_type (gst_encoding_profile_get_format (p));
+			}
+
+		}
+
+		/* now what? */
+		return NULL;
+	} else {
+		return rb_gst_caps_to_media_type (gst_encoding_profile_get_format (profile));
+	}
+}
+
+GstEncodingTarget *
+rb_gst_get_default_encoding_target ()
+{
+	if (default_target == NULL) {
+		char *target_file;
+		GError *error = NULL;
+
+		if (g_file_test (SOURCE_ENCODING_TARGET_FILE,
+			         G_FILE_TEST_EXISTS) != FALSE) {
+			target_file = SOURCE_ENCODING_TARGET_FILE;
+		} else {
+			target_file = INSTALLED_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);
+			return NULL;
+		}
+	}
+
+	return default_target;
+}
+
+GstEncodingProfile *
+rb_gst_get_encoding_profile (const char *media_type)
+{
+	const GList *l;
+	GstEncodingTarget *target;
+	target = rb_gst_get_default_encoding_target ();
+
+	for (l = gst_encoding_target_get_profiles (target); l != NULL; l = l->next) {
+		GstEncodingProfile *profile = l->data;
+		if (rb_gst_media_type_matches_profile (profile, media_type)) {
+			gst_encoding_profile_ref (profile);
+			return profile;
+		}
+	}
+
+	return NULL;
+}
+
+gboolean
+rb_gst_media_type_is_lossless (const char *media_type)
+{
+	int i;
+	const char *lossless_types[] = {
+		"audio/x-flac",
+		"audio/x-alac",
+		"audio/x-shorten",
+		"audio/x-wavpack"	/* not completely sure */
+	};
+
+	for (i = 0; i < G_N_ELEMENTS (lossless_types); i++) {
+		if (strcmp (media_type, lossless_types[i]) == 0) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+gboolean
+rb_gst_check_missing_plugins (GstEncodingProfile *profile,
+			      char ***details,
+			      char ***descriptions)
+{
+	GstElement *encodebin;
+	GstBus *bus;
+	GstPad *pad;
+	gboolean ret;
+
+	ret = FALSE;
+
+	encodebin = gst_element_factory_make ("encodebin", NULL);
+	if (encodebin == NULL) {
+		g_warning ("Unable to create encodebin");
+		return TRUE;
+	}
+
+	bus = gst_bus_new ();
+	gst_element_set_bus (encodebin, bus);
+	gst_bus_set_flushing (bus, FALSE);		/* necessary? */
+
+	g_object_set (encodebin, "profile", profile, NULL);
+	pad = gst_element_get_static_pad (encodebin, "audio_0");
+	if (pad == NULL) {
+		GstMessage *message;
+		GList *messages = NULL;
+		GList *m;
+		int i;
+
+		message = gst_bus_pop (bus);
+		while (message != NULL) {
+			if (gst_is_missing_plugin_message (message)) {
+				messages = g_list_append (messages, message);
+			} else {
+				gst_message_unref (message);
+			}
+			message = gst_bus_pop (bus);
+		}
+
+		if (messages != NULL) {
+			if (details != NULL) {
+				*details = g_new0(char *, g_list_length (messages)+1);
+			}
+			if (descriptions != NULL) {
+				*descriptions = g_new0(char *, g_list_length (messages)+1);
+			}
+			i = 0;
+			for (m = messages; m != NULL; m = m->next) {
+				char *str;
+				if (details != NULL) {
+					str = gst_missing_plugin_message_get_installer_detail (m->data);
+					(*details)[i] = str;
+				}
+				if (descriptions != NULL) {
+					str = gst_missing_plugin_message_get_description (m->data);
+					(*descriptions)[i] = str;
+				}
+				i++;
+			}
+
+			ret = TRUE;
+			g_list_foreach (messages, (GFunc)gst_message_unref, NULL);
+			g_list_free (messages);
+		}
+
+	} else {
+		gst_element_release_request_pad (encodebin, pad);
+		gst_object_unref (pad);
+	}
+
+	gst_object_unref (encodebin);
+	gst_object_unref (bus);
+	return ret;
+}
diff --git a/src/rb-gst-media-types.h b/src/rb-gst-media-types.h
new file mode 100644
index 0000000..9211361
--- /dev/null
+++ b/src/rb-gst-media-types.h
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 2010  Jonathan Matthew <jonathan d14n org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  The Rhythmbox authors hereby grant permission for non-GPL compatible
+ *  GStreamer plugins to be used and distributed together with GStreamer
+ *  and Rhythmbox. This permission is above and beyond the permissions granted
+ *  by the GPL license by which Rhythmbox is covered. If you modify this code
+ *  you may extend this exception to your version of the code, but you are not
+ *  obligated to do so. If you do not wish to do so, delete this exception
+ *  statement from your version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
+ *
+ */
+
+#ifndef __RB_GST_MEDIA_TYPES_H
+#define __RB_GST_MEDIA_TYPES_H
+
+#include <gst/gst.h>
+#include <gst/pbutils/encoding-target.h>
+#include <gst/pbutils/encoding-profile.h>
+
+G_BEGIN_DECLS
+
+/* some common media types */
+#define RB_GST_MEDIA_TYPE_MP3		"audio/mpeg"
+#define RB_GST_MEDIA_TYPE_OGG_VORBIS 	"audio/x-vorbis"
+#define RB_GST_MEDIA_TYPE_FLAC 		"audio/x-flac"
+#define RB_GST_MEDIA_TYPE_AAC 		"audio/x-aac"
+
+/* media type categories */
+typedef enum {
+	MEDIA_TYPE_NONE = 0,
+	MEDIA_TYPE_CONTAINER,
+	MEDIA_TYPE_AUDIO,
+	MEDIA_TYPE_VIDEO,
+	MEDIA_TYPE_OTHER
+} RBGstMediaType;
+
+char *		rb_gst_caps_to_media_type (const GstCaps *caps);
+GstCaps *	rb_gst_media_type_to_caps (const char *media_type);
+
+const char *	rb_gst_media_type_to_extension (const char *media_type);
+
+const char *	rb_gst_mime_type_to_media_type (const char *mime_type);
+
+const char *	rb_gst_media_type_to_mime_type (const char *media_type);
+
+GstEncodingTarget *rb_gst_get_default_encoding_target (void);
+
+GstEncodingProfile *rb_gst_get_encoding_profile (const char *media_type);
+
+gboolean	rb_gst_media_type_matches_profile (GstEncodingProfile *profile, const char *media_type);
+
+char *		rb_gst_encoding_profile_get_media_type (GstEncodingProfile *profile);
+
+gboolean	rb_gst_media_type_is_lossless (const char *media_type);
+gboolean	rb_gst_check_missing_plugins (GstEncodingProfile *profile,
+					      char ***details,
+					      char ***descriptions);
+
+G_END_DECLS
+
+#endif /* __RB_GST_MEDIA_TYPES_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]