fix compile errors on macosx
[platform/upstream/gst-plugins-base.git] / gst-libs / gst / pbutils / encoding-profile.c
1 /* GStreamer encoding profiles library
2  * Copyright (C) 2009-2010 Edward Hervey <edward.hervey@collabora.co.uk>
3  *           (C) 2009-2010 Nokia Corporation
4  *
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.
9  *
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.
14  *
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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * SECTION:encoding-profile
23  * @short_description: Encoding profile library
24  *
25  * <refsect2>
26  * <para>
27  * Functions to create and handle encoding profiles.
28  * </para>
29  * <para>
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 user-readable name and 
33  * description along with which container format to use) which references one or
34  * more #GstEncodingProfile(s) which indicate which encoding format should be
35  * used on each individual streams.
36  * </para>
37  * <para>
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.
41  * </para>
42  * <para>
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
45  * one wishes to use.
46  * </para>
47  * <para>
48  * Encoding profiles can be created at runtime by the application or loaded from (and saved
49  * to) file using the #GstEncodingTarget API.
50  * </para>
51  * </refsect2>
52  * <refsect2>
53  * <title>Example: Creating a profile</title>
54  * <para>
55  * |[
56  * #include <gst/pbutils/encoding-profile.h>
57  * ...
58  * GstEncodingProfile *
59  * create_ogg_theora_profile(void)
60  *{
61  *  GstEncodingContainerProfile *prof;
62  *  GstCaps *caps;
63  *
64  *  caps = gst_caps_from_string("application/ogg");
65  *  prof = gst_encoding_container_profile_new("Ogg audio/video",
66  *     "Standard OGG/THEORA/VORBIS",
67  *     caps, NULL);
68  *  gst_caps_unref (caps);
69  *
70  *  caps = gst_caps_from_string("video/x-theora");
71  *  sprof = gst_encoding_container_profile_add_profile(
72  *       (GstEncodingProfile*) gst_encoding_video_profile_new(caps, NULL, NULL, 0));
73  *  gst_caps_unref (caps);
74  *
75  *  caps = gst_caps_from_string("audio/x-vorbis");
76  *  sprof = gst_encoding_container_profile_add_profile(
77  *       (GstEncodingProfile*) gst_encoding_audio_profile_new(caps, NULL, NULL, 0));
78  *  gst_caps_unref (caps);
79  *
80  *  return (GstEncodingProfile*) prof;
81  *}
82  *
83  *
84  * ]|
85  * </para>
86  * </refsect2>
87  * <refsect2>
88  * <title>Example: Loading a profile from disk</title>
89  * <para>
90  * |[
91  * #include <gst/pbutils/encoding-profile.h>
92  * ...
93  *GstEncodingProfile *
94  *get_ogg_theora_profile(const gchar *path, const gchar *profilename)
95  *{
96  *  GstEncodingProfile *prof = NULL;
97  *  GstEncodingTarget *target = NULL;
98  *  GList *tmp;
99  *
100  *  target = gst_encoding_target_load_from (path);
101  *  if (target == NULL)
102  *    return NULL;
103  *
104  *  for (tmp = target->profiles; tmp; tmp = tmp->next) {
105  *    GstEncodingProfile *ptmp = (GstEncodingProfile*) tmp->data;
106  *
107  *    if (!strcmp(gst_encoding_profile_get_name(ptmp), profilename)) {
108  *      prof = ptmp;
109  *      break;
110  *    }
111  *  }
112  *
113  *  return prof;
114  *}
115  * ]|
116  * </para>
117  * </refsect2>
118  *
119  * Since: 0.10.32
120  */
121
122 #ifdef HAVE_CONFIG_H
123 #  include "config.h"
124 #endif
125
126 #include "encoding-profile.h"
127
128 /* GstEncodingProfile API */
129
130 struct _GstEncodingProfile
131 {
132   GstMiniObject parent;
133
134   /*< public > */
135   gchar *name;
136   gchar *description;
137   GstCaps *format;
138   gchar *preset;
139   guint presence;
140   GstCaps *restriction;
141 };
142
143 G_DEFINE_TYPE (GstEncodingProfile, gst_encoding_profile, GST_TYPE_MINI_OBJECT);
144
145 static void
146 gst_encoding_profile_init (GstEncodingProfile * prof)
147 {
148   /* Nothing to initialize */
149 }
150
151 static void
152 gst_encoding_profile_finalize (GstEncodingProfile * prof)
153 {
154   if (prof->name)
155     g_free (prof->name);
156   if (prof->format)
157     gst_caps_unref (prof->format);
158   if (prof->preset)
159     g_free (prof->preset);
160   if (prof->description)
161     g_free (prof->description);
162   if (prof->restriction)
163     gst_caps_unref (prof->restriction);
164 }
165
166 static void
167 gst_encoding_profile_class_init (GstMiniObjectClass * klass)
168 {
169   klass->finalize =
170       (GstMiniObjectFinalizeFunction) gst_encoding_profile_finalize;
171 }
172
173 /**
174  * gst_encoding_profile_get_name:
175  * @profile: a #GstEncodingProfile
176  *
177  * Since: 0.10.32
178  *
179  * Returns: the name of the profile, can be %NULL.
180  */
181 const gchar *
182 gst_encoding_profile_get_name (GstEncodingProfile * profile)
183 {
184   return profile->name;
185 }
186
187 /**
188  * gst_encoding_profile_get_description:
189  * @profile: a #GstEncodingProfile
190  *
191  * Since: 0.10.32
192  *
193  * Returns: the description of the profile, can be %NULL.
194  */
195 const gchar *
196 gst_encoding_profile_get_description (GstEncodingProfile * profile)
197 {
198   return profile->description;
199 }
200
201 /**
202  * gst_encoding_profile_get_format:
203  * @profile: a #GstEncodingProfile
204  *
205  * Since: 0.10.32
206  *
207  * Returns: the media format used in the profile.
208  */
209 const GstCaps *
210 gst_encoding_profile_get_format (GstEncodingProfile * profile)
211 {
212   return profile->format;
213 }
214
215 /**
216  * gst_encoding_profile_get_preset:
217  * @profile: a #GstEncodingProfile
218  *
219  * Since: 0.10.32
220  *
221  * Returns: the preset to be used in the profile.
222  */
223 const gchar *
224 gst_encoding_profile_get_preset (GstEncodingProfile * profile)
225 {
226   return profile->preset;
227 }
228
229 /**
230  * gst_encoding_profile_get_presence:
231  * @profile: a #GstEncodingProfile
232  *
233  * Since: 0.10.32
234  *
235  * Returns: The number of time the profile is used in its parent
236  * container profile. If 0, it is not a mandatory stream
237  */
238 guint
239 gst_encoding_profile_get_presence (GstEncodingProfile * profile)
240 {
241   return profile->presence;
242 }
243
244 /**
245  * gst_encoding_profile_get_restriction:
246  * @profile: a #GstEncodingProfile
247  *
248  * Since: 0.10.32
249  *
250  * Returns: The restriction #GstCaps to apply before the encoder
251  * that will be used in the profile. Does not apply to #GstEncodingContainerProfile.
252  * Can be %NULL.
253  */
254 const GstCaps *
255 gst_encoding_profile_get_restriction (GstEncodingProfile * profile)
256 {
257   return profile->restriction;
258 }
259
260 /**
261  * gst_encoding_profile_set_name:
262  * @profile: a #GstEncodingProfile
263  * @name: the name to set on the profile
264  *
265  * Since: 0.10.32
266  *
267  * Set @name as the given name for the @profile. A copy of @name will be made
268  * internally.
269  */
270 void
271 gst_encoding_profile_set_name (GstEncodingProfile * profile, const gchar * name)
272 {
273   if (profile->name)
274     g_free (profile->name);
275   profile->name = g_strdup (name);
276 }
277
278 /**
279  * gst_encoding_profile_set_description:
280  * @profile: a #GstEncodingProfile
281  * @description: the description to set on the profile
282  *
283  * Since: 0.10.32
284  *
285  * Set @description as the given description for the @profile. A copy of @description will be made
286  * internally.
287  */
288 void
289 gst_encoding_profile_set_description (GstEncodingProfile * profile,
290     const gchar * description)
291 {
292   if (profile->description)
293     g_free (profile->description);
294   profile->description = g_strdup (description);
295 }
296
297 /**
298  * gst_encoding_profile_set_format:
299  * @profile: a #GstEncodingProfile
300  * @format: the media format to use in the profile.
301  *
302  * Since: 0.10.32
303  *
304  * Sets the media format used in the profile.
305  */
306 void
307 gst_encoding_profile_set_format (GstEncodingProfile * profile, GstCaps * format)
308 {
309   if (profile->format)
310     gst_caps_unref (profile->format);
311   profile->format = gst_caps_ref (format);
312 }
313
314 /**
315  * gst_encoding_profile_set_preset:
316  * @profile: a #GstEncodingProfile
317  * @preset: the element preset to use
318  *
319  * Since: 0.10.32
320  *
321  * Sets the preset to use for the profile.
322  */
323 void
324 gst_encoding_profile_set_preset (GstEncodingProfile * profile,
325     const gchar * preset)
326 {
327   if (profile->preset)
328     g_free (profile->preset);
329   profile->preset = g_strdup (preset);
330 }
331
332 /**
333  * gst_encoding_profile_set_presence:
334  * @profile: a #GstEncodingProfile
335  * @presence: the number of time the profile can be used
336  *
337  * Since: 0.10.32
338  *
339  * Set the number of time the profile is used in its parent
340  * container profile. If 0, it is not a mandatory stream
341  */
342 void
343 gst_encoding_profile_set_presence (GstEncodingProfile * profile, guint presence)
344 {
345   profile->presence = presence;
346 }
347
348 /**
349  * gst_encoding_profile_set_restriction:
350  * @profile: a #GstEncodingProfile
351  * @restriction: the restriction to apply
352  *
353  * Since: 0.10.32
354  *
355  * Set the restriction #GstCaps to apply before the encoder
356  * that will be used in the profile. Does not apply to #GstEncodingContainerProfile.
357  */
358 void
359 gst_encoding_profile_set_restriction (GstEncodingProfile * profile,
360     GstCaps * restriction)
361 {
362   if (profile->restriction)
363     gst_caps_unref (profile->restriction);
364   profile->restriction = restriction;
365 }
366
367 /* Container profiles */
368
369 struct _GstEncodingContainerProfile
370 {
371   GstEncodingProfile parent;
372
373   GList *encodingprofiles;
374 };
375
376 G_DEFINE_TYPE (GstEncodingContainerProfile, gst_encoding_container_profile,
377     GST_TYPE_ENCODING_PROFILE);
378
379 static void
380 gst_encoding_container_profile_init (GstEncodingContainerProfile * prof)
381 {
382   /* Nothing to initialize */
383 }
384
385 static void
386 gst_encoding_container_profile_finalize (GstEncodingContainerProfile * prof)
387 {
388   g_list_foreach (prof->encodingprofiles, (GFunc) gst_mini_object_unref, NULL);
389   g_list_free (prof->encodingprofiles);
390
391   GST_MINI_OBJECT_CLASS (gst_encoding_container_profile_parent_class)->finalize
392       ((GstMiniObject *) prof);
393 }
394
395 static void
396 gst_encoding_container_profile_class_init (GstMiniObjectClass * klass)
397 {
398   klass->finalize =
399       (GstMiniObjectFinalizeFunction) gst_encoding_container_profile_finalize;
400 }
401
402 const GList *
403 gst_encoding_container_profile_get_profiles (GstEncodingContainerProfile *
404     profile)
405 {
406   return profile->encodingprofiles;
407 }
408
409 /* Video profiles */
410
411 struct _GstEncodingVideoProfile
412 {
413   GstEncodingProfile parent;
414
415   guint pass;
416   gboolean variableframerate;
417 };
418
419 G_DEFINE_TYPE (GstEncodingVideoProfile, gst_encoding_video_profile,
420     GST_TYPE_ENCODING_PROFILE);
421
422 static void
423 gst_encoding_video_profile_init (GstEncodingVideoProfile * prof)
424 {
425   /* Nothing to initialize */
426 }
427
428 static void
429 gst_encoding_video_profile_class_init (GstMiniObjectClass * klass)
430 {
431 }
432
433 /**
434  * gst_encoding_video_profile_get_pass:
435  * @prof: a #GstEncodingVideoProfile
436  *
437  * Since: 0.10.32
438  *
439  * Returns: The pass number if this is part of a multi-pass profile. Starts at
440  * 1 for multi-pass. 0 if this is not a multi-pass profile
441  **/
442 guint
443 gst_encoding_video_profile_get_pass (GstEncodingVideoProfile * prof)
444 {
445   return prof->pass;
446 }
447
448 /**
449  * gst_encoding_video_profile_get_variableframerate:
450  * @prof: a #GstEncodingVideoProfile
451  *
452  * Since: 0.10.32
453  *
454  * Returns: Whether non-constant video framerate is allowed for encoding.
455  */
456 gboolean
457 gst_encoding_video_profile_get_variableframerate (GstEncodingVideoProfile *
458     prof)
459 {
460   return prof->variableframerate;
461 }
462
463 /**
464  * gst_encoding_video_profile_set_pass:
465  * @prof: a #GstEncodingVideoProfile
466  * @pass: the pass number for this profile
467  *
468  * Since: 0.10.32
469  *
470  * Sets the pass number of this video profile. The first pass profile should have
471  * this value set to 1. If this video profile isn't part of a multi-pass profile,
472  * you may set it to 0 (the default value).
473  */
474 void
475 gst_encoding_video_profile_set_pass (GstEncodingVideoProfile * prof, guint pass)
476 {
477   prof->pass = pass;
478 }
479
480 /**
481  * gst_encoding_video_profile_set_variableframerate:
482  * @prof: a #GstEncodingVideoProfile
483  * @variableframerate: a boolean
484  *
485  * Since: 0.10.32
486  *
487  * If set to %TRUE, then the incoming streamm will be allowed to have non-constant
488  * framerate. If set to %FALSE (default value), then the incoming stream will
489  * be normalized by dropping/duplicating frames in order to produce a
490  * constance framerate.
491  */
492 void
493 gst_encoding_video_profile_set_variableframerate (GstEncodingVideoProfile *
494     prof, gboolean variableframerate)
495 {
496   prof->variableframerate = variableframerate;
497 }
498
499 /* Audio profiles */
500
501 struct _GstEncodingAudioProfile
502 {
503   GstEncodingProfile parent;
504 };
505
506 G_DEFINE_TYPE (GstEncodingAudioProfile, gst_encoding_audio_profile,
507     GST_TYPE_ENCODING_PROFILE);
508
509 static void
510 gst_encoding_audio_profile_init (GstEncodingAudioProfile * prof)
511 {
512   /* Nothing to initialize */
513 }
514
515 static void
516 gst_encoding_audio_profile_class_init (GstMiniObjectClass * klass)
517 {
518 }
519
520 static inline gboolean
521 _gst_caps_is_equal_safe (GstCaps * a, GstCaps * b)
522 {
523   if (a == b)
524     return TRUE;
525   if ((a == NULL) || (b == NULL))
526     return FALSE;
527   return gst_caps_is_equal (a, b);
528 }
529
530 static gint
531 _compare_container_encoding_profiles (GstEncodingContainerProfile * ca,
532     GstEncodingContainerProfile * cb)
533 {
534   GList *tmp;
535
536   if (g_list_length (ca->encodingprofiles) !=
537       g_list_length (cb->encodingprofiles))
538     return -1;
539
540   for (tmp = ca->encodingprofiles; tmp; tmp = tmp->next) {
541     GstEncodingProfile *prof = (GstEncodingProfile *) tmp->data;
542     if (!gst_encoding_container_profile_contains_profile (ca, prof))
543       return -1;
544   }
545
546   return 0;
547 }
548
549 static gint
550 _compare_encoding_profiles (const GstEncodingProfile * a,
551     const GstEncodingProfile * b)
552 {
553   if ((G_TYPE_FROM_INSTANCE (a) != G_TYPE_FROM_INSTANCE (b)) ||
554       !_gst_caps_is_equal_safe (a->format, b->format) ||
555       (g_strcmp0 (a->preset, b->preset) != 0) ||
556       (g_strcmp0 (a->name, b->name) != 0) ||
557       (g_strcmp0 (a->description, b->description) != 0))
558     return -1;
559
560   if (GST_IS_ENCODING_CONTAINER_PROFILE (a))
561     return
562         _compare_container_encoding_profiles (GST_ENCODING_CONTAINER_PROFILE
563         (a), GST_ENCODING_CONTAINER_PROFILE (b));
564
565   if (GST_IS_ENCODING_VIDEO_PROFILE (a)) {
566     GstEncodingVideoProfile *va = (GstEncodingVideoProfile *) a;
567     GstEncodingVideoProfile *vb = (GstEncodingVideoProfile *) b;
568
569     if ((va->pass != vb->pass)
570         || (va->variableframerate != vb->variableframerate))
571       return -1;
572   }
573
574   return 0;
575 }
576
577 /**
578  * gst_encoding_container_profile_contains_profile:
579  * @container: a #GstEncodingContainerProfile
580  * @profile: a #GstEncodingProfile
581  *
582  * Checks if @container contains a #GstEncodingProfile identical to
583  * @profile.
584  *
585  * Since: 0.10.32
586  *
587  * Returns: %TRUE if @container contains a #GstEncodingProfile identical
588  * to @profile, else %FALSE.
589  */
590 gboolean
591 gst_encoding_container_profile_contains_profile (GstEncodingContainerProfile *
592     container, GstEncodingProfile * profile)
593 {
594   g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
595   g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
596
597   return (g_list_find_custom (container->encodingprofiles, profile,
598           (GCompareFunc) _compare_encoding_profiles) != NULL);
599 }
600
601 /**
602  * gst_encoding_container_profile_add_profile:
603  * @container: the #GstEncodingContainerProfile to use
604  * @profile: the #GstEncodingProfile to add.
605  *
606  * Add a #GstEncodingProfile to the list of profiles handled by @container.
607  * 
608  * No copy of @profile will be made, if you wish to use it elsewhere after this
609  * method you should increment its reference count.
610  *
611  * Since: 0.10.32
612  *
613  * Returns: %TRUE if the @stream was properly added, else %FALSE.
614  */
615 gboolean
616 gst_encoding_container_profile_add_profile (GstEncodingContainerProfile *
617     container, GstEncodingProfile * profile)
618 {
619   g_return_val_if_fail (GST_IS_ENCODING_CONTAINER_PROFILE (container), FALSE);
620   g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);
621
622   if (g_list_find_custom (container->encodingprofiles, profile,
623           (GCompareFunc) _compare_encoding_profiles)) {
624     GST_ERROR
625         ("Encoding profile already contains an identical GstEncodingProfile");
626     return FALSE;
627   }
628
629   container->encodingprofiles =
630       g_list_append (container->encodingprofiles, profile);
631
632   return TRUE;
633 }
634
635 static GstEncodingProfile *
636 common_creation (GType objtype, GstCaps * format, const gchar * preset,
637     const gchar * name, const gchar * description, GstCaps * restriction,
638     guint presence)
639 {
640   GstEncodingProfile *prof;
641
642   prof = (GstEncodingProfile *) gst_mini_object_new (objtype);
643
644   if (name)
645     prof->name = g_strdup (name);
646   if (description)
647     prof->description = g_strdup (description);
648   if (preset)
649     prof->preset = g_strdup (preset);
650   if (format)
651     prof->format = gst_caps_ref (format);
652   if (restriction)
653     prof->restriction = gst_caps_ref (restriction);
654   prof->presence = presence;
655
656   return prof;
657 }
658
659 /**
660  * gst_encoding_container_profile_new:
661  * @name: The name of the container profile, can be %NULL
662  * @description: The description of the container profile, can be %NULL
663  * @format: The format to use for this profile
664  * @preset: The preset to use for this profile
665  *
666  * Creates a new #GstEncodingContainerProfile.
667  *
668  * Since: 0.10.32
669  *
670  * Returns: The newly created #GstEncodingContainerProfile.
671  */
672 GstEncodingContainerProfile *
673 gst_encoding_container_profile_new (const gchar * name,
674     const gchar * description, GstCaps * format, const gchar * preset)
675 {
676   return (GstEncodingContainerProfile *)
677       common_creation (GST_TYPE_ENCODING_CONTAINER_PROFILE, format, preset,
678       name, description, NULL, 0);
679 }
680
681 /**
682  * gst_encoding_video_profile_new:
683  * @format: the #GstCaps
684  * @preset: the preset(s) to use on the encoder, can be #NULL
685  * @restriction: the #GstCaps used to restrict the input to the encoder, can be
686  * NULL.
687  * @presence: the number of time this stream must be used. 0 means any number of
688  *  times (including never)
689  *
690  * Creates a new #GstEncodingVideoProfile
691  *
692  * All provided allocatable arguments will be internally copied, so can be
693  * safely freed/unreferenced after calling this method.
694  *
695  * If you wish to control the pass number (in case of multi-pass scenarios),
696  * please refer to the gst_encoding_video_profile_set_pass() documentation.
697  *
698  * If you wish to use/force a constant framerate please refer to the
699  * gst_encoding_video_profile_set_variableframerate() documentation.
700  *
701  * Since: 0.10.32
702  *
703  * Returns: the newly created #GstEncodingVideoProfile.
704  */
705 GstEncodingVideoProfile *
706 gst_encoding_video_profile_new (GstCaps * format, const gchar * preset,
707     GstCaps * restriction, guint presence)
708 {
709   return (GstEncodingVideoProfile *)
710       common_creation (GST_TYPE_ENCODING_VIDEO_PROFILE, format, preset, NULL,
711       NULL, restriction, presence);
712 }
713
714 /**
715  * gst_encoding_audio_profile_new:
716  * @format: the #GstCaps
717  * @preset: the preset(s) to use on the encoder, can be #NULL
718  * @restriction: the #GstCaps used to restrict the input to the encoder, can be
719  * NULL.
720  * @presence: the number of time this stream must be used. 0 means any number of
721  *  times (including never)
722  *
723  * Creates a new #GstEncodingAudioProfile
724  *
725  * All provided allocatable arguments will be internally copied, so can be
726  * safely freed/unreferenced after calling this method.
727  *
728  * Since: 0.10.32
729  *
730  * Returns: the newly created #GstEncodingAudioProfile.
731  */
732 GstEncodingAudioProfile *
733 gst_encoding_audio_profile_new (GstCaps * format, const gchar * preset,
734     GstCaps * restriction, guint presence)
735 {
736   return (GstEncodingAudioProfile *)
737       common_creation (GST_TYPE_ENCODING_AUDIO_PROFILE, format, preset, NULL,
738       NULL, restriction, presence);
739 }
740
741
742 /**
743  * gst_encoding_profile_is_equal:
744  * @a: a #GstEncodingProfile
745  * @b: a #GstEncodingProfile
746  *
747  * Checks whether the two #GstEncodingProfile are equal
748  *
749  * Since: 0.10.32
750  *
751  * Returns: %TRUE if @a and @b are equal, else %FALSE.
752  */
753 gboolean
754 gst_encoding_profile_is_equal (GstEncodingProfile * a, GstEncodingProfile * b)
755 {
756   return (_compare_encoding_profiles (a, b) == 0);
757 }
758
759
760 /**
761  * gst_encoding_profile_get_output_caps:
762  * @profile: a #GstEncodingProfile
763  *
764  * Computes the full output caps that this @profile will be able to consume.
765  *
766  * Since: 0.10.32
767  *
768  * Returns: The full caps the given @profile can consume. Call gst_caps_unref()
769  * when you are done with the caps.
770  */
771 GstCaps *
772 gst_encoding_profile_get_output_caps (GstEncodingProfile * profile)
773 {
774   GstCaps *out, *tmp;
775   GList *ltmp;
776   GstStructure *st, *outst;
777   GQuark out_name;
778   guint i, len;
779   const GstCaps *fcaps;
780
781   if (GST_IS_ENCODING_CONTAINER_PROFILE (profile)) {
782     GstCaps *res = gst_caps_new_empty ();
783
784     for (ltmp = GST_ENCODING_CONTAINER_PROFILE (profile)->encodingprofiles;
785         ltmp; ltmp = ltmp->next) {
786       GstEncodingProfile *sprof = (GstEncodingProfile *) ltmp->data;
787       gst_caps_merge (res, gst_encoding_profile_get_output_caps (sprof));
788     }
789     return res;
790   }
791
792   fcaps = profile->format;
793
794   /* fast-path */
795   if ((profile->restriction == NULL) || gst_caps_is_any (profile->restriction))
796     return gst_caps_copy (fcaps);
797
798   /* Combine the format with the restriction caps */
799   outst = gst_caps_get_structure (fcaps, 0);
800   out_name = gst_structure_get_name_id (outst);
801   tmp = gst_caps_new_empty ();
802   len = gst_caps_get_size (profile->restriction);
803
804   for (i = 0; i < len; i++) {
805     st = gst_structure_copy (gst_caps_get_structure (profile->restriction, i));
806     st->name = out_name;
807     gst_caps_append_structure (tmp, st);
808   }
809
810   out = gst_caps_intersect (tmp, fcaps);
811   gst_caps_unref (tmp);
812
813   return out;
814 }
815
816 /**
817  * gst_encoding_profile_get_type_nick:
818  * @profile: a #GstEncodingProfile
819  *
820  * Since: 0.10.32
821  *
822  * Returns: the human-readable name of the type of @profile.
823  */
824 const gchar *
825 gst_encoding_profile_get_type_nick (GstEncodingProfile * profile)
826 {
827   if (GST_IS_ENCODING_CONTAINER_PROFILE (profile))
828     return "container";
829   if (GST_IS_ENCODING_VIDEO_PROFILE (profile))
830     return "video";
831   if (GST_IS_ENCODING_AUDIO_PROFILE (profile))
832     return "audio";
833   return NULL;
834 }