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>
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.
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.
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.
26 * SECTION:gstpbutilscodecutils
27 * @title: Codec utilities
28 * @short_description: Miscellaneous codec-specific utility functions
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.
40 #include <gst/base/base.h>
41 #include <gst/base/gstbitreader.h>
42 #include <gst/tag/tag.h>
46 GST_DEBUG_CATEGORY_EXTERN (pbutils_debug);
47 #define GST_CAT_DEFAULT pbutils_debug
49 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
50 gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
52 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
53 gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
55 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
56 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
60 digit_to_string (guint digit)
62 static const char itoa[][2] = {
63 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
66 if (G_LIKELY (digit < 10))
73 * gst_codec_utils_aac_get_sample_rate_from_index:
74 * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
75 * container) or ADTS frame header
77 * Translates the sample rate index found in AAC headers to the actual sample
80 * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
83 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
85 if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
86 return aac_sample_rates[sr_idx];
88 GST_WARNING ("Invalid sample rate index %u", sr_idx);
93 * gst_codec_utils_aac_get_index_from_sample_rate:
96 * Translates the sample rate to the index corresponding to it in AAC spec.
98 * Returns: The AAC index for this sample rate, -1 if the rate is not a
99 * valid AAC sample rate.
102 gst_codec_utils_aac_get_index_from_sample_rate (guint rate)
106 for (n = 0; n < G_N_ELEMENTS (aac_sample_rates); n++)
107 if (aac_sample_rates[n] == rate)
110 GST_WARNING ("Invalid sample rate %u", rate);
115 gst_codec_utils_aac_get_audio_object_type (GstBitReader * br,
116 guint8 * audio_object_type)
120 if (!gst_bit_reader_get_bits_uint8 (br, &aot, 5))
124 if (!gst_bit_reader_get_bits_uint8 (br, &aot, 6))
129 *audio_object_type = aot;
135 gst_codec_utils_aac_get_audio_sample_rate (GstBitReader * br,
138 guint8 sampling_freq_index;
139 guint32 sampling_rate;
141 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_freq_index, 4))
144 if (sampling_freq_index == 0xf) {
145 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
149 gst_codec_utils_aac_get_sample_rate_from_index (sampling_freq_index);
154 *sample_rate = sampling_rate;
160 gst_codec_utils_aac_get_audio_object_type_full (GstBitReader * br,
161 guint8 * audio_object_type, guint8 * channel_config, guint * sample_rate)
163 guint8 aot, channels;
166 if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
169 if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
172 if (!gst_bit_reader_get_bits_uint8 (br, &channels, 4))
175 /* 5 indicates SBR extension (i.e. HE-AAC) */
176 /* 29 indicates PS extension */
177 if (aot == 5 || aot == 29) {
178 if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
180 if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
184 *audio_object_type = aot;
186 *channel_config = channels;
192 * gst_codec_utils_aac_get_sample_rate:
193 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
194 * as specified in the Elementary Stream Descriptor (esds)
195 * in ISO/IEC 14496-1.
196 * @len: Length of @audio_config
198 * Translates the sample rate index found in AAC headers to the actual sample
201 * Returns: The sample rate if sr_idx is valid, 0 otherwise.
206 gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
208 guint sample_rate = 0;
209 guint8 audio_object_type = 0, channel_config = 0;
210 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
215 gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
216 &channel_config, &sample_rate);
222 * gst_codec_utils_aac_get_channels:
223 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
224 * as specified in the Elementary Stream Descriptor (esds)
225 * in ISO/IEC 14496-1.
226 * @len: Length of @audio_config in bytes
228 * Returns the channels of the given AAC stream.
230 * Returns: The channels or 0 if the channel could not be determined.
235 gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
242 channels = (audio_config[1] & 0x7f) >> 3;
243 if (channels > 0 && channels < 7)
245 else if (channels == 7)
252 * gst_codec_utils_aac_get_profile:
253 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
254 * as specified in the Elementary Stream Descriptor (esds)
255 * in ISO/IEC 14496-1.
256 * @len: Length of @audio_config in bytes
258 * Returns the profile of the given AAC stream as a string. The profile is
259 * normally determined using the AudioObjectType field which is in the first
260 * 5 bits of @audio_config
262 * Returns: The profile as a const string and %NULL if the profile could not be
266 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
268 const gchar *profile = NULL;
270 guint8 audio_object_type, channel_config;
271 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
276 GST_MEMDUMP ("audio config", audio_config, len);
278 if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
279 &channel_config, &sample_rate)) {
283 switch (audio_object_type) {
297 GST_DEBUG ("Invalid profile idx: %u", audio_object_type);
305 * gst_codec_utils_aac_get_level:
306 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
307 * as specified in the Elementary Stream Descriptor (esds)
308 * in ISO/IEC 14496-1.
309 * @len: Length of @audio_config in bytes
311 * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
312 * streams, the constraints from the AAC audio profile are applied. For AAC
313 * Main, LTP, SSR and others, the Main profile is used.
315 * The @audio_config parameter follows the following format, starting from the
316 * most significant bit of the first byte:
318 * * Bit 0:4 contains the AudioObjectType (if this is 0x5, then the
319 * real AudioObjectType is carried after the rate and channel data)
320 * * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
321 * next 24 bits define the actual sample frequency, and subsequent
322 * fields are appropriately shifted).
323 * * Bit 9:12 contains the channel configuration
325 * Returns: The level as a const string and %NULL if the level could not be
329 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
331 guint8 audio_object_type = 0xFF, channel_config = 0xFF;
333 /* Number of single channel elements, channel pair elements, low frequency
334 * elements, independently switched coupling channel elements, and
335 * dependently switched coupling channel elements.
337 * Note: The 2 CCE types are ignored for now as they require us to actually
338 * parse the first frame, and they are rarely found in actual streams.
340 int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
342 /* Processor and RAM Complexity Units (calculated and "reference" for single
344 int pcu = -1, rcu = -1, pcu_ref, rcu_ref;
346 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
348 g_return_val_if_fail (audio_config != NULL, NULL);
353 GST_MEMDUMP ("audio config", audio_config, len);
355 if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
356 &channel_config, &rate)) {
360 switch (channel_config) {
362 /* Channel config is defined in the AudioObjectType's SpecificConfig,
363 * which requires some amount of digging through the headers. I only see
364 * this done in the MPEG conformance streams - FIXME */
365 GST_WARNING ("Found a stream with channel configuration in the "
366 "AudioSpecificConfig. Please file a bug with a link to the media if "
374 /* front left and right */
378 /* front left, right, and center */
383 /* front left, right, and center; rear surround */
388 /* front left, right, and center; rear left and right surround */
393 /* front left, right, center and LFE; rear left and right surround */
400 /* front left, right, center and LFE; outside front left and right;
401 * rear left and right surround */
412 GST_WARNING ("Unknown channel config in header: %d", channel_config);
416 switch (audio_object_type) {
418 GST_WARNING ("profile 0 is not a valid profile");
434 /* Other than a couple of ER profiles, Main is the worst-case */
440 /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
441 * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
443 pcu = ((float) rate / 48000) * pcu_ref *
444 ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
446 rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
447 (0.4 * num_cce_dep));
450 rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
452 rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
454 num_channels = num_sce + (2 * num_cpe);
456 if (audio_object_type == 2) {
457 /* AAC LC => return the level as per the 'AAC Profile' */
458 if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
460 else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
462 /* There is no level 3 for the AAC Profile */
463 else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
465 else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
467 else if (num_channels <= 7 && rate <= 48000 && pcu <= 25 && rcu <= 19)
469 else if (num_channels <= 7 && rate <= 96000 && pcu <= 50 && rcu <= 19)
472 /* Return the level as per the 'Main Profile' */
473 if (pcu < 40 && rcu < 20)
475 else if (pcu < 80 && rcu < 64)
477 else if (pcu < 160 && rcu < 128)
479 else if (pcu < 320 && rcu < 256)
484 GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
485 "channel_config=%u, pcu=%d,rcu=%d", audio_object_type, rate,
486 channel_config, pcu, rcu);
489 return digit_to_string (ret);
494 * gst_codec_utils_aac_caps_set_level_and_profile:
495 * @caps: the #GstCaps to which level and profile fields are to be added
496 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
497 * as specified in the Elementary Stream Descriptor (esds)
498 * in ISO/IEC 14496-1. (See below for more details)
499 * @len: Length of @audio_config in bytes
501 * Sets the level and profile on @caps if it can be determined from
502 * @audio_config. See gst_codec_utils_aac_get_level() and
503 * gst_codec_utils_aac_get_profile() for more details on the parameters.
504 * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
505 * If mpegversion is 4, the "base-profile" field is also set in @caps.
507 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
510 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
511 const guint8 * audio_config, guint len)
514 const gchar *level, *profile;
517 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
518 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
519 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
520 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
521 g_return_val_if_fail (audio_config != NULL, FALSE);
523 s = gst_caps_get_structure (caps, 0);
525 gst_structure_get_int (s, "mpegversion", &mpegversion);
526 g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
528 level = gst_codec_utils_aac_get_level (audio_config, len);
531 gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
533 profile = gst_codec_utils_aac_get_profile (audio_config, len);
535 if (profile != NULL) {
536 if (mpegversion == 4) {
537 gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
538 "profile", G_TYPE_STRING, profile, NULL);
540 gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
544 GST_LOG ("profile : %s", (profile) ? profile : "---");
545 GST_LOG ("level : %s", (level) ? level : "---");
547 return (level != NULL && profile != NULL);
551 * gst_codec_utils_h264_get_profile:
552 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
553 * @len: Length of the data available in @sps.
555 * Converts the profile indication (profile_idc) in the stream's
556 * sequence parameter set into a string. The SPS is expected to have the
557 * following format, as defined in the H.264 specification. The SPS is viewed
558 * as a bitstream here, with bit 0 being the most significant bit of the first
561 * * Bit 0:7 - Profile indication
562 * * Bit 8 - constraint_set0_flag
563 * * Bit 9 - constraint_set1_flag
564 * * Bit 10 - constraint_set2_flag
565 * * Bit 11 - constraint_set3_flag
566 * * Bit 12 - constraint_set3_flag
567 * * Bit 13:15 - Reserved
568 * * Bit 16:24 - Level indication
570 * Returns: The profile as a const string, or %NULL if there is an error.
573 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
575 const gchar *profile = NULL;
576 gint csf1, csf3, csf4, csf5;
578 g_return_val_if_fail (sps != NULL, NULL);
583 GST_MEMDUMP ("SPS", sps, len);
585 csf1 = (sps[1] & 0x40) >> 6;
586 csf3 = (sps[1] & 0x10) >> 4;
587 csf4 = (sps[1] & 0x08) >> 3;
588 csf5 = (sps[1] & 0x04) >> 2;
593 profile = "constrained-baseline";
595 profile = "baseline";
601 profile = "extended";
606 profile = "constrained-high";
608 profile = "progressive-high";
614 profile = "high-10-intra";
616 profile = "progressive-high-10";
622 profile = "high-4:2:2-intra";
624 profile = "high-4:2:2";
628 profile = "high-4:4:4-intra";
630 profile = "high-4:4:4";
633 profile = "cavlc-4:4:4-intra";
636 profile = "multiview-high";
639 profile = "stereo-high";
643 profile = "scalable-constrained-baseline";
645 profile = "scalable-baseline";
649 profile = "scalable-high-intra";
651 profile = "scalable-constrained-high";
653 profile = "scalable-high";
663 * gst_codec_utils_h264_get_level:
664 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
665 * @len: Length of the data available in @sps.
667 * Converts the level indication (level_idc) in the stream's
668 * sequence parameter set into a string. The SPS is expected to have the
669 * same format as for gst_codec_utils_h264_get_profile().
671 * Returns: The level as a const string, or %NULL if there is an error.
674 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
678 g_return_val_if_fail (sps != NULL, NULL);
683 GST_MEMDUMP ("SPS", sps, len);
685 csf3 = (sps[1] & 0x10) >> 4;
689 else if ((sps[2] == 11 && csf3) || sps[2] == 9)
691 else if (sps[2] % 10 == 0)
692 return digit_to_string (sps[2] / 10);
728 * gst_codec_utils_h264_get_level_idc:
729 * @level: A level string from caps
731 * Transform a level string from the caps into the level_idc
733 * Returns: the level_idc or 0 if the level is unknown
736 gst_codec_utils_h264_get_level_idc (const gchar * level)
738 g_return_val_if_fail (level != NULL, 0);
740 if (!strcmp (level, "1"))
742 else if (!strcmp (level, "1b"))
744 else if (!strcmp (level, "1.1"))
746 else if (!strcmp (level, "1.2"))
748 else if (!strcmp (level, "1.3"))
750 else if (!strcmp (level, "2"))
752 else if (!strcmp (level, "2.1"))
754 else if (!strcmp (level, "2.2"))
756 else if (!strcmp (level, "3"))
758 else if (!strcmp (level, "3.1"))
760 else if (!strcmp (level, "3.2"))
762 else if (!strcmp (level, "4"))
764 else if (!strcmp (level, "4.1"))
766 else if (!strcmp (level, "4.2"))
768 else if (!strcmp (level, "5"))
770 else if (!strcmp (level, "5.1"))
772 else if (!strcmp (level, "5.2"))
774 else if (!strcmp (level, "6"))
776 else if (!strcmp (level, "6.1"))
778 else if (!strcmp (level, "6.2"))
781 GST_WARNING ("Invalid level %s", level);
786 * gst_codec_utils_h264_caps_set_level_and_profile:
787 * @caps: the #GstCaps to which the level and profile are to be added
788 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
789 * @len: Length of the data available in @sps.
791 * Sets the level and profile in @caps if it can be determined from @sps. See
792 * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
793 * for more details on the parameters.
795 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
798 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
799 const guint8 * sps, guint len)
801 const gchar *level, *profile;
803 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
804 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
805 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
806 g_return_val_if_fail (sps != NULL, FALSE);
808 level = gst_codec_utils_h264_get_level (sps, len);
811 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
813 profile = gst_codec_utils_h264_get_profile (sps, len);
816 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
818 GST_LOG ("profile : %s", (profile) ? profile : "---");
819 GST_LOG ("level : %s", (level) ? level : "---");
821 return (level != NULL && profile != NULL);
825 * gst_codec_utils_h264_get_profile_flags_level:
826 * @codec_data: (array length=len): H264 AVCC extradata
827 * @len: length of @codec_data
828 * @profile: (optional) (out): return location for h264 profile_idc or %NULL
829 * @flags: (optional) (out): return location for h264 constraint set flags or %NULL
830 * @level: (optional) (out): return location h264 level_idc or %NULL
832 * Parses profile, flags, and level from a H264 AVCC extradata/sequence_header.
833 * These are most commonly retrieved from a video/x-h264 caps with a codec_data
836 * The format of H264 AVCC extradata/sequence_header is documented in the
837 * ITU-T H.264 specification section 7.3.2.1.1 as well as in ISO/IEC 14496-15
840 * Returns: %TRUE on success, %FALSE on failure
845 gst_codec_utils_h264_get_profile_flags_level (const guint8 * codec_data,
846 guint len, guint8 * profile, guint8 * flags, guint8 * level)
848 gboolean ret = FALSE;
850 g_return_val_if_fail (codec_data != NULL, FALSE);
853 GST_WARNING ("avc codec data is too small");
856 if (codec_data[0] != 1) {
857 GST_WARNING ("failed to parse avc codec version, must be 1");
862 *profile = codec_data[1];
865 *flags = codec_data[2];
868 *level = codec_data[3];
877 /* forked from gsth265parse.c */
880 const gchar *profile;
882 guint8 max_14bit_constraint_flag;
883 guint8 max_12bit_constraint_flag;
884 guint8 max_10bit_constraint_flag;
885 guint8 max_8bit_constraint_flag;
886 guint8 max_422chroma_constraint_flag;
887 guint8 max_420chroma_constraint_flag;
888 guint8 max_monochrome_constraint_flag;
889 guint8 intra_constraint_flag;
890 guint8 one_picture_only_constraint_flag;
891 guint8 lower_bit_rate_constraint_flag;
893 /* Tie breaker if more than one profiles are matching */
895 } GstH265ExtensionProfile;
899 const GstH265ExtensionProfile *profile;
900 guint extra_constraints;
901 } H265ExtensionProfileMatch;
904 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
905 H265ExtensionProfileMatch * b)
909 d = a->extra_constraints - b->extra_constraints;
913 return b->profile->priority - a->profile->priority;
917 utils_get_extension_profile (const GstH265ExtensionProfile * profiles,
918 guint num, GstH265ExtensionProfile * ext_profile)
921 const gchar *profile = NULL;
924 for (i = 0; i < num; i++) {
925 GstH265ExtensionProfile p = profiles[i];
926 guint extra_constraints = 0;
927 H265ExtensionProfileMatch *m;
929 /* Filter out all the profiles having constraints not satisfied by
931 * Then pick the one having the least extra constraints. This allow us
932 * to match the closet profile if bitstream contains not standard
934 if (p.max_14bit_constraint_flag != ext_profile->max_14bit_constraint_flag) {
935 if (p.max_14bit_constraint_flag)
940 if (p.max_12bit_constraint_flag != ext_profile->max_12bit_constraint_flag) {
941 if (p.max_12bit_constraint_flag)
946 if (p.max_10bit_constraint_flag != ext_profile->max_10bit_constraint_flag) {
947 if (p.max_10bit_constraint_flag)
952 if (p.max_8bit_constraint_flag != ext_profile->max_8bit_constraint_flag) {
953 if (p.max_8bit_constraint_flag)
958 if (p.max_422chroma_constraint_flag !=
959 ext_profile->max_422chroma_constraint_flag) {
960 if (p.max_422chroma_constraint_flag)
965 if (p.max_420chroma_constraint_flag !=
966 ext_profile->max_420chroma_constraint_flag) {
967 if (p.max_420chroma_constraint_flag)
972 if (p.max_monochrome_constraint_flag !=
973 ext_profile->max_monochrome_constraint_flag) {
974 if (p.max_monochrome_constraint_flag)
979 if (p.intra_constraint_flag != ext_profile->intra_constraint_flag) {
980 if (p.intra_constraint_flag)
985 if (p.one_picture_only_constraint_flag !=
986 ext_profile->one_picture_only_constraint_flag) {
987 if (p.one_picture_only_constraint_flag)
992 if (p.lower_bit_rate_constraint_flag
993 && !ext_profile->lower_bit_rate_constraint_flag)
996 /* choose this one if all flags are matched */
997 if (extra_constraints == 0) {
1002 m = g_new0 (H265ExtensionProfileMatch, 1);
1003 m->profile = &profiles[i];
1004 m->extra_constraints = extra_constraints;
1005 cand = g_list_prepend (cand, m);
1008 if (!profile && cand) {
1009 H265ExtensionProfileMatch *m;
1011 cand = g_list_sort (cand, (GCompareFunc) sort_fre_profile_matches);
1013 profile = m->profile->profile;
1017 g_list_free_full (cand, g_free);
1022 static const gchar *
1023 utils_get_format_range_extension_profile (GstH265ExtensionProfile * ext_profile)
1025 static const GstH265ExtensionProfile profiles[] = {
1026 /* FIXME 2.0: Consider ':' separated subsampling notation for consistency
1027 * https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/23
1029 /* Rec. ITU-T H.265 Table A.2 format range extensions profiles */
1031 {"monochrome", 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1032 {"monochrome-10", 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1},
1033 {"monochrome-12", 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1034 {"monochrome-16", 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 3},
1035 {"main-12", 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 4},
1036 {"main-422-10", 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 5},
1037 {"main-422-12", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 6},
1038 {"main-444", 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 7},
1039 {"main-444-10", 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 8},
1040 {"main-444-12", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 9},
1041 {"main-intra", 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 10},
1042 {"main-10-intra", 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 11},
1043 {"main-12-intra", 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 12},
1044 {"main-422-10-intra", 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 13},
1045 {"main-422-12-intra", 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 14},
1046 {"main-444-intra", 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 15},
1047 {"main-444-10-intra", 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 16},
1048 {"main-444-12-intra", 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17},
1049 {"main-444-16-intra", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 18},
1050 {"main-444-still-picture", 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 19},
1051 {"main-444-16-still-picture", 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 20},
1055 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1059 static const gchar *
1060 utils_get_3d_profile (GstH265ExtensionProfile * ext_profile)
1062 static const GstH265ExtensionProfile profiles[] = {
1063 /* Rec. ITU-T H.265 I.11.1 3D Main profile */
1065 {"3d-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1069 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1073 static const gchar *
1074 utils_get_multiview_profile (GstH265ExtensionProfile * ext_profile)
1076 static const GstH265ExtensionProfile profiles[] = {
1077 /* Rec. ITU-T H.265 G.11.1 Multiview Main profile */
1079 {"multiview-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1083 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1087 static const gchar *
1088 utils_get_scalable_profile (GstH265ExtensionProfile * ext_profile)
1090 static const GstH265ExtensionProfile profiles[] = {
1091 /* Rec. ITU-T H.265 H.11.1 */
1093 {"scalable-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1094 {"scalable-main-10", 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1098 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1102 static const gchar *
1103 utils_get_high_throughput_profile (GstH265ExtensionProfile * ext_profile)
1105 static const GstH265ExtensionProfile profiles[] = {
1106 /* Rec. ITU-T H.265 Table A.3 high throughput profiles */
1108 {"high-throughput-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0},
1109 {"high-throughput-444-10", 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1},
1110 {"high-throughput-444-14", 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2},
1111 {"high-throughput-444-16-intra", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3},
1115 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1119 static const gchar *
1120 utils_get_screen_content_coding_extensions_profile (GstH265ExtensionProfile *
1123 static const GstH265ExtensionProfile profiles[] = {
1124 /* Rec. ITU-T H.265 Table A.5 screen content coding extensions profiles */
1126 {"screen-extended-main", 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1127 {"screen-extended-main-10", 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1128 {"screen-extended-main-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2},
1129 {"screen-extended-main-444-10", 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 3},
1130 /* identical to screen-extended-main-444 */
1131 {"screen-extended-high-throughput-444",
1132 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 4},
1133 /* identical to screen-extended-main-444-10 */
1134 {"screen-extended-high-throughput-444-10",
1135 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 5},
1136 {"screen-extended-high-throughput-444-14",
1137 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6},
1141 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1145 static const gchar *
1146 utils_get_scalable_format_range_extensions_profile (GstH265ExtensionProfile *
1149 static const GstH265ExtensionProfile profiles[] = {
1150 /* Rec. ITU-T H.265 Table H.4 scalable range extensions profiles */
1152 {"scalable-monochrome", 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1153 {"scalable-monochrome-12", 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1},
1154 {"scalable-monochrome-16", 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1155 {"scalable-main-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 3},
1159 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1164 * gst_codec_utils_h265_get_profile:
1165 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1166 * structure for the stream.
1167 * @len: Length of the data available in @profile_tier_level
1169 * Converts the profile indication (general_profile_idc) in the stream's
1170 * profile_level_tier structure into a string. The profile_tier_level is
1171 * expected to have the following format, as defined in the H.265
1172 * specification. The profile_tier_level is viewed as a bitstream here,
1173 * with bit 0 being the most significant bit of the first byte.
1175 * * Bit 0:1 - general_profile_space
1176 * * Bit 2 - general_tier_flag
1177 * * Bit 3:7 - general_profile_idc
1178 * * Bit 8:39 - gernal_profile_compatibility_flags
1179 * * Bit 40 - general_progressive_source_flag
1180 * * Bit 41 - general_interlaced_source_flag
1181 * * Bit 42 - general_non_packed_constraint_flag
1182 * * Bit 43 - general_frame_only_constraint_flag
1183 * * Bit 44:87 - See below
1184 * * Bit 88:95 - general_level_idc
1186 * Returns: The profile as a const string, or %NULL if there is an error.
1191 gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
1193 const gchar *profile = NULL;
1196 guint8 profile_compatibility_flags[32] = { 0, };
1197 GstBitReader br = GST_BIT_READER_INIT (profile_tier_level, len);
1199 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1204 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1206 profile_idc = (profile_tier_level[0] & 0x1f);
1208 if (profile_idc == 1)
1210 else if (profile_idc == 2)
1211 profile = "main-10";
1212 else if (profile_idc == 3)
1213 profile = "main-still-picture";
1216 if (!gst_bit_reader_skip (&br, 8))
1219 for (i = 0; i < 32; i++) {
1220 if (!gst_bit_reader_get_bits_uint8 (&br, &profile_compatibility_flags[i],
1227 if (profile_compatibility_flags[1])
1229 else if (profile_compatibility_flags[2])
1230 profile = "main-10";
1231 else if (profile_compatibility_flags[3])
1232 profile = "main-still-picture";
1238 if (profile_idc >= 4 && profile_idc <= 11 && len >= 11) {
1239 GstH265ExtensionProfile ext_profile = { 0, };
1242 * Bit 40 - general_progressive_source_flag
1243 * Bit 41 - general_interlaced_source_flag
1244 * Bit 42 - general_non_packed_constraint_flag
1245 * Bit 43 - general_frame_only_constraint_flag
1247 if (!gst_bit_reader_skip (&br, 4))
1252 * 4 : Format range extensions profiles
1253 * 5 : High throughput profiles
1254 * 6 : Multiview main profile
1255 * 7 : Scalable main profiles
1256 * 8 : 3D Main profile
1257 * 9 : Screen content coding extensions profiles
1258 * 10 : Scalable format range extensions profiles
1260 * Bit 44 - general_max_12bit_constraint_flag
1261 * Bit 45 - general_max_10bit_constraint_flag
1262 * Bit 46 - general_max_8bit_constraint_flag
1263 * Bit 47 - general_max_422chroma_constraint_flag
1264 * Bit 48 - general_max_420chroma_constraint_flag
1265 * Bit 49 - general_max_monochrome_constraint_flag
1266 * Bit 50 - general_intra_constraint_flag
1267 * Bit 51 - general_one_picture_only_constraint_flag
1268 * Bit 52 - general_lower_bit_rate_constraint_flag
1270 if (!gst_bit_reader_get_bits_uint8 (&br,
1271 &ext_profile.max_12bit_constraint_flag, 1))
1274 if (!gst_bit_reader_get_bits_uint8 (&br,
1275 &ext_profile.max_10bit_constraint_flag, 1))
1278 if (!gst_bit_reader_get_bits_uint8 (&br,
1279 &ext_profile.max_8bit_constraint_flag, 1))
1282 if (!gst_bit_reader_get_bits_uint8 (&br,
1283 &ext_profile.max_422chroma_constraint_flag, 1))
1286 if (!gst_bit_reader_get_bits_uint8 (&br,
1287 &ext_profile.max_420chroma_constraint_flag, 1))
1290 if (!gst_bit_reader_get_bits_uint8 (&br,
1291 &ext_profile.max_monochrome_constraint_flag, 1))
1294 if (!gst_bit_reader_get_bits_uint8 (&br,
1295 &ext_profile.intra_constraint_flag, 1))
1298 if (!gst_bit_reader_get_bits_uint8 (&br,
1299 &ext_profile.one_picture_only_constraint_flag, 1))
1302 if (!gst_bit_reader_get_bits_uint8 (&br,
1303 &ext_profile.lower_bit_rate_constraint_flag, 1))
1306 if (profile_idc == 5 || profile_idc == 9 ||
1307 profile_idc == 10 || profile_idc == 11 ||
1308 profile_compatibility_flags[5] || profile_compatibility_flags[9] ||
1309 profile_compatibility_flags[10] || profile_compatibility_flags[11]) {
1310 /* Bit 53 - general_max_14bit_constraint_flag */
1311 if (!gst_bit_reader_get_bits_uint8 (&br,
1312 &ext_profile.max_14bit_constraint_flag, 1))
1316 if (profile_idc == 4 || profile_compatibility_flags[4])
1317 return utils_get_format_range_extension_profile (&ext_profile);
1319 if (profile_idc == 5 || profile_compatibility_flags[5])
1320 return utils_get_high_throughput_profile (&ext_profile);
1322 if (profile_idc == 6 || profile_compatibility_flags[6])
1323 return utils_get_multiview_profile (&ext_profile);
1325 if (profile_idc == 7 || profile_compatibility_flags[7])
1326 return utils_get_scalable_profile (&ext_profile);
1328 if (profile_idc == 8 || profile_compatibility_flags[8])
1329 return utils_get_3d_profile (&ext_profile);
1331 if (profile_idc == 9 || profile_compatibility_flags[9] ||
1332 profile_idc == 11 || profile_compatibility_flags[11])
1333 return utils_get_screen_content_coding_extensions_profile (&ext_profile);
1335 if (profile_idc == 10 || profile_compatibility_flags[10])
1336 return utils_get_scalable_format_range_extensions_profile (&ext_profile);
1343 * gst_codec_utils_h265_get_tier:
1344 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1346 * @len: Length of the data available in @profile_tier_level.
1348 * Converts the tier indication (general_tier_flag) in the stream's
1349 * profile_tier_level structure into a string. The profile_tier_level
1350 * is expected to have the same format as for gst_codec_utils_h264_get_profile().
1352 * Returns: The tier as a const string, or %NULL if there is an error.
1357 gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
1359 const gchar *tier = NULL;
1362 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1367 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1369 tier_flag = (profile_tier_level[0] & 0x20) >> 5;
1380 * gst_codec_utils_h265_get_level:
1381 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1383 * @len: Length of the data available in @profile_tier_level.
1385 * Converts the level indication (general_level_idc) in the stream's
1386 * profile_tier_level structure into a string. The profiel_tier_level is
1387 * expected to have the same format as for gst_codec_utils_h264_get_profile().
1389 * Returns: The level as a const string, or %NULL if there is an error.
1394 gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
1396 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1401 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1403 if (profile_tier_level[11] == 0)
1405 else if (profile_tier_level[11] % 30 == 0)
1406 return digit_to_string (profile_tier_level[11] / 30);
1408 switch (profile_tier_level[11]) {
1437 * gst_codec_utils_h265_get_level_idc:
1438 * @level: A level string from caps
1440 * Transform a level string from the caps into the level_idc
1442 * Returns: the level_idc or 0 if the level is unknown
1447 gst_codec_utils_h265_get_level_idc (const gchar * level)
1449 g_return_val_if_fail (level != NULL, 0);
1451 if (!strcmp (level, "1"))
1453 else if (!strcmp (level, "2"))
1455 else if (!strcmp (level, "2.1"))
1457 else if (!strcmp (level, "3"))
1459 else if (!strcmp (level, "3.1"))
1461 else if (!strcmp (level, "4"))
1463 else if (!strcmp (level, "4.1"))
1465 else if (!strcmp (level, "5"))
1467 else if (!strcmp (level, "5.1"))
1469 else if (!strcmp (level, "5.2"))
1471 else if (!strcmp (level, "6"))
1473 else if (!strcmp (level, "6.1"))
1475 else if (!strcmp (level, "6.2"))
1478 GST_WARNING ("Invalid level %s", level);
1483 * gst_codec_utils_h265_caps_set_level_tier_and_profile:
1484 * @caps: the #GstCaps to which the level, tier and profile are to be added
1485 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1487 * @len: Length of the data available in @profile_tier_level.
1489 * Sets the level, tier and profile in @caps if it can be determined from
1490 * @profile_tier_level. See gst_codec_utils_h265_get_level(),
1491 * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
1492 * for more details on the parameters.
1494 * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
1499 gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
1500 const guint8 * profile_tier_level, guint len)
1502 const gchar *level, *tier, *profile;
1504 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1505 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1506 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
1507 g_return_val_if_fail (profile_tier_level != NULL, FALSE);
1509 level = gst_codec_utils_h265_get_level (profile_tier_level, len);
1511 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1513 tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
1515 gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
1517 profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
1518 if (profile != NULL)
1519 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1521 GST_LOG ("profile : %s", (profile) ? profile : "---");
1522 GST_LOG ("tier : %s", (tier) ? tier : "---");
1523 GST_LOG ("level : %s", (level) ? level : "---");
1525 return (level != NULL && tier != NULL && profile != NULL);
1529 * gst_codec_utils_mpeg4video_get_profile:
1530 * @vis_obj_seq: (array length=len): Pointer to the visual object
1531 * sequence for the stream.
1532 * @len: Length of the data available in @sps.
1534 * Converts the profile indication in the stream's visual object sequence into
1535 * a string. @vis_obj_seq is expected to be the data following the visual
1536 * object sequence start code. Only the first byte
1537 * (profile_and_level_indication) is used.
1539 * Returns: The profile as a const string, or NULL if there is an error.
1542 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
1544 /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
1545 * sources: epan/dissectors/packet-mp4ves.c */
1547 /* These are a direct mapping from the integer profile id -> string. Profiles
1548 * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
1549 * second 4 bits of vis_obj_seq[0], so they are handled separately. */
1550 static const char *profiles[] = { "simple", "simple-scalable", "core",
1551 "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
1552 "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
1553 "advanced-core", "advanced-scalable-texture",
1555 int profile_id, level_id;
1557 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1562 GST_MEMDUMP ("VOS", vis_obj_seq, len);
1564 profile_id = vis_obj_seq[0] >> 4;
1565 level_id = vis_obj_seq[0] & 0xf;
1567 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1569 if (profile_id != 6 && profile_id < 0xe)
1570 return profiles[profile_id];
1572 if (profile_id != 0xf && level_id == 0)
1575 switch (profile_id) {
1578 return "simple-face";
1579 else if (level_id < 5)
1580 return "simple-fba";
1585 return "simple-studio";
1586 else if (level_id < 9)
1587 return "core-studio";
1592 return "advanced-simple";
1593 else if (level_id > 7 && level_id < 0xe)
1594 return "fine-granularity-scalable";
1602 * gst_codec_utils_mpeg4video_get_level:
1603 * @vis_obj_seq: (array length=len): Pointer to the visual object
1604 * sequence for the stream.
1605 * @len: Length of the data available in @sps.
1607 * Converts the level indication in the stream's visual object sequence into
1608 * a string. @vis_obj_seq is expected to be the data following the visual
1609 * object sequence start code. Only the first byte
1610 * (profile_and_level_indication) is used.
1612 * Returns: The level as a const string, or NULL if there is an error.
1615 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
1617 /* The profile/level codes are from 14496-2, table G-1, the Wireshark
1618 * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
1620 * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
1621 * (see Xvid sources vfw/config.c)
1623 * Each profile has a different maximum level it defines. Some of them still
1624 * need special case handling, because not all levels start from 1, and the
1625 * Simple profile defines an intermediate level as well. */
1626 static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
1629 int profile_id, level_id;
1631 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1636 GST_MEMDUMP ("VOS", vis_obj_seq, len);
1638 profile_id = vis_obj_seq[0] >> 4;
1639 level_id = vis_obj_seq[0] & 0xf;
1641 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1643 if (profile_id != 0xf && level_id == 0)
1646 /* Let's do some validation of the level */
1647 switch (profile_id) {
1669 if (level_id == 6 || level_id == 7 || level_id > 0xd)
1674 if (profile_id == 0 && level_id == 8)
1675 /* Simple Profile / Level 0 */
1677 else if (profile_id == 0 && level_id == 9)
1678 /* Simple Profile / Level 0b */
1680 else if (profile_id == 0 && level_id == 4)
1681 /* Simple Profile / Level 4a */
1683 else if (profile_id == 0xf && level_id > 7)
1684 /* Fine Granularity Scalable Profile */
1685 return digit_to_string (level_id - 8);
1686 else if (level_id <= level_max[profile_id])
1687 /* Levels for all other cases */
1688 return digit_to_string (level_id);
1694 * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
1695 * @caps: the #GstCaps to which the level and profile are to be added
1696 * @vis_obj_seq: (array length=len): Pointer to the visual object
1697 * sequence for the stream.
1698 * @len: Length of the data available in @sps.
1700 * Sets the level and profile in @caps if it can be determined from
1701 * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
1702 * gst_codec_utils_mpeg4video_get_profile() for more details on the
1705 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
1708 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
1709 const guint8 * vis_obj_seq, guint len)
1711 const gchar *profile, *level;
1713 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1714 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1715 g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
1717 profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
1719 if (profile != NULL)
1720 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1722 level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
1725 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1727 GST_LOG ("profile : %s", (profile) ? profile : "---");
1728 GST_LOG ("level : %s", (level) ? level : "---");
1730 return (profile != NULL && level != NULL);
1734 * gst_codec_utils_opus_parse_caps:
1735 * @caps: the #GstCaps to parse the data from
1736 * @rate: (optional) (out): the sample rate
1737 * @channels: (optional) (out): the number of channels
1738 * @channel_mapping_family: (optional) (out): the channel mapping family
1739 * @stream_count: (optional) (out): the number of independent streams
1740 * @coupled_count: (optional) (out): the number of stereo streams
1741 * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
1743 * Parses Opus caps and fills the different fields with defaults if possible.
1745 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
1750 gst_codec_utils_opus_parse_caps (GstCaps * caps,
1753 guint8 * channel_mapping_family,
1754 guint8 * stream_count, guint8 * coupled_count, guint8 channel_mapping[256])
1758 const GValue *va, *v;
1760 g_return_val_if_fail (caps != NULL, FALSE);
1761 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1762 g_return_val_if_fail (!gst_caps_is_empty (caps), FALSE);
1764 s = gst_caps_get_structure (caps, 0);
1766 g_return_val_if_fail (gst_structure_has_name (s, "audio/x-opus"), FALSE);
1767 g_return_val_if_fail (gst_structure_has_field_typed (s,
1768 "channel-mapping-family", G_TYPE_INT), FALSE);
1773 if (gst_structure_get_int (s, "rate", &r))
1779 gst_structure_get_int (s, "channel-mapping-family", &f);
1780 if (channel_mapping_family)
1781 *channel_mapping_family = f;
1783 if (!gst_structure_get_int (s, "channels", &c) || c == 0) {
1801 *coupled_count = c == 2 ? 1 : 0;
1803 if (channel_mapping) {
1804 channel_mapping[0] = 0;
1805 channel_mapping[1] = 1;
1811 if (!gst_structure_get_int (s, "stream-count", &sc))
1816 if (!gst_structure_get_int (s, "coupled-count", &cc))
1819 *coupled_count = cc;
1821 va = gst_structure_get_value (s, "channel-mapping");
1822 if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY))
1825 if (gst_value_array_get_size (va) != c)
1828 if (channel_mapping) {
1831 for (i = 0; i < c; i++) {
1834 v = gst_value_array_get_value (va, i);
1836 if (!G_VALUE_HOLDS (v, G_TYPE_INT))
1839 cm = g_value_get_int (v);
1840 if (cm < 0 || cm > 255)
1843 channel_mapping[i] = cm;
1851 * gst_codec_utils_opus_create_caps:
1852 * @rate: the sample rate
1853 * @channels: the number of channels
1854 * @channel_mapping_family: the channel mapping family
1855 * @stream_count: the number of independent streams
1856 * @coupled_count: the number of stereo streams
1857 * @channel_mapping: (nullable) (array): the mapping between the streams
1859 * Creates Opus caps from the given parameters.
1861 * Returns: The #GstCaps, or %NULL if the parameters would lead to
1862 * invalid Opus caps.
1867 gst_codec_utils_opus_create_caps (guint32 rate,
1869 guint8 channel_mapping_family,
1870 guint8 stream_count, guint8 coupled_count, const guint8 * channel_mapping)
1872 GstCaps *caps = NULL;
1873 GValue va = G_VALUE_INIT;
1874 GValue v = G_VALUE_INIT;
1880 if (channel_mapping_family == 0) {
1882 GST_ERROR ("Invalid channels count for channel_mapping_family 0: %d",
1887 if (stream_count > 1) {
1888 GST_ERROR ("Invalid stream count for channel_mapping_family 0: %d",
1893 if (coupled_count > 1) {
1894 GST_ERROR ("Invalid coupled count for channel_mapping_family 0: %d",
1902 if (stream_count == 0)
1905 if (coupled_count == 0)
1906 coupled_count = channels == 2 ? 1 : 0;
1908 return gst_caps_new_simple ("audio/x-opus",
1909 "rate", G_TYPE_INT, rate,
1910 "channels", G_TYPE_INT, channels,
1911 "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1912 "stream-count", G_TYPE_INT, stream_count,
1913 "coupled-count", G_TYPE_INT, coupled_count, NULL);
1916 if (channels == 0) {
1917 GST_ERROR ("Invalid channels count: %d", channels);
1921 if (stream_count == 0) {
1922 GST_ERROR ("Invalid stream count: %d", stream_count);
1926 if (coupled_count > stream_count) {
1927 GST_ERROR ("Coupled count %d > stream count: %d", coupled_count,
1932 if (channel_mapping == NULL) {
1934 ("A non NULL channel-mapping is needed for channel_mapping_family != 0");
1938 caps = gst_caps_new_simple ("audio/x-opus",
1939 "rate", G_TYPE_INT, rate,
1940 "channels", G_TYPE_INT, channels,
1941 "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1942 "stream-count", G_TYPE_INT, stream_count,
1943 "coupled-count", G_TYPE_INT, coupled_count, NULL);
1945 g_value_init (&va, GST_TYPE_ARRAY);
1946 g_value_init (&v, G_TYPE_INT);
1947 for (i = 0; i < channels; i++) {
1948 g_value_set_int (&v, channel_mapping[i]);
1949 gst_value_array_append_value (&va, &v);
1951 gst_structure_set_value (gst_caps_get_structure (caps, 0), "channel-mapping",
1953 g_value_unset (&va);
1961 * (really really) FIXME: move into core (dixit tpm)
1964 * _gst_caps_set_buffer_array:
1965 * @caps: (transfer full): a #GstCaps
1966 * @field: field in caps to set
1967 * @buf: header buffers
1969 * Adds given buffers to an array of buffers set as the given @field
1970 * on the given @caps. List of buffer arguments must be NULL-terminated.
1972 * Returns: (transfer full): input caps with a streamheader field added, or NULL
1973 * if some error occurred
1976 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
1977 GstBuffer * buf, ...)
1979 GstStructure *structure = NULL;
1981 GValue array = { 0 };
1982 GValue value = { 0 };
1984 g_return_val_if_fail (caps != NULL, NULL);
1985 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
1986 g_return_val_if_fail (field != NULL, NULL);
1988 caps = gst_caps_make_writable (caps);
1989 structure = gst_caps_get_structure (caps, 0);
1991 g_value_init (&array, GST_TYPE_ARRAY);
1994 /* put buffers in a fixed list */
1996 g_assert (gst_buffer_is_writable (buf));
1999 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2001 g_value_init (&value, GST_TYPE_BUFFER);
2002 buf = gst_buffer_copy (buf);
2003 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2004 gst_value_set_buffer (&value, buf);
2005 gst_buffer_unref (buf);
2006 gst_value_array_append_value (&array, &value);
2007 g_value_unset (&value);
2009 buf = va_arg (va, GstBuffer *);
2013 gst_structure_set_value (structure, field, &array);
2014 g_value_unset (&array);
2020 * gst_codec_utils_opus_create_caps_from_header:
2021 * @header: OpusHead header
2022 * @comments: (nullable): Comment header or NULL
2024 * Creates Opus caps from the given OpusHead @header and comment header
2027 * Returns: The #GstCaps.
2032 gst_codec_utils_opus_create_caps_from_header (GstBuffer * header,
2033 GstBuffer * comments)
2038 guint8 channel_mapping_family;
2039 guint8 stream_count;
2040 guint8 coupled_count;
2041 guint8 channel_mapping[256];
2042 GstBuffer *dummy_comments = NULL;
2044 g_return_val_if_fail (GST_IS_BUFFER (header), NULL);
2045 g_return_val_if_fail (comments == NULL || GST_IS_BUFFER (comments), NULL);
2047 if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
2048 &channel_mapping_family, &stream_count, &coupled_count,
2049 channel_mapping, NULL, NULL))
2053 gst_codec_utils_opus_create_caps (rate, channels,
2054 channel_mapping_family, stream_count, coupled_count,
2059 GstTagList *tags = gst_tag_list_new_empty ();
2061 gst_tag_list_to_vorbiscomment_buffer (tags, (const guint8 *) "OpusTags",
2063 gst_tag_list_unref (tags);
2065 _gst_caps_set_buffer_array (caps, "streamheader", header,
2066 comments ? comments : dummy_comments, NULL);
2069 gst_buffer_unref (dummy_comments);
2075 * gst_codec_utils_opus_create_header:
2076 * @rate: the sample rate
2077 * @channels: the number of channels
2078 * @channel_mapping_family: the channel mapping family
2079 * @stream_count: the number of independent streams
2080 * @coupled_count: the number of stereo streams
2081 * @channel_mapping: (nullable) (array): the mapping between the streams
2082 * @pre_skip: Pre-skip in 48kHz samples or 0
2083 * @output_gain: Output gain or 0
2085 * Creates OpusHead header from the given parameters.
2087 * Returns: The #GstBuffer containing the OpusHead.
2092 gst_codec_utils_opus_create_header (guint32 rate,
2094 guint8 channel_mapping_family,
2095 guint8 stream_count,
2096 guint8 coupled_count,
2097 const guint8 * channel_mapping, guint16 pre_skip, gint16 output_gain)
2101 gboolean hdl = TRUE;
2106 if (channel_mapping_family == 0) {
2107 g_return_val_if_fail (channels <= 2, NULL);
2111 g_return_val_if_fail (stream_count == 0 || stream_count == 1, NULL);
2112 if (stream_count == 0)
2115 g_return_val_if_fail (coupled_count == 0 || coupled_count == 1, NULL);
2116 if (coupled_count == 0)
2117 coupled_count = channels == 2 ? 1 : 0;
2119 channel_mapping = NULL;
2121 g_return_val_if_fail (channels > 0, NULL);
2122 g_return_val_if_fail (stream_count > 0, NULL);
2123 g_return_val_if_fail (coupled_count <= stream_count, NULL);
2124 g_return_val_if_fail (channel_mapping != NULL, NULL);
2127 gst_byte_writer_init (&bw);
2128 /* See http://wiki.xiph.org/OggOpus */
2129 hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
2130 hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
2131 hdl &= gst_byte_writer_put_uint8 (&bw, channels);
2132 hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
2133 hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
2134 hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
2135 hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
2136 if (channel_mapping_family > 0) {
2137 hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
2138 hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
2139 hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
2143 GST_WARNING ("Error creating header");
2144 gst_byte_writer_reset (&bw);
2148 buffer = gst_byte_writer_reset_and_get_buffer (&bw);
2149 GST_BUFFER_OFFSET (buffer) = 0;
2150 GST_BUFFER_OFFSET_END (buffer) = 0;
2156 * gst_codec_utils_opus_parse_header:
2157 * @header: the OpusHead #GstBuffer
2158 * @rate: (optional) (out): the sample rate
2159 * @channels: (optional) (out): the number of channels
2160 * @channel_mapping_family: (optional) (out): the channel mapping family
2161 * @stream_count: (optional) (out): the number of independent streams
2162 * @coupled_count: (optional) (out): the number of stereo streams
2163 * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
2164 * @pre_skip: (optional) (out): Pre-skip in 48kHz samples or 0
2165 * @output_gain: (optional) (out): Output gain or 0
2167 * Parses the OpusHead header.
2169 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
2174 gst_codec_utils_opus_parse_header (GstBuffer * header,
2177 guint8 * channel_mapping_family,
2178 guint8 * stream_count,
2179 guint8 * coupled_count,
2180 guint8 channel_mapping[256], guint16 * pre_skip, gint16 * output_gain)
2184 gboolean ret = TRUE;
2185 guint8 c, f, version;
2187 g_return_val_if_fail (GST_IS_BUFFER (header), FALSE);
2188 g_return_val_if_fail (gst_buffer_get_size (header) >= 19, FALSE);
2190 if (!gst_buffer_map (header, &map, GST_MAP_READ))
2192 gst_byte_reader_init (&br, map.data, map.size);
2193 /* See http://wiki.xiph.org/OggOpus */
2194 if (memcmp (gst_byte_reader_get_data_unchecked (&br, 8), "OpusHead", 8) != 0) {
2198 version = gst_byte_reader_get_uint8_unchecked (&br);
2199 if (version == 0x00)
2200 GST_ERROR ("Opus Header version is wrong, should be 0x01 and not 0x00");
2201 else if (version != 0x01) {
2206 c = gst_byte_reader_get_uint8_unchecked (&br);
2211 *pre_skip = gst_byte_reader_get_uint16_le_unchecked (&br);
2213 gst_byte_reader_skip_unchecked (&br, 2);
2216 *rate = gst_byte_reader_get_uint32_le_unchecked (&br);
2218 gst_byte_reader_skip_unchecked (&br, 4);
2221 *output_gain = gst_byte_reader_get_uint16_le_unchecked (&br);
2223 gst_byte_reader_skip_unchecked (&br, 2);
2225 f = gst_byte_reader_get_uint8_unchecked (&br);
2226 if (channel_mapping_family)
2227 *channel_mapping_family = f;
2228 if (f == 0 && c <= 2) {
2232 *coupled_count = c == 2 ? 1 : 0;
2233 if (channel_mapping) {
2234 channel_mapping[0] = 0;
2235 channel_mapping[1] = 1;
2241 if (gst_byte_reader_get_remaining (&br) < 2 + c) {
2247 *stream_count = gst_byte_reader_get_uint8_unchecked (&br);
2249 gst_byte_reader_skip_unchecked (&br, 1);
2252 *coupled_count = gst_byte_reader_get_uint8_unchecked (&br);
2254 gst_byte_reader_skip_unchecked (&br, 1);
2256 if (channel_mapping)
2257 memcpy (channel_mapping, gst_byte_reader_get_data_unchecked (&br, c), c);
2260 gst_buffer_unmap (header, &map);
2266 h264_caps_structure_get_profile_flags_level (GstStructure * caps_st,
2267 guint8 * profile, guint8 * flags, guint8 * level)
2269 const GValue *codec_data_value = NULL;
2270 GstBuffer *codec_data = NULL;
2272 gboolean ret = FALSE;
2273 guint8 *data = NULL;
2276 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2277 if (!codec_data_value) {
2279 ("video/x-h264 caps did not have codec_data set, cannot parse profile, flags and level");
2283 codec_data = gst_value_get_buffer (codec_data_value);
2284 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2290 if (!gst_codec_utils_h264_get_profile_flags_level (data, (guint) size,
2291 profile, flags, level)) {
2293 ("Failed to parse profile, flags and level from h264 codec data");
2300 gst_buffer_unmap (codec_data, &map);
2306 aac_caps_structure_get_audio_object_type (GstStructure * caps_st,
2307 guint8 * audio_object_type)
2309 gboolean ret = FALSE;
2310 const GValue *codec_data_value = NULL;
2311 GstBuffer *codec_data = NULL;
2313 guint8 *data = NULL;
2317 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2318 if (!codec_data_value) {
2320 ("audio/mpeg pad did not have codec_data set, cannot parse audio object type");
2324 codec_data = gst_value_get_buffer (codec_data_value);
2325 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2332 GST_WARNING ("aac codec data is too small");
2336 gst_bit_reader_init (&br, data, size);
2337 ret = gst_codec_utils_aac_get_audio_object_type (&br, audio_object_type);
2340 gst_buffer_unmap (codec_data, &map);
2346 hevc_caps_get_mime_codec (GstCaps * caps, gchar ** mime_codec)
2348 GstStructure *caps_st = NULL;
2349 const GValue *codec_data_value = NULL;
2350 GstBuffer *codec_data = NULL;
2352 gboolean ret = FALSE;
2353 const gchar *stream_format;
2354 guint8 *data = NULL;
2356 guint16 profile_space;
2358 guint16 profile_idc;
2359 guint32 compat_flags;
2360 guchar constraint_indicator_flags[6];
2362 guint32 compat_flag_parameter = 0;
2363 GString *codec_string;
2364 const guint8 *profile_tier_level;
2365 unsigned last_flag_index;
2367 caps_st = gst_caps_get_structure (caps, 0);
2368 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2369 stream_format = gst_structure_get_string (caps_st, "stream-format");
2370 if (!codec_data_value) {
2371 GST_DEBUG ("video/x-h265 caps did not have codec_data set, cannot parse");
2373 } else if (!stream_format) {
2375 ("video/x-h265 caps did not have stream-format set, cannot parse");
2379 codec_data = gst_value_get_buffer (codec_data_value);
2380 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2386 /* HEVCDecoderConfigurationRecord is at a minimum 23 bytes long */
2388 GST_DEBUG ("Incomplete HEVCDecoderConfigurationRecord");
2392 if (!g_str_equal (stream_format, "hev1")
2393 && !g_str_equal (stream_format, "hvc1")) {
2394 GST_DEBUG ("Unknown stream-format %s", stream_format);
2398 profile_tier_level = data + 1;
2399 profile_space = (profile_tier_level[0] & 0x11) >> 6;
2400 tier_flag = (profile_tier_level[0] & 0x001) >> 5;
2401 profile_idc = (profile_tier_level[0] & 0x1f);
2403 compat_flags = GST_READ_UINT32_BE (data + 2);
2404 for (unsigned i = 0; i < 6; ++i)
2405 constraint_indicator_flags[i] = GST_READ_UINT8 (data + 6 + i);
2407 level_idc = data[12];
2409 /* The 32 bits of the compat_flags, but in reverse bit order */
2411 ((compat_flags & 0xaaaaaaaa) >> 1) | ((compat_flags & 0x55555555) << 1);
2413 ((compat_flags & 0xcccccccc) >> 2) | ((compat_flags & 0x33333333) << 2);
2415 ((compat_flags & 0xf0f0f0f0) >> 4) | ((compat_flags & 0x0f0f0f0f) << 4);
2417 ((compat_flags & 0xff00ff00) >> 8) | ((compat_flags & 0x00ff00ff) << 8);
2418 compat_flag_parameter = (compat_flags >> 16) | (compat_flags << 16);
2420 codec_string = g_string_new (stream_format);
2421 codec_string = g_string_append_c (codec_string, '.');
2423 codec_string = g_string_append_c (codec_string, 'A' + profile_space - 1);
2424 g_string_append_printf (codec_string, "%" G_GUINT16_FORMAT ".%X.%c%d",
2425 profile_idc, compat_flag_parameter, tier_flag ? 'H' : 'L', level_idc);
2427 /* Each of the 6 bytes of the constraint flags, starting from the byte containing the
2428 * progressive_source_flag, each encoded as a hexadecimal number, and the encoding
2429 * of each byte separated by a period; trailing bytes that are zero may be omitted.
2431 last_flag_index = 5;
2432 while ((int) (constraint_indicator_flags[last_flag_index]) == 0)
2434 for (unsigned i = 0; i <= last_flag_index; ++i) {
2435 g_string_append_printf (codec_string, ".%02X",
2436 constraint_indicator_flags[i]);
2439 *mime_codec = g_string_free (codec_string, FALSE);
2444 gst_buffer_unmap (codec_data, &map);
2449 * gst_codec_utils_caps_get_mime_codec:
2450 * @caps: A #GstCaps to convert to mime codec
2452 * Converts @caps to a RFC 6381 compatible codec string if possible.
2454 * Useful for providing the 'codecs' field inside the 'Content-Type' HTTP
2455 * header for containerized formats, such as mp4 or matroska.
2457 * Registered codecs can be found at http://mp4ra.org/#/codecs
2459 * Returns: (transfer full): a RFC 6381 compatible codec string or %NULL
2464 gst_codec_utils_caps_get_mime_codec (GstCaps * caps)
2466 gchar *mime_codec = NULL;
2467 GstStructure *caps_st = NULL;
2468 const gchar *media_type = NULL;
2470 g_return_val_if_fail (caps != NULL, NULL);
2471 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2473 caps_st = gst_caps_get_structure (caps, 0);
2474 if (caps_st == NULL) {
2475 GST_WARNING ("Failed to get structure from caps");
2479 media_type = gst_structure_get_name (caps_st);
2481 if (g_strcmp0 (media_type, "video/x-h264") == 0) {
2484 * BB = constraint set flags
2491 if (!h264_caps_structure_get_profile_flags_level (caps_st, &profile, &flags,
2494 ("h264 caps did not contain 'codec_data', cannot determine detailed codecs info");
2495 mime_codec = g_strdup ("avc1");
2497 mime_codec = g_strdup_printf ("avc1.%02X%02X%02X", profile, flags, level);
2499 } else if (g_strcmp0 (media_type, "video/x-h265") == 0) {
2500 if (!hevc_caps_get_mime_codec (caps, &mime_codec)) {
2501 GST_DEBUG ("h265 caps parsing failed");
2502 mime_codec = g_strdup ("hev1");
2504 } else if (g_strcmp0 (media_type, "video/x-av1") == 0) {
2505 /* TODO: Some browsers won't play the video unless more codec information is
2506 * available in the mime codec for av1. This is documented in
2507 * https://aomediacodec.github.io/av1-isobmff/#codecsparam */
2508 mime_codec = g_strdup ("av01");
2509 } else if (g_strcmp0 (media_type, "video/x-vp8") == 0) {
2510 /* TODO: most browsers won't play the video unless more codec information is
2511 * available in the mime codec for vp8. */
2512 mime_codec = g_strdup ("vp08");
2513 } else if (g_strcmp0 (media_type, "video/x-vp9") == 0) {
2514 /* TODO: most browsers won't play the video unless more codec information is
2515 * available in the mime codec for vp9. This is documented in
2516 * https://www.webmproject.org/vp9/mp4/ */
2517 mime_codec = g_strdup ("vp09");
2518 } else if (g_strcmp0 (media_type, "image/jpeg") == 0) {
2519 mime_codec = g_strdup ("mjpg");
2520 } else if (g_strcmp0 (media_type, "audio/mpeg") == 0) {
2521 guint8 audio_object_type = 0;
2522 if (aac_caps_structure_get_audio_object_type (caps_st, &audio_object_type)) {
2523 mime_codec = g_strdup_printf ("mp4a.40.%u", audio_object_type);
2525 mime_codec = g_strdup ("mp4a.40");
2527 } else if (g_strcmp0 (media_type, "audio/x-opus") == 0) {
2528 mime_codec = g_strdup ("opus");
2529 } else if (g_strcmp0 (media_type, "audio/x-mulaw") == 0) {
2530 mime_codec = g_strdup ("ulaw");
2531 } else if (g_strcmp0 (media_type, "audio/x-adpcm") == 0) {
2532 if (g_strcmp0 (gst_structure_get_string (caps_st, "layout"), "g726") == 0) {
2533 mime_codec = g_strdup ("g726");