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