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