{"video/x-dv", "Digital Video (DV) System Stream",
FLAG_CONTAINER | FLAG_SYSTEMSTREAM, "dv"},
{"video/x-dv", "Digital Video (DV)", FLAG_VIDEO, ""},
- {"video/x-h263", NULL, FLAG_VIDEO, ""},
+ {"video/x-h263", NULL, FLAG_VIDEO, "h263"},
{"video/x-h264", NULL, FLAG_VIDEO, "h264"},
{"video/x-indeo", NULL, FLAG_VIDEO, ""},
{"video/x-msmpeg", NULL, FLAG_VIDEO, ""},
return str;
}
+/* internal helper functions for gst_encoding_profile_get_file_extension() */
+const gchar *pb_utils_get_file_extension_from_caps (const GstCaps * caps);
+gboolean pb_utils_is_tag (const GstCaps * caps);
+
+const gchar *
+pb_utils_get_file_extension_from_caps (const GstCaps * caps)
+{
+ const FormatInfo *info;
+ const gchar *ext = NULL;
+ GstCaps *stripped_caps;
+
+ g_assert (GST_IS_CAPS (caps));
+
+ stripped_caps = copy_and_clean_caps (caps);
+
+ g_assert (gst_caps_is_fixed (stripped_caps));
+
+ info = find_format_info (stripped_caps);
+
+ if (info && info->ext[0] != '\0') {
+ ext = info->ext;
+ } else if (info && info->desc == NULL) {
+ const GstStructure *s;
+
+ s = gst_caps_get_structure (stripped_caps, 0);
+
+ /* cases where we have to evaluate the caps more closely */
+ if (strcmp (info->type, "audio/mpeg") == 0) {
+ int version = 0, layer = 3;
+
+ if (gst_structure_get_int (s, "mpegversion", &version)) {
+ if (version == 2 || version == 4) {
+ ext = "aac";
+ } else if (version == 1) {
+ gst_structure_get_int (s, "layer", &layer);
+ if (layer == 1)
+ ext = "mp1";
+ else if (layer == 2)
+ ext = "mp2";
+ else
+ ext = "mp3";
+ }
+ }
+ }
+ }
+
+ gst_caps_unref (stripped_caps);
+ return ext;
+}
+
+gboolean
+pb_utils_is_tag (const GstCaps * caps)
+{
+ const FormatInfo *info;
+ GstCaps *stripped_caps;
+ gboolean is_tag = FALSE;
+
+ g_assert (GST_IS_CAPS (caps));
+
+ stripped_caps = copy_and_clean_caps (caps);
+
+ g_assert (gst_caps_is_fixed (stripped_caps));
+
+ info = find_format_info (stripped_caps);
+
+ if (info) {
+ is_tag = (info->flags & FLAG_TAG) != 0;
+ }
+ gst_caps_unref (stripped_caps);
+
+ return is_tag;
+}
+
#if 0
void
gst_pb_utils_list_all (void)
#include "encoding-profile.h"
#include "encoding-target.h"
+#include <string.h>
+
/* GstEncodingProfile API */
struct _GstEncodingProfile
return NULL;
}
+extern const gchar *pb_utils_get_file_extension_from_caps (const GstCaps *
+ caps);
+gboolean pb_utils_is_tag (const GstCaps * caps);
+
+static gboolean
+gst_encoding_profile_has_format (GstEncodingProfile * profile,
+ const gchar * media_type)
+{
+ GstCaps *caps;
+ gboolean ret;
+
+ caps = gst_encoding_profile_get_format (profile);
+ ret = gst_structure_has_name (gst_caps_get_structure (caps, 0), media_type);
+ gst_caps_unref (caps);
+
+ return ret;
+}
+
+static gboolean
+gst_encoding_container_profile_has_video (GstEncodingContainerProfile * profile)
+{
+ const GList *l;
+
+ for (l = profile->encodingprofiles; l != NULL; l = l->next) {
+ if (GST_IS_ENCODING_VIDEO_PROFILE (l->data))
+ return TRUE;
+ if (GST_IS_ENCODING_CONTAINER_PROFILE (l->data) &&
+ gst_encoding_container_profile_has_video (l->data))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * gst_encoding_profile_get_file_extension:
+ * @profile: a #GstEncodingProfile
+ *
+ * Returns: a suitable file extension for @profile, or NULL.
+ */
+const gchar *
+gst_encoding_profile_get_file_extension (GstEncodingProfile * profile)
+{
+ GstEncodingContainerProfile *cprofile;
+ const gchar *ext = NULL;
+ gboolean has_video;
+ GstCaps *caps;
+ guint num_children;
+
+ g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), NULL);
+
+ caps = gst_encoding_profile_get_format (profile);
+ ext = pb_utils_get_file_extension_from_caps (caps);
+
+ if (!GST_IS_ENCODING_CONTAINER_PROFILE (profile))
+ goto done;
+
+ cprofile = GST_ENCODING_CONTAINER_PROFILE (profile);
+
+ num_children = g_list_length (cprofile->encodingprofiles);
+
+ /* if it's a tag container profile (e.g. id3mux/apemux), we need
+ * to look at what's inside it */
+ if (pb_utils_is_tag (caps)) {
+ GST_DEBUG ("tag container profile");
+ if (num_children == 1) {
+ GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
+
+ ext = gst_encoding_profile_get_file_extension (child_profile);
+ } else {
+ GST_WARNING ("expected exactly one child profile with tag profile");
+ }
+ goto done;
+ }
+
+ /* special cases */
+ has_video = gst_encoding_container_profile_has_video (cprofile);
+
+ if (strcmp (ext, "ogg") == 0) {
+ /* ogg with video => .ogv */
+ if (has_video) {
+ ext = "ogv";
+ goto done;
+ }
+ /* ogg with just speex audio => .spx */
+ if (num_children == 1) {
+ GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
+
+ if (GST_IS_ENCODING_AUDIO_PROFILE (child_profile) &&
+ gst_encoding_profile_has_format (child_profile, "audio/x-speex")) {
+ ext = "spx";
+ goto done;
+ }
+ }
+ /* does anyone actually use .oga for ogg audio files? */
+ goto done;
+ }
+
+ if (has_video && strcmp (ext, "mka") == 0)
+ ext = "mkv";
+
+done:
+
+ GST_INFO ("caps %" GST_PTR_FORMAT ", ext: %s", caps, GST_STR_NULL (ext));
+ gst_caps_unref (caps);
+ return ext;
+}
+
/**
* gst_encoding_profile_find:
* @targetname: (transfer none): The name of the target
GstCaps * gst_encoding_profile_get_input_caps (GstEncodingProfile *profile);
const gchar * gst_encoding_profile_get_type_nick (GstEncodingProfile *profile);
+const gchar * gst_encoding_profile_get_file_extension (GstEncodingProfile * profile);
+
GstEncodingProfile * gst_encoding_profile_find (const gchar *targetname,
const gchar *profilename,
const gchar *category);
remove_profile_file ();
}
+GST_START_TEST (test_file_extension)
+{
+ GstEncodingContainerProfile *cprof;
+ GstCaps *ogg, *speex, *vorbis, *theora, *id3, *mp3;
+
+ /* 1 - ogg variants */
+ ogg = gst_caps_new_empty_simple ("application/ogg");
+ cprof = gst_encoding_container_profile_new ("myprofile", NULL, ogg, NULL);
+ gst_caps_unref (ogg);
+
+ fail_unless_equals_string (gst_encoding_profile_get_file_extension
+ (GST_ENCODING_PROFILE (cprof)), "ogg");
+
+ speex = gst_caps_new_empty_simple ("audio/x-speex");
+ gst_encoding_container_profile_add_profile (cprof,
+ (GstEncodingProfile *) gst_encoding_audio_profile_new (speex, NULL,
+ NULL, 1));
+ gst_caps_unref (speex);
+
+ fail_unless_equals_string (gst_encoding_profile_get_file_extension
+ (GST_ENCODING_PROFILE (cprof)), "spx");
+
+ vorbis = gst_caps_new_empty_simple ("audio/x-vorbis");
+ gst_encoding_container_profile_add_profile (cprof,
+ (GstEncodingProfile *) gst_encoding_audio_profile_new (vorbis, NULL,
+ NULL, 1));
+ gst_caps_unref (vorbis);
+
+ fail_unless_equals_string (gst_encoding_profile_get_file_extension
+ (GST_ENCODING_PROFILE (cprof)), "ogg");
+
+ theora = gst_caps_new_empty_simple ("video/x-theora");
+ gst_encoding_container_profile_add_profile (cprof,
+ (GstEncodingProfile *) gst_encoding_video_profile_new (theora, NULL,
+ NULL, 1));
+ gst_caps_unref (theora);
+
+ fail_unless_equals_string (gst_encoding_profile_get_file_extension
+ (GST_ENCODING_PROFILE (cprof)), "ogv");
+
+ gst_encoding_profile_unref (cprof);
+
+ /* 2 - tag container */
+ id3 = gst_caps_new_empty_simple ("application/x-id3");
+ cprof = gst_encoding_container_profile_new ("myprofile", NULL, id3, NULL);
+ gst_caps_unref (id3);
+
+ fail_unless (gst_encoding_profile_get_file_extension (GST_ENCODING_PROFILE
+ (cprof)) == NULL);
+
+ mp3 = gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 1,
+ "layer", G_TYPE_INT, 3, NULL);
+ gst_encoding_container_profile_add_profile (cprof,
+ (GstEncodingProfile *) gst_encoding_audio_profile_new (mp3, NULL,
+ NULL, 1));
+ gst_caps_unref (mp3);
+
+ fail_unless_equals_string (gst_encoding_profile_get_file_extension
+ (GST_ENCODING_PROFILE (cprof)), "mp3");
+
+ gst_encoding_profile_unref (cprof);
+}
+
+GST_END_TEST;
static Suite *
profile_suite (void)
tcase_add_test (tc_chain, test_profile_input_caps);
tcase_add_test (tc_chain, test_target_naming);
tcase_add_test (tc_chain, test_target_profile);
+ tcase_add_test (tc_chain, test_file_extension);
if (can_write) {
tcase_add_test (tc_chain, test_loading_profile);
tcase_add_test (tc_chain, test_saving_profile);
gst_encoding_profile_find
gst_encoding_profile_from_discoverer
gst_encoding_profile_get_description
+ gst_encoding_profile_get_file_extension
gst_encoding_profile_get_format
gst_encoding_profile_get_input_caps
gst_encoding_profile_get_name