mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
encoding-profile: add gst_encoding_profile_get_file_extension()
API: gst_encoding_profile_get_file_extension() https://bugzilla.gnome.org/show_bug.cgi?id=636753
This commit is contained in:
parent
76c0cca765
commit
42f971c5eb
5 changed files with 252 additions and 1 deletions
|
@ -300,7 +300,7 @@ static const FormatInfo formats[] = {
|
|||
{"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, ""},
|
||||
|
@ -1028,6 +1028,79 @@ gst_pb_utils_get_codec_description (const GstCaps * caps)
|
|||
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)
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
#include "encoding-profile.h"
|
||||
#include "encoding-target.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* GstEncodingProfile API */
|
||||
|
||||
struct _GstEncodingProfile
|
||||
|
@ -902,6 +904,114 @@ gst_encoding_profile_get_type_nick (GstEncodingProfile * profile)
|
|||
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
|
||||
|
|
|
@ -143,6 +143,8 @@ gboolean gst_encoding_profile_is_equal (GstEncodingProfile *a,
|
|||
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);
|
||||
|
|
|
@ -605,6 +605,70 @@ test_teardown (void)
|
|||
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)
|
||||
|
@ -625,6 +689,7 @@ 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);
|
||||
|
|
|
@ -78,6 +78,7 @@ EXPORTS
|
|||
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
|
||||
|
|
Loading…
Reference in a new issue