71d918034d54a36dc5f590ae1e0f629f891509fc
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-base / gst-libs / gst / pbutils / codec-utils.c
1 /* GStreamer base utils library codec-specific utility functions
2  * Copyright (C) 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
3  *               2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4  *               2010 Collabora Multimedia
5  *               2010 Nokia Corporation
6  *               2013 Intel Corporation
7  *               2015 Sebastian Dröge <sebastian@centricular.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 /**
26  * SECTION:gstpbutilscodecutils
27  * @title: Codec utilities
28  * @short_description: Miscellaneous codec-specific utility functions
29  *
30  * Provides codec-specific ulility functions such as functions to provide the
31  * codec profile and level in human-readable string form from header data.
32  *
33  */
34
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
38
39 #include "pbutils.h"
40 #include <gst/base/base.h>
41 #include <gst/base/gstbitreader.h>
42 #include <gst/tag/tag.h>
43
44 #include <string.h>
45
46 #ifndef GST_DISABLE_GST_DEBUG
47 #define GST_CAT_DEFAULT gst_pb_utils_codec_utils_ensure_debug_category()
48
49 static GstDebugCategory *
50 gst_pb_utils_codec_utils_ensure_debug_category (void)
51 {
52   static gsize cat_gonce = 0;
53
54   if (g_once_init_enter (&cat_gonce)) {
55     GstDebugCategory *cat = NULL;
56
57     GST_DEBUG_CATEGORY_INIT (cat, "codec-utils", 0,
58         "GstPbUtils codec helper functions");
59
60     g_once_init_leave (&cat_gonce, (gsize) cat);
61   }
62
63   return (GstDebugCategory *) cat_gonce;
64 }
65 #endif /* GST_DISABLE_GST_DEBUG */
66
67 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
68     gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
69
70 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
71     gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
72
73 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
74   32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
75 };
76
77 static const gchar *
78 digit_to_string (guint digit)
79 {
80   static const char itoa[][2] = {
81     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
82   };
83
84   if (G_LIKELY (digit < 10))
85     return itoa[digit];
86   else
87     return NULL;
88 }
89
90 /**
91  * gst_codec_utils_aac_get_sample_rate_from_index:
92  * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
93  *          container) or ADTS frame header
94  *
95  * Translates the sample rate index found in AAC headers to the actual sample
96  * rate.
97  *
98  * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
99  */
100 guint
101 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
102 {
103   if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
104     return aac_sample_rates[sr_idx];
105
106   GST_WARNING ("Invalid sample rate index %u", sr_idx);
107   return 0;
108 }
109
110 /**
111  * gst_codec_utils_aac_get_index_from_sample_rate:
112  * @rate: Sample rate
113  *
114  * Translates the sample rate to the index corresponding to it in AAC spec.
115  *
116  * Returns: The AAC index for this sample rate, -1 if the rate is not a
117  * valid AAC sample rate.
118  */
119 gint
120 gst_codec_utils_aac_get_index_from_sample_rate (guint rate)
121 {
122   guint n;
123
124   for (n = 0; n < G_N_ELEMENTS (aac_sample_rates); n++)
125     if (aac_sample_rates[n] == rate)
126       return n;
127
128   GST_WARNING ("Invalid sample rate %u", rate);
129   return -1;
130 }
131
132 static gboolean
133 gst_codec_utils_aac_get_audio_object_type (GstBitReader * br,
134     guint8 * audio_object_type)
135 {
136   guint8 aot;
137
138   if (!gst_bit_reader_get_bits_uint8 (br, &aot, 5))
139     return FALSE;
140
141   if (aot == 31) {
142     if (!gst_bit_reader_get_bits_uint8 (br, &aot, 6))
143       return FALSE;
144     aot += 32;
145   }
146
147   *audio_object_type = aot;
148
149   return TRUE;
150 }
151
152 static gboolean
153 gst_codec_utils_aac_get_audio_sample_rate (GstBitReader * br,
154     guint * sample_rate)
155 {
156   guint8 sampling_freq_index;
157   guint32 sampling_rate;
158
159   if (!gst_bit_reader_get_bits_uint8 (br, &sampling_freq_index, 4))
160     return FALSE;
161
162   if (sampling_freq_index == 0xf) {
163     if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
164       return FALSE;
165   } else {
166     sampling_rate =
167         gst_codec_utils_aac_get_sample_rate_from_index (sampling_freq_index);
168     if (!sampling_rate)
169       return FALSE;
170   }
171
172   *sample_rate = sampling_rate;
173
174   return TRUE;
175 }
176
177 static gboolean
178 gst_codec_utils_aac_get_audio_object_type_full (GstBitReader * br,
179     guint8 * audio_object_type, guint8 * channel_config, guint * sample_rate)
180 {
181   guint8 aot, channels;
182   guint rate;
183
184   if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
185     return FALSE;
186
187   if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
188     return FALSE;
189
190   if (!gst_bit_reader_get_bits_uint8 (br, &channels, 4))
191     return FALSE;
192
193   /* 5 indicates SBR extension (i.e. HE-AAC) */
194   /* 29 indicates PS extension */
195   if (aot == 5 || aot == 29) {
196     if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
197       return FALSE;
198     if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
199       return FALSE;
200   }
201
202   *audio_object_type = aot;
203   *sample_rate = rate;
204   *channel_config = channels;
205
206   return TRUE;
207 }
208
209 /**
210  * gst_codec_utils_aac_get_sample_rate:
211  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
212  *                as specified in the Elementary Stream Descriptor (esds)
213  *                in ISO/IEC 14496-1.
214  * @len: Length of @audio_config
215  *
216  * Translates the sample rate index found in AAC headers to the actual sample
217  * rate.
218  *
219  * Returns: The sample rate if sr_idx is valid, 0 otherwise.
220  *
221  * Since: 1.10
222  */
223 guint
224 gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
225 {
226   guint sample_rate = 0;
227   guint8 audio_object_type = 0, channel_config = 0;
228   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
229
230   if (len < 2)
231     return 0;
232
233   gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
234       &channel_config, &sample_rate);
235
236   return sample_rate;
237 }
238
239 /**
240  * gst_codec_utils_aac_get_channels:
241  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
242  *                as specified in the Elementary Stream Descriptor (esds)
243  *                in ISO/IEC 14496-1.
244  * @len: Length of @audio_config in bytes
245  *
246  * Returns the channels of the given AAC stream.
247  *
248  * Returns: The channels or 0 if the channel could not be determined.
249  *
250  * Since: 1.10
251  */
252 guint
253 gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
254 {
255   guint channels;
256
257   if (len < 2)
258     return 0;
259
260   channels = (audio_config[1] & 0x7f) >> 3;
261   if (channels > 0 && channels < 7)
262     return channels;
263   else if (channels == 7)
264     return 8;
265   else
266     return 0;
267 }
268
269 /**
270  * gst_codec_utils_aac_get_profile:
271  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
272  *                as specified in the Elementary Stream Descriptor (esds)
273  *                in ISO/IEC 14496-1.
274  * @len: Length of @audio_config in bytes
275  *
276  * Returns the profile of the given AAC stream as a string. The profile is
277  * normally determined using the AudioObjectType field which is in the first
278  * 5 bits of @audio_config
279  *
280  * Returns: (nullable): The profile as a const string and %NULL if the profile could not be
281  * determined.
282  */
283 const gchar *
284 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
285 {
286   const gchar *profile = NULL;
287   guint sample_rate;
288   guint8 audio_object_type, channel_config;
289   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
290
291   if (len < 1)
292     return NULL;
293
294   GST_MEMDUMP ("audio config", audio_config, len);
295
296   if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
297           &channel_config, &sample_rate)) {
298     return NULL;
299   }
300
301   switch (audio_object_type) {
302     case 1:
303       profile = "main";
304       break;
305     case 2:
306       profile = "lc";
307       break;
308     case 3:
309       profile = "ssr";
310       break;
311     case 4:
312       profile = "ltp";
313       break;
314     default:
315       GST_DEBUG ("Invalid profile idx: %u", audio_object_type);
316       break;
317   }
318
319   return profile;
320 }
321
322 /**
323  * gst_codec_utils_aac_get_level:
324  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
325  *                as specified in the Elementary Stream Descriptor (esds)
326  *                in ISO/IEC 14496-1.
327  * @len: Length of @audio_config in bytes
328  *
329  * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
330  * streams, the constraints from the AAC audio profile are applied. For AAC
331  * Main, LTP, SSR and others, the Main profile is used.
332  *
333  * The @audio_config parameter follows the following format, starting from the
334  * most significant bit of the first byte:
335  *
336  *   * Bit 0:4 contains the AudioObjectType (if this is 0x5, then the
337  *     real AudioObjectType is carried after the rate and channel data)
338  *   * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
339  *     next 24 bits define the actual sample frequency, and subsequent
340  *     fields are appropriately shifted).
341  *   * Bit 9:12 contains the channel configuration
342  *
343  * Returns: (nullable): The level as a const string and %NULL if the level could not be
344  * determined.
345  */
346 const gchar *
347 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
348 {
349   guint8 audio_object_type = 0xFF, channel_config = 0xFF;
350   guint rate;
351   /* Number of single channel elements, channel pair elements, low frequency
352    * elements, independently switched coupling channel elements, and
353    * dependently switched coupling channel elements.
354    *
355    * Note: The 2 CCE types are ignored for now as they require us to actually
356    * parse the first frame, and they are rarely found in actual streams.
357    */
358   int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
359   int num_channels;
360   /* Processor and RAM Complexity Units (calculated and "reference" for single
361    * channel) */
362   int pcu = -1, rcu = -1, pcu_ref, rcu_ref;
363   int ret = -1;
364   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
365
366   g_return_val_if_fail (audio_config != NULL, NULL);
367
368   if (len < 2)
369     return NULL;
370
371   GST_MEMDUMP ("audio config", audio_config, len);
372
373   if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
374           &channel_config, &rate)) {
375     return NULL;
376   }
377
378   switch (channel_config) {
379     case 0:
380       /* Channel config is defined in the AudioObjectType's SpecificConfig,
381        * which requires some amount of digging through the headers. I only see
382        * this done in the MPEG conformance streams - FIXME */
383       GST_WARNING ("Found a stream with channel configuration in the "
384           "AudioSpecificConfig. Please file a bug with a link to the media if "
385           "possible.");
386       return NULL;
387     case 1:
388       /* front center */
389       num_sce = 1;
390       break;
391     case 2:
392       /* front left and right */
393       num_cpe = 1;
394       break;
395     case 3:
396       /* front left, right, and center */
397       num_sce = 1;
398       num_cpe = 1;
399       break;
400     case 4:
401       /* front left, right, and center; rear surround */
402       num_sce = 2;
403       num_cpe = 1;
404       break;
405     case 5:
406       /* front left, right, and center; rear left and right surround */
407       num_sce = 1;
408       num_cpe = 2;
409       break;
410     case 6:
411       /* front left, right, center and LFE; rear left and right surround */
412       num_sce = 1;
413       num_cpe = 2;
414       break;
415     case 7:
416     case 12:
417     case 14:
418       /* front left, right, center and LFE; outside front left and right;
419        * rear left and right surround */
420       num_sce = 1;
421       num_cpe = 3;
422       num_lfe = 1;
423       break;
424     case 11:
425       num_sce = 2;
426       num_cpe = 2;
427       num_lfe = 1;
428       break;
429     default:
430       GST_WARNING ("Unknown channel config in header: %d", channel_config);
431       return NULL;
432   }
433
434   switch (audio_object_type) {
435     case 0:                    /* NULL */
436       GST_WARNING ("profile 0 is not a valid profile");
437       return NULL;
438     case 2:                    /* LC */
439       pcu_ref = 3;
440       rcu_ref = 3;
441       break;
442     case 3:                    /* SSR */
443       pcu_ref = 4;
444       rcu_ref = 3;
445       break;
446     case 4:                    /* LTP */
447       pcu_ref = 4;
448       rcu_ref = 4;
449       break;
450     case 1:                    /* Main */
451     default:
452       /* Other than a couple of ER profiles, Main is the worst-case */
453       pcu_ref = 5;
454       rcu_ref = 5;
455       break;
456   }
457
458   /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
459    * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
460
461   pcu = ((float) rate / 48000) * pcu_ref *
462       ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
463
464   rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
465       (0.4 * num_cce_dep));
466
467   if (num_cpe < 2)
468     rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
469   else
470     rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
471
472   num_channels = num_sce + (2 * num_cpe);
473
474   if (audio_object_type == 2) {
475     /* AAC LC => return the level as per the 'AAC Profile' */
476     if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
477       ret = 1;
478     else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
479       ret = 2;
480     /* There is no level 3 for the AAC Profile */
481     else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
482       ret = 4;
483     else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
484       ret = 5;
485     else if (num_channels <= 7 && rate <= 48000 && pcu <= 25 && rcu <= 19)
486       ret = 6;
487     else if (num_channels <= 7 && rate <= 96000 && pcu <= 50 && rcu <= 19)
488       ret = 7;
489   } else {
490     /* Return the level as per the 'Main Profile' */
491     if (pcu < 40 && rcu < 20)
492       ret = 1;
493     else if (pcu < 80 && rcu < 64)
494       ret = 2;
495     else if (pcu < 160 && rcu < 128)
496       ret = 3;
497     else if (pcu < 320 && rcu < 256)
498       ret = 4;
499   }
500
501   if (ret == -1) {
502     GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
503         "channel_config=%u, pcu=%d,rcu=%d", audio_object_type, rate,
504         channel_config, pcu, rcu);
505     return NULL;
506   } else {
507     return digit_to_string (ret);
508   }
509 }
510
511 /**
512  * gst_codec_utils_aac_caps_set_level_and_profile:
513  * @caps: the #GstCaps to which level and profile fields are to be added
514  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
515  *                as specified in the Elementary Stream Descriptor (esds)
516  *                in ISO/IEC 14496-1. (See below for more details)
517  * @len: Length of @audio_config in bytes
518  *
519  * Sets the level and profile on @caps if it can be determined from
520  * @audio_config. See gst_codec_utils_aac_get_level() and
521  * gst_codec_utils_aac_get_profile() for more details on the parameters.
522  * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
523  * If mpegversion is 4, the "base-profile" field is also set in @caps.
524  *
525  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
526  */
527 gboolean
528 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
529     const guint8 * audio_config, guint len)
530 {
531   GstStructure *s;
532   const gchar *level, *profile;
533   int mpegversion = 0;
534
535   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
536   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
537   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
538   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
539   g_return_val_if_fail (audio_config != NULL, FALSE);
540
541   s = gst_caps_get_structure (caps, 0);
542
543   gst_structure_get_int (s, "mpegversion", &mpegversion);
544   g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
545
546   level = gst_codec_utils_aac_get_level (audio_config, len);
547
548   if (level != NULL)
549     gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
550
551   profile = gst_codec_utils_aac_get_profile (audio_config, len);
552
553   if (profile != NULL) {
554     if (mpegversion == 4) {
555       gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
556           "profile", G_TYPE_STRING, profile, NULL);
557     } else {
558       gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
559     }
560   }
561
562   GST_LOG ("profile : %s", (profile) ? profile : "---");
563   GST_LOG ("level   : %s", (level) ? level : "---");
564
565   return (level != NULL && profile != NULL);
566 }
567
568 /**
569  * gst_codec_utils_h264_get_profile:
570  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
571  * @len: Length of the data available in @sps.
572  *
573  * Converts the profile indication (profile_idc) in the stream's
574  * sequence parameter set into a string. The SPS is expected to have the
575  * following format, as defined in the H.264 specification. The SPS is viewed
576  * as a bitstream here, with bit 0 being the most significant bit of the first
577  * byte.
578  *
579  * * Bit 0:7   - Profile indication
580  * * Bit 8     - constraint_set0_flag
581  * * Bit 9     - constraint_set1_flag
582  * * Bit 10    - constraint_set2_flag
583  * * Bit 11    - constraint_set3_flag
584  * * Bit 12    - constraint_set3_flag
585  * * Bit 13:15 - Reserved
586  * * Bit 16:24 - Level indication
587  *
588  * Returns: (nullable): The profile as a const string, or %NULL if there is an error.
589  */
590 const gchar *
591 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
592 {
593   const gchar *profile = NULL;
594   gint csf1, csf3, csf4, csf5;
595
596   g_return_val_if_fail (sps != NULL, NULL);
597
598   if (len < 2)
599     return NULL;
600
601   GST_MEMDUMP ("SPS", sps, len);
602
603   csf1 = (sps[1] & 0x40) >> 6;
604   csf3 = (sps[1] & 0x10) >> 4;
605   csf4 = (sps[1] & 0x08) >> 3;
606   csf5 = (sps[1] & 0x04) >> 2;
607
608   switch (sps[0]) {
609     case 66:
610       if (csf1)
611         profile = "constrained-baseline";
612       else
613         profile = "baseline";
614       break;
615     case 77:
616       profile = "main";
617       break;
618     case 88:
619       profile = "extended";
620       break;
621     case 100:
622       if (csf4) {
623         if (csf5)
624           profile = "constrained-high";
625         else
626           profile = "progressive-high";
627       } else
628         profile = "high";
629       break;
630     case 110:
631       if (csf3)
632         profile = "high-10-intra";
633       else if (csf4)
634         profile = "progressive-high-10";
635       else
636         profile = "high-10";
637       break;
638     case 122:
639       if (csf3)
640         profile = "high-4:2:2-intra";
641       else
642         profile = "high-4:2:2";
643       break;
644     case 244:
645       if (csf3)
646         profile = "high-4:4:4-intra";
647       else
648         profile = "high-4:4:4";
649       break;
650     case 44:
651       profile = "cavlc-4:4:4-intra";
652       break;
653     case 118:
654       profile = "multiview-high";
655       break;
656     case 128:
657       profile = "stereo-high";
658       break;
659     case 83:
660       if (csf5)
661         profile = "scalable-constrained-baseline";
662       else
663         profile = "scalable-baseline";
664       break;
665     case 86:
666       if (csf3)
667         profile = "scalable-high-intra";
668       else if (csf5)
669         profile = "scalable-constrained-high";
670       else
671         profile = "scalable-high";
672       break;
673     default:
674       return NULL;
675   }
676
677   return profile;
678 }
679
680 /**
681  * gst_codec_utils_h264_get_level:
682  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
683  * @len: Length of the data available in @sps.
684  *
685  * Converts the level indication (level_idc) in the stream's
686  * sequence parameter set into a string. The SPS is expected to have the
687  * same format as for gst_codec_utils_h264_get_profile().
688  *
689  * Returns: (nullable): The level as a const string, or %NULL if there is an error.
690  */
691 const gchar *
692 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
693 {
694   gint csf3;
695
696   g_return_val_if_fail (sps != NULL, NULL);
697
698   if (len < 3)
699     return NULL;
700
701   GST_MEMDUMP ("SPS", sps, len);
702
703   csf3 = (sps[1] & 0x10) >> 4;
704
705   if (sps[2] == 0)
706     return NULL;
707   else if ((sps[2] == 11 && csf3) || sps[2] == 9)
708     return "1b";
709   else if (sps[2] % 10 == 0)
710     return digit_to_string (sps[2] / 10);
711   else {
712     switch (sps[2]) {
713       case 11:
714         return "1.1";
715       case 12:
716         return "1.2";
717       case 13:
718         return "1.3";
719       case 21:
720         return "2.1";
721       case 22:
722         return "2.2";
723       case 31:
724         return "3.1";
725       case 32:
726         return "3.2";
727       case 41:
728         return "4.1";
729       case 42:
730         return "4.2";
731       case 51:
732         return "5.1";
733       case 52:
734         return "5.2";
735       case 61:
736         return "6.1";
737       case 62:
738         return "6.2";
739       default:
740         return NULL;
741     }
742   }
743 }
744
745 /**
746  * gst_codec_utils_h264_get_level_idc:
747  * @level: A level string from caps
748  *
749  * Transform a level string from the caps into the level_idc
750  *
751  * Returns: the level_idc or 0 if the level is unknown
752  */
753 guint8
754 gst_codec_utils_h264_get_level_idc (const gchar * level)
755 {
756   g_return_val_if_fail (level != NULL, 0);
757
758   if (!strcmp (level, "1"))
759     return 10;
760   else if (!strcmp (level, "1b"))
761     return 9;
762   else if (!strcmp (level, "1.1"))
763     return 11;
764   else if (!strcmp (level, "1.2"))
765     return 12;
766   else if (!strcmp (level, "1.3"))
767     return 13;
768   else if (!strcmp (level, "2"))
769     return 20;
770   else if (!strcmp (level, "2.1"))
771     return 21;
772   else if (!strcmp (level, "2.2"))
773     return 22;
774   else if (!strcmp (level, "3"))
775     return 30;
776   else if (!strcmp (level, "3.1"))
777     return 31;
778   else if (!strcmp (level, "3.2"))
779     return 32;
780   else if (!strcmp (level, "4"))
781     return 40;
782   else if (!strcmp (level, "4.1"))
783     return 41;
784   else if (!strcmp (level, "4.2"))
785     return 42;
786   else if (!strcmp (level, "5"))
787     return 50;
788   else if (!strcmp (level, "5.1"))
789     return 51;
790   else if (!strcmp (level, "5.2"))
791     return 52;
792   else if (!strcmp (level, "6"))
793     return 60;
794   else if (!strcmp (level, "6.1"))
795     return 61;
796   else if (!strcmp (level, "6.2"))
797     return 62;
798
799   GST_WARNING ("Invalid level %s", level);
800   return 0;
801 }
802
803 /**
804  * gst_codec_utils_h264_caps_set_level_and_profile:
805  * @caps: the #GstCaps to which the level and profile are to be added
806  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
807  * @len: Length of the data available in @sps.
808  *
809  * Sets the level and profile in @caps if it can be determined from @sps. See
810  * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
811  * for more details on the parameters.
812  *
813  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
814  */
815 gboolean
816 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
817     const guint8 * sps, guint len)
818 {
819   const gchar *level, *profile;
820
821   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
822   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
823   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
824   g_return_val_if_fail (sps != NULL, FALSE);
825
826   level = gst_codec_utils_h264_get_level (sps, len);
827
828   if (level != NULL)
829     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
830
831   profile = gst_codec_utils_h264_get_profile (sps, len);
832
833   if (profile != NULL)
834     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
835
836   GST_LOG ("profile : %s", (profile) ? profile : "---");
837   GST_LOG ("level   : %s", (level) ? level : "---");
838
839   return (level != NULL && profile != NULL);
840 }
841
842 /**
843  * gst_codec_utils_h264_get_profile_flags_level:
844  * @codec_data: (array length=len): H264 AVCC extradata
845  * @len: length of @codec_data
846  * @profile: (optional) (out): return location for h264 profile_idc or %NULL
847  * @flags: (optional) (out): return location for h264 constraint set flags or %NULL
848  * @level: (optional) (out): return location h264 level_idc or %NULL
849  *
850  * Parses profile, flags, and level from a H264 AVCC extradata/sequence_header.
851  * These are most commonly retrieved from a video/x-h264 caps with a codec_data
852  * buffer.
853  *
854  * The format of H264 AVCC extradata/sequence_header is documented in the
855  * ITU-T H.264 specification section 7.3.2.1.1 as well as in ISO/IEC 14496-15
856  * section 5.3.3.1.2.
857  *
858  * Returns: %TRUE on success, %FALSE on failure
859  *
860  * Since: 1.20
861  */
862 gboolean
863 gst_codec_utils_h264_get_profile_flags_level (const guint8 * codec_data,
864     guint len, guint8 * profile, guint8 * flags, guint8 * level)
865 {
866   gboolean ret = FALSE;
867
868   g_return_val_if_fail (codec_data != NULL, FALSE);
869
870   if (len < 7) {
871     GST_WARNING ("avc codec data is too small");
872     goto done;
873   }
874   if (codec_data[0] != 1) {
875     GST_WARNING ("failed to parse avc codec version, must be 1");
876     goto done;
877   }
878
879   if (profile) {
880     *profile = codec_data[1];
881   }
882   if (flags) {
883     *flags = codec_data[2];
884   }
885   if (level) {
886     *level = codec_data[3];
887   }
888
889   ret = TRUE;
890
891 done:
892   return ret;
893 }
894
895 /* forked from gsth265parse.c */
896 typedef struct
897 {
898   const gchar *profile;
899
900   guint8 max_14bit_constraint_flag;
901   guint8 max_12bit_constraint_flag;
902   guint8 max_10bit_constraint_flag;
903   guint8 max_8bit_constraint_flag;
904   guint8 max_422chroma_constraint_flag;
905   guint8 max_420chroma_constraint_flag;
906   guint8 max_monochrome_constraint_flag;
907   guint8 intra_constraint_flag;
908   guint8 one_picture_only_constraint_flag;
909   guint8 lower_bit_rate_constraint_flag;
910
911   /* Tie breaker if more than one profiles are matching */
912   guint priority;
913 } GstH265ExtensionProfile;
914
915 typedef struct
916 {
917   const GstH265ExtensionProfile *profile;
918   guint extra_constraints;
919 } H265ExtensionProfileMatch;
920
921 static gint
922 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
923     H265ExtensionProfileMatch * b)
924 {
925   gint d;
926
927   d = a->extra_constraints - b->extra_constraints;
928   if (d)
929     return d;
930
931   return b->profile->priority - a->profile->priority;
932 }
933
934 static const gchar *
935 utils_get_extension_profile (const GstH265ExtensionProfile * profiles,
936     guint num, GstH265ExtensionProfile * ext_profile)
937 {
938   guint i;
939   const gchar *profile = NULL;
940   GList *cand = NULL;
941
942   for (i = 0; i < num; i++) {
943     GstH265ExtensionProfile p = profiles[i];
944     guint extra_constraints = 0;
945     H265ExtensionProfileMatch *m;
946
947     /* Filter out all the profiles having constraints not satisfied by
948      * @ext_profile.
949      * Then pick the one having the least extra constraints. This allow us
950      * to match the closet profile if bitstream contains not standard
951      * constraints. */
952     if (p.max_14bit_constraint_flag != ext_profile->max_14bit_constraint_flag) {
953       if (p.max_14bit_constraint_flag)
954         continue;
955       extra_constraints++;
956     }
957
958     if (p.max_12bit_constraint_flag != ext_profile->max_12bit_constraint_flag) {
959       if (p.max_12bit_constraint_flag)
960         continue;
961       extra_constraints++;
962     }
963
964     if (p.max_10bit_constraint_flag != ext_profile->max_10bit_constraint_flag) {
965       if (p.max_10bit_constraint_flag)
966         continue;
967       extra_constraints++;
968     }
969
970     if (p.max_8bit_constraint_flag != ext_profile->max_8bit_constraint_flag) {
971       if (p.max_8bit_constraint_flag)
972         continue;
973       extra_constraints++;
974     }
975
976     if (p.max_422chroma_constraint_flag !=
977         ext_profile->max_422chroma_constraint_flag) {
978       if (p.max_422chroma_constraint_flag)
979         continue;
980       extra_constraints++;
981     }
982
983     if (p.max_420chroma_constraint_flag !=
984         ext_profile->max_420chroma_constraint_flag) {
985       if (p.max_420chroma_constraint_flag)
986         continue;
987       extra_constraints++;
988     }
989
990     if (p.max_monochrome_constraint_flag !=
991         ext_profile->max_monochrome_constraint_flag) {
992       if (p.max_monochrome_constraint_flag)
993         continue;
994       extra_constraints++;
995     }
996
997     if (p.intra_constraint_flag != ext_profile->intra_constraint_flag) {
998       if (p.intra_constraint_flag)
999         continue;
1000       extra_constraints++;
1001     }
1002
1003     if (p.one_picture_only_constraint_flag !=
1004         ext_profile->one_picture_only_constraint_flag) {
1005       if (p.one_picture_only_constraint_flag)
1006         continue;
1007       extra_constraints++;
1008     }
1009
1010     if (p.lower_bit_rate_constraint_flag
1011         && !ext_profile->lower_bit_rate_constraint_flag)
1012       continue;
1013
1014     /* choose this one if all flags are matched */
1015     if (extra_constraints == 0) {
1016       profile = p.profile;
1017       break;
1018     }
1019
1020     m = g_new0 (H265ExtensionProfileMatch, 1);
1021     m->profile = &profiles[i];
1022     m->extra_constraints = extra_constraints;
1023     cand = g_list_prepend (cand, m);
1024   }
1025
1026   if (!profile && cand) {
1027     H265ExtensionProfileMatch *m;
1028
1029     cand = g_list_sort (cand, (GCompareFunc) sort_fre_profile_matches);
1030     m = cand->data;
1031     profile = m->profile->profile;
1032   }
1033
1034   if (cand)
1035     g_list_free_full (cand, g_free);
1036
1037   return profile;
1038 }
1039
1040 static const gchar *
1041 utils_get_format_range_extension_profile (GstH265ExtensionProfile * ext_profile)
1042 {
1043   static const GstH265ExtensionProfile profiles[] = {
1044     /* FIXME 2.0: Consider ':' separated subsampling notation for consistency
1045      * https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/23
1046      */
1047     /* Rec. ITU-T H.265 Table A.2 format range extensions profiles */
1048     /* *INDENT-OFF* */
1049     {"monochrome",                    0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1050     {"monochrome-10",                 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1},
1051     {"monochrome-12",                 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1052     {"monochrome-16",                 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 3},
1053     {"main-12",                       0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 4},
1054     {"main-422-10",                   0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 5},
1055     {"main-422-12",                   0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 6},
1056     {"main-444",                      0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 7},
1057     {"main-444-10",                   0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 8},
1058     {"main-444-12",                   0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 9},
1059     {"main-intra",                    0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 10},
1060     {"main-10-intra",                 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 11},
1061     {"main-12-intra",                 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 12},
1062     {"main-422-10-intra",             0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 13},
1063     {"main-422-12-intra",             0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 14},
1064     {"main-444-intra",                0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 15},
1065     {"main-444-10-intra",             0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 16},
1066     {"main-444-12-intra",             0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17},
1067     {"main-444-16-intra",             0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 18},
1068     {"main-444-still-picture",        0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 19},
1069     {"main-444-16-still-picture",     0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 20},
1070     /* *INDENT-ON* */
1071   };
1072
1073   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1074       ext_profile);
1075 }
1076
1077 static const gchar *
1078 utils_get_3d_profile (GstH265ExtensionProfile * ext_profile)
1079 {
1080   static const GstH265ExtensionProfile profiles[] = {
1081     /* Rec. ITU-T H.265 I.11.1 3D Main profile */
1082     /* *INDENT-OFF* */
1083     {"3d-main",                       0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1084     /* *INDENT-ON* */
1085   };
1086
1087   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1088       ext_profile);
1089 }
1090
1091 static const gchar *
1092 utils_get_multiview_profile (GstH265ExtensionProfile * ext_profile)
1093 {
1094   static const GstH265ExtensionProfile profiles[] = {
1095     /* Rec. ITU-T H.265 G.11.1 Multiview Main profile */
1096     /* *INDENT-OFF* */
1097     {"multiview-main",                0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1098     /* *INDENT-ON* */
1099   };
1100
1101   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1102       ext_profile);
1103 }
1104
1105 static const gchar *
1106 utils_get_scalable_profile (GstH265ExtensionProfile * ext_profile)
1107 {
1108   static const GstH265ExtensionProfile profiles[] = {
1109     /* Rec. ITU-T H.265 H.11.1 */
1110     /* *INDENT-OFF* */
1111     {"scalable-main",                 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1112     {"scalable-main-10",              0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1113     /* *INDENT-ON* */
1114   };
1115
1116   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1117       ext_profile);
1118 }
1119
1120 static const gchar *
1121 utils_get_high_throughput_profile (GstH265ExtensionProfile * ext_profile)
1122 {
1123   static const GstH265ExtensionProfile profiles[] = {
1124     /* Rec. ITU-T H.265 Table A.3 high throughput profiles */
1125     /* *INDENT-OFF* */
1126     {"high-throughput-444",           1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0},
1127     {"high-throughput-444-10",        1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1},
1128     {"high-throughput-444-14",        1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2},
1129     {"high-throughput-444-16-intra",  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3},
1130     /* *INDENT-ON* */
1131   };
1132
1133   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1134       ext_profile);
1135 }
1136
1137 static const gchar *
1138 utils_get_screen_content_coding_extensions_profile (GstH265ExtensionProfile *
1139     ext_profile)
1140 {
1141   static const GstH265ExtensionProfile profiles[] = {
1142     /* Rec. ITU-T H.265 Table A.5 screen content coding extensions profiles */
1143     /* *INDENT-OFF* */
1144     {"screen-extended-main",          1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1145     {"screen-extended-main-10",       1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1146     {"screen-extended-main-444",      1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2},
1147     {"screen-extended-main-444-10",   1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 3},
1148     /* identical to screen-extended-main-444 */
1149     {"screen-extended-high-throughput-444",
1150                                       1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 4},
1151     /* identical to screen-extended-main-444-10 */
1152     {"screen-extended-high-throughput-444-10",
1153                                       1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 5},
1154     {"screen-extended-high-throughput-444-14",
1155                                       1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6},
1156     /* *INDENT-ON* */
1157   };
1158
1159   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1160       ext_profile);
1161 }
1162
1163 static const gchar *
1164 utils_get_scalable_format_range_extensions_profile (GstH265ExtensionProfile *
1165     ext_profile)
1166 {
1167   static const GstH265ExtensionProfile profiles[] = {
1168     /* Rec. ITU-T H.265 Table H.4 scalable range extensions profiles */
1169     /* *INDENT-OFF* */
1170     {"scalable-monochrome",           1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1171     {"scalable-monochrome-12",        1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1},
1172     {"scalable-monochrome-16",        0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1173     {"scalable-main-444",             1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 3},
1174     /* *INDENT-ON* */
1175   };
1176
1177   return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1178       ext_profile);
1179 }
1180
1181 /**
1182  * gst_codec_utils_h265_get_profile:
1183  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1184  *   structure for the stream.
1185  * @len: Length of the data available in @profile_tier_level
1186  *
1187  * Converts the profile indication (general_profile_idc) in the stream's
1188  * profile_level_tier structure into a string. The profile_tier_level is
1189  * expected to have the following format, as defined in the H.265
1190  * specification. The profile_tier_level is viewed as a bitstream here,
1191  * with bit 0 being the most significant bit of the first byte.
1192  *
1193  * * Bit 0:1   - general_profile_space
1194  * * Bit 2     - general_tier_flag
1195  * * Bit 3:7   - general_profile_idc
1196  * * Bit 8:39  - gernal_profile_compatibility_flags
1197  * * Bit 40    - general_progressive_source_flag
1198  * * Bit 41    - general_interlaced_source_flag
1199  * * Bit 42    - general_non_packed_constraint_flag
1200  * * Bit 43    - general_frame_only_constraint_flag
1201  * * Bit 44:87 - See below
1202  * * Bit 88:95 - general_level_idc
1203  *
1204  * Returns: (nullable): The profile as a const string, or %NULL if there is an error.
1205  *
1206  * Since: 1.4
1207  */
1208 const gchar *
1209 gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
1210 {
1211   const gchar *profile = NULL;
1212   gint profile_idc;
1213   guint i;
1214   guint8 profile_compatibility_flags[32] = { 0, };
1215   GstBitReader br = GST_BIT_READER_INIT (profile_tier_level, len);
1216
1217   g_return_val_if_fail (profile_tier_level != NULL, NULL);
1218
1219   if (len < 2)
1220     return NULL;
1221
1222   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1223
1224   profile_idc = (profile_tier_level[0] & 0x1f);
1225
1226   if (profile_idc == 1)
1227     profile = "main";
1228   else if (profile_idc == 2)
1229     profile = "main-10";
1230   else if (profile_idc == 3)
1231     profile = "main-still-picture";
1232
1233   if (len > 4) {
1234     if (!gst_bit_reader_skip (&br, 8))
1235       return NULL;
1236
1237     for (i = 0; i < 32; i++) {
1238       if (!gst_bit_reader_get_bits_uint8 (&br, &profile_compatibility_flags[i],
1239               1))
1240         return NULL;
1241     }
1242   }
1243
1244   if (!profile) {
1245     if (profile_compatibility_flags[1])
1246       profile = "main";
1247     else if (profile_compatibility_flags[2])
1248       profile = "main-10";
1249     else if (profile_compatibility_flags[3])
1250       profile = "main-still-picture";
1251   }
1252
1253   if (profile)
1254     return profile;
1255
1256   if (profile_idc >= 4 && profile_idc <= 11 && len >= 11) {
1257     GstH265ExtensionProfile ext_profile = { 0, };
1258
1259     /*
1260      * Bit 40 - general_progressive_source_flag
1261      * Bit 41 - general_interlaced_source_flag
1262      * Bit 42 - general_non_packed_constraint_flag
1263      * Bit 43 - general_frame_only_constraint_flag
1264      */
1265     if (!gst_bit_reader_skip (&br, 4))
1266       return NULL;
1267
1268     /* Range extensions
1269      * profile_idc
1270      *   4 : Format range extensions profiles
1271      *   5 : High throughput profiles
1272      *   6 : Multiview main profile
1273      *   7 : Scalable main profiles
1274      *   8 : 3D Main profile
1275      *   9 : Screen content coding extensions profiles
1276      *  10 : Scalable format range extensions profiles
1277      *
1278      * Bit 44 - general_max_12bit_constraint_flag
1279      * Bit 45 - general_max_10bit_constraint_flag
1280      * Bit 46 - general_max_8bit_constraint_flag
1281      * Bit 47 - general_max_422chroma_constraint_flag
1282      * Bit 48 - general_max_420chroma_constraint_flag
1283      * Bit 49 - general_max_monochrome_constraint_flag
1284      * Bit 50 - general_intra_constraint_flag
1285      * Bit 51 - general_one_picture_only_constraint_flag
1286      * Bit 52 - general_lower_bit_rate_constraint_flag
1287      */
1288     if (!gst_bit_reader_get_bits_uint8 (&br,
1289             &ext_profile.max_12bit_constraint_flag, 1))
1290       return NULL;
1291
1292     if (!gst_bit_reader_get_bits_uint8 (&br,
1293             &ext_profile.max_10bit_constraint_flag, 1))
1294       return NULL;
1295
1296     if (!gst_bit_reader_get_bits_uint8 (&br,
1297             &ext_profile.max_8bit_constraint_flag, 1))
1298       return NULL;
1299
1300     if (!gst_bit_reader_get_bits_uint8 (&br,
1301             &ext_profile.max_422chroma_constraint_flag, 1))
1302       return NULL;
1303
1304     if (!gst_bit_reader_get_bits_uint8 (&br,
1305             &ext_profile.max_420chroma_constraint_flag, 1))
1306       return NULL;
1307
1308     if (!gst_bit_reader_get_bits_uint8 (&br,
1309             &ext_profile.max_monochrome_constraint_flag, 1))
1310       return NULL;
1311
1312     if (!gst_bit_reader_get_bits_uint8 (&br,
1313             &ext_profile.intra_constraint_flag, 1))
1314       return NULL;
1315
1316     if (!gst_bit_reader_get_bits_uint8 (&br,
1317             &ext_profile.one_picture_only_constraint_flag, 1))
1318       return NULL;
1319
1320     if (!gst_bit_reader_get_bits_uint8 (&br,
1321             &ext_profile.lower_bit_rate_constraint_flag, 1))
1322       return NULL;
1323
1324     if (profile_idc == 5 || profile_idc == 9 ||
1325         profile_idc == 10 || profile_idc == 11 ||
1326         profile_compatibility_flags[5] || profile_compatibility_flags[9] ||
1327         profile_compatibility_flags[10] || profile_compatibility_flags[11]) {
1328       /* Bit 53 - general_max_14bit_constraint_flag */
1329       if (!gst_bit_reader_get_bits_uint8 (&br,
1330               &ext_profile.max_14bit_constraint_flag, 1))
1331         return NULL;
1332     }
1333
1334     if (profile_idc == 4 || profile_compatibility_flags[4])
1335       return utils_get_format_range_extension_profile (&ext_profile);
1336
1337     if (profile_idc == 5 || profile_compatibility_flags[5])
1338       return utils_get_high_throughput_profile (&ext_profile);
1339
1340     if (profile_idc == 6 || profile_compatibility_flags[6])
1341       return utils_get_multiview_profile (&ext_profile);
1342
1343     if (profile_idc == 7 || profile_compatibility_flags[7])
1344       return utils_get_scalable_profile (&ext_profile);
1345
1346     if (profile_idc == 8 || profile_compatibility_flags[8])
1347       return utils_get_3d_profile (&ext_profile);
1348
1349     if (profile_idc == 9 || profile_compatibility_flags[9] ||
1350         profile_idc == 11 || profile_compatibility_flags[11])
1351       return utils_get_screen_content_coding_extensions_profile (&ext_profile);
1352
1353     if (profile_idc == 10 || profile_compatibility_flags[10])
1354       return utils_get_scalable_format_range_extensions_profile (&ext_profile);
1355   }
1356
1357   return profile;
1358 }
1359
1360 /**
1361  * gst_codec_utils_h265_get_tier:
1362  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1363  *   for the stream.
1364  * @len: Length of the data available in @profile_tier_level.
1365  *
1366  * Converts the tier indication (general_tier_flag) in the stream's
1367  * profile_tier_level structure into a string. The profile_tier_level
1368  * is expected to have the same format as for gst_codec_utils_h264_get_profile().
1369  *
1370  * Returns: (nullable): The tier as a const string, or %NULL if there is an error.
1371  *
1372  * Since: 1.4
1373  */
1374 const gchar *
1375 gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
1376 {
1377   const gchar *tier = NULL;
1378   gint tier_flag = 0;
1379
1380   g_return_val_if_fail (profile_tier_level != NULL, NULL);
1381
1382   if (len < 1)
1383     return NULL;
1384
1385   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1386
1387   tier_flag = (profile_tier_level[0] & 0x20) >> 5;
1388
1389   if (tier_flag)
1390     tier = "high";
1391   else
1392     tier = "main";
1393
1394   return tier;
1395 }
1396
1397 /**
1398  * gst_codec_utils_h265_get_level:
1399  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1400  *   for the stream
1401  * @len: Length of the data available in @profile_tier_level.
1402  *
1403  * Converts the level indication (general_level_idc) in the stream's
1404  * profile_tier_level structure into a string. The profiel_tier_level is
1405  * expected to have the same format as for gst_codec_utils_h264_get_profile().
1406  *
1407  * Returns: (nullable): The level as a const string, or %NULL if there is an error.
1408  *
1409  * Since: 1.4
1410  */
1411 const gchar *
1412 gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
1413 {
1414   g_return_val_if_fail (profile_tier_level != NULL, NULL);
1415
1416   if (len < 12)
1417     return NULL;
1418
1419   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1420
1421   if (profile_tier_level[11] == 0)
1422     return NULL;
1423   else if (profile_tier_level[11] % 30 == 0)
1424     return digit_to_string (profile_tier_level[11] / 30);
1425   else {
1426     switch (profile_tier_level[11]) {
1427       case 63:
1428         return "2.1";
1429         break;
1430       case 93:
1431         return "3.1";
1432         break;
1433       case 123:
1434         return "4.1";
1435         break;
1436       case 153:
1437         return "5.1";
1438         break;
1439       case 156:
1440         return "5.2";
1441         break;
1442       case 183:
1443         return "6.1";
1444         break;
1445       case 186:
1446         return "6.2";
1447         break;
1448       default:
1449         return NULL;
1450     }
1451   }
1452 }
1453
1454 /**
1455  * gst_codec_utils_h265_get_level_idc:
1456  * @level: A level string from caps
1457  *
1458  * Transform a level string from the caps into the level_idc
1459  *
1460  * Returns: the level_idc or 0 if the level is unknown
1461  *
1462  * Since: 1.4
1463  */
1464 guint8
1465 gst_codec_utils_h265_get_level_idc (const gchar * level)
1466 {
1467   g_return_val_if_fail (level != NULL, 0);
1468
1469   if (!strcmp (level, "1"))
1470     return 30;
1471   else if (!strcmp (level, "2"))
1472     return 60;
1473   else if (!strcmp (level, "2.1"))
1474     return 63;
1475   else if (!strcmp (level, "3"))
1476     return 90;
1477   else if (!strcmp (level, "3.1"))
1478     return 93;
1479   else if (!strcmp (level, "4"))
1480     return 120;
1481   else if (!strcmp (level, "4.1"))
1482     return 123;
1483   else if (!strcmp (level, "5"))
1484     return 150;
1485   else if (!strcmp (level, "5.1"))
1486     return 153;
1487   else if (!strcmp (level, "5.2"))
1488     return 156;
1489   else if (!strcmp (level, "6"))
1490     return 180;
1491   else if (!strcmp (level, "6.1"))
1492     return 183;
1493   else if (!strcmp (level, "6.2"))
1494     return 186;
1495
1496   GST_WARNING ("Invalid level %s", level);
1497   return 0;
1498 }
1499
1500 /**
1501  * gst_codec_utils_h265_caps_set_level_tier_and_profile:
1502  * @caps: the #GstCaps to which the level, tier and profile are to be added
1503  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1504  *   struct
1505  * @len: Length of the data available in @profile_tier_level.
1506  *
1507  * Sets the level, tier and profile in @caps if it can be determined from
1508  * @profile_tier_level. See gst_codec_utils_h265_get_level(),
1509  * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
1510  * for more details on the parameters.
1511  *
1512  * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
1513  *
1514  * Since: 1.4
1515  */
1516 gboolean
1517 gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
1518     const guint8 * profile_tier_level, guint len)
1519 {
1520   const gchar *level, *tier, *profile;
1521
1522   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1523   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1524   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
1525   g_return_val_if_fail (profile_tier_level != NULL, FALSE);
1526
1527   level = gst_codec_utils_h265_get_level (profile_tier_level, len);
1528   if (level != NULL)
1529     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1530
1531   tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
1532   if (tier != NULL)
1533     gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
1534
1535   profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
1536   if (profile != NULL)
1537     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1538
1539   GST_LOG ("profile : %s", (profile) ? profile : "---");
1540   GST_LOG ("tier    : %s", (tier) ? tier : "---");
1541   GST_LOG ("level   : %s", (level) ? level : "---");
1542
1543   return (level != NULL && tier != NULL && profile != NULL);
1544 }
1545
1546 /**
1547  * gst_codec_utils_mpeg4video_get_profile:
1548  * @vis_obj_seq: (array length=len): Pointer to the visual object
1549  *   sequence for the stream.
1550  * @len: Length of the data available in @sps.
1551  *
1552  * Converts the profile indication in the stream's visual object sequence into
1553  * a string. @vis_obj_seq is expected to be the data following the visual
1554  * object sequence start code. Only the first byte
1555  * (profile_and_level_indication) is used.
1556  *
1557  * Returns: (nullable): The profile as a const string, or NULL if there is an error.
1558  */
1559 const gchar *
1560 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
1561 {
1562   /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
1563    * sources: epan/dissectors/packet-mp4ves.c */
1564
1565   /* These are a direct mapping from the integer profile id -> string. Profiles
1566    * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
1567    * second 4 bits of vis_obj_seq[0], so they are handled separately. */
1568   static const char *profiles[] = { "simple", "simple-scalable", "core",
1569     "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
1570     "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
1571     "advanced-core", "advanced-scalable-texture",
1572   };
1573   int profile_id, level_id;
1574
1575   g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1576
1577   if (len < 1)
1578     return NULL;
1579
1580   GST_MEMDUMP ("VOS", vis_obj_seq, len);
1581
1582   profile_id = vis_obj_seq[0] >> 4;
1583   level_id = vis_obj_seq[0] & 0xf;
1584
1585   GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1586
1587   if (profile_id != 6 && profile_id < 0xe)
1588     return profiles[profile_id];
1589
1590   if (profile_id != 0xf && level_id == 0)
1591     return NULL;
1592
1593   switch (profile_id) {
1594     case 0x6:
1595       if (level_id < 3)
1596         return "simple-face";
1597       else if (level_id < 5)
1598         return "simple-fba";
1599       break;
1600
1601     case 0xe:
1602       if (level_id < 5)
1603         return "simple-studio";
1604       else if (level_id < 9)
1605         return "core-studio";
1606       break;
1607
1608     case 0xf:
1609       if (level_id < 6)
1610         return "advanced-simple";
1611       else if (level_id > 7 && level_id < 0xe)
1612         return "fine-granularity-scalable";
1613       break;
1614   }
1615
1616   return NULL;
1617 }
1618
1619 /**
1620  * gst_codec_utils_mpeg4video_get_level:
1621  * @vis_obj_seq: (array length=len): Pointer to the visual object
1622  *   sequence for the stream.
1623  * @len: Length of the data available in @sps.
1624  *
1625  * Converts the level indication in the stream's visual object sequence into
1626  * a string. @vis_obj_seq is expected to be the data following the visual
1627  * object sequence start code. Only the first byte
1628  * (profile_and_level_indication) is used.
1629  *
1630  * Returns: (nullable): The level as a const string, or NULL if there is an error.
1631  */
1632 const gchar *
1633 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
1634 {
1635   /* The profile/level codes are from 14496-2, table G-1, the Wireshark
1636    * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
1637    * src/xvid.h.
1638    * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
1639    * (see Xvid sources vfw/config.c)
1640    *
1641    * Each profile has a different maximum level it defines. Some of them still
1642    * need special case handling, because not all levels start from 1, and the
1643    * Simple profile defines an intermediate level as well. */
1644   static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
1645     5
1646   };
1647   int profile_id, level_id;
1648
1649   g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1650
1651   if (len < 1)
1652     return NULL;
1653
1654   GST_MEMDUMP ("VOS", vis_obj_seq, len);
1655
1656   profile_id = vis_obj_seq[0] >> 4;
1657   level_id = vis_obj_seq[0] & 0xf;
1658
1659   GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1660
1661   if (profile_id != 0xf && level_id == 0)
1662     return NULL;
1663
1664   /* Let's do some validation of the level */
1665   switch (profile_id) {
1666     case 0x3:
1667       if (level_id == 1)
1668         return NULL;
1669       break;
1670
1671     case 0x4:
1672       if (level_id != 2)
1673         return NULL;
1674       break;
1675
1676     case 0x6:
1677       if (level_id > 5)
1678         return NULL;
1679       break;
1680
1681     case 0xe:
1682       if (level_id > 9)
1683         return NULL;
1684       break;
1685
1686     case 0xf:
1687       if (level_id == 6 || level_id == 7 || level_id > 0xd)
1688         return NULL;
1689       break;
1690   }
1691
1692   if (profile_id == 0 && level_id == 8)
1693     /* Simple Profile / Level 0 */
1694     return "0";
1695   else if (profile_id == 0 && level_id == 9)
1696     /* Simple Profile / Level 0b */
1697     return "0b";
1698   else if (profile_id == 0 && level_id == 4)
1699     /* Simple Profile / Level 4a */
1700     return "4a";
1701   else if (profile_id == 0xf && level_id > 7)
1702     /* Fine Granularity Scalable Profile */
1703     return digit_to_string (level_id - 8);
1704   else if (level_id <= level_max[profile_id])
1705     /* Levels for all other cases */
1706     return digit_to_string (level_id);
1707
1708   return NULL;
1709 }
1710
1711 /**
1712  * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
1713  * @caps: the #GstCaps to which the level and profile are to be added
1714  * @vis_obj_seq: (array length=len): Pointer to the visual object
1715  *   sequence for the stream.
1716  * @len: Length of the data available in @sps.
1717  *
1718  * Sets the level and profile in @caps if it can be determined from
1719  * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
1720  * gst_codec_utils_mpeg4video_get_profile() for more details on the
1721  * parameters.
1722  *
1723  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
1724  */
1725 gboolean
1726 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
1727     const guint8 * vis_obj_seq, guint len)
1728 {
1729   const gchar *profile, *level;
1730
1731   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1732   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1733   g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
1734
1735   profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
1736
1737   if (profile != NULL)
1738     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1739
1740   level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
1741
1742   if (level != NULL)
1743     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1744
1745   GST_LOG ("profile : %s", (profile) ? profile : "---");
1746   GST_LOG ("level   : %s", (level) ? level : "---");
1747
1748   return (profile != NULL && level != NULL);
1749 }
1750
1751 /**
1752  * gst_codec_utils_opus_parse_caps:
1753  * @caps: the #GstCaps to parse the data from
1754  * @rate: (optional) (out): the sample rate
1755  * @channels: (optional) (out): the number of channels
1756  * @channel_mapping_family: (optional) (out): the channel mapping family
1757  * @stream_count: (optional) (out): the number of independent streams
1758  * @coupled_count: (optional) (out): the number of stereo streams
1759  * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
1760  *
1761  * Parses Opus caps and fills the different fields with defaults if possible.
1762  *
1763  * Returns: %TRUE if parsing was successful, %FALSE otherwise.
1764  *
1765  * Since: 1.8
1766  */
1767 gboolean
1768 gst_codec_utils_opus_parse_caps (GstCaps * caps,
1769     guint32 * rate,
1770     guint8 * channels,
1771     guint8 * channel_mapping_family,
1772     guint8 * stream_count, guint8 * coupled_count, guint8 channel_mapping[256])
1773 {
1774   GstStructure *s;
1775   gint c, f, sc, cc;
1776   const GValue *va, *v;
1777
1778   g_return_val_if_fail (caps != NULL, FALSE);
1779   g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1780   g_return_val_if_fail (!gst_caps_is_empty (caps), FALSE);
1781
1782   s = gst_caps_get_structure (caps, 0);
1783
1784   g_return_val_if_fail (gst_structure_has_name (s, "audio/x-opus"), FALSE);
1785   g_return_val_if_fail (gst_structure_has_field_typed (s,
1786           "channel-mapping-family", G_TYPE_INT), FALSE);
1787
1788   if (rate) {
1789     gint r;
1790
1791     if (gst_structure_get_int (s, "rate", &r))
1792       *rate = r;
1793     else
1794       *rate = 48000;
1795   }
1796
1797   gst_structure_get_int (s, "channel-mapping-family", &f);
1798   if (channel_mapping_family)
1799     *channel_mapping_family = f;
1800
1801   if (!gst_structure_get_int (s, "channels", &c) || c == 0) {
1802     if (f == 0)
1803       c = 2;
1804     else
1805       return FALSE;
1806   }
1807
1808   if (channels)
1809     *channels = c;
1810
1811   /* RTP mapping */
1812   if (f == 0) {
1813     if (c > 2)
1814       return FALSE;
1815
1816     if (stream_count)
1817       *stream_count = 1;
1818     if (coupled_count)
1819       *coupled_count = c == 2 ? 1 : 0;
1820
1821     if (channel_mapping) {
1822       channel_mapping[0] = 0;
1823       channel_mapping[1] = 1;
1824     }
1825
1826     return TRUE;
1827   }
1828
1829   if (!gst_structure_get_int (s, "stream-count", &sc))
1830     return FALSE;
1831   if (stream_count)
1832     *stream_count = sc;
1833
1834   if (!gst_structure_get_int (s, "coupled-count", &cc))
1835     return FALSE;
1836   if (coupled_count)
1837     *coupled_count = cc;
1838
1839   va = gst_structure_get_value (s, "channel-mapping");
1840   if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY))
1841     return FALSE;
1842
1843   if (gst_value_array_get_size (va) != c)
1844     return FALSE;
1845
1846   if (channel_mapping) {
1847     gint i;
1848
1849     for (i = 0; i < c; i++) {
1850       gint cm;
1851
1852       v = gst_value_array_get_value (va, i);
1853
1854       if (!G_VALUE_HOLDS (v, G_TYPE_INT))
1855         return FALSE;
1856
1857       cm = g_value_get_int (v);
1858       if (cm < 0 || cm > 255)
1859         return FALSE;
1860
1861       channel_mapping[i] = cm;
1862     }
1863   }
1864
1865   return TRUE;
1866 }
1867
1868 /**
1869  * gst_codec_utils_opus_create_caps:
1870  * @rate: the sample rate
1871  * @channels: the number of channels
1872  * @channel_mapping_family: the channel mapping family
1873  * @stream_count: the number of independent streams
1874  * @coupled_count: the number of stereo streams
1875  * @channel_mapping: (nullable) (array): the mapping between the streams
1876  *
1877  * Creates Opus caps from the given parameters.
1878  *
1879  * Returns: (transfer full) (nullable): The #GstCaps, or %NULL if the parameters would lead to
1880  * invalid Opus caps.
1881  *
1882  * Since: 1.8
1883  */
1884 GstCaps *
1885 gst_codec_utils_opus_create_caps (guint32 rate,
1886     guint8 channels,
1887     guint8 channel_mapping_family,
1888     guint8 stream_count, guint8 coupled_count, const guint8 * channel_mapping)
1889 {
1890   GstCaps *caps = NULL;
1891   GValue va = G_VALUE_INIT;
1892   GValue v = G_VALUE_INIT;
1893   gint i;
1894
1895   if (rate == 0)
1896     rate = 48000;
1897
1898   if (channel_mapping_family == 0) {
1899     if (channels > 2) {
1900       GST_ERROR ("Invalid channels count for channel_mapping_family 0: %d",
1901           channels);
1902       goto done;
1903     }
1904
1905     if (stream_count > 1) {
1906       GST_ERROR ("Invalid stream count for channel_mapping_family 0: %d",
1907           stream_count);
1908       goto done;
1909     }
1910
1911     if (coupled_count > 1) {
1912       GST_ERROR ("Invalid coupled count for channel_mapping_family 0: %d",
1913           coupled_count);
1914       goto done;
1915     }
1916
1917     if (channels == 0)
1918       channels = 2;
1919
1920     if (stream_count == 0)
1921       stream_count = 1;
1922
1923     if (coupled_count == 0)
1924       coupled_count = channels == 2 ? 1 : 0;
1925
1926     return gst_caps_new_simple ("audio/x-opus",
1927         "rate", G_TYPE_INT, rate,
1928         "channels", G_TYPE_INT, channels,
1929         "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1930         "stream-count", G_TYPE_INT, stream_count,
1931         "coupled-count", G_TYPE_INT, coupled_count, NULL);
1932   }
1933
1934   if (channels == 0) {
1935     GST_ERROR ("Invalid channels count: %d", channels);
1936     goto done;
1937   }
1938
1939   if (stream_count == 0) {
1940     GST_ERROR ("Invalid stream count: %d", stream_count);
1941     goto done;
1942   }
1943
1944   if (coupled_count > stream_count) {
1945     GST_ERROR ("Coupled count %d > stream count: %d", coupled_count,
1946         stream_count);
1947     goto done;
1948   }
1949
1950   if (channel_mapping == NULL) {
1951     GST_ERROR
1952         ("A non NULL channel-mapping is needed for channel_mapping_family != 0");
1953     goto done;
1954   }
1955
1956   caps = gst_caps_new_simple ("audio/x-opus",
1957       "rate", G_TYPE_INT, rate,
1958       "channels", G_TYPE_INT, channels,
1959       "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1960       "stream-count", G_TYPE_INT, stream_count,
1961       "coupled-count", G_TYPE_INT, coupled_count, NULL);
1962
1963   g_value_init (&va, GST_TYPE_ARRAY);
1964   g_value_init (&v, G_TYPE_INT);
1965   for (i = 0; i < channels; i++) {
1966     g_value_set_int (&v, channel_mapping[i]);
1967     gst_value_array_append_value (&va, &v);
1968   }
1969   gst_structure_set_value (gst_caps_get_structure (caps, 0), "channel-mapping",
1970       &va);
1971   g_value_unset (&va);
1972   g_value_unset (&v);
1973
1974 done:
1975   return caps;
1976 }
1977
1978 /*
1979  * (really really) FIXME: move into core (dixit tpm)
1980  */
1981 /*
1982  * _gst_caps_set_buffer_array:
1983  * @caps: (transfer full): a #GstCaps
1984  * @field: field in caps to set
1985  * @buf: header buffers
1986  *
1987  * Adds given buffers to an array of buffers set as the given @field
1988  * on the given @caps.  List of buffer arguments must be NULL-terminated.
1989  *
1990  * Returns: (transfer full): input caps with a streamheader field added, or NULL
1991  *     if some error occurred
1992  */
1993 static GstCaps *
1994 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
1995     GstBuffer * buf, ...)
1996 {
1997   GstStructure *structure = NULL;
1998   va_list va;
1999   GValue array = { 0 };
2000   GValue value = { 0 };
2001
2002   g_return_val_if_fail (caps != NULL, NULL);
2003   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2004   g_return_val_if_fail (field != NULL, NULL);
2005
2006   caps = gst_caps_make_writable (caps);
2007   structure = gst_caps_get_structure (caps, 0);
2008
2009   g_value_init (&array, GST_TYPE_ARRAY);
2010
2011   va_start (va, buf);
2012   /* put buffers in a fixed list */
2013   while (buf) {
2014     g_assert (gst_buffer_is_writable (buf));
2015
2016     /* mark buffer */
2017     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2018
2019     g_value_init (&value, GST_TYPE_BUFFER);
2020     buf = gst_buffer_copy (buf);
2021     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2022     gst_value_set_buffer (&value, buf);
2023     gst_buffer_unref (buf);
2024     gst_value_array_append_value (&array, &value);
2025     g_value_unset (&value);
2026
2027     buf = va_arg (va, GstBuffer *);
2028   }
2029   va_end (va);
2030
2031   gst_structure_set_value (structure, field, &array);
2032   g_value_unset (&array);
2033
2034   return caps;
2035 }
2036
2037 /**
2038  * gst_codec_utils_opus_create_caps_from_header:
2039  * @header: OpusHead header
2040  * @comments: (nullable): Comment header or NULL
2041  *
2042  * Creates Opus caps from the given OpusHead @header and comment header
2043  * @comments.
2044  *
2045  * Returns: (transfer full) (nullable): The #GstCaps.
2046  *
2047  * Since: 1.8
2048  */
2049 GstCaps *
2050 gst_codec_utils_opus_create_caps_from_header (GstBuffer * header,
2051     GstBuffer * comments)
2052 {
2053   GstCaps *caps;
2054   guint32 rate;
2055   guint8 channels;
2056   guint8 channel_mapping_family;
2057   guint8 stream_count;
2058   guint8 coupled_count;
2059   guint8 channel_mapping[256];
2060   GstBuffer *dummy_comments = NULL;
2061
2062   g_return_val_if_fail (GST_IS_BUFFER (header), NULL);
2063   g_return_val_if_fail (comments == NULL || GST_IS_BUFFER (comments), NULL);
2064
2065   if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
2066           &channel_mapping_family, &stream_count, &coupled_count,
2067           channel_mapping, NULL, NULL))
2068     return NULL;
2069
2070   if (!(caps =
2071           gst_codec_utils_opus_create_caps (rate, channels,
2072               channel_mapping_family, stream_count, coupled_count,
2073               channel_mapping)))
2074     return NULL;
2075
2076   if (!comments) {
2077     GstTagList *tags = gst_tag_list_new_empty ();
2078     dummy_comments =
2079         gst_tag_list_to_vorbiscomment_buffer (tags, (const guint8 *) "OpusTags",
2080         8, NULL);
2081     gst_tag_list_unref (tags);
2082   }
2083   _gst_caps_set_buffer_array (caps, "streamheader", header,
2084       comments ? comments : dummy_comments, NULL);
2085
2086   if (dummy_comments)
2087     gst_buffer_unref (dummy_comments);
2088
2089   return caps;
2090 }
2091
2092 /**
2093  * gst_codec_utils_opus_create_header:
2094  * @rate: the sample rate
2095  * @channels: the number of channels
2096  * @channel_mapping_family: the channel mapping family
2097  * @stream_count: the number of independent streams
2098  * @coupled_count: the number of stereo streams
2099  * @channel_mapping: (nullable) (array): the mapping between the streams
2100  * @pre_skip: Pre-skip in 48kHz samples or 0
2101  * @output_gain: Output gain or 0
2102  *
2103  * Creates OpusHead header from the given parameters.
2104  *
2105  * Returns: (transfer full) (nullable): The #GstBuffer containing the OpusHead.
2106  *
2107  * Since: 1.8
2108  */
2109 GstBuffer *
2110 gst_codec_utils_opus_create_header (guint32 rate,
2111     guint8 channels,
2112     guint8 channel_mapping_family,
2113     guint8 stream_count,
2114     guint8 coupled_count,
2115     const guint8 * channel_mapping, guint16 pre_skip, gint16 output_gain)
2116 {
2117   GstBuffer *buffer;
2118   GstByteWriter bw;
2119   gboolean hdl = TRUE;
2120
2121   if (rate == 0)
2122     rate = 48000;
2123
2124   if (channel_mapping_family == 0) {
2125     g_return_val_if_fail (channels <= 2, NULL);
2126     if (channels == 0)
2127       channels = 2;
2128
2129     g_return_val_if_fail (stream_count == 0 || stream_count == 1, NULL);
2130     if (stream_count == 0)
2131       stream_count = 1;
2132
2133     g_return_val_if_fail (coupled_count == 0 || coupled_count == 1, NULL);
2134     if (coupled_count == 0)
2135       coupled_count = channels == 2 ? 1 : 0;
2136
2137     channel_mapping = NULL;
2138   } else {
2139     g_return_val_if_fail (channels > 0, NULL);
2140     g_return_val_if_fail (stream_count > 0, NULL);
2141     g_return_val_if_fail (coupled_count <= stream_count, NULL);
2142     g_return_val_if_fail (channel_mapping != NULL, NULL);
2143   }
2144
2145   gst_byte_writer_init (&bw);
2146   /* See http://wiki.xiph.org/OggOpus */
2147   hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
2148   hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
2149   hdl &= gst_byte_writer_put_uint8 (&bw, channels);
2150   hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
2151   hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
2152   hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
2153   hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
2154   if (channel_mapping_family > 0) {
2155     hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
2156     hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
2157     hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
2158   }
2159
2160   if (!hdl) {
2161     GST_WARNING ("Error creating header");
2162     gst_byte_writer_reset (&bw);
2163     return NULL;
2164   }
2165
2166   buffer = gst_byte_writer_reset_and_get_buffer (&bw);
2167   GST_BUFFER_OFFSET (buffer) = 0;
2168   GST_BUFFER_OFFSET_END (buffer) = 0;
2169
2170   return buffer;
2171 }
2172
2173 /**
2174  * gst_codec_utils_opus_parse_header:
2175  * @header: the OpusHead #GstBuffer
2176  * @rate: (optional) (out): the sample rate
2177  * @channels: (optional) (out): the number of channels
2178  * @channel_mapping_family: (optional) (out): the channel mapping family
2179  * @stream_count: (optional) (out): the number of independent streams
2180  * @coupled_count: (optional) (out): the number of stereo streams
2181  * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
2182  * @pre_skip: (optional) (out): Pre-skip in 48kHz samples or 0
2183  * @output_gain: (optional) (out): Output gain or 0
2184  *
2185  * Parses the OpusHead header.
2186  *
2187  * Returns: %TRUE if parsing was successful, %FALSE otherwise.
2188  *
2189  * Since: 1.8
2190  */
2191 gboolean
2192 gst_codec_utils_opus_parse_header (GstBuffer * header,
2193     guint32 * rate,
2194     guint8 * channels,
2195     guint8 * channel_mapping_family,
2196     guint8 * stream_count,
2197     guint8 * coupled_count,
2198     guint8 channel_mapping[256], guint16 * pre_skip, gint16 * output_gain)
2199 {
2200   GstByteReader br;
2201   GstMapInfo map;
2202   gboolean ret = TRUE;
2203   guint8 c, f, version;
2204
2205   g_return_val_if_fail (GST_IS_BUFFER (header), FALSE);
2206   g_return_val_if_fail (gst_buffer_get_size (header) >= 19, FALSE);
2207
2208   if (!gst_buffer_map (header, &map, GST_MAP_READ))
2209     return FALSE;
2210   gst_byte_reader_init (&br, map.data, map.size);
2211   /* See http://wiki.xiph.org/OggOpus */
2212   if (memcmp (gst_byte_reader_get_data_unchecked (&br, 8), "OpusHead", 8) != 0) {
2213     ret = FALSE;
2214     goto done;
2215   }
2216   version = gst_byte_reader_get_uint8_unchecked (&br);
2217   if (version == 0x00)
2218     GST_ERROR ("Opus Header version is wrong, should be 0x01 and not 0x00");
2219   else if (version != 0x01) {
2220     ret = FALSE;
2221     goto done;
2222   }
2223
2224   c = gst_byte_reader_get_uint8_unchecked (&br);
2225   if (channels)
2226     *channels = c;
2227
2228   if (pre_skip)
2229     *pre_skip = gst_byte_reader_get_uint16_le_unchecked (&br);
2230   else
2231     gst_byte_reader_skip_unchecked (&br, 2);
2232
2233   if (rate)
2234     *rate = gst_byte_reader_get_uint32_le_unchecked (&br);
2235   else
2236     gst_byte_reader_skip_unchecked (&br, 4);
2237
2238   if (output_gain)
2239     *output_gain = gst_byte_reader_get_uint16_le_unchecked (&br);
2240   else
2241     gst_byte_reader_skip_unchecked (&br, 2);
2242
2243   f = gst_byte_reader_get_uint8_unchecked (&br);
2244   if (channel_mapping_family)
2245     *channel_mapping_family = f;
2246   if (f == 0 && c <= 2) {
2247     if (stream_count)
2248       *stream_count = 1;
2249     if (coupled_count)
2250       *coupled_count = c == 2 ? 1 : 0;
2251     if (channel_mapping) {
2252       channel_mapping[0] = 0;
2253       channel_mapping[1] = 1;
2254     }
2255
2256     goto done;
2257   }
2258
2259   if (gst_byte_reader_get_remaining (&br) < 2 + c) {
2260     ret = FALSE;
2261     goto done;
2262   }
2263
2264   if (stream_count)
2265     *stream_count = gst_byte_reader_get_uint8_unchecked (&br);
2266   else
2267     gst_byte_reader_skip_unchecked (&br, 1);
2268
2269   if (coupled_count)
2270     *coupled_count = gst_byte_reader_get_uint8_unchecked (&br);
2271   else
2272     gst_byte_reader_skip_unchecked (&br, 1);
2273
2274   if (channel_mapping)
2275     memcpy (channel_mapping, gst_byte_reader_get_data_unchecked (&br, c), c);
2276
2277 done:
2278   gst_buffer_unmap (header, &map);
2279
2280   return ret;
2281 }
2282
2283 static gboolean
2284 h264_caps_structure_get_profile_flags_level (GstStructure * caps_st,
2285     guint8 * profile, guint8 * flags, guint8 * level)
2286 {
2287   const GValue *codec_data_value = NULL;
2288   GstBuffer *codec_data = NULL;
2289   GstMapInfo map;
2290   gboolean ret = FALSE;
2291   guint8 *data = NULL;
2292   gsize size;
2293
2294   codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2295   if (!codec_data_value) {
2296     GST_DEBUG
2297         ("video/x-h264 caps did not have codec_data set, cannot parse profile, flags and level");
2298     return FALSE;
2299   }
2300
2301   codec_data = gst_value_get_buffer (codec_data_value);
2302   if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2303     return FALSE;
2304   }
2305   data = map.data;
2306   size = map.size;
2307
2308   if (!gst_codec_utils_h264_get_profile_flags_level (data, (guint) size,
2309           profile, flags, level)) {
2310     GST_WARNING
2311         ("Failed to parse profile, flags and level from h264 codec data");
2312     goto done;
2313   }
2314
2315   ret = TRUE;
2316
2317 done:
2318   gst_buffer_unmap (codec_data, &map);
2319
2320   return ret;
2321 }
2322
2323 static gboolean
2324 aac_caps_structure_get_audio_object_type (GstStructure * caps_st,
2325     guint8 * audio_object_type)
2326 {
2327   gboolean ret = FALSE;
2328   const GValue *codec_data_value = NULL;
2329   GstBuffer *codec_data = NULL;
2330   GstMapInfo map;
2331   guint8 *data = NULL;
2332   gsize size;
2333   GstBitReader br;
2334
2335   codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2336   if (!codec_data_value) {
2337     GST_DEBUG
2338         ("audio/mpeg pad did not have codec_data set, cannot parse audio object type");
2339     return FALSE;
2340   }
2341
2342   codec_data = gst_value_get_buffer (codec_data_value);
2343   if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2344     return FALSE;
2345   }
2346   data = map.data;
2347   size = map.size;
2348
2349   if (size < 2) {
2350     GST_WARNING ("aac codec data is too small");
2351     goto done;
2352   }
2353
2354   gst_bit_reader_init (&br, data, size);
2355   ret = gst_codec_utils_aac_get_audio_object_type (&br, audio_object_type);
2356
2357 done:
2358   gst_buffer_unmap (codec_data, &map);
2359
2360   return ret;
2361 }
2362
2363 static gboolean
2364 hevc_caps_get_mime_codec (GstCaps * caps, gchar ** mime_codec)
2365 {
2366   GstStructure *caps_st = NULL;
2367   const GValue *codec_data_value = NULL;
2368   GstBuffer *codec_data = NULL;
2369   GstMapInfo map;
2370   gboolean ret = FALSE;
2371   const gchar *stream_format;
2372   guint8 *data = NULL;
2373   gsize size;
2374   guint16 profile_space;
2375   guint8 tier_flag;
2376   guint16 profile_idc;
2377   guint32 compat_flags;
2378   guchar constraint_indicator_flags[6];
2379   guint8 level_idc;
2380   guint32 compat_flag_parameter = 0;
2381   GString *codec_string;
2382   const guint8 *profile_tier_level;
2383   gint last_flag_index;
2384
2385   caps_st = gst_caps_get_structure (caps, 0);
2386   codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2387   stream_format = gst_structure_get_string (caps_st, "stream-format");
2388   if (!codec_data_value) {
2389     GST_DEBUG ("video/x-h265 caps did not have codec_data set, cannot parse");
2390     return FALSE;
2391   } else if (!stream_format) {
2392     GST_DEBUG
2393         ("video/x-h265 caps did not have stream-format set, cannot parse");
2394     return FALSE;
2395   }
2396
2397   codec_data = gst_value_get_buffer (codec_data_value);
2398   if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2399     return FALSE;
2400   }
2401   data = map.data;
2402   size = map.size;
2403
2404   /* HEVCDecoderConfigurationRecord is at a minimum 23 bytes long */
2405   if (size < 23) {
2406     GST_DEBUG ("Incomplete HEVCDecoderConfigurationRecord");
2407     goto done;
2408   }
2409
2410   if (!g_str_equal (stream_format, "hev1")
2411       && !g_str_equal (stream_format, "hvc1")) {
2412     GST_DEBUG ("Unknown stream-format %s", stream_format);
2413     goto done;
2414   }
2415
2416   profile_tier_level = data + 1;
2417   profile_space = (profile_tier_level[0] & 0x11) >> 6;
2418   tier_flag = (profile_tier_level[0] & 0x001) >> 5;
2419   profile_idc = (profile_tier_level[0] & 0x1f);
2420
2421   compat_flags = GST_READ_UINT32_BE (data + 2);
2422   for (unsigned i = 0; i < 6; ++i)
2423     constraint_indicator_flags[i] = GST_READ_UINT8 (data + 6 + i);
2424
2425   level_idc = data[12];
2426
2427   /* The 32 bits of the compat_flags, but in reverse bit order */
2428   compat_flags =
2429       ((compat_flags & 0xaaaaaaaa) >> 1) | ((compat_flags & 0x55555555) << 1);
2430   compat_flags =
2431       ((compat_flags & 0xcccccccc) >> 2) | ((compat_flags & 0x33333333) << 2);
2432   compat_flags =
2433       ((compat_flags & 0xf0f0f0f0) >> 4) | ((compat_flags & 0x0f0f0f0f) << 4);
2434   compat_flags =
2435       ((compat_flags & 0xff00ff00) >> 8) | ((compat_flags & 0x00ff00ff) << 8);
2436   compat_flag_parameter = (compat_flags >> 16) | (compat_flags << 16);
2437
2438   codec_string = g_string_new (stream_format);
2439   codec_string = g_string_append_c (codec_string, '.');
2440   if (profile_space)
2441     codec_string = g_string_append_c (codec_string, 'A' + profile_space - 1);
2442   g_string_append_printf (codec_string, "%" G_GUINT16_FORMAT ".%X.%c%d",
2443       profile_idc, compat_flag_parameter, tier_flag ? 'H' : 'L', level_idc);
2444
2445   /* Each of the 6 bytes of the constraint flags, starting from the byte containing the
2446    * progressive_source_flag, each encoded as a hexadecimal number, and the encoding
2447    * of each byte separated by a period; trailing bytes that are zero may be omitted.
2448    */
2449   last_flag_index = 5;
2450   while (last_flag_index >= 0
2451       && (int) (constraint_indicator_flags[last_flag_index]) == 0)
2452     --last_flag_index;
2453   for (gint i = 0; i <= last_flag_index; ++i) {
2454     g_string_append_printf (codec_string, ".%02X",
2455         constraint_indicator_flags[i]);
2456   }
2457
2458   *mime_codec = g_string_free (codec_string, FALSE);
2459
2460   ret = TRUE;
2461
2462 done:
2463   gst_buffer_unmap (codec_data, &map);
2464   return ret;
2465 }
2466
2467 /* https://www.webmproject.org/vp9/mp4/#codecs-parameter-string */
2468 static char *
2469 vp9_caps_get_mime_codec (GstCaps * caps)
2470 {
2471   GstStructure *caps_st;
2472   const char *profile_str, *chroma_format_str, *colorimetry_str;
2473   guint bitdepth_luma, bitdepth_chroma;
2474   guint8 profile = -1, chroma_format = -1, level = -1, color_primaries =
2475       -1, color_transfer = -1, color_matrix = -1;
2476   gboolean video_full_range;
2477   GstVideoColorimetry cinfo = { 0, };
2478   GString *codec_string;
2479
2480   caps_st = gst_caps_get_structure (caps, 0);
2481   codec_string = g_string_new ("vp09");
2482
2483   profile_str = gst_structure_get_string (caps_st, "profile");
2484   if (g_strcmp0 (profile_str, "0") == 0) {
2485     profile = 0;
2486   } else if (g_strcmp0 (profile_str, "1") == 0) {
2487     profile = 1;
2488   } else if (g_strcmp0 (profile_str, "2") == 0) {
2489     profile = 2;
2490   } else if (g_strcmp0 (profile_str, "3") == 0) {
2491     profile = 3;
2492   } else {
2493     goto done;
2494   }
2495
2496   /* XXX: hardcoded level */
2497   level = 10;
2498
2499   gst_structure_get (caps_st, "bit-depth-luma", G_TYPE_UINT,
2500       &bitdepth_luma, "bit-depth-chroma", G_TYPE_UINT, &bitdepth_chroma, NULL);
2501
2502   if (bitdepth_luma == 0)
2503     goto done;
2504   if (bitdepth_luma != bitdepth_chroma)
2505     goto done;
2506
2507   /* mandatory elements */
2508   g_string_append_printf (codec_string, ".%02u.%02u.%02u", profile, level,
2509       bitdepth_luma);
2510
2511   colorimetry_str = gst_structure_get_string (caps_st, "colorimetry");
2512   if (!colorimetry_str)
2513     goto done;
2514   if (!gst_video_colorimetry_from_string (&cinfo, colorimetry_str))
2515     goto done;
2516   video_full_range = cinfo.range == GST_VIDEO_COLOR_RANGE_0_255;
2517
2518   chroma_format_str = gst_structure_get_string (caps_st, "chroma-format");
2519   if (g_strcmp0 (chroma_format_str, "4:2:0") == 0) {
2520     const char *chroma_site_str;
2521     GstVideoChromaSite chroma_site;
2522
2523     chroma_site_str = gst_structure_get_string (caps_st, "chroma-site");
2524     if (chroma_site_str)
2525       chroma_site = gst_video_chroma_site_from_string (chroma_site_str);
2526     else
2527       chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN;
2528     if (chroma_site == GST_VIDEO_CHROMA_SITE_V_COSITED) {
2529       chroma_format = 0;
2530     } else if (chroma_site == GST_VIDEO_CHROMA_SITE_COSITED) {
2531       chroma_format = 1;
2532     } else {
2533       chroma_format = 1;
2534     }
2535   } else if (g_strcmp0 (chroma_format_str, "4:2:2") == 0) {
2536     chroma_format = 2;
2537   } else if (g_strcmp0 (chroma_format_str, "4:4:4") == 0) {
2538     chroma_format = 3;
2539   } else {
2540     goto done;
2541   }
2542
2543   /* optional but all or nothing. Include them if any parameter differs from the default value */
2544   color_primaries = gst_video_color_primaries_to_iso (cinfo.primaries);
2545   color_transfer = gst_video_transfer_function_to_iso (cinfo.transfer);
2546   color_matrix = gst_video_color_matrix_to_iso (cinfo.matrix);
2547   if (chroma_format != 1 || color_primaries != 1 || color_transfer != 1
2548       || color_matrix != 1 || video_full_range) {
2549     g_string_append_printf (codec_string, ".%02u.%02u.%02u.%02u.%02u",
2550         chroma_format, color_primaries, color_transfer, color_matrix,
2551         video_full_range);
2552   }
2553
2554 done:
2555   return g_string_free (codec_string, FALSE);
2556 }
2557
2558 /**
2559  * gst_codec_utils_caps_get_mime_codec:
2560  * @caps: A #GstCaps to convert to mime codec
2561  *
2562  * Converts @caps to a RFC 6381 compatible codec string if possible.
2563  *
2564  * Useful for providing the 'codecs' field inside the 'Content-Type' HTTP
2565  * header for containerized formats, such as mp4 or matroska.
2566  *
2567  * Registered codecs can be found at http://mp4ra.org/#/codecs
2568  *
2569  * Returns: (transfer full) (nullable): a RFC 6381 compatible codec string or %NULL
2570  *
2571  * Since: 1.20
2572  */
2573 gchar *
2574 gst_codec_utils_caps_get_mime_codec (GstCaps * caps)
2575 {
2576   gchar *mime_codec = NULL;
2577   GstStructure *caps_st = NULL;
2578   const gchar *media_type = NULL;
2579
2580   g_return_val_if_fail (caps != NULL, NULL);
2581   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2582
2583   caps_st = gst_caps_get_structure (caps, 0);
2584   if (caps_st == NULL) {
2585     GST_WARNING ("Failed to get structure from caps");
2586     goto done;
2587   }
2588
2589   media_type = gst_structure_get_name (caps_st);
2590
2591   if (g_strcmp0 (media_type, "video/x-h264") == 0) {
2592     /* avc1.AABBCC
2593      *   AA = profile
2594      *   BB = constraint set flags
2595      *   CC = level
2596      */
2597     guint8 profile = 0;
2598     guint8 flags = 0;
2599     guint8 level = 0;
2600
2601     if (!h264_caps_structure_get_profile_flags_level (caps_st, &profile, &flags,
2602             &level)) {
2603       GST_DEBUG
2604           ("h264 caps did not contain 'codec_data', cannot determine detailed codecs info");
2605       mime_codec = g_strdup ("avc1");
2606     } else {
2607       mime_codec = g_strdup_printf ("avc1.%02X%02X%02X", profile, flags, level);
2608     }
2609   } else if (g_strcmp0 (media_type, "video/x-h265") == 0) {
2610     if (!hevc_caps_get_mime_codec (caps, &mime_codec)) {
2611       GST_DEBUG ("h265 caps parsing failed");
2612       mime_codec = g_strdup ("hev1");
2613     }
2614   } else if (g_strcmp0 (media_type, "video/x-av1") == 0) {
2615     /* TODO: Some browsers won't play the video unless more codec information is
2616      * available in the mime codec for av1. This is documented in
2617      * https://aomediacodec.github.io/av1-isobmff/#codecsparam */
2618     mime_codec = g_strdup ("av01");
2619   } else if (g_strcmp0 (media_type, "video/x-vp8") == 0) {
2620     /* TODO: most browsers won't play the video unless more codec information is
2621      * available in the mime codec for vp8. */
2622     mime_codec = g_strdup ("vp08");
2623   } else if (g_strcmp0 (media_type, "video/x-vp9") == 0) {
2624     mime_codec = vp9_caps_get_mime_codec (caps);
2625   } else if (g_strcmp0 (media_type, "image/jpeg") == 0) {
2626     mime_codec = g_strdup ("mjpg");
2627   } else if (g_strcmp0 (media_type, "audio/mpeg") == 0) {
2628     guint8 audio_object_type = 0;
2629     if (aac_caps_structure_get_audio_object_type (caps_st, &audio_object_type)) {
2630       mime_codec = g_strdup_printf ("mp4a.40.%u", audio_object_type);
2631     } else {
2632       mime_codec = g_strdup ("mp4a.40");
2633     }
2634   } else if (g_strcmp0 (media_type, "audio/x-opus") == 0) {
2635     mime_codec = g_strdup ("opus");
2636   } else if (g_strcmp0 (media_type, "audio/x-mulaw") == 0) {
2637     mime_codec = g_strdup ("ulaw");
2638   } else if (g_strcmp0 (media_type, "audio/x-adpcm") == 0) {
2639     if (g_strcmp0 (gst_structure_get_string (caps_st, "layout"), "g726") == 0) {
2640       mime_codec = g_strdup ("g726");
2641     }
2642   }
2643
2644 done:
2645   return mime_codec;
2646 }
2647
2648 static GstCaps *
2649 gst_codec_utils_caps_from_mime_codec_single (const gchar * codec)
2650 {
2651   GstCaps *caps = NULL;
2652   gchar **subcodec = NULL;
2653   gchar *subcodec0;
2654   guint32 codec_fourcc;
2655
2656   GST_DEBUG ("Analyzing codec '%s'", codec);
2657
2658   /* rfc 6381 3.3
2659    *
2660    * For the ISO Base Media File Format, and the QuickTime movie file
2661    * format, the first element of a 'codecs' parameter value is a sample
2662    * description entry four-character code as registered by the MP4
2663    * Registration Authority [MP4RA].
2664    *
2665    * See Also : http://mp4ra.org/#/codecs
2666    */
2667   if (strlen (codec) < 4) {
2668     GST_WARNING ("Invalid codec (smaller than 4 characters) : '%s'", codec);
2669     goto beach;
2670   }
2671
2672   subcodec = g_strsplit (codec, ".", 0);
2673   subcodec0 = subcodec[0];
2674
2675   if (subcodec0 == NULL)
2676     goto beach;
2677
2678   /* Skip any leading spaces */
2679   while (*subcodec0 == ' ')
2680     subcodec0++;
2681
2682   if (strlen (subcodec0) < 4) {
2683     GST_WARNING ("Invalid codec (smaller than 4 characters) : '%s'", subcodec0);
2684     goto beach;
2685   }
2686
2687   GST_LOG ("subcodec[0] '%s'", subcodec0);
2688
2689   codec_fourcc = GST_READ_UINT32_LE (subcodec0);
2690   switch (codec_fourcc) {
2691     case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
2692     case GST_MAKE_FOURCC ('a', 'v', 'c', '2'):
2693     case GST_MAKE_FOURCC ('a', 'v', 'c', '3'):
2694     case GST_MAKE_FOURCC ('a', 'v', 'c', '4'):
2695     {
2696       guint8 sps[3];
2697       guint64 spsint64;
2698
2699       /* ISO 14496-15 Annex E : Sub-parameters for the MIME type “codecs”
2700        * parameter */
2701       caps = gst_caps_new_empty_simple ("video/x-h264");
2702
2703       if (subcodec[1]) {
2704         /* The second element is the hexadecimal representation of the following
2705          * three bytes in the (subset) sequence parameter set Network
2706          * Abstraction Layer (NAL) unit specified in [AVC]:
2707          * * profile_idc
2708          * * constraint_set flags
2709          * * level_idc
2710          * */
2711         spsint64 = g_ascii_strtoull (subcodec[1], NULL, 16);
2712         sps[0] = spsint64 >> 16;
2713         sps[1] = (spsint64 >> 8) & 0xff;
2714         sps[2] = spsint64 & 0xff;
2715         gst_codec_utils_h264_caps_set_level_and_profile (caps,
2716             (const guint8 *) &sps, 3);
2717       }
2718     }
2719       break;
2720     case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
2721     {
2722       guint64 oti;
2723
2724       if (!subcodec[1])
2725         break;
2726       oti = g_ascii_strtoull (subcodec[1], NULL, 16);
2727       /* For mp4a, mp4v and mp4s, the second element is the hexadecimal
2728        * representation of the MP4 Registration Authority
2729        * ObjectTypeIndication */
2730       switch (oti) {
2731         case 0x40:
2732         {
2733           guint64 audio_oti;
2734           const gchar *profile = NULL;
2735
2736           /* MPEG-4 Audio (ISO/IEC 14496-3 */
2737           caps =
2738               gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4,
2739               NULL);
2740
2741           if (!subcodec[2])
2742             break;
2743           /* If present, last element is the audio object type */
2744           audio_oti = g_ascii_strtoull (subcodec[2], NULL, 16);
2745
2746           switch (audio_oti) {
2747             case 1:
2748               profile = "main";
2749               break;
2750             case 2:
2751               profile = "lc";
2752               break;
2753             case 3:
2754               profile = "ssr";
2755               break;
2756             case 4:
2757               profile = "ltp";
2758               break;
2759             default:
2760               GST_WARNING ("Unhandled MPEG-4 Audio Object Type: 0x%"
2761                   G_GUINT64_FORMAT "x", audio_oti);
2762               break;
2763           }
2764           if (profile)
2765             gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
2766           break;
2767         }
2768         default:
2769           GST_WARNING ("Unknown ObjectTypeIndication 0x%" G_GUINT64_FORMAT "x",
2770               oti);
2771           break;
2772       }
2773     }
2774       break;
2775     case GST_MAKE_FOURCC ('h', 'e', 'v', '1'):
2776     case GST_MAKE_FOURCC ('h', 'v', 'c', '1'):
2777     {
2778       /* ISO 14496-15 Annex E : Sub-parameters for the MIME type “codecs”
2779        * parameter */
2780       caps = gst_caps_new_empty_simple ("video/x-h265");
2781
2782       /* FIXME : Extract information from the following component */
2783       break;
2784     }
2785       /* Following are not defined in rfc 6831 but are registered MP4RA codecs */
2786     case GST_MAKE_FOURCC ('a', 'c', '-', '3'):
2787       /* ETSI TS 102 366 v1.4.1 - Digital Audio Compression (AC-3, Enhanced AC-3) Standard, Annex F */
2788       caps = gst_caps_new_empty_simple ("audio/x-ac3");
2789       break;
2790     case GST_MAKE_FOURCC ('e', 'c', '+', '3'):
2791       GST_FIXME
2792           ("Signalling of ATMOS ('ec+3') isn't defined yet. Falling back to EAC3 caps");
2793       /* withdrawn, unused, do not use (was enhanced AC-3 audio with JOC) */
2794     case GST_MAKE_FOURCC ('e', 'c', '-', '3'):
2795       /* ETSI TS 102 366 v1.4.1 - Digital Audio Compression (AC-3, Enhanced AC-3) Standard, Annex F */
2796       caps = gst_caps_new_empty_simple ("audio/x-eac3");
2797       break;
2798     case GST_MAKE_FOURCC ('s', 't', 'p', 'p'):
2799       /* IMSC1-conformant TTM XML */
2800       caps = gst_caps_new_empty_simple ("application/ttml+xml");
2801       break;
2802     case GST_MAKE_FOURCC ('w', 'v', 't', 't'):
2803       /* WebVTT subtitles */
2804       caps = gst_caps_new_empty_simple ("application/x-subtitle-vtt");
2805       break;
2806     case GST_MAKE_FOURCC ('v', 'p', '0', '8'):
2807       /* VP8 */
2808       caps = gst_caps_new_empty_simple ("video/x-vp8");
2809       break;
2810     case GST_MAKE_FOURCC ('v', 'p', '0', '9'):
2811       /* VP9 */
2812       caps = gst_caps_new_empty_simple ("video/x-vp9");
2813       break;
2814     case GST_MAKE_FOURCC ('a', 'v', '0', '1'):
2815       /* AV1 */
2816       caps = gst_caps_new_empty_simple ("video/x-av1");
2817       break;
2818     case GST_MAKE_FOURCC ('o', 'p', 'u', 's'):
2819       /* Opus */
2820       caps = gst_caps_new_empty_simple ("audio/x-opus");
2821       break;
2822     case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
2823       /* ulaw */
2824       caps = gst_caps_new_empty_simple ("audio/x-mulaw");
2825       break;
2826     case GST_MAKE_FOURCC ('g', '7', '2', '6'):
2827       /* ulaw */
2828       caps =
2829           gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "g726",
2830           NULL);
2831       break;
2832     default:
2833       GST_WARNING ("Unknown codec '%s' please file a bug", codec);
2834       break;
2835   }
2836
2837 beach:
2838   if (subcodec != NULL)
2839     g_strfreev (subcodec);
2840   return caps;
2841 }
2842
2843 /**
2844  * gst_codec_utils_caps_from_mime_codec:
2845  * @codecs_field: A mime codec string field
2846  *
2847  * Converts a RFC 6381 compatible codec string to #GstCaps. More than one codec
2848  * string can be present (separated by `,`).
2849  *
2850  * Registered codecs can be found at http://mp4ra.org/#/codecs
2851  *
2852  * Returns: (transfer full) (nullable): The corresponding #GstCaps or %NULL
2853  *
2854  * Since: 1.22
2855  */
2856 GstCaps *
2857 gst_codec_utils_caps_from_mime_codec (const gchar * codecs_field)
2858 {
2859   gchar **codecs = NULL;
2860   GstCaps *caps = NULL;
2861   guint i;
2862
2863   g_return_val_if_fail (codecs_field != NULL, NULL);
2864
2865   GST_LOG ("codecs_field '%s'", codecs_field);
2866
2867   codecs = g_strsplit (codecs_field, ",", 0);
2868   if (codecs == NULL) {
2869     GST_WARNING ("Invalid 'codecs' field : '%s'", codecs_field);
2870     goto beach;
2871   }
2872
2873   for (i = 0; codecs[i]; i++) {
2874     const gchar *codec = codecs[i];
2875     if (caps == NULL)
2876       caps = gst_codec_utils_caps_from_mime_codec_single (codec);
2877     else
2878       gst_caps_append (caps,
2879           gst_codec_utils_caps_from_mime_codec_single (codec));
2880   }
2881
2882 beach:
2883   g_strfreev (codecs);
2884   GST_LOG ("caps %" GST_PTR_FORMAT, caps);
2885   return caps;
2886 }