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 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
47     gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
48 
49 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
50     gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
51 
52 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
53   32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
54 };
55 
56 static const gchar *
digit_to_string(guint digit)57 digit_to_string (guint digit)
58 {
59   static const char itoa[][2] = {
60     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
61   };
62 
63   if (G_LIKELY (digit < 10))
64     return itoa[digit];
65   else
66     return NULL;
67 }
68 
69 /**
70  * gst_codec_utils_aac_get_sample_rate_from_index:
71  * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
72  *          container) or ADTS frame header
73  *
74  * Translates the sample rate index found in AAC headers to the actual sample
75  * rate.
76  *
77  * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
78  */
79 guint
gst_codec_utils_aac_get_sample_rate_from_index(guint sr_idx)80 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
81 {
82   if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
83     return aac_sample_rates[sr_idx];
84 
85   GST_WARNING ("Invalid sample rate index %u", sr_idx);
86   return 0;
87 }
88 
89 /**
90  * gst_codec_utils_aac_get_index_from_sample_rate:
91  * @rate: Sample rate
92  *
93  * Translates the sample rate to the index corresponding to it in AAC spec.
94  *
95  * Returns: The AAC index for this sample rate, -1 if the rate is not a
96  * valid AAC sample rate.
97  */
98 gint
gst_codec_utils_aac_get_index_from_sample_rate(guint rate)99 gst_codec_utils_aac_get_index_from_sample_rate (guint rate)
100 {
101   guint n;
102 
103   for (n = 0; n < G_N_ELEMENTS (aac_sample_rates); n++)
104     if (aac_sample_rates[n] == rate)
105       return n;
106 
107   GST_WARNING ("Invalid sample rate %u", rate);
108   return -1;
109 }
110 
111 static gboolean
gst_codec_utils_aac_get_audio_object_type(GstBitReader * br,guint8 * audio_object_type)112 gst_codec_utils_aac_get_audio_object_type (GstBitReader * br,
113     guint8 * audio_object_type)
114 {
115   guint8 aot;
116 
117   if (!gst_bit_reader_get_bits_uint8 (br, &aot, 5))
118     return FALSE;
119 
120   if (aot == 31) {
121     if (!gst_bit_reader_get_bits_uint8 (br, &aot, 6))
122       return FALSE;
123     aot += 32;
124   }
125 
126   *audio_object_type = aot;
127 
128   return TRUE;
129 }
130 
131 static gboolean
gst_codec_utils_aac_get_audio_sample_rate(GstBitReader * br,guint * sample_rate)132 gst_codec_utils_aac_get_audio_sample_rate (GstBitReader * br,
133     guint * sample_rate)
134 {
135   guint8 sampling_freq_index;
136   guint32 sampling_rate;
137 
138   if (!gst_bit_reader_get_bits_uint8 (br, &sampling_freq_index, 4))
139     return FALSE;
140 
141   if (sampling_freq_index == 0xf) {
142     if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
143       return FALSE;
144   } else {
145     sampling_rate =
146         gst_codec_utils_aac_get_sample_rate_from_index (sampling_freq_index);
147     if (!sampling_rate)
148       return FALSE;
149   }
150 
151   *sample_rate = sampling_rate;
152 
153   return TRUE;
154 }
155 
156 static gboolean
gst_codec_utils_aac_get_audio_object_type_full(GstBitReader * br,guint8 * audio_object_type,guint8 * channel_config,guint * sample_rate)157 gst_codec_utils_aac_get_audio_object_type_full (GstBitReader * br,
158     guint8 * audio_object_type, guint8 * channel_config, guint * sample_rate)
159 {
160   guint8 aot, channels;
161   guint rate;
162 
163   if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
164     return FALSE;
165 
166   if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
167     return FALSE;
168 
169   if (!gst_bit_reader_get_bits_uint8 (br, &channels, 4))
170     return FALSE;
171 
172   /* 5 indicates SBR extension (i.e. HE-AAC) */
173   /* 29 indicates PS extension */
174   if (aot == 5 || aot == 29) {
175     if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
176       return FALSE;
177     if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
178       return FALSE;
179   }
180 
181   *audio_object_type = aot;
182   *sample_rate = rate;
183   *channel_config = channels;
184 
185   return TRUE;
186 }
187 
188 /**
189  * gst_codec_utils_aac_get_sample_rate:
190  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
191  *                as specified in the Elementary Stream Descriptor (esds)
192  *                in ISO/IEC 14496-1.
193  * @len: Length of @audio_config
194  *
195  * Translates the sample rate index found in AAC headers to the actual sample
196  * rate.
197  *
198  * Returns: The sample rate if sr_idx is valid, 0 otherwise.
199  *
200  * Since: 1.10
201  */
202 guint
gst_codec_utils_aac_get_sample_rate(const guint8 * audio_config,guint len)203 gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
204 {
205   guint sample_rate = 0;
206   guint8 audio_object_type = 0, channel_config = 0;
207   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
208 
209   if (len < 2)
210     return 0;
211 
212   gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
213       &channel_config, &sample_rate);
214 
215   return sample_rate;
216 }
217 
218 /**
219  * gst_codec_utils_aac_get_channels:
220  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
221  *                as specified in the Elementary Stream Descriptor (esds)
222  *                in ISO/IEC 14496-1.
223  * @len: Length of @audio_config in bytes
224  *
225  * Returns the channels of the given AAC stream.
226  *
227  * Returns: The channels or 0 if the channel could not be determined.
228  *
229  * Since: 1.10
230  */
231 guint
gst_codec_utils_aac_get_channels(const guint8 * audio_config,guint len)232 gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
233 {
234   guint channels;
235 
236   if (len < 2)
237     return 0;
238 
239   channels = (audio_config[1] & 0x7f) >> 3;
240   if (channels > 0 && channels < 7)
241     return channels;
242   else if (channels == 7)
243     return 8;
244   else
245     return 0;
246 }
247 
248 /**
249  * gst_codec_utils_aac_get_profile:
250  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
251  *                as specified in the Elementary Stream Descriptor (esds)
252  *                in ISO/IEC 14496-1.
253  * @len: Length of @audio_config in bytes
254  *
255  * Returns the profile of the given AAC stream as a string. The profile is
256  * normally determined using the AudioObjectType field which is in the first
257  * 5 bits of @audio_config
258  *
259  * Returns: The profile as a const string and %NULL if the profile could not be
260  * determined.
261  */
262 const gchar *
gst_codec_utils_aac_get_profile(const guint8 * audio_config,guint len)263 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
264 {
265   const gchar *profile = NULL;
266   guint sample_rate;
267   guint8 audio_object_type, channel_config;
268   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
269 
270   if (len < 1)
271     return NULL;
272 
273   GST_MEMDUMP ("audio config", audio_config, len);
274 
275   if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
276           &channel_config, &sample_rate)) {
277     return NULL;
278   }
279 
280   switch (audio_object_type) {
281     case 1:
282       profile = "main";
283       break;
284     case 2:
285       profile = "lc";
286       break;
287     case 3:
288       profile = "ssr";
289       break;
290     case 4:
291       profile = "ltp";
292       break;
293     default:
294       GST_DEBUG ("Invalid profile idx: %u", audio_object_type);
295       break;
296   }
297 
298   return profile;
299 }
300 
301 /**
302  * gst_codec_utils_aac_get_level:
303  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
304  *                as specified in the Elementary Stream Descriptor (esds)
305  *                in ISO/IEC 14496-1.
306  * @len: Length of @audio_config in bytes
307  *
308  * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
309  * streams, the constraints from the AAC audio profile are applied. For AAC
310  * Main, LTP, SSR and others, the Main profile is used.
311  *
312  * The @audio_config parameter follows the following format, starting from the
313  * most significant bit of the first byte:
314  *
315  *   * Bit 0:4 contains the AudioObjectType (if this is 0x5, then the
316  *     real AudioObjectType is carried after the rate and channel data)
317  *   * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
318  *     next 24 bits define the actual sample frequency, and subsequent
319  *     fields are appropriately shifted).
320  *   * Bit 9:12 contains the channel configuration
321  *
322  * Returns: The level as a const string and %NULL if the level could not be
323  * determined.
324  */
325 const gchar *
gst_codec_utils_aac_get_level(const guint8 * audio_config,guint len)326 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
327 {
328   guint8 audio_object_type = 0xFF, channel_config = 0xFF;
329   guint rate;
330   /* Number of single channel elements, channel pair elements, low frequency
331    * elements, independently switched coupling channel elements, and
332    * dependently switched coupling channel elements.
333    *
334    * Note: The 2 CCE types are ignored for now as they require us to actually
335    * parse the first frame, and they are rarely found in actual streams.
336    */
337   int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
338   int num_channels;
339   /* Processor and RAM Complexity Units (calculated and "reference" for single
340    * channel) */
341   int pcu = -1, rcu = -1, pcu_ref, rcu_ref;
342   int ret = -1;
343   GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
344 
345   g_return_val_if_fail (audio_config != NULL, NULL);
346 
347   if (len < 2)
348     return NULL;
349 
350   GST_MEMDUMP ("audio config", audio_config, len);
351 
352   if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
353           &channel_config, &rate)) {
354     return NULL;
355   }
356 
357   switch (channel_config) {
358     case 0:
359       /* Channel config is defined in the AudioObjectType's SpecificConfig,
360        * which requires some amount of digging through the headers. I only see
361        * this done in the MPEG conformance streams - FIXME */
362       GST_WARNING ("Found a stream with channel configuration in the "
363           "AudioSpecificConfig. Please file a bug with a link to the media if "
364           "possible.");
365       return NULL;
366     case 1:
367       /* front center */
368       num_sce = 1;
369       break;
370     case 2:
371       /* front left and right */
372       num_cpe = 1;
373       break;
374     case 3:
375       /* front left, right, and center */
376       num_sce = 1;
377       num_cpe = 1;
378       break;
379     case 4:
380       /* front left, right, and center; rear surround */
381       num_sce = 2;
382       num_cpe = 1;
383       break;
384     case 5:
385       /* front left, right, and center; rear left and right surround */
386       num_sce = 1;
387       num_cpe = 2;
388       break;
389     case 6:
390       /* front left, right, center and LFE; rear left and right surround */
391       num_sce = 1;
392       num_cpe = 2;
393       break;
394     case 7:
395     case 12:
396     case 14:
397       /* front left, right, center and LFE; outside front left and right;
398        * rear left and right surround */
399       num_sce = 1;
400       num_cpe = 3;
401       num_lfe = 1;
402       break;
403     case 11:
404       num_sce = 2;
405       num_cpe = 2;
406       num_lfe = 1;
407       break;
408     default:
409       GST_WARNING ("Unknown channel config in header: %d", channel_config);
410       return NULL;
411   }
412 
413   switch (audio_object_type) {
414     case 0:                    /* NULL */
415       GST_WARNING ("profile 0 is not a valid profile");
416       return NULL;
417     case 2:                    /* LC */
418       pcu_ref = 3;
419       rcu_ref = 3;
420       break;
421     case 3:                    /* SSR */
422       pcu_ref = 4;
423       rcu_ref = 3;
424       break;
425     case 4:                    /* LTP */
426       pcu_ref = 4;
427       rcu_ref = 4;
428       break;
429     case 1:                    /* Main */
430     default:
431       /* Other than a couple of ER profiles, Main is the worst-case */
432       pcu_ref = 5;
433       rcu_ref = 5;
434       break;
435   }
436 
437   /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
438    * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
439 
440   pcu = ((float) rate / 48000) * pcu_ref *
441       ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
442 
443   rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
444       (0.4 * num_cce_dep));
445 
446   if (num_cpe < 2)
447     rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
448   else
449     rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
450 
451   num_channels = num_sce + (2 * num_cpe) + num_lfe;
452 
453   if (audio_object_type == 2) {
454     /* AAC LC => return the level as per the 'AAC Profile' */
455     if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
456       ret = 1;
457     else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
458       ret = 2;
459     /* There is no level 3 for the AAC Profile */
460     else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
461       ret = 4;
462     else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
463       ret = 5;
464     else if (num_channels <= 7 && rate <= 48000 && pcu <= 25 && rcu <= 19)
465       ret = 6;
466     else if (num_channels <= 7 && rate <= 96000 && pcu <= 50 && rcu <= 19)
467       ret = 7;
468   } else {
469     /* Return the level as per the 'Main Profile' */
470     if (pcu < 40 && rcu < 20)
471       ret = 1;
472     else if (pcu < 80 && rcu < 64)
473       ret = 2;
474     else if (pcu < 160 && rcu < 128)
475       ret = 3;
476     else if (pcu < 320 && rcu < 256)
477       ret = 4;
478   }
479 
480   if (ret == -1) {
481     GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
482         "channel_config=%u, pcu=%d,rcu=%d", audio_object_type, rate,
483         channel_config, pcu, rcu);
484     return NULL;
485   } else {
486     return digit_to_string (ret);
487   }
488 }
489 
490 /**
491  * gst_codec_utils_aac_caps_set_level_and_profile:
492  * @caps: the #GstCaps to which level and profile fields are to be added
493  * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
494  *                as specified in the Elementary Stream Descriptor (esds)
495  *                in ISO/IEC 14496-1. (See below for more details)
496  * @len: Length of @audio_config in bytes
497  *
498  * Sets the level and profile on @caps if it can be determined from
499  * @audio_config. See gst_codec_utils_aac_get_level() and
500  * gst_codec_utils_aac_get_profile() for more details on the parameters.
501  * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
502  * If mpegversion is 4, the "base-profile" field is also set in @caps.
503  *
504  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
505  */
506 gboolean
gst_codec_utils_aac_caps_set_level_and_profile(GstCaps * caps,const guint8 * audio_config,guint len)507 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
508     const guint8 * audio_config, guint len)
509 {
510   GstStructure *s;
511   const gchar *level, *profile;
512   int mpegversion = 0;
513 
514   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
515   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
516   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
517   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
518   g_return_val_if_fail (audio_config != NULL, FALSE);
519 
520   s = gst_caps_get_structure (caps, 0);
521 
522   gst_structure_get_int (s, "mpegversion", &mpegversion);
523   g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
524 
525   level = gst_codec_utils_aac_get_level (audio_config, len);
526 
527   if (level != NULL)
528     gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
529 
530   profile = gst_codec_utils_aac_get_profile (audio_config, len);
531 
532   if (profile != NULL) {
533     if (mpegversion == 4) {
534       gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
535           "profile", G_TYPE_STRING, profile, NULL);
536     } else {
537       gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
538     }
539   }
540 
541   GST_LOG ("profile : %s", (profile) ? profile : "---");
542   GST_LOG ("level   : %s", (level) ? level : "---");
543 
544   return (level != NULL && profile != NULL);
545 }
546 
547 /**
548  * gst_codec_utils_h264_get_profile:
549  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
550  * @len: Length of the data available in @sps.
551  *
552  * Converts the profile indication (profile_idc) in the stream's
553  * sequence parameter set into a string. The SPS is expected to have the
554  * following format, as defined in the H.264 specification. The SPS is viewed
555  * as a bitstream here, with bit 0 being the most significant bit of the first
556  * byte.
557  *
558  * * Bit 0:7   - Profile indication
559  * * Bit 8     - constraint_set0_flag
560  * * Bit 9     - constraint_set1_flag
561  * * Bit 10    - constraint_set2_flag
562  * * Bit 11    - constraint_set3_flag
563  * * Bit 12    - constraint_set3_flag
564  * * Bit 13:15 - Reserved
565  * * Bit 16:24 - Level indication
566  *
567  * Returns: The profile as a const string, or %NULL if there is an error.
568  */
569 const gchar *
gst_codec_utils_h264_get_profile(const guint8 * sps,guint len)570 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
571 {
572   const gchar *profile = NULL;
573   gint csf1, csf3, csf5;
574 
575   g_return_val_if_fail (sps != NULL, NULL);
576 
577   if (len < 2)
578     return NULL;
579 
580   GST_MEMDUMP ("SPS", sps, len);
581 
582   csf1 = (sps[1] & 0x40) >> 6;
583   csf3 = (sps[1] & 0x10) >> 4;
584   csf5 = (sps[1] & 0x04) >> 2;
585 
586   switch (sps[0]) {
587     case 66:
588       if (csf1)
589         profile = "constrained-baseline";
590       else
591         profile = "baseline";
592       break;
593     case 77:
594       profile = "main";
595       break;
596     case 88:
597       profile = "extended";
598       break;
599     case 100:
600       profile = "high";
601       break;
602     case 110:
603       if (csf3)
604         profile = "high-10-intra";
605       else
606         profile = "high-10";
607       break;
608     case 122:
609       if (csf3)
610         profile = "high-4:2:2-intra";
611       else
612         profile = "high-4:2:2";
613       break;
614     case 244:
615       if (csf3)
616         profile = "high-4:4:4-intra";
617       else
618         profile = "high-4:4:4";
619       break;
620     case 44:
621       profile = "cavlc-4:4:4-intra";
622       break;
623     case 118:
624       profile = "multiview-high";
625       break;
626     case 128:
627       profile = "stereo-high";
628       break;
629     case 83:
630       if (csf5)
631         profile = "scalable-constrained-baseline";
632       else
633         profile = "scalable-baseline";
634       break;
635     case 86:
636       if (csf3)
637         profile = "scalable-high-intra";
638       else if (csf5)
639         profile = "scalable-constrained-high";
640       else
641         profile = "scalable-high";
642       break;
643     default:
644       return NULL;
645   }
646 
647   return profile;
648 }
649 
650 /**
651  * gst_codec_utils_h264_get_level:
652  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
653  * @len: Length of the data available in @sps.
654  *
655  * Converts the level indication (level_idc) in the stream's
656  * sequence parameter set into a string. The SPS is expected to have the
657  * same format as for gst_codec_utils_h264_get_profile().
658  *
659  * Returns: The level as a const string, or %NULL if there is an error.
660  */
661 const gchar *
gst_codec_utils_h264_get_level(const guint8 * sps,guint len)662 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
663 {
664   gint csf3;
665 
666   g_return_val_if_fail (sps != NULL, NULL);
667 
668   if (len < 3)
669     return NULL;
670 
671   GST_MEMDUMP ("SPS", sps, len);
672 
673   csf3 = (sps[1] & 0x10) >> 4;
674 
675   if (sps[2] == 0)
676     return NULL;
677   else if ((sps[2] == 11 && csf3) || sps[2] == 9)
678     return "1b";
679   else if (sps[2] % 10 == 0)
680     return digit_to_string (sps[2] / 10);
681   else {
682     switch (sps[2]) {
683       case 11:
684         return "1.1";
685       case 12:
686         return "1.2";
687       case 13:
688         return "1.3";
689       case 21:
690         return "2.1";
691       case 22:
692         return "2.2";
693       case 31:
694         return "3.1";
695       case 32:
696         return "3.2";
697       case 41:
698         return "4.1";
699       case 42:
700         return "4.2";
701       case 51:
702         return "5.1";
703       case 52:
704         return "5.2";
705       default:
706         return NULL;
707     }
708   }
709 }
710 
711 /**
712  * gst_codec_utils_h264_get_level_idc:
713  * @level: A level string from caps
714  *
715  * Transform a level string from the caps into the level_idc
716  *
717  * Returns: the level_idc or 0 if the level is unknown
718  */
719 guint8
gst_codec_utils_h264_get_level_idc(const gchar * level)720 gst_codec_utils_h264_get_level_idc (const gchar * level)
721 {
722   g_return_val_if_fail (level != NULL, 0);
723 
724   if (!strcmp (level, "1"))
725     return 10;
726   else if (!strcmp (level, "1b"))
727     return 9;
728   else if (!strcmp (level, "1.1"))
729     return 11;
730   else if (!strcmp (level, "1.2"))
731     return 12;
732   else if (!strcmp (level, "1.3"))
733     return 13;
734   else if (!strcmp (level, "2"))
735     return 20;
736   else if (!strcmp (level, "2.1"))
737     return 21;
738   else if (!strcmp (level, "2.2"))
739     return 22;
740   else if (!strcmp (level, "3"))
741     return 30;
742   else if (!strcmp (level, "3.1"))
743     return 31;
744   else if (!strcmp (level, "3.2"))
745     return 32;
746   else if (!strcmp (level, "4"))
747     return 40;
748   else if (!strcmp (level, "4.1"))
749     return 41;
750   else if (!strcmp (level, "4.2"))
751     return 42;
752   else if (!strcmp (level, "5"))
753     return 50;
754   else if (!strcmp (level, "5.1"))
755     return 51;
756   else if (!strcmp (level, "5.2"))
757     return 52;
758 
759   GST_WARNING ("Invalid level %s", level);
760   return 0;
761 }
762 
763 /**
764  * gst_codec_utils_h264_caps_set_level_and_profile:
765  * @caps: the #GstCaps to which the level and profile are to be added
766  * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
767  * @len: Length of the data available in @sps.
768  *
769  * Sets the level and profile in @caps if it can be determined from @sps. See
770  * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
771  * for more details on the parameters.
772  *
773  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
774  */
775 gboolean
gst_codec_utils_h264_caps_set_level_and_profile(GstCaps * caps,const guint8 * sps,guint len)776 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
777     const guint8 * sps, guint len)
778 {
779   const gchar *level, *profile;
780 
781   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
782   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
783   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
784   g_return_val_if_fail (sps != NULL, FALSE);
785 
786   level = gst_codec_utils_h264_get_level (sps, len);
787 
788   if (level != NULL)
789     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
790 
791   profile = gst_codec_utils_h264_get_profile (sps, len);
792 
793   if (profile != NULL)
794     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
795 
796   GST_LOG ("profile : %s", (profile) ? profile : "---");
797   GST_LOG ("level   : %s", (level) ? level : "---");
798 
799   return (level != NULL && profile != NULL);
800 }
801 
802 /**
803  * gst_codec_utils_h265_get_profile:
804  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
805  *   structure for the stream.
806  * @len: Length of the data available in @profile_tier_level
807  *
808  * Converts the profile indication (general_profile_idc) in the stream's
809  * profile_level_tier structure into a string. The profile_tier_level is
810  * expected to have the following format, as defined in the H.265
811  * specification. The profile_tier_level is viewed as a bitstream here,
812  * with bit 0 being the most significant bit of the first byte.
813  *
814  * * Bit 0:1   - general_profile_space
815  * * Bit 2     - general_tier_flag
816  * * Bit 3:7   - general_profile_idc
817  * * Bit 8:39  - gernal_profile_compatibility_flags
818  * * Bit 40    - general_progressive_source_flag
819  * * Bit 41    - general_interlaced_source_flag
820  * * Bit 42    - general_non_packed_constraint_flag
821  * * Bit 43    - general_frame_only_constraint_flag
822  * * Bit 44:87 - general_reserved_zero_44bits
823  * * Bit 88:95 - general_level_idc
824  *
825  * Returns: The profile as a const string, or %NULL if there is an error.
826  *
827  * Since: 1.4
828  */
829 const gchar *
gst_codec_utils_h265_get_profile(const guint8 * profile_tier_level,guint len)830 gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
831 {
832   const gchar *profile = NULL;
833   gint profile_idc;
834 
835   g_return_val_if_fail (profile_tier_level != NULL, NULL);
836 
837   if (len < 2)
838     return NULL;
839 
840   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
841 
842   profile_idc = (profile_tier_level[0] & 0x1f);
843 
844   if (profile_idc == 1)
845     profile = "main";
846   else if (profile_idc == 2)
847     profile = "main-10";
848   else if (profile_idc == 3)
849     profile = "main-still-picture";
850   else
851     profile = NULL;
852 
853   return profile;
854 }
855 
856 /**
857  * gst_codec_utils_h265_get_tier:
858  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
859  *   for the stream.
860  * @len: Length of the data available in @profile_tier_level.
861  *
862  * Converts the tier indication (general_tier_flag) in the stream's
863  * profile_tier_level structure into a string. The profile_tier_level
864  * is expected to have the same format as for gst_codec_utils_h264_get_profile().
865  *
866  * Returns: The tier as a const string, or %NULL if there is an error.
867  *
868  * Since: 1.4
869  */
870 const gchar *
gst_codec_utils_h265_get_tier(const guint8 * profile_tier_level,guint len)871 gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
872 {
873   const gchar *tier = NULL;
874   gint tier_flag = 0;
875 
876   g_return_val_if_fail (profile_tier_level != NULL, NULL);
877 
878   if (len < 1)
879     return NULL;
880 
881   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
882 
883   tier_flag = (profile_tier_level[0] & 0x20) >> 5;
884 
885   if (tier_flag)
886     tier = "high";
887   else
888     tier = "main";
889 
890   return tier;
891 }
892 
893 /**
894  * gst_codec_utils_h265_get_level:
895  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
896  *   for the stream
897  * @len: Length of the data available in @profile_tier_level.
898  *
899  * Converts the level indication (general_level_idc) in the stream's
900  * profile_tier_level structure into a string. The profiel_tier_level is
901  * expected to have the same format as for gst_codec_utils_h264_get_profile().
902  *
903  * Returns: The level as a const string, or %NULL if there is an error.
904  *
905  * Since: 1.4
906  */
907 const gchar *
gst_codec_utils_h265_get_level(const guint8 * profile_tier_level,guint len)908 gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
909 {
910   g_return_val_if_fail (profile_tier_level != NULL, NULL);
911 
912   if (len < 12)
913     return NULL;
914 
915   GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
916 
917   if (profile_tier_level[11] == 0)
918     return NULL;
919   else if (profile_tier_level[11] % 30 == 0)
920     return digit_to_string (profile_tier_level[11] / 30);
921   else {
922     switch (profile_tier_level[11]) {
923       case 63:
924         return "2.1";
925         break;
926       case 93:
927         return "3.1";
928         break;
929       case 123:
930         return "4.1";
931         break;
932       case 153:
933         return "5.1";
934         break;
935       case 156:
936         return "5.2";
937         break;
938       case 183:
939         return "6.1";
940         break;
941       case 186:
942         return "6.2";
943         break;
944       default:
945         return NULL;
946     }
947   }
948 }
949 
950 /**
951  * gst_codec_utils_h265_get_level_idc:
952  * @level: A level string from caps
953  *
954  * Transform a level string from the caps into the level_idc
955  *
956  * Returns: the level_idc or 0 if the level is unknown
957  *
958  * Since: 1.4
959  */
960 guint8
gst_codec_utils_h265_get_level_idc(const gchar * level)961 gst_codec_utils_h265_get_level_idc (const gchar * level)
962 {
963   g_return_val_if_fail (level != NULL, 0);
964 
965   if (!strcmp (level, "1"))
966     return 30;
967   else if (!strcmp (level, "2"))
968     return 60;
969   else if (!strcmp (level, "2.1"))
970     return 63;
971   else if (!strcmp (level, "3"))
972     return 90;
973   else if (!strcmp (level, "3.1"))
974     return 93;
975   else if (!strcmp (level, "4"))
976     return 120;
977   else if (!strcmp (level, "4.1"))
978     return 123;
979   else if (!strcmp (level, "5"))
980     return 150;
981   else if (!strcmp (level, "5.1"))
982     return 153;
983   else if (!strcmp (level, "5.2"))
984     return 156;
985   else if (!strcmp (level, "6"))
986     return 180;
987   else if (!strcmp (level, "6.1"))
988     return 183;
989   else if (!strcmp (level, "6.2"))
990     return 186;
991 
992   GST_WARNING ("Invalid level %s", level);
993   return 0;
994 }
995 
996 /**
997  * gst_codec_utils_h265_caps_set_level_tier_and_profile:
998  * @caps: the #GstCaps to which the level, tier and profile are to be added
999  * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1000  *   struct
1001  * @len: Length of the data available in @profile_tier_level.
1002  *
1003  * Sets the level, tier and profile in @caps if it can be determined from
1004  * @profile_tier_level. See gst_codec_utils_h265_get_level(),
1005  * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
1006  * for more details on the parameters.
1007  *
1008  * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
1009  *
1010  * Since: 1.4
1011  */
1012 gboolean
gst_codec_utils_h265_caps_set_level_tier_and_profile(GstCaps * caps,const guint8 * profile_tier_level,guint len)1013 gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
1014     const guint8 * profile_tier_level, guint len)
1015 {
1016   const gchar *level, *tier, *profile;
1017 
1018   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1019   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1020   g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
1021   g_return_val_if_fail (profile_tier_level != NULL, FALSE);
1022 
1023   level = gst_codec_utils_h265_get_level (profile_tier_level, len);
1024   if (level != NULL)
1025     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1026 
1027   tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
1028   if (tier != NULL)
1029     gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
1030 
1031   profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
1032   if (profile != NULL)
1033     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1034 
1035   GST_LOG ("profile : %s", (profile) ? profile : "---");
1036   GST_LOG ("tier    : %s", (tier) ? tier : "---");
1037   GST_LOG ("level   : %s", (level) ? level : "---");
1038 
1039   return (level != NULL && tier != NULL && profile != NULL);
1040 }
1041 
1042 /**
1043  * gst_codec_utils_mpeg4video_get_profile:
1044  * @vis_obj_seq: (array length=len): Pointer to the visual object
1045  *   sequence for the stream.
1046  * @len: Length of the data available in @sps.
1047  *
1048  * Converts the profile indication in the stream's visual object sequence into
1049  * a string. @vis_obj_seq is expected to be the data following the visual
1050  * object sequence start code. Only the first byte
1051  * (profile_and_level_indication) is used.
1052  *
1053  * Returns: The profile as a const string, or NULL if there is an error.
1054  */
1055 const gchar *
gst_codec_utils_mpeg4video_get_profile(const guint8 * vis_obj_seq,guint len)1056 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
1057 {
1058   /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
1059    * sources: epan/dissectors/packet-mp4ves.c */
1060 
1061   /* These are a direct mapping from the integer profile id -> string. Profiles
1062    * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
1063    * second 4 bits of vis_obj_seq[0], so they are handled separately. */
1064   static const char *profiles[] = { "simple", "simple-scalable", "core",
1065     "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
1066     "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
1067     "advanced-core", "advanced-scalable-texture",
1068   };
1069   int profile_id, level_id;
1070 
1071   g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1072 
1073   if (len < 1)
1074     return NULL;
1075 
1076   GST_MEMDUMP ("VOS", vis_obj_seq, len);
1077 
1078   profile_id = vis_obj_seq[0] >> 4;
1079   level_id = vis_obj_seq[0] & 0xf;
1080 
1081   GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1082 
1083   if (profile_id != 6 && profile_id < 0xe)
1084     return profiles[profile_id];
1085 
1086   if (profile_id != 0xf && level_id == 0)
1087     return NULL;
1088 
1089   switch (profile_id) {
1090     case 0x6:
1091       if (level_id < 3)
1092         return "simple-face";
1093       else if (level_id < 5)
1094         return "simple-fba";
1095       break;
1096 
1097     case 0xe:
1098       if (level_id < 5)
1099         return "simple-studio";
1100       else if (level_id < 9)
1101         return "core-studio";
1102       break;
1103 
1104     case 0xf:
1105       if (level_id < 6)
1106         return "advanced-simple";
1107       else if (level_id > 7 && level_id < 0xe)
1108         return "fine-granularity-scalable";
1109       break;
1110   }
1111 
1112   return NULL;
1113 }
1114 
1115 /**
1116  * gst_codec_utils_mpeg4video_get_level:
1117  * @vis_obj_seq: (array length=len): Pointer to the visual object
1118  *   sequence for the stream.
1119  * @len: Length of the data available in @sps.
1120  *
1121  * Converts the level indication in the stream's visual object sequence into
1122  * a string. @vis_obj_seq is expected to be the data following the visual
1123  * object sequence start code. Only the first byte
1124  * (profile_and_level_indication) is used.
1125  *
1126  * Returns: The level as a const string, or NULL if there is an error.
1127  */
1128 const gchar *
gst_codec_utils_mpeg4video_get_level(const guint8 * vis_obj_seq,guint len)1129 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
1130 {
1131   /* The profile/level codes are from 14496-2, table G-1, the Wireshark
1132    * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
1133    * src/xvid.h.
1134    * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
1135    * (see Xvid sources vfw/config.c)
1136    *
1137    * Each profile has a different maximum level it defines. Some of them still
1138    * need special case handling, because not all levels start from 1, and the
1139    * Simple profile defines an intermediate level as well. */
1140   static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
1141     5
1142   };
1143   int profile_id, level_id;
1144 
1145   g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1146 
1147   if (len < 1)
1148     return NULL;
1149 
1150   GST_MEMDUMP ("VOS", vis_obj_seq, len);
1151 
1152   profile_id = vis_obj_seq[0] >> 4;
1153   level_id = vis_obj_seq[0] & 0xf;
1154 
1155   GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1156 
1157   if (profile_id != 0xf && level_id == 0)
1158     return NULL;
1159 
1160   /* Let's do some validation of the level */
1161   switch (profile_id) {
1162     case 0x3:
1163       if (level_id == 1)
1164         return NULL;
1165       break;
1166 
1167     case 0x4:
1168       if (level_id != 2)
1169         return NULL;
1170       break;
1171 
1172     case 0x6:
1173       if (level_id > 5)
1174         return NULL;
1175       break;
1176 
1177     case 0xe:
1178       if (level_id > 9)
1179         return NULL;
1180       break;
1181 
1182     case 0xf:
1183       if (level_id == 6 || level_id == 7 || level_id > 0xd)
1184         return NULL;
1185       break;
1186   }
1187 
1188   if (profile_id == 0 && level_id == 8)
1189     /* Simple Profile / Level 0 */
1190     return "0";
1191   else if (profile_id == 0 && level_id == 9)
1192     /* Simple Profile / Level 0b */
1193     return "0b";
1194   else if (profile_id == 0 && level_id == 4)
1195     /* Simple Profile / Level 4a */
1196     return "4a";
1197   else if (profile_id == 0xf && level_id > 7)
1198     /* Fine Granularity Scalable Profile */
1199     return digit_to_string (level_id - 8);
1200   else if (level_id <= level_max[profile_id])
1201     /* Levels for all other cases */
1202     return digit_to_string (level_id);
1203 
1204   return NULL;
1205 }
1206 
1207 /**
1208  * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
1209  * @caps: the #GstCaps to which the level and profile are to be added
1210  * @vis_obj_seq: (array length=len): Pointer to the visual object
1211  *   sequence for the stream.
1212  * @len: Length of the data available in @sps.
1213  *
1214  * Sets the level and profile in @caps if it can be determined from
1215  * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
1216  * gst_codec_utils_mpeg4video_get_profile() for more details on the
1217  * parameters.
1218  *
1219  * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
1220  */
1221 gboolean
gst_codec_utils_mpeg4video_caps_set_level_and_profile(GstCaps * caps,const guint8 * vis_obj_seq,guint len)1222 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
1223     const guint8 * vis_obj_seq, guint len)
1224 {
1225   const gchar *profile, *level;
1226 
1227   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1228   g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1229   g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
1230 
1231   profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
1232 
1233   if (profile != NULL)
1234     gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1235 
1236   level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
1237 
1238   if (level != NULL)
1239     gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1240 
1241   GST_LOG ("profile : %s", (profile) ? profile : "---");
1242   GST_LOG ("level   : %s", (level) ? level : "---");
1243 
1244   return (profile != NULL && level != NULL);
1245 }
1246 
1247 /**
1248  * gst_codec_utils_opus_parse_caps:
1249  * @caps: the #GstCaps to parse the data from
1250  * @rate: (out): the sample rate
1251  * @channels: (out): the number of channels
1252  * @channel_mapping_family: (out): the channel mapping family
1253  * @stream_count: (out): the number of independent streams
1254  * @coupled_count: (out): the number of stereo streams
1255  * @channel_mapping: (out) (array fixed-size=256): the mapping between the streams
1256  *
1257  * Parses Opus caps and fills the different fields with defaults if possible.
1258  *
1259  * Returns: %TRUE if parsing was successful, %FALSE otherwise.
1260  *
1261  * Since: 1.8
1262  */
1263 gboolean
gst_codec_utils_opus_parse_caps(GstCaps * caps,guint32 * rate,guint8 * channels,guint8 * channel_mapping_family,guint8 * stream_count,guint8 * coupled_count,guint8 channel_mapping[256])1264 gst_codec_utils_opus_parse_caps (GstCaps * caps,
1265     guint32 * rate,
1266     guint8 * channels,
1267     guint8 * channel_mapping_family,
1268     guint8 * stream_count, guint8 * coupled_count, guint8 channel_mapping[256])
1269 {
1270   GstStructure *s;
1271   gint c, f, sc, cc;
1272   const GValue *va, *v;
1273 
1274   g_return_val_if_fail (caps != NULL, FALSE);
1275   g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1276   g_return_val_if_fail (!gst_caps_is_empty (caps), FALSE);
1277 
1278   s = gst_caps_get_structure (caps, 0);
1279 
1280   g_return_val_if_fail (gst_structure_has_name (s, "audio/x-opus"), FALSE);
1281   g_return_val_if_fail (gst_structure_has_field_typed (s,
1282           "channel-mapping-family", G_TYPE_INT), FALSE);
1283 
1284   if (rate) {
1285     gint r;
1286 
1287     if (gst_structure_get_int (s, "rate", &r))
1288       *rate = r;
1289     else
1290       *rate = 48000;
1291   }
1292 
1293   gst_structure_get_int (s, "channel-mapping-family", &f);
1294   if (channel_mapping_family)
1295     *channel_mapping_family = f;
1296 
1297   if (!gst_structure_get_int (s, "channels", &c)) {
1298     if (f == 0)
1299       c = 2;
1300     else
1301       return FALSE;
1302   }
1303 
1304   if (channels)
1305     *channels = c;
1306 
1307   /* RTP mapping */
1308   if (f == 0) {
1309     if (c > 2)
1310       return FALSE;
1311 
1312     if (stream_count)
1313       *stream_count = 1;
1314     if (coupled_count)
1315       *coupled_count = c == 2 ? 1 : 0;
1316 
1317     if (channel_mapping) {
1318       channel_mapping[0] = 0;
1319       channel_mapping[1] = 1;
1320     }
1321 
1322     return TRUE;
1323   }
1324 
1325   if (!gst_structure_get_int (s, "stream-count", &sc))
1326     return FALSE;
1327   if (stream_count)
1328     *stream_count = sc;
1329 
1330   if (!gst_structure_get_int (s, "coupled-count", &cc))
1331     return FALSE;
1332   if (coupled_count)
1333     *coupled_count = cc;
1334 
1335   va = gst_structure_get_value (s, "channel-mapping");
1336   if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY))
1337     return FALSE;
1338 
1339   if (gst_value_array_get_size (va) != c)
1340     return FALSE;
1341 
1342   if (channel_mapping) {
1343     gint i;
1344 
1345     for (i = 0; i < c; i++) {
1346       gint cm;
1347 
1348       v = gst_value_array_get_value (va, i);
1349 
1350       if (!G_VALUE_HOLDS (v, G_TYPE_INT))
1351         return FALSE;
1352 
1353       cm = g_value_get_int (v);
1354       if (cm < 0 || cm > 255)
1355         return FALSE;
1356 
1357       channel_mapping[i] = cm;
1358     }
1359   }
1360 
1361   return TRUE;
1362 }
1363 
1364 /**
1365  * gst_codec_utils_opus_create_caps:
1366  * @rate: the sample rate
1367  * @channels: the number of channels
1368  * @channel_mapping_family: the channel mapping family
1369  * @stream_count: the number of independent streams
1370  * @coupled_count: the number of stereo streams
1371  * @channel_mapping: (allow-none) (array): the mapping between the streams
1372  *
1373  * Creates Opus caps from the given parameters.
1374  *
1375  * Returns: The #GstCaps, or %NULL if the parameters would lead to
1376  * invalid Opus caps.
1377  *
1378  * Since: 1.8
1379  */
1380 GstCaps *
gst_codec_utils_opus_create_caps(guint32 rate,guint8 channels,guint8 channel_mapping_family,guint8 stream_count,guint8 coupled_count,const guint8 * channel_mapping)1381 gst_codec_utils_opus_create_caps (guint32 rate,
1382     guint8 channels,
1383     guint8 channel_mapping_family,
1384     guint8 stream_count, guint8 coupled_count, const guint8 * channel_mapping)
1385 {
1386   GstCaps *caps = NULL;
1387   GValue va = G_VALUE_INIT;
1388   GValue v = G_VALUE_INIT;
1389   gint i;
1390 
1391   if (rate == 0)
1392     rate = 48000;
1393 
1394   if (channel_mapping_family == 0) {
1395     if (channels > 2) {
1396       GST_ERROR ("Invalid channels count for channel_mapping_family 0: %d",
1397           channels);
1398       goto done;
1399     }
1400 
1401     if (stream_count > 1) {
1402       GST_ERROR ("Invalid stream count for channel_mapping_family 0: %d",
1403           stream_count);
1404       goto done;
1405     }
1406 
1407     if (coupled_count > 1) {
1408       GST_ERROR ("Invalid coupled count for channel_mapping_family 0: %d",
1409           coupled_count);
1410       goto done;
1411     }
1412 
1413     if (channels == 0)
1414       channels = 2;
1415 
1416     if (stream_count == 0)
1417       stream_count = 1;
1418 
1419     if (coupled_count == 0)
1420       coupled_count = channels == 2 ? 1 : 0;
1421 
1422     return gst_caps_new_simple ("audio/x-opus",
1423         "rate", G_TYPE_INT, rate,
1424         "channels", G_TYPE_INT, channels,
1425         "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1426         "stream-count", G_TYPE_INT, stream_count,
1427         "coupled-count", G_TYPE_INT, coupled_count, NULL);
1428   }
1429 
1430   if (channels == 0) {
1431     GST_ERROR ("Invalid channels count: %d", channels);
1432     goto done;
1433   }
1434 
1435   if (stream_count == 0) {
1436     GST_ERROR ("Invalid stream count: %d", stream_count);
1437     goto done;
1438   }
1439 
1440   if (coupled_count > stream_count) {
1441     GST_ERROR ("Coupled count %d > stream count: %d", coupled_count,
1442         stream_count);
1443     goto done;
1444   }
1445 
1446   if (channel_mapping == NULL) {
1447     GST_ERROR
1448         ("A non NULL channel-mapping is needed for channel_mapping_family != 0");
1449     goto done;
1450   }
1451 
1452   caps = gst_caps_new_simple ("audio/x-opus",
1453       "rate", G_TYPE_INT, rate,
1454       "channels", G_TYPE_INT, channels,
1455       "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1456       "stream-count", G_TYPE_INT, stream_count,
1457       "coupled-count", G_TYPE_INT, coupled_count, NULL);
1458 
1459   g_value_init (&va, GST_TYPE_ARRAY);
1460   g_value_init (&v, G_TYPE_INT);
1461   for (i = 0; i < channels; i++) {
1462     g_value_set_int (&v, channel_mapping[i]);
1463     gst_value_array_append_value (&va, &v);
1464   }
1465   gst_structure_set_value (gst_caps_get_structure (caps, 0), "channel-mapping",
1466       &va);
1467   g_value_unset (&va);
1468   g_value_unset (&v);
1469 
1470 done:
1471   return caps;
1472 }
1473 
1474 /*
1475  * (really really) FIXME: move into core (dixit tpm)
1476  */
1477 /*
1478  * _gst_caps_set_buffer_array:
1479  * @caps: (transfer full): a #GstCaps
1480  * @field: field in caps to set
1481  * @buf: header buffers
1482  *
1483  * Adds given buffers to an array of buffers set as the given @field
1484  * on the given @caps.  List of buffer arguments must be NULL-terminated.
1485  *
1486  * Returns: (transfer full): input caps with a streamheader field added, or NULL
1487  *     if some error occurred
1488  */
1489 static GstCaps *
_gst_caps_set_buffer_array(GstCaps * caps,const gchar * field,GstBuffer * buf,...)1490 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
1491     GstBuffer * buf, ...)
1492 {
1493   GstStructure *structure = NULL;
1494   va_list va;
1495   GValue array = { 0 };
1496   GValue value = { 0 };
1497 
1498   g_return_val_if_fail (caps != NULL, NULL);
1499   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
1500   g_return_val_if_fail (field != NULL, NULL);
1501 
1502   caps = gst_caps_make_writable (caps);
1503   structure = gst_caps_get_structure (caps, 0);
1504 
1505   g_value_init (&array, GST_TYPE_ARRAY);
1506 
1507   va_start (va, buf);
1508   /* put buffers in a fixed list */
1509   while (buf) {
1510     g_assert (gst_buffer_is_writable (buf));
1511 
1512     /* mark buffer */
1513     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1514 
1515     g_value_init (&value, GST_TYPE_BUFFER);
1516     buf = gst_buffer_copy (buf);
1517     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
1518     gst_value_set_buffer (&value, buf);
1519     gst_buffer_unref (buf);
1520     gst_value_array_append_value (&array, &value);
1521     g_value_unset (&value);
1522 
1523     buf = va_arg (va, GstBuffer *);
1524   }
1525   va_end (va);
1526 
1527   gst_structure_set_value (structure, field, &array);
1528   g_value_unset (&array);
1529 
1530   return caps;
1531 }
1532 
1533 /**
1534  * gst_codec_utils_opus_create_caps_from_header:
1535  * @header: OpusHead header
1536  * @comments: (allow-none): Comment header or NULL
1537  *
1538  * Creates Opus caps from the given OpusHead @header and comment header
1539  * @comments.
1540  *
1541  * Returns: The #GstCaps.
1542  *
1543  * Since: 1.8
1544  */
1545 GstCaps *
gst_codec_utils_opus_create_caps_from_header(GstBuffer * header,GstBuffer * comments)1546 gst_codec_utils_opus_create_caps_from_header (GstBuffer * header,
1547     GstBuffer * comments)
1548 {
1549   GstCaps *caps;
1550   guint32 rate;
1551   guint8 channels;
1552   guint8 channel_mapping_family;
1553   guint8 stream_count;
1554   guint8 coupled_count;
1555   guint8 channel_mapping[256];
1556   GstBuffer *dummy_comments = NULL;
1557 
1558   g_return_val_if_fail (GST_IS_BUFFER (header), NULL);
1559   g_return_val_if_fail (comments == NULL || GST_IS_BUFFER (comments), NULL);
1560 
1561   if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
1562           &channel_mapping_family, &stream_count, &coupled_count,
1563           channel_mapping, NULL, NULL))
1564     return NULL;
1565 
1566   if (!(caps =
1567           gst_codec_utils_opus_create_caps (rate, channels,
1568               channel_mapping_family, stream_count, coupled_count,
1569               channel_mapping)))
1570     return NULL;
1571 
1572   if (!comments) {
1573     GstTagList *tags = gst_tag_list_new_empty ();
1574     dummy_comments =
1575         gst_tag_list_to_vorbiscomment_buffer (tags, (const guint8 *) "OpusTags",
1576         8, NULL);
1577     gst_tag_list_unref (tags);
1578   }
1579   _gst_caps_set_buffer_array (caps, "streamheader", header,
1580       comments ? comments : dummy_comments, NULL);
1581 
1582   if (dummy_comments)
1583     gst_buffer_unref (dummy_comments);
1584 
1585   return caps;
1586 }
1587 
1588 /**
1589  * gst_codec_utils_opus_create_header:
1590  * @rate: the sample rate
1591  * @channels: the number of channels
1592  * @channel_mapping_family: the channel mapping family
1593  * @stream_count: the number of independent streams
1594  * @coupled_count: the number of stereo streams
1595  * @channel_mapping: (allow-none) (array): the mapping between the streams
1596  * @pre_skip: Pre-skip in 48kHz samples or 0
1597  * @output_gain: Output gain or 0
1598  *
1599  * Creates OpusHead header from the given parameters.
1600  *
1601  * Returns: The #GstBuffer containing the OpusHead.
1602  *
1603  * Since: 1.8
1604  */
1605 GstBuffer *
gst_codec_utils_opus_create_header(guint32 rate,guint8 channels,guint8 channel_mapping_family,guint8 stream_count,guint8 coupled_count,const guint8 * channel_mapping,guint16 pre_skip,gint16 output_gain)1606 gst_codec_utils_opus_create_header (guint32 rate,
1607     guint8 channels,
1608     guint8 channel_mapping_family,
1609     guint8 stream_count,
1610     guint8 coupled_count,
1611     const guint8 * channel_mapping, guint16 pre_skip, gint16 output_gain)
1612 {
1613   GstBuffer *buffer;
1614   GstByteWriter bw;
1615   gboolean hdl = TRUE;
1616 
1617   if (rate == 0)
1618     rate = 48000;
1619 
1620   if (channel_mapping_family == 0) {
1621     g_return_val_if_fail (channels <= 2, NULL);
1622     if (channels == 0)
1623       channels = 2;
1624 
1625     g_return_val_if_fail (stream_count == 0 || stream_count == 1, NULL);
1626     if (stream_count == 0)
1627       stream_count = 1;
1628 
1629     g_return_val_if_fail (coupled_count == 0 || coupled_count == 1, NULL);
1630     if (coupled_count == 0)
1631       coupled_count = channels == 2 ? 1 : 0;
1632 
1633     channel_mapping = NULL;
1634   } else {
1635     g_return_val_if_fail (channels > 0, NULL);
1636     g_return_val_if_fail (stream_count > 0, NULL);
1637     g_return_val_if_fail (coupled_count <= stream_count, NULL);
1638     g_return_val_if_fail (channel_mapping != NULL, NULL);
1639   }
1640 
1641   gst_byte_writer_init (&bw);
1642   /* See http://wiki.xiph.org/OggOpus */
1643   hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
1644   hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
1645   hdl &= gst_byte_writer_put_uint8 (&bw, channels);
1646   hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
1647   hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
1648   hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
1649   hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
1650   if (channel_mapping_family > 0) {
1651     hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
1652     hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
1653     hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
1654   }
1655 
1656   if (!hdl) {
1657     GST_WARNING ("Error creating header");
1658     gst_byte_writer_reset (&bw);
1659     return NULL;
1660   }
1661 
1662   buffer = gst_byte_writer_reset_and_get_buffer (&bw);
1663   GST_BUFFER_OFFSET (buffer) = 0;
1664   GST_BUFFER_OFFSET_END (buffer) = 0;
1665 
1666   return buffer;
1667 }
1668 
1669 /**
1670  * gst_codec_utils_opus_parse_header:
1671  * @header: the OpusHead #GstBuffer
1672  * @rate: (out): the sample rate
1673  * @channels: (out): the number of channels
1674  * @channel_mapping_family: (out): the channel mapping family
1675  * @stream_count: (out): the number of independent streams
1676  * @coupled_count: (out): the number of stereo streams
1677  * @channel_mapping: (out) (array fixed-size=256): the mapping between the streams
1678  * @pre_skip: (out): Pre-skip in 48kHz samples or 0
1679  * @output_gain: (out): Output gain or 0
1680  *
1681  * Parses the OpusHead header.
1682  *
1683  * Returns: %TRUE if parsing was successful, %FALSE otherwise.
1684  *
1685  * Since: 1.8
1686  */
1687 gboolean
gst_codec_utils_opus_parse_header(GstBuffer * header,guint32 * rate,guint8 * channels,guint8 * channel_mapping_family,guint8 * stream_count,guint8 * coupled_count,guint8 channel_mapping[256],guint16 * pre_skip,gint16 * output_gain)1688 gst_codec_utils_opus_parse_header (GstBuffer * header,
1689     guint32 * rate,
1690     guint8 * channels,
1691     guint8 * channel_mapping_family,
1692     guint8 * stream_count,
1693     guint8 * coupled_count,
1694     guint8 channel_mapping[256], guint16 * pre_skip, gint16 * output_gain)
1695 {
1696   GstByteReader br;
1697   GstMapInfo map;
1698   gboolean ret = TRUE;
1699   guint8 c, f, version;
1700 
1701   g_return_val_if_fail (GST_IS_BUFFER (header), FALSE);
1702   g_return_val_if_fail (gst_buffer_get_size (header) >= 19, FALSE);
1703 
1704   if (!gst_buffer_map (header, &map, GST_MAP_READ))
1705     return FALSE;
1706   gst_byte_reader_init (&br, map.data, map.size);
1707   /* See http://wiki.xiph.org/OggOpus */
1708   if (memcmp (gst_byte_reader_get_data_unchecked (&br, 8), "OpusHead", 8) != 0) {
1709     ret = FALSE;
1710     goto done;
1711   }
1712   version = gst_byte_reader_get_uint8_unchecked (&br);
1713   if (version == 0x00)
1714     GST_ERROR ("Opus Header version is wrong, should be 0x01 and not 0x00");
1715   else if (version != 0x01) {
1716     ret = FALSE;
1717     goto done;
1718   }
1719 
1720   c = gst_byte_reader_get_uint8_unchecked (&br);
1721   if (channels)
1722     *channels = c;
1723 
1724   if (pre_skip)
1725     *pre_skip = gst_byte_reader_get_uint16_le_unchecked (&br);
1726   else
1727     gst_byte_reader_skip_unchecked (&br, 2);
1728 
1729   if (rate)
1730     *rate = gst_byte_reader_get_uint32_le_unchecked (&br);
1731   else
1732     gst_byte_reader_skip_unchecked (&br, 4);
1733 
1734   if (output_gain)
1735     *output_gain = gst_byte_reader_get_uint16_le_unchecked (&br);
1736   else
1737     gst_byte_reader_skip_unchecked (&br, 2);
1738 
1739   f = gst_byte_reader_get_uint8_unchecked (&br);
1740   if (channel_mapping_family)
1741     *channel_mapping_family = f;
1742   if (f == 0 && c <= 2) {
1743     if (stream_count)
1744       *stream_count = 1;
1745     if (coupled_count)
1746       *coupled_count = c == 2 ? 1 : 0;
1747     if (channel_mapping) {
1748       channel_mapping[0] = 0;
1749       channel_mapping[1] = 1;
1750     }
1751 
1752     goto done;
1753   }
1754 
1755   if (gst_byte_reader_get_remaining (&br) < 2 + c) {
1756     ret = FALSE;
1757     goto done;
1758   }
1759 
1760   if (stream_count)
1761     *stream_count = gst_byte_reader_get_uint8_unchecked (&br);
1762   else
1763     gst_byte_reader_skip_unchecked (&br, 1);
1764 
1765   if (coupled_count)
1766     *coupled_count = gst_byte_reader_get_uint8_unchecked (&br);
1767   else
1768     gst_byte_reader_skip_unchecked (&br, 1);
1769 
1770   if (channel_mapping)
1771     memcpy (channel_mapping, gst_byte_reader_get_data_unchecked (&br, c), c);
1772 
1773 done:
1774   gst_buffer_unmap (header, &map);
1775 
1776   return ret;
1777 }
1778