1 /* GStreamer encoding profiles library
2 * Copyright (C) 2009-2010 Edward Hervey <edward.hervey@collabora.co.uk>
3 * (C) 2009-2010 Nokia Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
22 * SECTION:encoding-profile
23 * @short_description: Encoding profile library
27 * Functions to create and handle encoding profiles.
30 * Encoding profiles describe the media types and settings one wishes to use for
31 * an encoding process. The top-level profiles are commonly
32 * #GstEncodingContainerProfile(s) (which contains a user-readable name and
33 * description along with which container format to use). These, in turn,
34 * reference one or more #GstEncodingProfile(s) which indicate which encoding
35 * format should be used on each individual streams.
38 * #GstEncodingProfile(s) can be provided to the 'encodebin' element, which will take
39 * care of selecting and setting up the required elements to produce an output stream
40 * conforming to the specifications of the profile.
43 * Unlike other systems, the encoding profiles do not specify which #GstElement to use
44 * for the various encoding and muxing steps, but instead relies on specifying the format
48 * Encoding profiles can be created at runtime by the application or loaded from (and saved
49 * to) file using the #GstEncodingTarget API.
53 * <title>Example: Creating a profile</title>
56 * #include <gst/pbutils/encoding-profile.h>
58 * GstEncodingProfile *
59 * create_ogg_theora_profile(void)
61 * GstEncodingContainerProfile *prof;
64 * caps = gst_caps_from_string("application/ogg");
65 * prof = gst_encoding_container_profile_new("Ogg audio/video",
66 * "Standard OGG/THEORA/VORBIS",
68 * gst_caps_unref (caps);
70 * caps = gst_caps_from_string("video/x-theora");
71 * gst_encoding_container_profile_add_profile(prof,
72 * (GstEncodingProfile*) gst_encoding_video_profile_new(caps, NULL, NULL, 0));
73 * gst_caps_unref (caps);
75 * caps = gst_caps_from_string("audio/x-vorbis");
76 * gst_encoding_container_profile_add_profile(prof,
77 * (GstEncodingProfile*) gst_encoding_audio_profile_new(caps, NULL, NULL, 0));
78 * gst_caps_unref (caps);
80 * return (GstEncodingProfile*) prof;
88 * <title>Example: Listing categories, targets and profiles</title>
91 * #include <gst/pbutils/encoding-profile.h>
93 * GstEncodingProfile *prof;
94 * GList *categories, *tmpc;
95 * GList *targets, *tmpt;
97 * categories = gst_encoding_target_list_available_categories();
99 * ... Show available categories to user ...
101 * for (tmpc = categories; tmpc; tmpc = tmpc->next) {
102 * gchar *category = (gchar *) tmpc->data;
104 * ... and we can list all targets within that category ...
106 * targets = gst_encoding_target_list_all (category);
108 * ... and show a list to our users ...
110 * g_list_foreach (targets, (GFunc) gst_encoding_target_unref, NULL);
111 * g_list_free (targets);
114 * g_list_foreach (categories, (GFunc) g_free, NULL);
115 * g_list_free (categories);
127 #include "encoding-profile.h"
128 #include "encoding-target.h"
132 /* GstEncodingProfile API */
134 struct _GstEncodingProfile
145 GstCaps *restriction;
148 struct _GstEncodingProfileClass
150 GObjectClass parent_class;
153 static void string_to_profile_transform (const GValue * src_value,
154 GValue * dest_value);
155 static gboolean gst_encoding_profile_deserialize_valfunc (GValue * value,
158 static void gst_encoding_profile_class_init (GstEncodingProfileClass * klass);
159 static gpointer gst_encoding_profile_parent_class = NULL;
162 gst_encoding_profile_class_intern_init (gpointer klass)
164 gst_encoding_profile_parent_class = g_type_class_peek_parent (klass);
165 gst_encoding_profile_class_init ((GstEncodingProfileClass *) klass);
169 gst_encoding_profile_get_type (void)
171 static volatile gsize g_define_type_id__volatile = 0;
173 if (g_once_init_enter (&g_define_type_id__volatile)) {
174 GType g_define_type_id = g_type_register_static_simple (G_TYPE_OBJECT,
175 g_intern_static_string ("GstEncodingProfile"),
176 sizeof (GstEncodingProfileClass),
177 (GClassInitFunc) gst_encoding_profile_class_intern_init,
178 sizeof (GstEncodingProfile),
181 static GstValueTable gstvtable = {
183 (GstValueCompareFunc) NULL,
184 (GstValueSerializeFunc) NULL,
185 (GstValueDeserializeFunc) gst_encoding_profile_deserialize_valfunc
188 gstvtable.type = g_define_type_id;
190 /* Register a STRING=>PROFILE GValueTransformFunc */
191 g_value_register_transform_func (G_TYPE_STRING, g_define_type_id,
192 string_to_profile_transform);
193 /* Register gst-specific GValue functions */
194 gst_value_register (&gstvtable);
196 g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
198 return g_define_type_id__volatile;
202 gst_encoding_profile_finalize (GObject * object)
204 GstEncodingProfile *prof = (GstEncodingProfile *) object;
208 gst_caps_unref (prof->format);
210 g_free (prof->preset);
211 if (prof->description)
212 g_free (prof->description);
213 if (prof->restriction)
214 gst_caps_unref (prof->restriction);
218 gst_encoding_profile_class_init (GstEncodingProfileClass * klass)
220 GObjectClass *gobject_class = (GObjectClass *) klass;
222 gobject_class->finalize = gst_encoding_profile_finalize;
226 * gst_encoding_profile_get_name:
227 * @profile: a #GstEncodingProfile
229 * Returns: the name of the profile, can be %NULL.
232 gst_encoding_profile_get_name (GstEncodingProfile * profile)
234 return profile->name;
238 * gst_encoding_profile_get_description:
239 * @profile: a #GstEncodingProfile
241 * Returns: the description of the profile, can be %NULL.
244 gst_encoding_profile_get_description (GstEncodingProfile * profile)
246 return profile->description;
250 * gst_encoding_profile_get_format:
251 * @profile: a #GstEncodingProfile
253 * Returns: (transfer full): the #GstCaps corresponding to the media format used
254 * in the profile. Unref after usage.
257 gst_encoding_profile_get_format (GstEncodingProfile * profile)
259 return (profile->format ? gst_caps_ref (profile->format) : NULL);
263 * gst_encoding_profile_get_preset:
264 * @profile: a #GstEncodingProfile
266 * Returns: the name of the #GstPreset to be used in the profile.
267 * This is the name that has been set when saving the preset.
270 gst_encoding_profile_get_preset (GstEncodingProfile * profile)
272 return profile->preset;
276 * gst_encoding_profile_get_preset_name:
277 * @profile: a #GstEncodingProfile
279 * Returns: the name of the #GstPreset factory to be used in the profile.
282 gst_encoding_profile_get_preset_name (GstEncodingProfile * profile)
284 return profile->preset_name;
288 * gst_encoding_profile_get_presence:
289 * @profile: a #GstEncodingProfile
291 * Returns: The number of times the profile is used in its parent
292 * container profile. If 0, it is not a mandatory stream.
295 gst_encoding_profile_get_presence (GstEncodingProfile * profile)
297 return profile->presence;
301 * gst_encoding_profile_get_restriction:
302 * @profile: a #GstEncodingProfile
304 * Returns: (transfer full): The restriction #GstCaps to apply before the encoder
305 * that will be used in the profile. The fields present in restriction caps are
306 * properties of the raw stream (that is before encoding), such as height and
307 * width for video and depth and sampling rate for audio. Does not apply to
308 * #GstEncodingContainerProfile (since there is no corresponding raw stream).
309 * Can be %NULL. Unref after usage.
312 gst_encoding_profile_get_restriction (GstEncodingProfile * profile)
314 return (profile->restriction ? gst_caps_ref (profile->restriction) : NULL);
318 * gst_encoding_profile_set_name:
319 * @profile: a #GstEncodingProfile
320 * @name: the name to set on the profile
322 * Set @name as the given name for the @profile. A copy of @name will be made
326 gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name)
329 g_free (profile->name);
330 profile->name = g_strdup (name);
334 * gst_encoding_profile_set_description:
335 * @profile: a #GstEncodingProfile
336 * @description: the description to set on the profile
338 * Set @description as the given description for the @profile. A copy of
339 * @description will be made internally.
342 gst_encoding_profile_set_description (GstEncodingProfile * profile,
343 const gchar * description)
345 if (profile->description)
346 g_free (profile->description);
347 profile->description = g_strdup (description);
351 * gst_encoding_profile_set_format:
352 * @profile: a #GstEncodingProfile
353 * @format: the media format to use in the profile.
355 * Sets the media format used in the profile.
358 gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format)
361 gst_caps_unref (profile->format);
362 profile->format = gst_caps_ref (format);
366 * gst_encoding_profile_set_preset:
367 * @profile: a #GstEncodingProfile
368 * @preset: the element preset to use
370 * Sets the name of the #GstElement that implements the #GstPreset interface
371 * to use for the profile.
372 * This is the name that has been set when saving the preset.
375 gst_encoding_profile_set_preset (GstEncodingProfile * profile,
376 const gchar * preset)
379 g_free (profile->preset);
380 profile->preset = g_strdup (preset);
384 * gst_encoding_profile_get_preset_name:
385 * @profile: a #GstEncodingProfile
386 * @preset_name: The name of the preset to use in this @profile.
388 * Sets the name of the #GstPreset's factory to be used in the profile.
391 gst_encoding_profile_set_preset_name (GstEncodingProfile * profile,
392 const gchar * preset_name)
394 if (profile->preset_name)
395 g_free (profile->preset_name);
396 profile->preset_name = g_strdup (preset_name);
400 * gst_encoding_profile_set_presence:
401 * @profile: a #GstEncodingProfile
402 * @presence: the number of time the profile can be used
404 * Set the number of time the profile is used in its parent
405 * container profile. If 0, it is not a mandatory stream
408 gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence)
410 profile->presence = presence;
414 * gst_encoding_profile_set_restriction:
415 * @profile: a #GstEncodingProfile
416 * @restriction: (transfer full): the restriction to apply
418 * Set the restriction #GstCaps to apply before the encoder
419 * that will be used in the profile. See gst_encoding_profile_set_restriction()
420 * for more about restrictions. Does not apply to #GstEncodingContainerProfile.
423 gst_encoding_profile_set_restriction (GstEncodingProfile * profile,
424 GstCaps * restriction)
426 if (profile->restriction)
427 gst_caps_unref (profile->restriction);
428 profile->restriction = restriction;
431 /* Container profiles */
433 struct _GstEncodingContainerProfile
435 GstEncodingProfile parent;
437 GList *encodingprofiles;
440 struct _GstEncodingContainerProfileClass
442 GstEncodingProfileClass parent;
445 G_DEFINE_TYPE (GstEncodingContainerProfile, gst_encoding_container_profile,
446 GST_TYPE_ENCODING_PROFILE);
449 gst_encoding_container_profile_init (GstEncodingContainerProfile * prof)
451 /* Nothing to initialize */
455 gst_encoding_container_profile_finalize (GObject * object)
457 GstEncodingContainerProfile *prof = (GstEncodingContainerProfile *) object;
459 g_list_foreach (prof->encodingprofiles, (GFunc) g_object_unref, NULL);
460 g_list_free (prof->encodingprofiles);
462 G_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize
467 gst_encoding_container_profile_class_init (GstEncodingContainerProfileClass * k)
469 GObjectClass *gobject_class = (GObjectClass *) k;
471 gobject_class->finalize = gst_encoding_container_profile_finalize;
475 * gst_encoding_container_profile_get_profiles:
476 * @profile: a #GstEncodingContainerProfile
478 * Returns: (element-type GstPbutils.EncodingProfile) (transfer none):
479 * the list of contained #GstEncodingProfile.
482 gst_encoding_container_profile_get_profiles (GstEncodingContainerProfile *
485 return profile->encodingprofiles;
490 struct _GstEncodingVideoProfile
492 GstEncodingProfile parent;
495 gboolean variableframerate;
498 struct _GstEncodingVideoProfileClass
500 GstEncodingProfileClass parent;
503 G_DEFINE_TYPE (GstEncodingVideoProfile, gst_encoding_video_profile,
504 GST_TYPE_ENCODING_PROFILE);
507 gst_encoding_video_profile_init (GstEncodingVideoProfile * prof)
509 /* Nothing to initialize */
513 gst_encoding_video_profile_class_init (GstEncodingVideoProfileClass * klass)
518 * gst_encoding_video_profile_get_pass:
519 * @prof: a #GstEncodingVideoProfile
521 * Get the pass number if this is part of a multi-pass profile.
523 * Returns: The pass number. Starts at 1 for multi-pass. 0 if this is
524 * not a multi-pass profile
527 gst_encoding_video_profile_get_pass (GstEncodingVideoProfile * prof)
533 * gst_encoding_video_profile_get_variableframerate:
534 * @prof: a #GstEncodingVideoProfile
536 * Returns: Whether non-constant video framerate is allowed for encoding.
539 gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile *
542 return prof->variableframerate;
546 * gst_encoding_video_profile_set_pass:
547 * @prof: a #GstEncodingVideoProfile
548 * @pass: the pass number for this profile
550 * Sets the pass number of this video profile. The first pass profile should have
551 * this value set to 1. If this video profile isn't part of a multi-pass profile,
552 * you may set it to 0 (the default value).
555 gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass)
561 * gst_encoding_video_profile_set_variableframerate:
562 * @prof: a #GstEncodingVideoProfile
563 * @variableframerate: a boolean
565 * If set to %TRUE, then the incoming stream will be allowed to have non-constant
566 * framerate. If set to %FALSE (default value), then the incoming stream will
567 * be normalized by dropping/duplicating frames in order to produce a
568 * constance framerate.
571 gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *
572 prof, gboolean variableframerate)
574 prof->variableframerate = variableframerate;
579 struct _GstEncodingAudioProfile
581 GstEncodingProfile parent;
584 struct _GstEncodingAudioProfileClass
586 GstEncodingProfileClass parent;
589 G_DEFINE_TYPE (GstEncodingAudioProfile, gst_encoding_audio_profile,
590 GST_TYPE_ENCODING_PROFILE);
593 gst_encoding_audio_profile_init (GstEncodingAudioProfile * prof)
595 /* Nothing to initialize */
599 gst_encoding_audio_profile_class_init (GstEncodingAudioProfileClass * klass)
603 static inline gboolean
604 _gst_caps_is_equal_safe (GstCaps * a, GstCaps * b)
608 if ((a == NULL) || (b == NULL))
610 return gst_caps_is_equal (a, b);
614 _compare_container_encoding_profiles (GstEncodingContainerProfile * ca,
615 GstEncodingContainerProfile * cb)
619 if (g_list_length (ca->encodingprofiles) !=
620 g_list_length (cb->encodingprofiles))
623 for (tmp = ca->encodingprofiles; tmp; tmp = tmp->next) {
624 GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data;
625 if (!gst_encoding_container_profile_contains_profile (ca, prof))
633 _compare_encoding_profiles (const GstEncodingProfile * a,
634 const GstEncodingProfile * b)
636 if ((G_TYPE_FROM_INSTANCE (a) != G_TYPE_FROM_INSTANCE (b)) ||
637 !_gst_caps_is_equal_safe (a->format, b->format) ||
638 (g_strcmp0 (a->preset, b->preset) != 0) ||
639 (g_strcmp0 (a->name, b->name) != 0) ||
640 (g_strcmp0 (a->description, b->description) != 0))
643 if (GST_IS_ENCODING_CONTAINER_PROFILE (a))
645 _compare_container_encoding_profiles (GST_ENCODING_CONTAINER_PROFILE
646 (a), GST_ENCODING_CONTAINER_PROFILE (b));
648 if (GST_IS_ENCODING_VIDEO_PROFILE (a)) {
649 GstEncodingVideoProfile *va = (GstEncodingVideoProfile *) a;
650 GstEncodingVideoProfile *vb = (GstEncodingVideoProfile *) b;
652 if ((va->pass != vb->pass)
653 || (va->variableframerate != vb->variableframerate))
661 * gst_encoding_container_profile_contains_profile:
662 * @container: a #GstEncodingContainerProfile
663 * @profile: a #GstEncodingProfile
665 * Checks if @container contains a #GstEncodingProfile identical to
668 * Returns: %TRUE if @container contains a #GstEncodingProfile identical
669 * to @profile, else %FALSE.
672 gst_encoding_container_profile_contains_profile (GstEncodingContainerProfile *
673 container, GstEncodingProfile * profile)
675 g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
676 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
678 return (g_list_find_custom (container->encodingprofiles, profile,
679 (GCompareFunc) _compare_encoding_profiles) != NULL);
683 * gst_encoding_container_profile_add_profile:
684 * @container: the #GstEncodingContainerProfile to use
685 * @profile: (transfer full): the #GstEncodingProfile to add.
687 * Add a #GstEncodingProfile to the list of profiles handled by @container.
689 * No copy of @profile will be made, if you wish to use it elsewhere after this
690 * method you should increment its reference count.
692 * Returns: %TRUE if the @stream was properly added, else %FALSE.
695 gst_encoding_container_profile_add_profile (GstEncodingContainerProfile *
696 container, GstEncodingProfile * profile)
698 g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
699 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
701 if (g_list_find_custom (container->encodingprofiles, profile,
702 (GCompareFunc) _compare_encoding_profiles)) {
704 ("Encoding profile already contains an identical GstEncodingProfile");
708 container->encodingprofiles =
709 g_list_append (container->encodingprofiles, profile);
714 static GstEncodingProfile *
715 common_creation (GType objtype, GstCaps * format, const gchar * preset,
716 const gchar * name, const gchar * description, GstCaps * restriction,
719 GstEncodingProfile *prof;
721 prof = (GstEncodingProfile *) g_object_new (objtype, NULL);
724 prof->name = g_strdup (name);
726 prof->description = g_strdup (description);
728 prof->preset = g_strdup (preset);
730 prof->format = gst_caps_ref (format);
732 prof->restriction = gst_caps_ref (restriction);
733 prof->presence = presence;
734 prof->preset_name = NULL;
740 * gst_encoding_container_profile_new:
741 * @name: (allow-none): The name of the container profile, can be %NULL
742 * @description: (allow-none): The description of the container profile,
744 * @format: The format to use for this profile
745 * @preset: (allow-none): The preset to use for this profile.
747 * Creates a new #GstEncodingContainerProfile.
749 * Returns: The newly created #GstEncodingContainerProfile.
751 GstEncodingContainerProfile *
752 gst_encoding_container_profile_new (const gchar * name,
753 const gchar * description, GstCaps * format, const gchar * preset)
755 g_return_val_if_fail (GST_IS_CAPS (format), NULL);
757 return (GstEncodingContainerProfile *)
758 common_creation (GST_TYPE_ENCODING_CONTAINER_PROFILE, format, preset,
759 name, description, NULL, 0);
763 * gst_encoding_video_profile_new:
764 * @format: the #GstCaps
765 * @preset: (allow-none): the preset(s) to use on the encoder, can be #NULL
766 * @restriction: (allow-none): the #GstCaps used to restrict the input to the encoder, can be
767 * NULL. See gst_encoding_profile_get_restriction() for more details.
768 * @presence: the number of time this stream must be used. 0 means any number of
769 * times (including never)
771 * Creates a new #GstEncodingVideoProfile
773 * All provided allocatable arguments will be internally copied, so can be
774 * safely freed/unreferenced after calling this method.
776 * If you wish to control the pass number (in case of multi-pass scenarios),
777 * please refer to the gst_encoding_video_profile_set_pass() documentation.
779 * If you wish to use/force a constant framerate please refer to the
780 * gst_encoding_video_profile_set_variableframerate() documentation.
782 * Returns: the newly created #GstEncodingVideoProfile.
784 GstEncodingVideoProfile *
785 gst_encoding_video_profile_new (GstCaps * format, const gchar * preset,
786 GstCaps * restriction, guint presence)
788 return (GstEncodingVideoProfile *)
789 common_creation (GST_TYPE_ENCODING_VIDEO_PROFILE, format, preset, NULL,
790 NULL, restriction, presence);
794 * gst_encoding_audio_profile_new:
795 * @format: the #GstCaps
796 * @preset: (allow-none): the preset(s) to use on the encoder, can be #NULL
797 * @restriction: (allow-none): the #GstCaps used to restrict the input to the encoder, can be
798 * NULL. See gst_encoding_profile_get_restriction() for more details.
799 * @presence: the number of time this stream must be used. 0 means any number of
800 * times (including never)
802 * Creates a new #GstEncodingAudioProfile
804 * All provided allocatable arguments will be internally copied, so can be
805 * safely freed/unreferenced after calling this method.
807 * Returns: the newly created #GstEncodingAudioProfile.
809 GstEncodingAudioProfile *
810 gst_encoding_audio_profile_new (GstCaps * format, const gchar * preset,
811 GstCaps * restriction, guint presence)
813 return (GstEncodingAudioProfile *)
814 common_creation (GST_TYPE_ENCODING_AUDIO_PROFILE, format, preset, NULL,
815 NULL, restriction, presence);
820 * gst_encoding_profile_is_equal:
821 * @a: a #GstEncodingProfile
822 * @b: a #GstEncodingProfile
824 * Checks whether the two #GstEncodingProfile are equal
826 * Returns: %TRUE if @a and @b are equal, else %FALSE.
829 gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b)
831 return (_compare_encoding_profiles (a, b) == 0);
836 * gst_encoding_profile_get_input_caps:
837 * @profile: a #GstEncodingProfile
839 * Computes the full output caps that this @profile will be able to consume.
841 * Returns: (transfer full): The full caps the given @profile can consume. Call
842 * gst_caps_unref() when you are done with the caps.
845 gst_encoding_profile_get_input_caps (GstEncodingProfile * profile)
849 GstStructure *st, *outst;
854 if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
855 GstCaps *res = gst_caps_new_empty ();
857 for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles;
858 ltmp; ltmp = ltmp->next) {
859 GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data;
860 res = gst_caps_merge (res, gst_encoding_profile_get_input_caps (sprof));
865 fcaps = profile->format;
868 if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction))
869 return gst_caps_ref (fcaps);
871 /* Combine the format with the restriction caps */
872 outst = gst_caps_get_structure (fcaps, 0);
873 out_name = gst_structure_get_name_id (outst);
874 tmp = gst_caps_new_empty ();
875 len = gst_caps_get_size (profile->restriction);
877 for (i = 0; i < len; i++) {
878 st = gst_structure_copy (gst_caps_get_structure (profile->restriction, i));
880 gst_caps_append_structure (tmp, st);
883 out = gst_caps_intersect (tmp, fcaps);
884 gst_caps_unref (tmp);
890 * gst_encoding_profile_get_type_nick:
891 * @profile: a #GstEncodingProfile
893 * Returns: the human-readable name of the type of @profile.
896 gst_encoding_profile_get_type_nick (GstEncodingProfile * profile)
898 if (GST_IS_ENCODING_CONTAINER_PROFILE (profile))
900 if (GST_IS_ENCODING_VIDEO_PROFILE (profile))
902 if (GST_IS_ENCODING_AUDIO_PROFILE (profile))
907 extern const gchar *pb_utils_get_file_extension_from_caps (const GstCaps *
909 gboolean pb_utils_is_tag (const GstCaps * caps);
912 gst_encoding_profile_has_format (GstEncodingProfile * profile,
913 const gchar * media_type)
918 caps = gst_encoding_profile_get_format (profile);
919 ret = gst_structure_has_name (gst_caps_get_structure (caps, 0), media_type);
920 gst_caps_unref (caps);
926 gst_encoding_container_profile_has_video (GstEncodingContainerProfile * profile)
930 for (l = profile->encodingprofiles; l != NULL; l = l->next) {
931 if (GST_IS_ENCODING_VIDEO_PROFILE (l->data))
933 if (GST_IS_ENCODING_CONTAINER_PROFILE (l->data) &&
934 gst_encoding_container_profile_has_video (l->data))
942 * gst_encoding_profile_get_file_extension:
943 * @profile: a #GstEncodingProfile
945 * Returns: a suitable file extension for @profile, or NULL.
948 gst_encoding_profile_get_file_extension (GstEncodingProfile * profile)
950 GstEncodingContainerProfile *cprofile;
951 const gchar *ext = NULL;
956 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), NULL);
958 caps = gst_encoding_profile_get_format (profile);
959 ext = pb_utils_get_file_extension_from_caps (caps);
961 if (!GST_IS_ENCODING_CONTAINER_PROFILE (profile))
964 cprofile = GST_ENCODING_CONTAINER_PROFILE (profile);
966 num_children = g_list_length (cprofile->encodingprofiles);
968 /* if it's a tag container profile (e.g. id3mux/apemux), we need
969 * to look at what's inside it */
970 if (pb_utils_is_tag (caps)) {
971 GST_DEBUG ("tag container profile");
972 if (num_children == 1) {
973 GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
975 ext = gst_encoding_profile_get_file_extension (child_profile);
977 GST_WARNING ("expected exactly one child profile with tag profile");
983 has_video = gst_encoding_container_profile_has_video (cprofile);
985 if (strcmp (ext, "ogg") == 0) {
986 /* ogg with video => .ogv */
991 /* ogg with just speex audio => .spx */
992 if (num_children == 1) {
993 GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
995 if (GST_IS_ENCODING_AUDIO_PROFILE (child_profile) &&
996 gst_encoding_profile_has_format (child_profile, "audio/x-speex")) {
1001 /* does anyone actually use .oga for ogg audio files? */
1005 if (has_video && strcmp (ext, "mka") == 0)
1010 GST_INFO ("caps %" GST_PTR_FORMAT ", ext: %s", caps, GST_STR_NULL (ext));
1011 gst_caps_unref (caps);
1016 * gst_encoding_profile_find:
1017 * @targetname: (transfer none): The name of the target
1018 * @profilename: (transfer none): The name of the profile
1019 * @category: (transfer none) (allow-none): The target category. Can be %NULL
1021 * Find the #GstEncodingProfile with the specified name and category.
1023 * Returns: (transfer full): The matching #GstEncodingProfile or %NULL.
1025 GstEncodingProfile *
1026 gst_encoding_profile_find (const gchar * targetname, const gchar * profilename,
1027 const gchar * category)
1029 GstEncodingProfile *res = NULL;
1030 GstEncodingTarget *target;
1032 g_return_val_if_fail (targetname != NULL, NULL);
1033 g_return_val_if_fail (profilename != NULL, NULL);
1035 /* FIXME : how do we handle profiles named the same in several
1036 * categories but of which only one has the required profile ? */
1037 target = gst_encoding_target_load (targetname, category, NULL);
1039 res = gst_encoding_target_get_profile (target, profilename);
1040 gst_encoding_target_unref (target);
1046 static GstEncodingProfile *
1047 combo_search (const gchar * pname)
1049 GstEncodingProfile *res;
1053 split = g_strsplit (pname, "/", 2);
1054 if (g_strv_length (split) != 2)
1057 res = gst_encoding_profile_find (split[0], split[1], NULL);
1064 /* GValue transform function */
1066 string_to_profile_transform (const GValue * src_value, GValue * dest_value)
1068 const gchar *profilename;
1069 GstEncodingProfile *profile;
1071 profilename = g_value_get_string (src_value);
1073 profile = combo_search (profilename);
1076 g_value_take_object (dest_value, (GObject *) profile);
1080 gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
1082 GstEncodingProfile *profile;
1084 profile = combo_search (s);
1087 g_value_take_object (value, (GObject *) profile);
1095 * gst_encoding_profile_from_discoverer:
1096 * @info: (transfer none): The #GstDiscovererInfo to read from
1098 * Creates a #GstEncodingProfile matching the formats from the given
1099 * #GstEncodingProfile. Streams other than audio or video (eg,
1100 * subtitles), are currently ignored.
1102 * Returns: (transfer full): The new #GstEncodingProfile or %NULL.
1104 GstEncodingProfile *
1105 gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
1107 GstEncodingContainerProfile *profile;
1108 GstDiscovererStreamInfo *sinfo;
1109 GList *streams, *stream;
1110 GstCaps *caps = NULL;
1112 if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK)
1115 sinfo = gst_discoverer_info_get_stream_info (info);
1119 caps = gst_discoverer_stream_info_get_caps (sinfo);
1120 GST_LOG ("Container: %" GST_PTR_FORMAT "\n", caps);
1122 gst_encoding_container_profile_new ("auto-generated",
1123 "Automatically generated from GstDiscovererInfo", caps, NULL);
1124 gst_caps_unref (caps);
1126 GST_ERROR ("Failed to create container profile from caps %" GST_PTR_FORMAT,
1132 gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
1134 for (stream = streams; stream; stream = stream->next) {
1135 GstEncodingProfile *sprofile = NULL;
1136 sinfo = (GstDiscovererStreamInfo *) stream->data;
1137 caps = gst_discoverer_stream_info_get_caps (sinfo);
1138 GST_LOG ("Stream: %" GST_PTR_FORMAT "\n", caps);
1139 if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
1141 (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
1143 } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
1145 (GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
1148 /* subtitles or other ? ignore for now */
1151 gst_encoding_container_profile_add_profile (profile, sprofile);
1153 GST_ERROR ("Failed to create stream profile from caps %" GST_PTR_FORMAT,
1155 gst_caps_unref (caps);
1157 gst_discoverer_stream_info_list_free (streams);
1159 return (GstEncodingProfile *) profile;