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: Using an encoder preset with a profile</title>
91 * #include <gst/pbutils/encoding-profile.h>
93 * GstEncodingProfile *
94 * create_ogg_theora_profile(void)
96 * GstEncodingVideoProfile *v;
97 * GstEncodingAudioProfile *a;
98 * GstEncodingContainerProfile *prof;
102 * caps = gst_caps_from_string ("application/ogg");
103 * prof = gst_encoding_container_profile_new ("Ogg audio/video",
104 * "Standard OGG/THEORA/VORBIS",
106 * gst_caps_unref (caps);
108 * preset = GST_PRESET (gst_element_factory_make ("theoraenc", "theorapreset"));
109 * g_object_set (preset, "bitrate", 1000, NULL);
110 * // The preset will be saved on the filesystem,
111 * // so try to use a descriptive name
112 * gst_preset_save_preset (preset, "theora_bitrate_preset");
113 * gst_object_unref (preset);
115 * caps = gst_caps_from_string ("video/x-theora");
116 * v = gst_encoding_video_profile_new (caps, "theorapreset", NULL, 0);
117 * gst_encoding_container_profile_add_profile (prof, (GstEncodingProfile*) v);
118 * gst_caps_unref (caps);
120 * caps = gst_caps_from_string ("audio/x-vorbis");
121 * a = gst_encoding_audio_profile_new (caps, NULL, NULL, 0);
122 * gst_encoding_container_profile_add_profile (prof, (GstEncodingProfile*) a);
123 * gst_caps_unref (caps);
125 * return (GstEncodingProfile*) prof;
133 * <title>Example: Listing categories, targets and profiles</title>
136 * #include <gst/pbutils/encoding-profile.h>
138 * GstEncodingProfile *prof;
139 * GList *categories, *tmpc;
140 * GList *targets, *tmpt;
142 * categories = gst_encoding_list_available_categories ();
144 * ... Show available categories to user ...
146 * for (tmpc = categories; tmpc; tmpc = tmpc->next) {
147 * gchar *category = (gchar *) tmpc->data;
149 * ... and we can list all targets within that category ...
151 * targets = gst_encoding_list_all_targets (category);
153 * ... and show a list to our users ...
155 * g_list_foreach (targets, (GFunc) gst_encoding_target_unref, NULL);
156 * g_list_free (targets);
159 * g_list_foreach (categories, (GFunc) g_free, NULL);
160 * g_list_free (categories);
172 #include "encoding-profile.h"
173 #include "encoding-target.h"
177 /* GstEncodingProfile API */
179 struct _GstEncodingProfile
190 GstCaps *restriction;
191 gboolean allow_dynamic_output;
194 struct _GstEncodingProfileClass
196 GObjectClass parent_class;
202 PROP_RESTRICTION_CAPS,
206 static GParamSpec *_properties[LAST_PROPERTY];
208 static void string_to_profile_transform (const GValue * src_value,
209 GValue * dest_value);
210 static gboolean gst_encoding_profile_deserialize_valfunc (GValue * value,
213 static void gst_encoding_profile_class_init (GstEncodingProfileClass * klass);
214 static gpointer gst_encoding_profile_parent_class = NULL;
217 gst_encoding_profile_class_intern_init (gpointer klass)
219 gst_encoding_profile_parent_class = g_type_class_peek_parent (klass);
220 gst_encoding_profile_class_init ((GstEncodingProfileClass *) klass);
224 gst_encoding_profile_get_type (void)
226 static volatile gsize g_define_type_id__volatile = 0;
228 if (g_once_init_enter (&g_define_type_id__volatile)) {
229 GType g_define_type_id = g_type_register_static_simple (G_TYPE_OBJECT,
230 g_intern_static_string ("GstEncodingProfile"),
231 sizeof (GstEncodingProfileClass),
232 (GClassInitFunc) gst_encoding_profile_class_intern_init,
233 sizeof (GstEncodingProfile),
236 static GstValueTable gstvtable = {
238 (GstValueCompareFunc) NULL,
239 (GstValueSerializeFunc) NULL,
240 (GstValueDeserializeFunc) gst_encoding_profile_deserialize_valfunc
243 gstvtable.type = g_define_type_id;
245 /* Register a STRING=>PROFILE GValueTransformFunc */
246 g_value_register_transform_func (G_TYPE_STRING, g_define_type_id,
247 string_to_profile_transform);
248 /* Register gst-specific GValue functions */
249 gst_value_register (&gstvtable);
251 g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
253 return g_define_type_id__volatile;
258 _encoding_profile_get_property (GObject * object, guint prop_id,
259 GValue * value, GParamSpec * pspec)
261 GstEncodingProfile *prof = (GstEncodingProfile *) object;
264 case PROP_RESTRICTION_CAPS:
265 gst_value_set_caps (value, prof->restriction);
268 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274 _encoding_profile_set_property (GObject * object, guint prop_id,
275 const GValue * value, GParamSpec * pspec)
277 GstEncodingProfile *prof = (GstEncodingProfile *) object;
280 case PROP_RESTRICTION_CAPS:
281 gst_encoding_profile_set_restriction (prof, gst_caps_copy
282 (gst_value_get_caps (value)));
285 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
291 gst_encoding_profile_finalize (GObject * object)
293 GstEncodingProfile *prof = (GstEncodingProfile *) object;
297 gst_caps_unref (prof->format);
299 g_free (prof->preset);
300 if (prof->description)
301 g_free (prof->description);
302 if (prof->restriction)
303 gst_caps_unref (prof->restriction);
304 if (prof->preset_name)
305 g_free (prof->preset_name);
309 gst_encoding_profile_class_init (GstEncodingProfileClass * klass)
311 GObjectClass *gobject_class = (GObjectClass *) klass;
313 gobject_class->finalize = gst_encoding_profile_finalize;
315 gobject_class->set_property = _encoding_profile_set_property;
316 gobject_class->get_property = _encoding_profile_get_property;
318 _properties[PROP_RESTRICTION_CAPS] =
319 g_param_spec_boxed ("restriction-caps", "Restriction caps",
320 "The restriction caps to use", GST_TYPE_CAPS,
321 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
323 g_object_class_install_property (gobject_class,
324 PROP_RESTRICTION_CAPS, _properties[PROP_RESTRICTION_CAPS]);
329 * gst_encoding_profile_get_name:
330 * @profile: a #GstEncodingProfile
332 * Returns: the name of the profile, can be %NULL.
335 gst_encoding_profile_get_name (GstEncodingProfile * profile)
337 return profile->name;
341 * gst_encoding_profile_get_description:
342 * @profile: a #GstEncodingProfile
344 * Returns: the description of the profile, can be %NULL.
347 gst_encoding_profile_get_description (GstEncodingProfile * profile)
349 return profile->description;
353 * gst_encoding_profile_get_format:
354 * @profile: a #GstEncodingProfile
356 * Returns: (transfer full): the #GstCaps corresponding to the media format used
357 * in the profile. Unref after usage.
360 gst_encoding_profile_get_format (GstEncodingProfile * profile)
362 return (profile->format ? gst_caps_ref (profile->format) : NULL);
366 * gst_encoding_profile_get_preset:
367 * @profile: a #GstEncodingProfile
369 * Returns: the name of the #GstPreset to be used in the profile.
370 * This is the name that has been set when saving the preset.
373 gst_encoding_profile_get_preset (GstEncodingProfile * profile)
375 return profile->preset;
379 * gst_encoding_profile_get_preset_name:
380 * @profile: a #GstEncodingProfile
382 * Returns: the name of the #GstPreset factory to be used in the profile.
385 gst_encoding_profile_get_preset_name (GstEncodingProfile * profile)
387 return profile->preset_name;
391 * gst_encoding_profile_get_presence:
392 * @profile: a #GstEncodingProfile
394 * Returns: The number of times the profile is used in its parent
395 * container profile. If 0, it is not a mandatory stream.
398 gst_encoding_profile_get_presence (GstEncodingProfile * profile)
400 return profile->presence;
404 * gst_encoding_profile_get_restriction:
405 * @profile: a #GstEncodingProfile
407 * Returns: (transfer full): The restriction #GstCaps to apply before the encoder
408 * that will be used in the profile. The fields present in restriction caps are
409 * properties of the raw stream (that is before encoding), such as height and
410 * width for video and depth and sampling rate for audio. Does not apply to
411 * #GstEncodingContainerProfile (since there is no corresponding raw stream).
412 * Can be %NULL. Unref after usage.
415 gst_encoding_profile_get_restriction (GstEncodingProfile * profile)
417 return (profile->restriction ? gst_caps_ref (profile->restriction) : NULL);
421 * gst_encoding_profile_set_name:
422 * @profile: a #GstEncodingProfile
423 * @name: the name to set on the profile
425 * Set @name as the given name for the @profile. A copy of @name will be made
429 gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name)
432 g_free (profile->name);
433 profile->name = g_strdup (name);
437 * gst_encoding_profile_set_description:
438 * @profile: a #GstEncodingProfile
439 * @description: the description to set on the profile
441 * Set @description as the given description for the @profile. A copy of
442 * @description will be made internally.
445 gst_encoding_profile_set_description (GstEncodingProfile * profile,
446 const gchar * description)
448 if (profile->description)
449 g_free (profile->description);
450 profile->description = g_strdup (description);
454 * gst_encoding_profile_set_format:
455 * @profile: a #GstEncodingProfile
456 * @format: the media format to use in the profile.
458 * Sets the media format used in the profile.
461 gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format)
464 gst_caps_unref (profile->format);
465 profile->format = gst_caps_ref (format);
469 * gst_encoding_profile_get_allow_dynamic_output:
470 * @profile: a #GstEncodingProfile
472 * Get whether the format that has been negotiated in at some point can be renegotiated
473 * later during the encoding.
476 gst_encoding_profile_get_allow_dynamic_output (GstEncodingProfile * profile)
478 return profile->allow_dynamic_output;
482 * gst_encoding_profile_set_allow_dynamic_output:
483 * @profile: a #GstEncodingProfile
484 * @allow_dynamic_output: Whether the format that has been negotiated first can be renegotiated
485 * during the encoding
487 * Sets whether the format that has been negotiated in at some point can be renegotiated
488 * later during the encoding.
491 gst_encoding_profile_set_allow_dynamic_output (GstEncodingProfile * profile,
492 gboolean allow_dynamic_output)
494 profile->allow_dynamic_output = allow_dynamic_output;
498 * gst_encoding_profile_set_preset:
499 * @profile: a #GstEncodingProfile
500 * @preset: the element preset to use
502 * Sets the name of the #GstElement that implements the #GstPreset interface
503 * to use for the profile.
504 * This is the name that has been set when saving the preset.
507 gst_encoding_profile_set_preset (GstEncodingProfile * profile,
508 const gchar * preset)
511 g_free (profile->preset);
512 profile->preset = g_strdup (preset);
516 * gst_encoding_profile_set_preset_name:
517 * @profile: a #GstEncodingProfile
518 * @preset_name: The name of the preset to use in this @profile.
520 * Sets the name of the #GstPreset's factory to be used in the profile.
523 gst_encoding_profile_set_preset_name (GstEncodingProfile * profile,
524 const gchar * preset_name)
526 if (profile->preset_name)
527 g_free (profile->preset_name);
528 profile->preset_name = g_strdup (preset_name);
532 * gst_encoding_profile_set_presence:
533 * @profile: a #GstEncodingProfile
534 * @presence: the number of time the profile can be used
536 * Set the number of time the profile is used in its parent
537 * container profile. If 0, it is not a mandatory stream
540 gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence)
542 profile->presence = presence;
546 * gst_encoding_profile_set_restriction:
547 * @profile: a #GstEncodingProfile
548 * @restriction: (transfer full): the restriction to apply
550 * Set the restriction #GstCaps to apply before the encoder
551 * that will be used in the profile. See gst_encoding_profile_get_restriction()
552 * for more about restrictions. Does not apply to #GstEncodingContainerProfile.
555 gst_encoding_profile_set_restriction (GstEncodingProfile * profile,
556 GstCaps * restriction)
558 if (profile->restriction)
559 gst_caps_unref (profile->restriction);
560 profile->restriction = restriction;
562 g_object_notify_by_pspec (G_OBJECT (profile),
563 _properties[PROP_RESTRICTION_CAPS]);
566 /* Container profiles */
568 struct _GstEncodingContainerProfile
570 GstEncodingProfile parent;
572 GList *encodingprofiles;
575 struct _GstEncodingContainerProfileClass
577 GstEncodingProfileClass parent;
580 G_DEFINE_TYPE (GstEncodingContainerProfile, gst_encoding_container_profile,
581 GST_TYPE_ENCODING_PROFILE);
584 gst_encoding_container_profile_init (GstEncodingContainerProfile * prof)
586 /* Nothing to initialize */
590 gst_encoding_container_profile_finalize (GObject * object)
592 GstEncodingContainerProfile *prof = (GstEncodingContainerProfile *) object;
594 g_list_foreach (prof->encodingprofiles, (GFunc) g_object_unref, NULL);
595 g_list_free (prof->encodingprofiles);
597 G_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize
602 gst_encoding_container_profile_class_init (GstEncodingContainerProfileClass * k)
604 GObjectClass *gobject_class = (GObjectClass *) k;
606 gobject_class->finalize = gst_encoding_container_profile_finalize;
610 * gst_encoding_container_profile_get_profiles:
611 * @profile: a #GstEncodingContainerProfile
613 * Returns: (element-type GstPbutils.EncodingProfile) (transfer none):
614 * the list of contained #GstEncodingProfile.
617 gst_encoding_container_profile_get_profiles (GstEncodingContainerProfile *
620 return profile->encodingprofiles;
625 struct _GstEncodingVideoProfile
627 GstEncodingProfile parent;
630 gboolean variableframerate;
633 struct _GstEncodingVideoProfileClass
635 GstEncodingProfileClass parent;
638 G_DEFINE_TYPE (GstEncodingVideoProfile, gst_encoding_video_profile,
639 GST_TYPE_ENCODING_PROFILE);
642 gst_encoding_video_profile_init (GstEncodingVideoProfile * prof)
644 /* Nothing to initialize */
648 gst_encoding_video_profile_class_init (GstEncodingVideoProfileClass * klass)
653 * gst_encoding_video_profile_get_pass:
654 * @prof: a #GstEncodingVideoProfile
656 * Get the pass number if this is part of a multi-pass profile.
658 * Returns: The pass number. Starts at 1 for multi-pass. 0 if this is
659 * not a multi-pass profile
662 gst_encoding_video_profile_get_pass (GstEncodingVideoProfile * prof)
668 * gst_encoding_video_profile_get_variableframerate:
669 * @prof: a #GstEncodingVideoProfile
671 * Returns: Whether non-constant video framerate is allowed for encoding.
674 gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile *
677 return prof->variableframerate;
681 * gst_encoding_video_profile_set_pass:
682 * @prof: a #GstEncodingVideoProfile
683 * @pass: the pass number for this profile
685 * Sets the pass number of this video profile. The first pass profile should have
686 * this value set to 1. If this video profile isn't part of a multi-pass profile,
687 * you may set it to 0 (the default value).
690 gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass)
696 * gst_encoding_video_profile_set_variableframerate:
697 * @prof: a #GstEncodingVideoProfile
698 * @variableframerate: a boolean
700 * If set to %TRUE, then the incoming stream will be allowed to have non-constant
701 * framerate. If set to %FALSE (default value), then the incoming stream will
702 * be normalized by dropping/duplicating frames in order to produce a
703 * constance framerate.
706 gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *
707 prof, gboolean variableframerate)
709 prof->variableframerate = variableframerate;
714 struct _GstEncodingAudioProfile
716 GstEncodingProfile parent;
719 struct _GstEncodingAudioProfileClass
721 GstEncodingProfileClass parent;
724 G_DEFINE_TYPE (GstEncodingAudioProfile, gst_encoding_audio_profile,
725 GST_TYPE_ENCODING_PROFILE);
728 gst_encoding_audio_profile_init (GstEncodingAudioProfile * prof)
730 /* Nothing to initialize */
734 gst_encoding_audio_profile_class_init (GstEncodingAudioProfileClass * klass)
738 static inline gboolean
739 _gst_caps_is_equal_safe (GstCaps * a, GstCaps * b)
743 if ((a == NULL) || (b == NULL))
745 return gst_caps_is_equal (a, b);
749 _compare_container_encoding_profiles (GstEncodingContainerProfile * ca,
750 GstEncodingContainerProfile * cb)
754 if (g_list_length (ca->encodingprofiles) !=
755 g_list_length (cb->encodingprofiles))
758 for (tmp = ca->encodingprofiles; tmp; tmp = tmp->next) {
759 GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data;
760 if (!gst_encoding_container_profile_contains_profile (ca, prof))
768 _compare_encoding_profiles (const GstEncodingProfile * a,
769 const GstEncodingProfile * b)
771 if ((G_TYPE_FROM_INSTANCE (a) != G_TYPE_FROM_INSTANCE (b)) ||
772 !_gst_caps_is_equal_safe (a->format, b->format) ||
773 (g_strcmp0 (a->preset, b->preset) != 0) ||
774 (g_strcmp0 (a->name, b->name) != 0) ||
775 (g_strcmp0 (a->description, b->description) != 0))
778 if (GST_IS_ENCODING_CONTAINER_PROFILE (a))
780 _compare_container_encoding_profiles (GST_ENCODING_CONTAINER_PROFILE
781 (a), GST_ENCODING_CONTAINER_PROFILE (b));
783 if (GST_IS_ENCODING_VIDEO_PROFILE (a)) {
784 GstEncodingVideoProfile *va = (GstEncodingVideoProfile *) a;
785 GstEncodingVideoProfile *vb = (GstEncodingVideoProfile *) b;
787 if ((va->pass != vb->pass)
788 || (va->variableframerate != vb->variableframerate))
796 * gst_encoding_container_profile_contains_profile:
797 * @container: a #GstEncodingContainerProfile
798 * @profile: a #GstEncodingProfile
800 * Checks if @container contains a #GstEncodingProfile identical to
803 * Returns: %TRUE if @container contains a #GstEncodingProfile identical
804 * to @profile, else %FALSE.
807 gst_encoding_container_profile_contains_profile (GstEncodingContainerProfile *
808 container, GstEncodingProfile * profile)
810 g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
811 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
813 return (g_list_find_custom (container->encodingprofiles, profile,
814 (GCompareFunc) _compare_encoding_profiles) != NULL);
818 * gst_encoding_container_profile_add_profile:
819 * @container: the #GstEncodingContainerProfile to use
820 * @profile: (transfer full): the #GstEncodingProfile to add.
822 * Add a #GstEncodingProfile to the list of profiles handled by @container.
824 * No copy of @profile will be made, if you wish to use it elsewhere after this
825 * method you should increment its reference count.
827 * Returns: %TRUE if the @stream was properly added, else %FALSE.
830 gst_encoding_container_profile_add_profile (GstEncodingContainerProfile *
831 container, GstEncodingProfile * profile)
833 g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
834 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
836 if (g_list_find_custom (container->encodingprofiles, profile,
837 (GCompareFunc) _compare_encoding_profiles)) {
839 ("Encoding profile already contains an identical GstEncodingProfile");
843 container->encodingprofiles =
844 g_list_append (container->encodingprofiles, profile);
849 static GstEncodingProfile *
850 common_creation (GType objtype, GstCaps * format, const gchar * preset,
851 const gchar * name, const gchar * description, GstCaps * restriction,
854 GstEncodingProfile *prof;
856 prof = (GstEncodingProfile *) g_object_new (objtype, NULL);
859 prof->name = g_strdup (name);
861 prof->description = g_strdup (description);
863 prof->preset = g_strdup (preset);
865 prof->format = gst_caps_ref (format);
867 prof->restriction = gst_caps_ref (restriction);
868 prof->presence = presence;
869 prof->preset_name = NULL;
870 prof->allow_dynamic_output = TRUE;
876 * gst_encoding_container_profile_new:
877 * @name: (allow-none): The name of the container profile, can be %NULL
878 * @description: (allow-none): The description of the container profile,
880 * @format: The format to use for this profile
881 * @preset: (allow-none): The preset to use for this profile.
883 * Creates a new #GstEncodingContainerProfile.
885 * Returns: The newly created #GstEncodingContainerProfile.
887 GstEncodingContainerProfile *
888 gst_encoding_container_profile_new (const gchar * name,
889 const gchar * description, GstCaps * format, const gchar * preset)
891 g_return_val_if_fail (GST_IS_CAPS (format), NULL);
893 return (GstEncodingContainerProfile *)
894 common_creation (GST_TYPE_ENCODING_CONTAINER_PROFILE, format, preset,
895 name, description, NULL, 0);
899 * gst_encoding_video_profile_new:
900 * @format: the #GstCaps
901 * @preset: (allow-none): the preset(s) to use on the encoder, can be #NULL
902 * @restriction: (allow-none): the #GstCaps used to restrict the input to the encoder, can be
903 * NULL. See gst_encoding_profile_get_restriction() for more details.
904 * @presence: the number of time this stream must be used. 0 means any number of
905 * times (including never)
907 * Creates a new #GstEncodingVideoProfile
909 * All provided allocatable arguments will be internally copied, so can be
910 * safely freed/unreferenced after calling this method.
912 * If you wish to control the pass number (in case of multi-pass scenarios),
913 * please refer to the gst_encoding_video_profile_set_pass() documentation.
915 * If you wish to use/force a constant framerate please refer to the
916 * gst_encoding_video_profile_set_variableframerate() documentation.
918 * Returns: the newly created #GstEncodingVideoProfile.
920 GstEncodingVideoProfile *
921 gst_encoding_video_profile_new (GstCaps * format, const gchar * preset,
922 GstCaps * restriction, guint presence)
924 return (GstEncodingVideoProfile *)
925 common_creation (GST_TYPE_ENCODING_VIDEO_PROFILE, format, preset, NULL,
926 NULL, restriction, presence);
930 * gst_encoding_audio_profile_new:
931 * @format: the #GstCaps
932 * @preset: (allow-none): the preset(s) to use on the encoder, can be #NULL
933 * @restriction: (allow-none): the #GstCaps used to restrict the input to the encoder, can be
934 * NULL. See gst_encoding_profile_get_restriction() for more details.
935 * @presence: the number of time this stream must be used. 0 means any number of
936 * times (including never)
938 * Creates a new #GstEncodingAudioProfile
940 * All provided allocatable arguments will be internally copied, so can be
941 * safely freed/unreferenced after calling this method.
943 * Returns: the newly created #GstEncodingAudioProfile.
945 GstEncodingAudioProfile *
946 gst_encoding_audio_profile_new (GstCaps * format, const gchar * preset,
947 GstCaps * restriction, guint presence)
949 return (GstEncodingAudioProfile *)
950 common_creation (GST_TYPE_ENCODING_AUDIO_PROFILE, format, preset, NULL,
951 NULL, restriction, presence);
956 * gst_encoding_profile_is_equal:
957 * @a: a #GstEncodingProfile
958 * @b: a #GstEncodingProfile
960 * Checks whether the two #GstEncodingProfile are equal
962 * Returns: %TRUE if @a and @b are equal, else %FALSE.
965 gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b)
967 return (_compare_encoding_profiles (a, b) == 0);
972 * gst_encoding_profile_get_input_caps:
973 * @profile: a #GstEncodingProfile
975 * Computes the full output caps that this @profile will be able to consume.
977 * Returns: (transfer full): The full caps the given @profile can consume. Call
978 * gst_caps_unref() when you are done with the caps.
981 gst_encoding_profile_get_input_caps (GstEncodingProfile * profile)
985 GstStructure *st, *outst;
990 if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
991 GstCaps *res = gst_caps_new_empty ();
993 for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles;
994 ltmp; ltmp = ltmp->next) {
995 GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data;
996 res = gst_caps_merge (res, gst_encoding_profile_get_input_caps (sprof));
1001 fcaps = profile->format;
1004 if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction))
1005 return gst_caps_ref (fcaps);
1007 /* Combine the format with the restriction caps */
1008 outst = gst_caps_get_structure (fcaps, 0);
1009 out_name = gst_structure_get_name_id (outst);
1010 tmp = gst_caps_new_empty ();
1011 len = gst_caps_get_size (profile->restriction);
1013 for (i = 0; i < len; i++) {
1014 st = gst_structure_copy (gst_caps_get_structure (profile->restriction, i));
1015 st->name = out_name;
1016 gst_caps_append_structure (tmp, st);
1019 out = gst_caps_intersect (tmp, fcaps);
1020 gst_caps_unref (tmp);
1026 * gst_encoding_profile_get_type_nick:
1027 * @profile: a #GstEncodingProfile
1029 * Returns: the human-readable name of the type of @profile.
1032 gst_encoding_profile_get_type_nick (GstEncodingProfile * profile)
1034 if (GST_IS_ENCODING_CONTAINER_PROFILE (profile))
1036 if (GST_IS_ENCODING_VIDEO_PROFILE (profile))
1038 if (GST_IS_ENCODING_AUDIO_PROFILE (profile))
1043 extern const gchar *pb_utils_get_file_extension_from_caps (const GstCaps *
1045 gboolean pb_utils_is_tag (const GstCaps * caps);
1048 gst_encoding_profile_has_format (GstEncodingProfile * profile,
1049 const gchar * media_type)
1054 caps = gst_encoding_profile_get_format (profile);
1055 ret = gst_structure_has_name (gst_caps_get_structure (caps, 0), media_type);
1056 gst_caps_unref (caps);
1062 gst_encoding_container_profile_has_video (GstEncodingContainerProfile * profile)
1066 for (l = profile->encodingprofiles; l != NULL; l = l->next) {
1067 if (GST_IS_ENCODING_VIDEO_PROFILE (l->data))
1069 if (GST_IS_ENCODING_CONTAINER_PROFILE (l->data) &&
1070 gst_encoding_container_profile_has_video (l->data))
1078 * gst_encoding_profile_get_file_extension:
1079 * @profile: a #GstEncodingProfile
1081 * Returns: a suitable file extension for @profile, or NULL.
1084 gst_encoding_profile_get_file_extension (GstEncodingProfile * profile)
1086 GstEncodingContainerProfile *cprofile;
1087 const gchar *ext = NULL;
1092 g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), NULL);
1094 caps = gst_encoding_profile_get_format (profile);
1095 ext = pb_utils_get_file_extension_from_caps (caps);
1097 if (!GST_IS_ENCODING_CONTAINER_PROFILE (profile))
1100 cprofile = GST_ENCODING_CONTAINER_PROFILE (profile);
1102 num_children = g_list_length (cprofile->encodingprofiles);
1104 /* if it's a tag container profile (e.g. id3mux/apemux), we need
1105 * to look at what's inside it */
1106 if (pb_utils_is_tag (caps)) {
1107 GST_DEBUG ("tag container profile");
1108 if (num_children == 1) {
1109 GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
1111 ext = gst_encoding_profile_get_file_extension (child_profile);
1113 GST_WARNING ("expected exactly one child profile with tag profile");
1118 if (num_children == 0)
1122 has_video = gst_encoding_container_profile_has_video (cprofile);
1125 if (strcmp (ext, "ogg") == 0) {
1126 /* ogg with video => .ogv */
1131 /* ogg with just speex audio => .spx */
1132 if (num_children == 1) {
1133 GstEncodingProfile *child_profile = cprofile->encodingprofiles->data;
1135 if (GST_IS_ENCODING_AUDIO_PROFILE (child_profile) &&
1136 gst_encoding_profile_has_format (child_profile, "audio/x-speex")) {
1141 /* does anyone actually use .oga for ogg audio files? */
1146 if (has_video && strcmp (ext, "mka") == 0) {
1151 /* Windows Media / ASF */
1152 if (gst_encoding_profile_has_format (profile, "video/x-ms-asf")) {
1154 guint num_wmv = 0, num_wma = 0, num_other = 0;
1156 for (l = cprofile->encodingprofiles; l != NULL; l = l->next) {
1157 if (gst_encoding_profile_has_format (l->data, "video/x-wmv"))
1159 else if (gst_encoding_profile_has_format (l->data, "audio/x-wma"))
1167 else if (num_wmv > 0)
1169 else if (num_wma > 0)
1177 GST_INFO ("caps %" GST_PTR_FORMAT ", ext: %s", caps, GST_STR_NULL (ext));
1178 gst_caps_unref (caps);
1183 * gst_encoding_profile_find:
1184 * @targetname: (transfer none): The name of the target
1185 * @profilename: (transfer none): The name of the profile
1186 * @category: (transfer none) (allow-none): The target category. Can be %NULL
1188 * Find the #GstEncodingProfile with the specified name and category.
1190 * Returns: (transfer full): The matching #GstEncodingProfile or %NULL.
1192 GstEncodingProfile *
1193 gst_encoding_profile_find (const gchar * targetname, const gchar * profilename,
1194 const gchar * category)
1196 GstEncodingProfile *res = NULL;
1197 GstEncodingTarget *target;
1199 g_return_val_if_fail (targetname != NULL, NULL);
1200 g_return_val_if_fail (profilename != NULL, NULL);
1202 /* FIXME : how do we handle profiles named the same in several
1203 * categories but of which only one has the required profile ? */
1204 target = gst_encoding_target_load (targetname, category, NULL);
1206 res = gst_encoding_target_get_profile (target, profilename);
1207 gst_encoding_target_unref (target);
1213 static GstEncodingProfile *
1214 combo_search (const gchar * pname)
1216 GstEncodingProfile *res;
1220 split = g_strsplit (pname, "/", 2);
1221 if (g_strv_length (split) != 2)
1224 res = gst_encoding_profile_find (split[0], split[1], NULL);
1231 /* GValue transform function */
1233 string_to_profile_transform (const GValue * src_value, GValue * dest_value)
1235 const gchar *profilename;
1236 GstEncodingProfile *profile;
1238 profilename = g_value_get_string (src_value);
1240 profile = combo_search (profilename);
1243 g_value_take_object (dest_value, (GObject *) profile);
1247 gst_encoding_profile_deserialize_valfunc (GValue * value, const gchar * s)
1249 GstEncodingProfile *profile;
1251 profile = combo_search (s);
1254 g_value_take_object (value, (GObject *) profile);
1262 * gst_encoding_profile_from_discoverer:
1263 * @info: (transfer none): The #GstDiscovererInfo to read from
1265 * Creates a #GstEncodingProfile matching the formats from the given
1266 * #GstDiscovererInfo. Streams other than audio or video (eg,
1267 * subtitles), are currently ignored.
1269 * Returns: (transfer full): The new #GstEncodingProfile or %NULL.
1271 GstEncodingProfile *
1272 gst_encoding_profile_from_discoverer (GstDiscovererInfo * info)
1274 GstEncodingContainerProfile *profile;
1275 GstDiscovererStreamInfo *sinfo;
1276 GList *streams, *stream;
1277 GstCaps *caps = NULL;
1279 if (!info || gst_discoverer_info_get_result (info) != GST_DISCOVERER_OK)
1282 sinfo = gst_discoverer_info_get_stream_info (info);
1286 caps = gst_discoverer_stream_info_get_caps (sinfo);
1287 GST_LOG ("Container: %" GST_PTR_FORMAT "\n", caps);
1289 gst_encoding_container_profile_new ("auto-generated",
1290 "Automatically generated from GstDiscovererInfo", caps, NULL);
1291 gst_caps_unref (caps);
1293 GST_ERROR ("Failed to create container profile from caps %" GST_PTR_FORMAT,
1299 gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
1301 for (stream = streams; stream; stream = stream->next) {
1302 GstEncodingProfile *sprofile = NULL;
1303 sinfo = (GstDiscovererStreamInfo *) stream->data;
1304 caps = gst_discoverer_stream_info_get_caps (sinfo);
1305 GST_LOG ("Stream: %" GST_PTR_FORMAT "\n", caps);
1306 if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
1308 (GstEncodingProfile *) gst_encoding_audio_profile_new (caps, NULL,
1310 } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
1312 (GstEncodingProfile *) gst_encoding_video_profile_new (caps, NULL,
1315 /* subtitles or other ? ignore for now */
1318 gst_encoding_container_profile_add_profile (profile, sprofile);
1320 GST_ERROR ("Failed to create stream profile from caps %" GST_PTR_FORMAT,
1322 gst_caps_unref (caps);
1324 gst_discoverer_stream_info_list_free (streams);
1326 return (GstEncodingProfile *) profile;