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 #ifndef GST_DISABLE_GST_DEBUG
47 #define GST_CAT_DEFAULT gst_pb_utils_codec_utils_ensure_debug_category()
49 static GstDebugCategory *
50 gst_pb_utils_codec_utils_ensure_debug_category (void)
52 static gsize cat_gonce = 0;
54 if (g_once_init_enter (&cat_gonce)) {
55 GstDebugCategory *cat = NULL;
57 GST_DEBUG_CATEGORY_INIT (cat, "codec-utils", 0,
58 "GstPbUtils codec helper functions");
60 g_once_init_leave (&cat_gonce, (gsize) cat);
63 return (GstDebugCategory *) cat_gonce;
65 #endif /* GST_DISABLE_GST_DEBUG */
67 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
68 gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
70 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
71 gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
73 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
74 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
78 digit_to_string (guint digit)
80 static const char itoa[][2] = {
81 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
84 if (G_LIKELY (digit < 10))
91 * gst_codec_utils_aac_get_sample_rate_from_index:
92 * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
93 * container) or ADTS frame header
95 * Translates the sample rate index found in AAC headers to the actual sample
98 * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
101 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
103 if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
104 return aac_sample_rates[sr_idx];
106 GST_WARNING ("Invalid sample rate index %u", sr_idx);
111 * gst_codec_utils_aac_get_index_from_sample_rate:
114 * Translates the sample rate to the index corresponding to it in AAC spec.
116 * Returns: The AAC index for this sample rate, -1 if the rate is not a
117 * valid AAC sample rate.
120 gst_codec_utils_aac_get_index_from_sample_rate (guint rate)
124 for (n = 0; n < G_N_ELEMENTS (aac_sample_rates); n++)
125 if (aac_sample_rates[n] == rate)
128 GST_WARNING ("Invalid sample rate %u", rate);
133 gst_codec_utils_aac_get_audio_object_type (GstBitReader * br,
134 guint8 * audio_object_type)
138 if (!gst_bit_reader_get_bits_uint8 (br, &aot, 5))
142 if (!gst_bit_reader_get_bits_uint8 (br, &aot, 6))
147 *audio_object_type = aot;
153 gst_codec_utils_aac_get_audio_sample_rate (GstBitReader * br,
156 guint8 sampling_freq_index;
157 guint32 sampling_rate;
159 if (!gst_bit_reader_get_bits_uint8 (br, &sampling_freq_index, 4))
162 if (sampling_freq_index == 0xf) {
163 if (!gst_bit_reader_get_bits_uint32 (br, &sampling_rate, 24))
167 gst_codec_utils_aac_get_sample_rate_from_index (sampling_freq_index);
172 *sample_rate = sampling_rate;
178 gst_codec_utils_aac_get_audio_object_type_full (GstBitReader * br,
179 guint8 * audio_object_type, guint8 * channel_config, guint * sample_rate)
181 guint8 aot, channels;
184 if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
187 if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
190 if (!gst_bit_reader_get_bits_uint8 (br, &channels, 4))
193 /* 5 indicates SBR extension (i.e. HE-AAC) */
194 /* 29 indicates PS extension */
195 if (aot == 5 || aot == 29) {
196 if (!gst_codec_utils_aac_get_audio_sample_rate (br, &rate))
198 if (!gst_codec_utils_aac_get_audio_object_type (br, &aot))
202 *audio_object_type = aot;
204 *channel_config = channels;
210 * gst_codec_utils_aac_get_sample_rate:
211 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
212 * as specified in the Elementary Stream Descriptor (esds)
213 * in ISO/IEC 14496-1.
214 * @len: Length of @audio_config
216 * Translates the sample rate index found in AAC headers to the actual sample
219 * Returns: The sample rate if sr_idx is valid, 0 otherwise.
224 gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
226 guint sample_rate = 0;
227 guint8 audio_object_type = 0, channel_config = 0;
228 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
233 gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
234 &channel_config, &sample_rate);
240 * gst_codec_utils_aac_get_channels:
241 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
242 * as specified in the Elementary Stream Descriptor (esds)
243 * in ISO/IEC 14496-1.
244 * @len: Length of @audio_config in bytes
246 * Returns the channels of the given AAC stream.
248 * Returns: The channels or 0 if the channel could not be determined.
253 gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
260 channels = (audio_config[1] & 0x7f) >> 3;
261 if (channels > 0 && channels < 7)
263 else if (channels == 7)
270 * gst_codec_utils_aac_get_profile:
271 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
272 * as specified in the Elementary Stream Descriptor (esds)
273 * in ISO/IEC 14496-1.
274 * @len: Length of @audio_config in bytes
276 * Returns the profile of the given AAC stream as a string. The profile is
277 * normally determined using the AudioObjectType field which is in the first
278 * 5 bits of @audio_config
280 * Returns: (nullable): The profile as a const string and %NULL if the profile could not be
284 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
286 const gchar *profile = NULL;
288 guint8 audio_object_type, channel_config;
289 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
294 GST_MEMDUMP ("audio config", audio_config, len);
296 if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
297 &channel_config, &sample_rate)) {
301 switch (audio_object_type) {
315 GST_DEBUG ("Invalid profile idx: %u", audio_object_type);
323 * gst_codec_utils_aac_get_level:
324 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
325 * as specified in the Elementary Stream Descriptor (esds)
326 * in ISO/IEC 14496-1.
327 * @len: Length of @audio_config in bytes
329 * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
330 * streams, the constraints from the AAC audio profile are applied. For AAC
331 * Main, LTP, SSR and others, the Main profile is used.
333 * The @audio_config parameter follows the following format, starting from the
334 * most significant bit of the first byte:
336 * * Bit 0:4 contains the AudioObjectType (if this is 0x5, then the
337 * real AudioObjectType is carried after the rate and channel data)
338 * * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
339 * next 24 bits define the actual sample frequency, and subsequent
340 * fields are appropriately shifted).
341 * * Bit 9:12 contains the channel configuration
343 * Returns: (nullable): The level as a const string and %NULL if the level could not be
347 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
349 guint8 audio_object_type = 0xFF, channel_config = 0xFF;
351 /* Number of single channel elements, channel pair elements, low frequency
352 * elements, independently switched coupling channel elements, and
353 * dependently switched coupling channel elements.
355 * Note: The 2 CCE types are ignored for now as they require us to actually
356 * parse the first frame, and they are rarely found in actual streams.
358 int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
360 /* Processor and RAM Complexity Units (calculated and "reference" for single
362 int pcu = -1, rcu = -1, pcu_ref, rcu_ref;
364 GstBitReader br = GST_BIT_READER_INIT (audio_config, len);
366 g_return_val_if_fail (audio_config != NULL, NULL);
371 GST_MEMDUMP ("audio config", audio_config, len);
373 if (!gst_codec_utils_aac_get_audio_object_type_full (&br, &audio_object_type,
374 &channel_config, &rate)) {
378 switch (channel_config) {
380 /* Channel config is defined in the AudioObjectType's SpecificConfig,
381 * which requires some amount of digging through the headers. I only see
382 * this done in the MPEG conformance streams - FIXME */
383 GST_WARNING ("Found a stream with channel configuration in the "
384 "AudioSpecificConfig. Please file a bug with a link to the media if "
392 /* front left and right */
396 /* front left, right, and center */
401 /* front left, right, and center; rear surround */
406 /* front left, right, and center; rear left and right surround */
411 /* front left, right, center and LFE; rear left and right surround */
418 /* front left, right, center and LFE; outside front left and right;
419 * rear left and right surround */
430 GST_WARNING ("Unknown channel config in header: %d", channel_config);
434 switch (audio_object_type) {
436 GST_WARNING ("profile 0 is not a valid profile");
452 /* Other than a couple of ER profiles, Main is the worst-case */
458 /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
459 * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
461 pcu = ((float) rate / 48000) * pcu_ref *
462 ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
464 rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
465 (0.4 * num_cce_dep));
468 rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
470 rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
472 num_channels = num_sce + (2 * num_cpe);
474 if (audio_object_type == 2) {
475 /* AAC LC => return the level as per the 'AAC Profile' */
476 if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
478 else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
480 /* There is no level 3 for the AAC Profile */
481 else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
483 else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
485 else if (num_channels <= 7 && rate <= 48000 && pcu <= 25 && rcu <= 19)
487 else if (num_channels <= 7 && rate <= 96000 && pcu <= 50 && rcu <= 19)
490 /* Return the level as per the 'Main Profile' */
491 if (pcu < 40 && rcu < 20)
493 else if (pcu < 80 && rcu < 64)
495 else if (pcu < 160 && rcu < 128)
497 else if (pcu < 320 && rcu < 256)
502 GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
503 "channel_config=%u, pcu=%d,rcu=%d", audio_object_type, rate,
504 channel_config, pcu, rcu);
507 return digit_to_string (ret);
512 * gst_codec_utils_aac_caps_set_level_and_profile:
513 * @caps: the #GstCaps to which level and profile fields are to be added
514 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
515 * as specified in the Elementary Stream Descriptor (esds)
516 * in ISO/IEC 14496-1. (See below for more details)
517 * @len: Length of @audio_config in bytes
519 * Sets the level and profile on @caps if it can be determined from
520 * @audio_config. See gst_codec_utils_aac_get_level() and
521 * gst_codec_utils_aac_get_profile() for more details on the parameters.
522 * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
523 * If mpegversion is 4, the "base-profile" field is also set in @caps.
525 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
528 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
529 const guint8 * audio_config, guint len)
532 const gchar *level, *profile;
535 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
536 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
537 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
538 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
539 g_return_val_if_fail (audio_config != NULL, FALSE);
541 s = gst_caps_get_structure (caps, 0);
543 gst_structure_get_int (s, "mpegversion", &mpegversion);
544 g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
546 level = gst_codec_utils_aac_get_level (audio_config, len);
549 gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
551 profile = gst_codec_utils_aac_get_profile (audio_config, len);
553 if (profile != NULL) {
554 if (mpegversion == 4) {
555 gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
556 "profile", G_TYPE_STRING, profile, NULL);
558 gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
562 GST_LOG ("profile : %s", (profile) ? profile : "---");
563 GST_LOG ("level : %s", (level) ? level : "---");
565 return (level != NULL && profile != NULL);
569 * gst_codec_utils_h264_get_profile:
570 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
571 * @len: Length of the data available in @sps.
573 * Converts the profile indication (profile_idc) in the stream's
574 * sequence parameter set into a string. The SPS is expected to have the
575 * following format, as defined in the H.264 specification. The SPS is viewed
576 * as a bitstream here, with bit 0 being the most significant bit of the first
579 * * Bit 0:7 - Profile indication
580 * * Bit 8 - constraint_set0_flag
581 * * Bit 9 - constraint_set1_flag
582 * * Bit 10 - constraint_set2_flag
583 * * Bit 11 - constraint_set3_flag
584 * * Bit 12 - constraint_set3_flag
585 * * Bit 13:15 - Reserved
586 * * Bit 16:24 - Level indication
588 * Returns: (nullable): The profile as a const string, or %NULL if there is an error.
591 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
593 const gchar *profile = NULL;
594 gint csf1, csf3, csf4, csf5;
596 g_return_val_if_fail (sps != NULL, NULL);
601 GST_MEMDUMP ("SPS", sps, len);
603 csf1 = (sps[1] & 0x40) >> 6;
604 csf3 = (sps[1] & 0x10) >> 4;
605 csf4 = (sps[1] & 0x08) >> 3;
606 csf5 = (sps[1] & 0x04) >> 2;
611 profile = "constrained-baseline";
613 profile = "baseline";
619 profile = "extended";
624 profile = "constrained-high";
626 profile = "progressive-high";
632 profile = "high-10-intra";
634 profile = "progressive-high-10";
640 profile = "high-4:2:2-intra";
642 profile = "high-4:2:2";
646 profile = "high-4:4:4-intra";
648 profile = "high-4:4:4";
651 profile = "cavlc-4:4:4-intra";
654 profile = "multiview-high";
657 profile = "stereo-high";
661 profile = "scalable-constrained-baseline";
663 profile = "scalable-baseline";
667 profile = "scalable-high-intra";
669 profile = "scalable-constrained-high";
671 profile = "scalable-high";
681 * gst_codec_utils_h264_get_level:
682 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
683 * @len: Length of the data available in @sps.
685 * Converts the level indication (level_idc) in the stream's
686 * sequence parameter set into a string. The SPS is expected to have the
687 * same format as for gst_codec_utils_h264_get_profile().
689 * Returns: (nullable): The level as a const string, or %NULL if there is an error.
692 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
696 g_return_val_if_fail (sps != NULL, NULL);
701 GST_MEMDUMP ("SPS", sps, len);
703 csf3 = (sps[1] & 0x10) >> 4;
707 else if ((sps[2] == 11 && csf3) || sps[2] == 9)
709 else if (sps[2] % 10 == 0)
710 return digit_to_string (sps[2] / 10);
746 * gst_codec_utils_h264_get_level_idc:
747 * @level: A level string from caps
749 * Transform a level string from the caps into the level_idc
751 * Returns: the level_idc or 0 if the level is unknown
754 gst_codec_utils_h264_get_level_idc (const gchar * level)
756 g_return_val_if_fail (level != NULL, 0);
758 if (!strcmp (level, "1"))
760 else if (!strcmp (level, "1b"))
762 else if (!strcmp (level, "1.1"))
764 else if (!strcmp (level, "1.2"))
766 else if (!strcmp (level, "1.3"))
768 else if (!strcmp (level, "2"))
770 else if (!strcmp (level, "2.1"))
772 else if (!strcmp (level, "2.2"))
774 else if (!strcmp (level, "3"))
776 else if (!strcmp (level, "3.1"))
778 else if (!strcmp (level, "3.2"))
780 else if (!strcmp (level, "4"))
782 else if (!strcmp (level, "4.1"))
784 else if (!strcmp (level, "4.2"))
786 else if (!strcmp (level, "5"))
788 else if (!strcmp (level, "5.1"))
790 else if (!strcmp (level, "5.2"))
792 else if (!strcmp (level, "6"))
794 else if (!strcmp (level, "6.1"))
796 else if (!strcmp (level, "6.2"))
799 GST_WARNING ("Invalid level %s", level);
804 * gst_codec_utils_h264_caps_set_level_and_profile:
805 * @caps: the #GstCaps to which the level and profile are to be added
806 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
807 * @len: Length of the data available in @sps.
809 * Sets the level and profile in @caps if it can be determined from @sps. See
810 * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
811 * for more details on the parameters.
813 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
816 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
817 const guint8 * sps, guint len)
819 const gchar *level, *profile;
821 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
822 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
823 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
824 g_return_val_if_fail (sps != NULL, FALSE);
826 level = gst_codec_utils_h264_get_level (sps, len);
829 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
831 profile = gst_codec_utils_h264_get_profile (sps, len);
834 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
836 GST_LOG ("profile : %s", (profile) ? profile : "---");
837 GST_LOG ("level : %s", (level) ? level : "---");
839 return (level != NULL && profile != NULL);
843 * gst_codec_utils_h264_get_profile_flags_level:
844 * @codec_data: (array length=len): H264 AVCC extradata
845 * @len: length of @codec_data
846 * @profile: (optional) (out): return location for h264 profile_idc or %NULL
847 * @flags: (optional) (out): return location for h264 constraint set flags or %NULL
848 * @level: (optional) (out): return location h264 level_idc or %NULL
850 * Parses profile, flags, and level from a H264 AVCC extradata/sequence_header.
851 * These are most commonly retrieved from a video/x-h264 caps with a codec_data
854 * The format of H264 AVCC extradata/sequence_header is documented in the
855 * ITU-T H.264 specification section 7.3.2.1.1 as well as in ISO/IEC 14496-15
858 * Returns: %TRUE on success, %FALSE on failure
863 gst_codec_utils_h264_get_profile_flags_level (const guint8 * codec_data,
864 guint len, guint8 * profile, guint8 * flags, guint8 * level)
866 gboolean ret = FALSE;
868 g_return_val_if_fail (codec_data != NULL, FALSE);
871 GST_WARNING ("avc codec data is too small");
874 if (codec_data[0] != 1) {
875 GST_WARNING ("failed to parse avc codec version, must be 1");
880 *profile = codec_data[1];
883 *flags = codec_data[2];
886 *level = codec_data[3];
895 /* forked from gsth265parse.c */
898 const gchar *profile;
900 guint8 max_14bit_constraint_flag;
901 guint8 max_12bit_constraint_flag;
902 guint8 max_10bit_constraint_flag;
903 guint8 max_8bit_constraint_flag;
904 guint8 max_422chroma_constraint_flag;
905 guint8 max_420chroma_constraint_flag;
906 guint8 max_monochrome_constraint_flag;
907 guint8 intra_constraint_flag;
908 guint8 one_picture_only_constraint_flag;
909 guint8 lower_bit_rate_constraint_flag;
911 /* Tie breaker if more than one profiles are matching */
913 } GstH265ExtensionProfile;
917 const GstH265ExtensionProfile *profile;
918 guint extra_constraints;
919 } H265ExtensionProfileMatch;
922 sort_fre_profile_matches (H265ExtensionProfileMatch * a,
923 H265ExtensionProfileMatch * b)
927 d = a->extra_constraints - b->extra_constraints;
931 return b->profile->priority - a->profile->priority;
935 utils_get_extension_profile (const GstH265ExtensionProfile * profiles,
936 guint num, GstH265ExtensionProfile * ext_profile)
939 const gchar *profile = NULL;
942 for (i = 0; i < num; i++) {
943 GstH265ExtensionProfile p = profiles[i];
944 guint extra_constraints = 0;
945 H265ExtensionProfileMatch *m;
947 /* Filter out all the profiles having constraints not satisfied by
949 * Then pick the one having the least extra constraints. This allow us
950 * to match the closet profile if bitstream contains not standard
952 if (p.max_14bit_constraint_flag != ext_profile->max_14bit_constraint_flag) {
953 if (p.max_14bit_constraint_flag)
958 if (p.max_12bit_constraint_flag != ext_profile->max_12bit_constraint_flag) {
959 if (p.max_12bit_constraint_flag)
964 if (p.max_10bit_constraint_flag != ext_profile->max_10bit_constraint_flag) {
965 if (p.max_10bit_constraint_flag)
970 if (p.max_8bit_constraint_flag != ext_profile->max_8bit_constraint_flag) {
971 if (p.max_8bit_constraint_flag)
976 if (p.max_422chroma_constraint_flag !=
977 ext_profile->max_422chroma_constraint_flag) {
978 if (p.max_422chroma_constraint_flag)
983 if (p.max_420chroma_constraint_flag !=
984 ext_profile->max_420chroma_constraint_flag) {
985 if (p.max_420chroma_constraint_flag)
990 if (p.max_monochrome_constraint_flag !=
991 ext_profile->max_monochrome_constraint_flag) {
992 if (p.max_monochrome_constraint_flag)
997 if (p.intra_constraint_flag != ext_profile->intra_constraint_flag) {
998 if (p.intra_constraint_flag)
1000 extra_constraints++;
1003 if (p.one_picture_only_constraint_flag !=
1004 ext_profile->one_picture_only_constraint_flag) {
1005 if (p.one_picture_only_constraint_flag)
1007 extra_constraints++;
1010 if (p.lower_bit_rate_constraint_flag
1011 && !ext_profile->lower_bit_rate_constraint_flag)
1014 /* choose this one if all flags are matched */
1015 if (extra_constraints == 0) {
1016 profile = p.profile;
1020 m = g_new0 (H265ExtensionProfileMatch, 1);
1021 m->profile = &profiles[i];
1022 m->extra_constraints = extra_constraints;
1023 cand = g_list_prepend (cand, m);
1026 if (!profile && cand) {
1027 H265ExtensionProfileMatch *m;
1029 cand = g_list_sort (cand, (GCompareFunc) sort_fre_profile_matches);
1031 profile = m->profile->profile;
1035 g_list_free_full (cand, g_free);
1040 static const gchar *
1041 utils_get_format_range_extension_profile (GstH265ExtensionProfile * ext_profile)
1043 static const GstH265ExtensionProfile profiles[] = {
1044 /* FIXME 2.0: Consider ':' separated subsampling notation for consistency
1045 * https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/merge_requests/23
1047 /* Rec. ITU-T H.265 Table A.2 format range extensions profiles */
1049 {"monochrome", 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1050 {"monochrome-10", 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1},
1051 {"monochrome-12", 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1052 {"monochrome-16", 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 3},
1053 {"main-12", 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 4},
1054 {"main-422-10", 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 5},
1055 {"main-422-12", 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 6},
1056 {"main-444", 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 7},
1057 {"main-444-10", 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 8},
1058 {"main-444-12", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 9},
1059 {"main-intra", 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 10},
1060 {"main-10-intra", 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 11},
1061 {"main-12-intra", 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 12},
1062 {"main-422-10-intra", 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 13},
1063 {"main-422-12-intra", 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 14},
1064 {"main-444-intra", 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 15},
1065 {"main-444-10-intra", 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 16},
1066 {"main-444-12-intra", 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17},
1067 {"main-444-16-intra", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 18},
1068 {"main-444-still-picture", 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 19},
1069 {"main-444-16-still-picture", 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 20},
1073 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1077 static const gchar *
1078 utils_get_3d_profile (GstH265ExtensionProfile * ext_profile)
1080 static const GstH265ExtensionProfile profiles[] = {
1081 /* Rec. ITU-T H.265 I.11.1 3D Main profile */
1083 {"3d-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1087 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1091 static const gchar *
1092 utils_get_multiview_profile (GstH265ExtensionProfile * ext_profile)
1094 static const GstH265ExtensionProfile profiles[] = {
1095 /* Rec. ITU-T H.265 G.11.1 Multiview Main profile */
1097 {"multiview-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1101 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1105 static const gchar *
1106 utils_get_scalable_profile (GstH265ExtensionProfile * ext_profile)
1108 static const GstH265ExtensionProfile profiles[] = {
1109 /* Rec. ITU-T H.265 H.11.1 */
1111 {"scalable-main", 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1112 {"scalable-main-10", 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1116 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1120 static const gchar *
1121 utils_get_high_throughput_profile (GstH265ExtensionProfile * ext_profile)
1123 static const GstH265ExtensionProfile profiles[] = {
1124 /* Rec. ITU-T H.265 Table A.3 high throughput profiles */
1126 {"high-throughput-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0},
1127 {"high-throughput-444-10", 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1},
1128 {"high-throughput-444-14", 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2},
1129 {"high-throughput-444-16-intra", 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3},
1133 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1137 static const gchar *
1138 utils_get_screen_content_coding_extensions_profile (GstH265ExtensionProfile *
1141 static const GstH265ExtensionProfile profiles[] = {
1142 /* Rec. ITU-T H.265 Table A.5 screen content coding extensions profiles */
1144 {"screen-extended-main", 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
1145 {"screen-extended-main-10", 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1},
1146 {"screen-extended-main-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2},
1147 {"screen-extended-main-444-10", 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 3},
1148 /* identical to screen-extended-main-444 */
1149 {"screen-extended-high-throughput-444",
1150 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 4},
1151 /* identical to screen-extended-main-444-10 */
1152 {"screen-extended-high-throughput-444-10",
1153 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 5},
1154 {"screen-extended-high-throughput-444-14",
1155 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6},
1159 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1163 static const gchar *
1164 utils_get_scalable_format_range_extensions_profile (GstH265ExtensionProfile *
1167 static const GstH265ExtensionProfile profiles[] = {
1168 /* Rec. ITU-T H.265 Table H.4 scalable range extensions profiles */
1170 {"scalable-monochrome", 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0},
1171 {"scalable-monochrome-12", 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1},
1172 {"scalable-monochrome-16", 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 2},
1173 {"scalable-main-444", 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 3},
1177 return utils_get_extension_profile (profiles, G_N_ELEMENTS (profiles),
1182 * gst_codec_utils_h265_get_profile:
1183 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1184 * structure for the stream.
1185 * @len: Length of the data available in @profile_tier_level
1187 * Converts the profile indication (general_profile_idc) in the stream's
1188 * profile_level_tier structure into a string. The profile_tier_level is
1189 * expected to have the following format, as defined in the H.265
1190 * specification. The profile_tier_level is viewed as a bitstream here,
1191 * with bit 0 being the most significant bit of the first byte.
1193 * * Bit 0:1 - general_profile_space
1194 * * Bit 2 - general_tier_flag
1195 * * Bit 3:7 - general_profile_idc
1196 * * Bit 8:39 - gernal_profile_compatibility_flags
1197 * * Bit 40 - general_progressive_source_flag
1198 * * Bit 41 - general_interlaced_source_flag
1199 * * Bit 42 - general_non_packed_constraint_flag
1200 * * Bit 43 - general_frame_only_constraint_flag
1201 * * Bit 44:87 - See below
1202 * * Bit 88:95 - general_level_idc
1204 * Returns: (nullable): The profile as a const string, or %NULL if there is an error.
1209 gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
1211 const gchar *profile = NULL;
1214 guint8 profile_compatibility_flags[32] = { 0, };
1215 GstBitReader br = GST_BIT_READER_INIT (profile_tier_level, len);
1217 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1222 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1224 profile_idc = (profile_tier_level[0] & 0x1f);
1226 if (profile_idc == 1)
1228 else if (profile_idc == 2)
1229 profile = "main-10";
1230 else if (profile_idc == 3)
1231 profile = "main-still-picture";
1234 if (!gst_bit_reader_skip (&br, 8))
1237 for (i = 0; i < 32; i++) {
1238 if (!gst_bit_reader_get_bits_uint8 (&br, &profile_compatibility_flags[i],
1245 if (profile_compatibility_flags[1])
1247 else if (profile_compatibility_flags[2])
1248 profile = "main-10";
1249 else if (profile_compatibility_flags[3])
1250 profile = "main-still-picture";
1256 if (profile_idc >= 4 && profile_idc <= 11 && len >= 11) {
1257 GstH265ExtensionProfile ext_profile = { 0, };
1260 * Bit 40 - general_progressive_source_flag
1261 * Bit 41 - general_interlaced_source_flag
1262 * Bit 42 - general_non_packed_constraint_flag
1263 * Bit 43 - general_frame_only_constraint_flag
1265 if (!gst_bit_reader_skip (&br, 4))
1270 * 4 : Format range extensions profiles
1271 * 5 : High throughput profiles
1272 * 6 : Multiview main profile
1273 * 7 : Scalable main profiles
1274 * 8 : 3D Main profile
1275 * 9 : Screen content coding extensions profiles
1276 * 10 : Scalable format range extensions profiles
1278 * Bit 44 - general_max_12bit_constraint_flag
1279 * Bit 45 - general_max_10bit_constraint_flag
1280 * Bit 46 - general_max_8bit_constraint_flag
1281 * Bit 47 - general_max_422chroma_constraint_flag
1282 * Bit 48 - general_max_420chroma_constraint_flag
1283 * Bit 49 - general_max_monochrome_constraint_flag
1284 * Bit 50 - general_intra_constraint_flag
1285 * Bit 51 - general_one_picture_only_constraint_flag
1286 * Bit 52 - general_lower_bit_rate_constraint_flag
1288 if (!gst_bit_reader_get_bits_uint8 (&br,
1289 &ext_profile.max_12bit_constraint_flag, 1))
1292 if (!gst_bit_reader_get_bits_uint8 (&br,
1293 &ext_profile.max_10bit_constraint_flag, 1))
1296 if (!gst_bit_reader_get_bits_uint8 (&br,
1297 &ext_profile.max_8bit_constraint_flag, 1))
1300 if (!gst_bit_reader_get_bits_uint8 (&br,
1301 &ext_profile.max_422chroma_constraint_flag, 1))
1304 if (!gst_bit_reader_get_bits_uint8 (&br,
1305 &ext_profile.max_420chroma_constraint_flag, 1))
1308 if (!gst_bit_reader_get_bits_uint8 (&br,
1309 &ext_profile.max_monochrome_constraint_flag, 1))
1312 if (!gst_bit_reader_get_bits_uint8 (&br,
1313 &ext_profile.intra_constraint_flag, 1))
1316 if (!gst_bit_reader_get_bits_uint8 (&br,
1317 &ext_profile.one_picture_only_constraint_flag, 1))
1320 if (!gst_bit_reader_get_bits_uint8 (&br,
1321 &ext_profile.lower_bit_rate_constraint_flag, 1))
1324 if (profile_idc == 5 || profile_idc == 9 ||
1325 profile_idc == 10 || profile_idc == 11 ||
1326 profile_compatibility_flags[5] || profile_compatibility_flags[9] ||
1327 profile_compatibility_flags[10] || profile_compatibility_flags[11]) {
1328 /* Bit 53 - general_max_14bit_constraint_flag */
1329 if (!gst_bit_reader_get_bits_uint8 (&br,
1330 &ext_profile.max_14bit_constraint_flag, 1))
1334 if (profile_idc == 4 || profile_compatibility_flags[4])
1335 return utils_get_format_range_extension_profile (&ext_profile);
1337 if (profile_idc == 5 || profile_compatibility_flags[5])
1338 return utils_get_high_throughput_profile (&ext_profile);
1340 if (profile_idc == 6 || profile_compatibility_flags[6])
1341 return utils_get_multiview_profile (&ext_profile);
1343 if (profile_idc == 7 || profile_compatibility_flags[7])
1344 return utils_get_scalable_profile (&ext_profile);
1346 if (profile_idc == 8 || profile_compatibility_flags[8])
1347 return utils_get_3d_profile (&ext_profile);
1349 if (profile_idc == 9 || profile_compatibility_flags[9] ||
1350 profile_idc == 11 || profile_compatibility_flags[11])
1351 return utils_get_screen_content_coding_extensions_profile (&ext_profile);
1353 if (profile_idc == 10 || profile_compatibility_flags[10])
1354 return utils_get_scalable_format_range_extensions_profile (&ext_profile);
1361 * gst_codec_utils_h265_get_tier:
1362 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1364 * @len: Length of the data available in @profile_tier_level.
1366 * Converts the tier indication (general_tier_flag) in the stream's
1367 * profile_tier_level structure into a string. The profile_tier_level
1368 * is expected to have the same format as for gst_codec_utils_h264_get_profile().
1370 * Returns: (nullable): The tier as a const string, or %NULL if there is an error.
1375 gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
1377 const gchar *tier = NULL;
1380 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1385 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1387 tier_flag = (profile_tier_level[0] & 0x20) >> 5;
1398 * gst_codec_utils_h265_get_level:
1399 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1401 * @len: Length of the data available in @profile_tier_level.
1403 * Converts the level indication (general_level_idc) in the stream's
1404 * profile_tier_level structure into a string. The profiel_tier_level is
1405 * expected to have the same format as for gst_codec_utils_h264_get_profile().
1407 * Returns: (nullable): The level as a const string, or %NULL if there is an error.
1412 gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
1414 g_return_val_if_fail (profile_tier_level != NULL, NULL);
1419 GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);
1421 if (profile_tier_level[11] == 0)
1423 else if (profile_tier_level[11] % 30 == 0)
1424 return digit_to_string (profile_tier_level[11] / 30);
1426 switch (profile_tier_level[11]) {
1455 * gst_codec_utils_h265_get_level_idc:
1456 * @level: A level string from caps
1458 * Transform a level string from the caps into the level_idc
1460 * Returns: the level_idc or 0 if the level is unknown
1465 gst_codec_utils_h265_get_level_idc (const gchar * level)
1467 g_return_val_if_fail (level != NULL, 0);
1469 if (!strcmp (level, "1"))
1471 else if (!strcmp (level, "2"))
1473 else if (!strcmp (level, "2.1"))
1475 else if (!strcmp (level, "3"))
1477 else if (!strcmp (level, "3.1"))
1479 else if (!strcmp (level, "4"))
1481 else if (!strcmp (level, "4.1"))
1483 else if (!strcmp (level, "5"))
1485 else if (!strcmp (level, "5.1"))
1487 else if (!strcmp (level, "5.2"))
1489 else if (!strcmp (level, "6"))
1491 else if (!strcmp (level, "6.1"))
1493 else if (!strcmp (level, "6.2"))
1496 GST_WARNING ("Invalid level %s", level);
1501 * gst_codec_utils_h265_caps_set_level_tier_and_profile:
1502 * @caps: the #GstCaps to which the level, tier and profile are to be added
1503 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
1505 * @len: Length of the data available in @profile_tier_level.
1507 * Sets the level, tier and profile in @caps if it can be determined from
1508 * @profile_tier_level. See gst_codec_utils_h265_get_level(),
1509 * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
1510 * for more details on the parameters.
1512 * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
1517 gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
1518 const guint8 * profile_tier_level, guint len)
1520 const gchar *level, *tier, *profile;
1522 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1523 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1524 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
1525 g_return_val_if_fail (profile_tier_level != NULL, FALSE);
1527 level = gst_codec_utils_h265_get_level (profile_tier_level, len);
1529 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1531 tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
1533 gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);
1535 profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
1536 if (profile != NULL)
1537 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1539 GST_LOG ("profile : %s", (profile) ? profile : "---");
1540 GST_LOG ("tier : %s", (tier) ? tier : "---");
1541 GST_LOG ("level : %s", (level) ? level : "---");
1543 return (level != NULL && tier != NULL && profile != NULL);
1547 * gst_codec_utils_mpeg4video_get_profile:
1548 * @vis_obj_seq: (array length=len): Pointer to the visual object
1549 * sequence for the stream.
1550 * @len: Length of the data available in @sps.
1552 * Converts the profile indication in the stream's visual object sequence into
1553 * a string. @vis_obj_seq is expected to be the data following the visual
1554 * object sequence start code. Only the first byte
1555 * (profile_and_level_indication) is used.
1557 * Returns: (nullable): The profile as a const string, or NULL if there is an error.
1560 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
1562 /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
1563 * sources: epan/dissectors/packet-mp4ves.c */
1565 /* These are a direct mapping from the integer profile id -> string. Profiles
1566 * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
1567 * second 4 bits of vis_obj_seq[0], so they are handled separately. */
1568 static const char *profiles[] = { "simple", "simple-scalable", "core",
1569 "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
1570 "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
1571 "advanced-core", "advanced-scalable-texture",
1573 int profile_id, level_id;
1575 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1580 GST_MEMDUMP ("VOS", vis_obj_seq, len);
1582 profile_id = vis_obj_seq[0] >> 4;
1583 level_id = vis_obj_seq[0] & 0xf;
1585 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1587 if (profile_id != 6 && profile_id < 0xe)
1588 return profiles[profile_id];
1590 if (profile_id != 0xf && level_id == 0)
1593 switch (profile_id) {
1596 return "simple-face";
1597 else if (level_id < 5)
1598 return "simple-fba";
1603 return "simple-studio";
1604 else if (level_id < 9)
1605 return "core-studio";
1610 return "advanced-simple";
1611 else if (level_id > 7 && level_id < 0xe)
1612 return "fine-granularity-scalable";
1620 * gst_codec_utils_mpeg4video_get_level:
1621 * @vis_obj_seq: (array length=len): Pointer to the visual object
1622 * sequence for the stream.
1623 * @len: Length of the data available in @sps.
1625 * Converts the level indication in the stream's visual object sequence into
1626 * a string. @vis_obj_seq is expected to be the data following the visual
1627 * object sequence start code. Only the first byte
1628 * (profile_and_level_indication) is used.
1630 * Returns: (nullable): The level as a const string, or NULL if there is an error.
1633 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
1635 /* The profile/level codes are from 14496-2, table G-1, the Wireshark
1636 * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
1638 * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
1639 * (see Xvid sources vfw/config.c)
1641 * Each profile has a different maximum level it defines. Some of them still
1642 * need special case handling, because not all levels start from 1, and the
1643 * Simple profile defines an intermediate level as well. */
1644 static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
1647 int profile_id, level_id;
1649 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
1654 GST_MEMDUMP ("VOS", vis_obj_seq, len);
1656 profile_id = vis_obj_seq[0] >> 4;
1657 level_id = vis_obj_seq[0] & 0xf;
1659 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
1661 if (profile_id != 0xf && level_id == 0)
1664 /* Let's do some validation of the level */
1665 switch (profile_id) {
1687 if (level_id == 6 || level_id == 7 || level_id > 0xd)
1692 if (profile_id == 0 && level_id == 8)
1693 /* Simple Profile / Level 0 */
1695 else if (profile_id == 0 && level_id == 9)
1696 /* Simple Profile / Level 0b */
1698 else if (profile_id == 0 && level_id == 4)
1699 /* Simple Profile / Level 4a */
1701 else if (profile_id == 0xf && level_id > 7)
1702 /* Fine Granularity Scalable Profile */
1703 return digit_to_string (level_id - 8);
1704 else if (level_id <= level_max[profile_id])
1705 /* Levels for all other cases */
1706 return digit_to_string (level_id);
1712 * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
1713 * @caps: the #GstCaps to which the level and profile are to be added
1714 * @vis_obj_seq: (array length=len): Pointer to the visual object
1715 * sequence for the stream.
1716 * @len: Length of the data available in @sps.
1718 * Sets the level and profile in @caps if it can be determined from
1719 * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
1720 * gst_codec_utils_mpeg4video_get_profile() for more details on the
1723 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
1726 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
1727 const guint8 * vis_obj_seq, guint len)
1729 const gchar *profile, *level;
1731 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
1732 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
1733 g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
1735 profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
1737 if (profile != NULL)
1738 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
1740 level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
1743 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
1745 GST_LOG ("profile : %s", (profile) ? profile : "---");
1746 GST_LOG ("level : %s", (level) ? level : "---");
1748 return (profile != NULL && level != NULL);
1752 * gst_codec_utils_opus_parse_caps:
1753 * @caps: the #GstCaps to parse the data from
1754 * @rate: (optional) (out): the sample rate
1755 * @channels: (optional) (out): the number of channels
1756 * @channel_mapping_family: (optional) (out): the channel mapping family
1757 * @stream_count: (optional) (out): the number of independent streams
1758 * @coupled_count: (optional) (out): the number of stereo streams
1759 * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
1761 * Parses Opus caps and fills the different fields with defaults if possible.
1763 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
1768 gst_codec_utils_opus_parse_caps (GstCaps * caps,
1771 guint8 * channel_mapping_family,
1772 guint8 * stream_count, guint8 * coupled_count, guint8 channel_mapping[256])
1776 const GValue *va, *v;
1778 g_return_val_if_fail (caps != NULL, FALSE);
1779 g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
1780 g_return_val_if_fail (!gst_caps_is_empty (caps), FALSE);
1782 s = gst_caps_get_structure (caps, 0);
1784 g_return_val_if_fail (gst_structure_has_name (s, "audio/x-opus"), FALSE);
1785 g_return_val_if_fail (gst_structure_has_field_typed (s,
1786 "channel-mapping-family", G_TYPE_INT), FALSE);
1791 if (gst_structure_get_int (s, "rate", &r))
1797 gst_structure_get_int (s, "channel-mapping-family", &f);
1798 if (channel_mapping_family)
1799 *channel_mapping_family = f;
1801 if (!gst_structure_get_int (s, "channels", &c) || c == 0) {
1819 *coupled_count = c == 2 ? 1 : 0;
1821 if (channel_mapping) {
1822 channel_mapping[0] = 0;
1823 channel_mapping[1] = 1;
1829 if (!gst_structure_get_int (s, "stream-count", &sc))
1834 if (!gst_structure_get_int (s, "coupled-count", &cc))
1837 *coupled_count = cc;
1839 va = gst_structure_get_value (s, "channel-mapping");
1840 if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY))
1843 if (gst_value_array_get_size (va) != c)
1846 if (channel_mapping) {
1849 for (i = 0; i < c; i++) {
1852 v = gst_value_array_get_value (va, i);
1854 if (!G_VALUE_HOLDS (v, G_TYPE_INT))
1857 cm = g_value_get_int (v);
1858 if (cm < 0 || cm > 255)
1861 channel_mapping[i] = cm;
1869 * gst_codec_utils_opus_create_caps:
1870 * @rate: the sample rate
1871 * @channels: the number of channels
1872 * @channel_mapping_family: the channel mapping family
1873 * @stream_count: the number of independent streams
1874 * @coupled_count: the number of stereo streams
1875 * @channel_mapping: (nullable) (array): the mapping between the streams
1877 * Creates Opus caps from the given parameters.
1879 * Returns: (transfer full) (nullable): The #GstCaps, or %NULL if the parameters would lead to
1880 * invalid Opus caps.
1885 gst_codec_utils_opus_create_caps (guint32 rate,
1887 guint8 channel_mapping_family,
1888 guint8 stream_count, guint8 coupled_count, const guint8 * channel_mapping)
1890 GstCaps *caps = NULL;
1891 GValue va = G_VALUE_INIT;
1892 GValue v = G_VALUE_INIT;
1898 if (channel_mapping_family == 0) {
1900 GST_ERROR ("Invalid channels count for channel_mapping_family 0: %d",
1905 if (stream_count > 1) {
1906 GST_ERROR ("Invalid stream count for channel_mapping_family 0: %d",
1911 if (coupled_count > 1) {
1912 GST_ERROR ("Invalid coupled count for channel_mapping_family 0: %d",
1920 if (stream_count == 0)
1923 if (coupled_count == 0)
1924 coupled_count = channels == 2 ? 1 : 0;
1926 return gst_caps_new_simple ("audio/x-opus",
1927 "rate", G_TYPE_INT, rate,
1928 "channels", G_TYPE_INT, channels,
1929 "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1930 "stream-count", G_TYPE_INT, stream_count,
1931 "coupled-count", G_TYPE_INT, coupled_count, NULL);
1934 if (channels == 0) {
1935 GST_ERROR ("Invalid channels count: %d", channels);
1939 if (stream_count == 0) {
1940 GST_ERROR ("Invalid stream count: %d", stream_count);
1944 if (coupled_count > stream_count) {
1945 GST_ERROR ("Coupled count %d > stream count: %d", coupled_count,
1950 if (channel_mapping == NULL) {
1952 ("A non NULL channel-mapping is needed for channel_mapping_family != 0");
1956 caps = gst_caps_new_simple ("audio/x-opus",
1957 "rate", G_TYPE_INT, rate,
1958 "channels", G_TYPE_INT, channels,
1959 "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
1960 "stream-count", G_TYPE_INT, stream_count,
1961 "coupled-count", G_TYPE_INT, coupled_count, NULL);
1963 g_value_init (&va, GST_TYPE_ARRAY);
1964 g_value_init (&v, G_TYPE_INT);
1965 for (i = 0; i < channels; i++) {
1966 g_value_set_int (&v, channel_mapping[i]);
1967 gst_value_array_append_value (&va, &v);
1969 gst_structure_set_value (gst_caps_get_structure (caps, 0), "channel-mapping",
1971 g_value_unset (&va);
1979 * (really really) FIXME: move into core (dixit tpm)
1982 * _gst_caps_set_buffer_array:
1983 * @caps: (transfer full): a #GstCaps
1984 * @field: field in caps to set
1985 * @buf: header buffers
1987 * Adds given buffers to an array of buffers set as the given @field
1988 * on the given @caps. List of buffer arguments must be NULL-terminated.
1990 * Returns: (transfer full): input caps with a streamheader field added, or NULL
1991 * if some error occurred
1994 _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
1995 GstBuffer * buf, ...)
1997 GstStructure *structure = NULL;
1999 GValue array = { 0 };
2000 GValue value = { 0 };
2002 g_return_val_if_fail (caps != NULL, NULL);
2003 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2004 g_return_val_if_fail (field != NULL, NULL);
2006 caps = gst_caps_make_writable (caps);
2007 structure = gst_caps_get_structure (caps, 0);
2009 g_value_init (&array, GST_TYPE_ARRAY);
2012 /* put buffers in a fixed list */
2014 g_assert (gst_buffer_is_writable (buf));
2017 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2019 g_value_init (&value, GST_TYPE_BUFFER);
2020 buf = gst_buffer_copy (buf);
2021 GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
2022 gst_value_set_buffer (&value, buf);
2023 gst_buffer_unref (buf);
2024 gst_value_array_append_value (&array, &value);
2025 g_value_unset (&value);
2027 buf = va_arg (va, GstBuffer *);
2031 gst_structure_set_value (structure, field, &array);
2032 g_value_unset (&array);
2038 * gst_codec_utils_opus_create_caps_from_header:
2039 * @header: OpusHead header
2040 * @comments: (nullable): Comment header or NULL
2042 * Creates Opus caps from the given OpusHead @header and comment header
2045 * Returns: (transfer full) (nullable): The #GstCaps.
2050 gst_codec_utils_opus_create_caps_from_header (GstBuffer * header,
2051 GstBuffer * comments)
2056 guint8 channel_mapping_family;
2057 guint8 stream_count;
2058 guint8 coupled_count;
2059 guint8 channel_mapping[256];
2060 GstBuffer *dummy_comments = NULL;
2062 g_return_val_if_fail (GST_IS_BUFFER (header), NULL);
2063 g_return_val_if_fail (comments == NULL || GST_IS_BUFFER (comments), NULL);
2065 if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
2066 &channel_mapping_family, &stream_count, &coupled_count,
2067 channel_mapping, NULL, NULL))
2071 gst_codec_utils_opus_create_caps (rate, channels,
2072 channel_mapping_family, stream_count, coupled_count,
2077 GstTagList *tags = gst_tag_list_new_empty ();
2079 gst_tag_list_to_vorbiscomment_buffer (tags, (const guint8 *) "OpusTags",
2081 gst_tag_list_unref (tags);
2083 _gst_caps_set_buffer_array (caps, "streamheader", header,
2084 comments ? comments : dummy_comments, NULL);
2087 gst_buffer_unref (dummy_comments);
2093 * gst_codec_utils_opus_create_header:
2094 * @rate: the sample rate
2095 * @channels: the number of channels
2096 * @channel_mapping_family: the channel mapping family
2097 * @stream_count: the number of independent streams
2098 * @coupled_count: the number of stereo streams
2099 * @channel_mapping: (nullable) (array): the mapping between the streams
2100 * @pre_skip: Pre-skip in 48kHz samples or 0
2101 * @output_gain: Output gain or 0
2103 * Creates OpusHead header from the given parameters.
2105 * Returns: (transfer full) (nullable): The #GstBuffer containing the OpusHead.
2110 gst_codec_utils_opus_create_header (guint32 rate,
2112 guint8 channel_mapping_family,
2113 guint8 stream_count,
2114 guint8 coupled_count,
2115 const guint8 * channel_mapping, guint16 pre_skip, gint16 output_gain)
2119 gboolean hdl = TRUE;
2124 if (channel_mapping_family == 0) {
2125 g_return_val_if_fail (channels <= 2, NULL);
2129 g_return_val_if_fail (stream_count == 0 || stream_count == 1, NULL);
2130 if (stream_count == 0)
2133 g_return_val_if_fail (coupled_count == 0 || coupled_count == 1, NULL);
2134 if (coupled_count == 0)
2135 coupled_count = channels == 2 ? 1 : 0;
2137 channel_mapping = NULL;
2139 g_return_val_if_fail (channels > 0, NULL);
2140 g_return_val_if_fail (stream_count > 0, NULL);
2141 g_return_val_if_fail (coupled_count <= stream_count, NULL);
2142 g_return_val_if_fail (channel_mapping != NULL, NULL);
2145 gst_byte_writer_init (&bw);
2146 /* See http://wiki.xiph.org/OggOpus */
2147 hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
2148 hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
2149 hdl &= gst_byte_writer_put_uint8 (&bw, channels);
2150 hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
2151 hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
2152 hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
2153 hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
2154 if (channel_mapping_family > 0) {
2155 hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
2156 hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
2157 hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
2161 GST_WARNING ("Error creating header");
2162 gst_byte_writer_reset (&bw);
2166 buffer = gst_byte_writer_reset_and_get_buffer (&bw);
2167 GST_BUFFER_OFFSET (buffer) = 0;
2168 GST_BUFFER_OFFSET_END (buffer) = 0;
2174 * gst_codec_utils_opus_parse_header:
2175 * @header: the OpusHead #GstBuffer
2176 * @rate: (optional) (out): the sample rate
2177 * @channels: (optional) (out): the number of channels
2178 * @channel_mapping_family: (optional) (out): the channel mapping family
2179 * @stream_count: (optional) (out): the number of independent streams
2180 * @coupled_count: (optional) (out): the number of stereo streams
2181 * @channel_mapping: (optional) (out) (array fixed-size=256): the mapping between the streams
2182 * @pre_skip: (optional) (out): Pre-skip in 48kHz samples or 0
2183 * @output_gain: (optional) (out): Output gain or 0
2185 * Parses the OpusHead header.
2187 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
2192 gst_codec_utils_opus_parse_header (GstBuffer * header,
2195 guint8 * channel_mapping_family,
2196 guint8 * stream_count,
2197 guint8 * coupled_count,
2198 guint8 channel_mapping[256], guint16 * pre_skip, gint16 * output_gain)
2202 gboolean ret = TRUE;
2203 guint8 c, f, version;
2205 g_return_val_if_fail (GST_IS_BUFFER (header), FALSE);
2206 g_return_val_if_fail (gst_buffer_get_size (header) >= 19, FALSE);
2208 if (!gst_buffer_map (header, &map, GST_MAP_READ))
2210 gst_byte_reader_init (&br, map.data, map.size);
2211 /* See http://wiki.xiph.org/OggOpus */
2212 if (memcmp (gst_byte_reader_get_data_unchecked (&br, 8), "OpusHead", 8) != 0) {
2216 version = gst_byte_reader_get_uint8_unchecked (&br);
2217 if (version == 0x00)
2218 GST_ERROR ("Opus Header version is wrong, should be 0x01 and not 0x00");
2219 else if (version != 0x01) {
2224 c = gst_byte_reader_get_uint8_unchecked (&br);
2229 *pre_skip = gst_byte_reader_get_uint16_le_unchecked (&br);
2231 gst_byte_reader_skip_unchecked (&br, 2);
2234 *rate = gst_byte_reader_get_uint32_le_unchecked (&br);
2236 gst_byte_reader_skip_unchecked (&br, 4);
2239 *output_gain = gst_byte_reader_get_uint16_le_unchecked (&br);
2241 gst_byte_reader_skip_unchecked (&br, 2);
2243 f = gst_byte_reader_get_uint8_unchecked (&br);
2244 if (channel_mapping_family)
2245 *channel_mapping_family = f;
2246 if (f == 0 && c <= 2) {
2250 *coupled_count = c == 2 ? 1 : 0;
2251 if (channel_mapping) {
2252 channel_mapping[0] = 0;
2253 channel_mapping[1] = 1;
2259 if (gst_byte_reader_get_remaining (&br) < 2 + c) {
2265 *stream_count = gst_byte_reader_get_uint8_unchecked (&br);
2267 gst_byte_reader_skip_unchecked (&br, 1);
2270 *coupled_count = gst_byte_reader_get_uint8_unchecked (&br);
2272 gst_byte_reader_skip_unchecked (&br, 1);
2274 if (channel_mapping)
2275 memcpy (channel_mapping, gst_byte_reader_get_data_unchecked (&br, c), c);
2278 gst_buffer_unmap (header, &map);
2284 h264_caps_structure_get_profile_flags_level (GstStructure * caps_st,
2285 guint8 * profile, guint8 * flags, guint8 * level)
2287 const GValue *codec_data_value = NULL;
2288 GstBuffer *codec_data = NULL;
2290 gboolean ret = FALSE;
2291 guint8 *data = NULL;
2294 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2295 if (!codec_data_value) {
2297 ("video/x-h264 caps did not have codec_data set, cannot parse profile, flags and level");
2301 codec_data = gst_value_get_buffer (codec_data_value);
2302 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2308 if (!gst_codec_utils_h264_get_profile_flags_level (data, (guint) size,
2309 profile, flags, level)) {
2311 ("Failed to parse profile, flags and level from h264 codec data");
2318 gst_buffer_unmap (codec_data, &map);
2324 aac_caps_structure_get_audio_object_type (GstStructure * caps_st,
2325 guint8 * audio_object_type)
2327 gboolean ret = FALSE;
2328 const GValue *codec_data_value = NULL;
2329 GstBuffer *codec_data = NULL;
2331 guint8 *data = NULL;
2335 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2336 if (!codec_data_value) {
2338 ("audio/mpeg pad did not have codec_data set, cannot parse audio object type");
2342 codec_data = gst_value_get_buffer (codec_data_value);
2343 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2350 GST_WARNING ("aac codec data is too small");
2354 gst_bit_reader_init (&br, data, size);
2355 ret = gst_codec_utils_aac_get_audio_object_type (&br, audio_object_type);
2358 gst_buffer_unmap (codec_data, &map);
2364 hevc_caps_get_mime_codec (GstCaps * caps, gchar ** mime_codec)
2366 GstStructure *caps_st = NULL;
2367 const GValue *codec_data_value = NULL;
2368 GstBuffer *codec_data = NULL;
2370 gboolean ret = FALSE;
2371 const gchar *stream_format;
2372 guint8 *data = NULL;
2374 guint16 profile_space;
2376 guint16 profile_idc;
2377 guint32 compat_flags;
2378 guchar constraint_indicator_flags[6];
2380 guint32 compat_flag_parameter = 0;
2381 GString *codec_string;
2382 const guint8 *profile_tier_level;
2383 gint last_flag_index;
2385 caps_st = gst_caps_get_structure (caps, 0);
2386 codec_data_value = gst_structure_get_value (caps_st, "codec_data");
2387 stream_format = gst_structure_get_string (caps_st, "stream-format");
2388 if (!codec_data_value) {
2389 GST_DEBUG ("video/x-h265 caps did not have codec_data set, cannot parse");
2391 } else if (!stream_format) {
2393 ("video/x-h265 caps did not have stream-format set, cannot parse");
2397 codec_data = gst_value_get_buffer (codec_data_value);
2398 if (!gst_buffer_map (codec_data, &map, GST_MAP_READ)) {
2404 /* HEVCDecoderConfigurationRecord is at a minimum 23 bytes long */
2406 GST_DEBUG ("Incomplete HEVCDecoderConfigurationRecord");
2410 if (!g_str_equal (stream_format, "hev1")
2411 && !g_str_equal (stream_format, "hvc1")) {
2412 GST_DEBUG ("Unknown stream-format %s", stream_format);
2416 profile_tier_level = data + 1;
2417 profile_space = (profile_tier_level[0] & 0x11) >> 6;
2418 tier_flag = (profile_tier_level[0] & 0x001) >> 5;
2419 profile_idc = (profile_tier_level[0] & 0x1f);
2421 compat_flags = GST_READ_UINT32_BE (data + 2);
2422 for (unsigned i = 0; i < 6; ++i)
2423 constraint_indicator_flags[i] = GST_READ_UINT8 (data + 6 + i);
2425 level_idc = data[12];
2427 /* The 32 bits of the compat_flags, but in reverse bit order */
2429 ((compat_flags & 0xaaaaaaaa) >> 1) | ((compat_flags & 0x55555555) << 1);
2431 ((compat_flags & 0xcccccccc) >> 2) | ((compat_flags & 0x33333333) << 2);
2433 ((compat_flags & 0xf0f0f0f0) >> 4) | ((compat_flags & 0x0f0f0f0f) << 4);
2435 ((compat_flags & 0xff00ff00) >> 8) | ((compat_flags & 0x00ff00ff) << 8);
2436 compat_flag_parameter = (compat_flags >> 16) | (compat_flags << 16);
2438 codec_string = g_string_new (stream_format);
2439 codec_string = g_string_append_c (codec_string, '.');
2441 codec_string = g_string_append_c (codec_string, 'A' + profile_space - 1);
2442 g_string_append_printf (codec_string, "%" G_GUINT16_FORMAT ".%X.%c%d",
2443 profile_idc, compat_flag_parameter, tier_flag ? 'H' : 'L', level_idc);
2445 /* Each of the 6 bytes of the constraint flags, starting from the byte containing the
2446 * progressive_source_flag, each encoded as a hexadecimal number, and the encoding
2447 * of each byte separated by a period; trailing bytes that are zero may be omitted.
2449 last_flag_index = 5;
2450 while (last_flag_index >= 0
2451 && (int) (constraint_indicator_flags[last_flag_index]) == 0)
2453 for (gint i = 0; i <= last_flag_index; ++i) {
2454 g_string_append_printf (codec_string, ".%02X",
2455 constraint_indicator_flags[i]);
2458 *mime_codec = g_string_free (codec_string, FALSE);
2463 gst_buffer_unmap (codec_data, &map);
2467 /* https://www.webmproject.org/vp9/mp4/#codecs-parameter-string */
2469 vp9_caps_get_mime_codec (GstCaps * caps)
2471 GstStructure *caps_st;
2472 const char *profile_str, *chroma_format_str, *colorimetry_str;
2473 guint bitdepth_luma, bitdepth_chroma;
2474 guint8 profile = -1, chroma_format = -1, level = -1, color_primaries =
2475 -1, color_transfer = -1, color_matrix = -1;
2476 gboolean video_full_range;
2477 GstVideoColorimetry cinfo = { 0, };
2478 GString *codec_string;
2480 caps_st = gst_caps_get_structure (caps, 0);
2481 codec_string = g_string_new ("vp09");
2483 profile_str = gst_structure_get_string (caps_st, "profile");
2484 if (g_strcmp0 (profile_str, "0") == 0) {
2486 } else if (g_strcmp0 (profile_str, "1") == 0) {
2488 } else if (g_strcmp0 (profile_str, "2") == 0) {
2490 } else if (g_strcmp0 (profile_str, "3") == 0) {
2496 /* XXX: hardcoded level */
2499 gst_structure_get (caps_st, "bit-depth-luma", G_TYPE_UINT,
2500 &bitdepth_luma, "bit-depth-chroma", G_TYPE_UINT, &bitdepth_chroma, NULL);
2502 if (bitdepth_luma == 0)
2504 if (bitdepth_luma != bitdepth_chroma)
2507 /* mandatory elements */
2508 g_string_append_printf (codec_string, ".%02u.%02u.%02u", profile, level,
2511 colorimetry_str = gst_structure_get_string (caps_st, "colorimetry");
2512 if (!colorimetry_str)
2514 if (!gst_video_colorimetry_from_string (&cinfo, colorimetry_str))
2516 video_full_range = cinfo.range == GST_VIDEO_COLOR_RANGE_0_255;
2518 chroma_format_str = gst_structure_get_string (caps_st, "chroma-format");
2519 if (g_strcmp0 (chroma_format_str, "4:2:0") == 0) {
2520 const char *chroma_site_str;
2521 GstVideoChromaSite chroma_site;
2523 chroma_site_str = gst_structure_get_string (caps_st, "chroma-site");
2524 if (chroma_site_str)
2525 chroma_site = gst_video_chroma_site_from_string (chroma_site_str);
2527 chroma_site = GST_VIDEO_CHROMA_SITE_UNKNOWN;
2528 if (chroma_site == GST_VIDEO_CHROMA_SITE_V_COSITED) {
2530 } else if (chroma_site == GST_VIDEO_CHROMA_SITE_COSITED) {
2535 } else if (g_strcmp0 (chroma_format_str, "4:2:2") == 0) {
2537 } else if (g_strcmp0 (chroma_format_str, "4:4:4") == 0) {
2543 /* optional but all or nothing. Include them if any parameter differs from the default value */
2544 color_primaries = gst_video_color_primaries_to_iso (cinfo.primaries);
2545 color_transfer = gst_video_transfer_function_to_iso (cinfo.transfer);
2546 color_matrix = gst_video_color_matrix_to_iso (cinfo.matrix);
2547 if (chroma_format != 1 || color_primaries != 1 || color_transfer != 1
2548 || color_matrix != 1 || video_full_range) {
2549 g_string_append_printf (codec_string, ".%02u.%02u.%02u.%02u.%02u",
2550 chroma_format, color_primaries, color_transfer, color_matrix,
2555 return g_string_free (codec_string, FALSE);
2559 * gst_codec_utils_caps_get_mime_codec:
2560 * @caps: A #GstCaps to convert to mime codec
2562 * Converts @caps to a RFC 6381 compatible codec string if possible.
2564 * Useful for providing the 'codecs' field inside the 'Content-Type' HTTP
2565 * header for containerized formats, such as mp4 or matroska.
2567 * Registered codecs can be found at http://mp4ra.org/#/codecs
2569 * Returns: (transfer full) (nullable): a RFC 6381 compatible codec string or %NULL
2574 gst_codec_utils_caps_get_mime_codec (GstCaps * caps)
2576 gchar *mime_codec = NULL;
2577 GstStructure *caps_st = NULL;
2578 const gchar *media_type = NULL;
2580 g_return_val_if_fail (caps != NULL, NULL);
2581 g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
2583 caps_st = gst_caps_get_structure (caps, 0);
2584 if (caps_st == NULL) {
2585 GST_WARNING ("Failed to get structure from caps");
2589 media_type = gst_structure_get_name (caps_st);
2591 if (g_strcmp0 (media_type, "video/x-h264") == 0) {
2594 * BB = constraint set flags
2601 if (!h264_caps_structure_get_profile_flags_level (caps_st, &profile, &flags,
2604 ("h264 caps did not contain 'codec_data', cannot determine detailed codecs info");
2605 mime_codec = g_strdup ("avc1");
2607 mime_codec = g_strdup_printf ("avc1.%02X%02X%02X", profile, flags, level);
2609 } else if (g_strcmp0 (media_type, "video/x-h265") == 0) {
2610 if (!hevc_caps_get_mime_codec (caps, &mime_codec)) {
2611 GST_DEBUG ("h265 caps parsing failed");
2612 mime_codec = g_strdup ("hev1");
2614 } else if (g_strcmp0 (media_type, "video/x-av1") == 0) {
2615 /* TODO: Some browsers won't play the video unless more codec information is
2616 * available in the mime codec for av1. This is documented in
2617 * https://aomediacodec.github.io/av1-isobmff/#codecsparam */
2618 mime_codec = g_strdup ("av01");
2619 } else if (g_strcmp0 (media_type, "video/x-vp8") == 0) {
2620 /* TODO: most browsers won't play the video unless more codec information is
2621 * available in the mime codec for vp8. */
2622 mime_codec = g_strdup ("vp08");
2623 } else if (g_strcmp0 (media_type, "video/x-vp9") == 0) {
2624 mime_codec = vp9_caps_get_mime_codec (caps);
2625 } else if (g_strcmp0 (media_type, "image/jpeg") == 0) {
2626 mime_codec = g_strdup ("mjpg");
2627 } else if (g_strcmp0 (media_type, "audio/mpeg") == 0) {
2628 guint8 audio_object_type = 0;
2629 if (aac_caps_structure_get_audio_object_type (caps_st, &audio_object_type)) {
2630 mime_codec = g_strdup_printf ("mp4a.40.%u", audio_object_type);
2632 mime_codec = g_strdup ("mp4a.40");
2634 } else if (g_strcmp0 (media_type, "audio/x-opus") == 0) {
2635 mime_codec = g_strdup ("opus");
2636 } else if (g_strcmp0 (media_type, "audio/x-mulaw") == 0) {
2637 mime_codec = g_strdup ("ulaw");
2638 } else if (g_strcmp0 (media_type, "audio/x-adpcm") == 0) {
2639 if (g_strcmp0 (gst_structure_get_string (caps_st, "layout"), "g726") == 0) {
2640 mime_codec = g_strdup ("g726");
2649 gst_codec_utils_caps_from_mime_codec_single (const gchar * codec)
2651 GstCaps *caps = NULL;
2652 gchar **subcodec = NULL;
2654 guint32 codec_fourcc;
2656 GST_DEBUG ("Analyzing codec '%s'", codec);
2660 * For the ISO Base Media File Format, and the QuickTime movie file
2661 * format, the first element of a 'codecs' parameter value is a sample
2662 * description entry four-character code as registered by the MP4
2663 * Registration Authority [MP4RA].
2665 * See Also : http://mp4ra.org/#/codecs
2667 if (strlen (codec) < 4) {
2668 GST_WARNING ("Invalid codec (smaller than 4 characters) : '%s'", codec);
2672 subcodec = g_strsplit (codec, ".", 0);
2673 subcodec0 = subcodec[0];
2675 if (subcodec0 == NULL)
2678 /* Skip any leading spaces */
2679 while (*subcodec0 == ' ')
2682 if (strlen (subcodec0) < 4) {
2683 GST_WARNING ("Invalid codec (smaller than 4 characters) : '%s'", subcodec0);
2687 GST_LOG ("subcodec[0] '%s'", subcodec0);
2689 codec_fourcc = GST_READ_UINT32_LE (subcodec0);
2690 switch (codec_fourcc) {
2691 case GST_MAKE_FOURCC ('a', 'v', 'c', '1'):
2692 case GST_MAKE_FOURCC ('a', 'v', 'c', '2'):
2693 case GST_MAKE_FOURCC ('a', 'v', 'c', '3'):
2694 case GST_MAKE_FOURCC ('a', 'v', 'c', '4'):
2699 /* ISO 14496-15 Annex E : Sub-parameters for the MIME type “codecs”
2701 caps = gst_caps_new_empty_simple ("video/x-h264");
2704 /* The second element is the hexadecimal representation of the following
2705 * three bytes in the (subset) sequence parameter set Network
2706 * Abstraction Layer (NAL) unit specified in [AVC]:
2708 * * constraint_set flags
2711 spsint64 = g_ascii_strtoull (subcodec[1], NULL, 16);
2712 sps[0] = spsint64 >> 16;
2713 sps[1] = (spsint64 >> 8) & 0xff;
2714 sps[2] = spsint64 & 0xff;
2715 gst_codec_utils_h264_caps_set_level_and_profile (caps,
2716 (const guint8 *) &sps, 3);
2720 case GST_MAKE_FOURCC ('m', 'p', '4', 'a'):
2726 oti = g_ascii_strtoull (subcodec[1], NULL, 16);
2727 /* For mp4a, mp4v and mp4s, the second element is the hexadecimal
2728 * representation of the MP4 Registration Authority
2729 * ObjectTypeIndication */
2734 const gchar *profile = NULL;
2736 /* MPEG-4 Audio (ISO/IEC 14496-3 */
2738 gst_caps_new_simple ("audio/mpeg", "mpegversion", G_TYPE_INT, 4,
2743 /* If present, last element is the audio object type */
2744 audio_oti = g_ascii_strtoull (subcodec[2], NULL, 16);
2746 switch (audio_oti) {
2760 GST_WARNING ("Unhandled MPEG-4 Audio Object Type: 0x%"
2761 G_GUINT64_FORMAT "x", audio_oti);
2765 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
2769 GST_WARNING ("Unknown ObjectTypeIndication 0x%" G_GUINT64_FORMAT "x",
2775 case GST_MAKE_FOURCC ('h', 'e', 'v', '1'):
2776 case GST_MAKE_FOURCC ('h', 'v', 'c', '1'):
2778 /* ISO 14496-15 Annex E : Sub-parameters for the MIME type “codecs”
2780 caps = gst_caps_new_empty_simple ("video/x-h265");
2782 /* FIXME : Extract information from the following component */
2785 /* Following are not defined in rfc 6831 but are registered MP4RA codecs */
2786 case GST_MAKE_FOURCC ('a', 'c', '-', '3'):
2787 /* ETSI TS 102 366 v1.4.1 - Digital Audio Compression (AC-3, Enhanced AC-3) Standard, Annex F */
2788 caps = gst_caps_new_empty_simple ("audio/x-ac3");
2790 case GST_MAKE_FOURCC ('e', 'c', '+', '3'):
2792 ("Signalling of ATMOS ('ec+3') isn't defined yet. Falling back to EAC3 caps");
2793 /* withdrawn, unused, do not use (was enhanced AC-3 audio with JOC) */
2794 case GST_MAKE_FOURCC ('e', 'c', '-', '3'):
2795 /* ETSI TS 102 366 v1.4.1 - Digital Audio Compression (AC-3, Enhanced AC-3) Standard, Annex F */
2796 caps = gst_caps_new_empty_simple ("audio/x-eac3");
2798 case GST_MAKE_FOURCC ('s', 't', 'p', 'p'):
2799 /* IMSC1-conformant TTM XML */
2800 caps = gst_caps_new_empty_simple ("application/ttml+xml");
2802 case GST_MAKE_FOURCC ('w', 'v', 't', 't'):
2803 /* WebVTT subtitles */
2804 caps = gst_caps_new_empty_simple ("application/x-subtitle-vtt");
2806 case GST_MAKE_FOURCC ('v', 'p', '0', '8'):
2808 caps = gst_caps_new_empty_simple ("video/x-vp8");
2810 case GST_MAKE_FOURCC ('v', 'p', '0', '9'):
2812 caps = gst_caps_new_empty_simple ("video/x-vp9");
2814 case GST_MAKE_FOURCC ('a', 'v', '0', '1'):
2816 caps = gst_caps_new_empty_simple ("video/x-av1");
2818 case GST_MAKE_FOURCC ('o', 'p', 'u', 's'):
2820 caps = gst_caps_new_empty_simple ("audio/x-opus");
2822 case GST_MAKE_FOURCC ('u', 'l', 'a', 'w'):
2824 caps = gst_caps_new_empty_simple ("audio/x-mulaw");
2826 case GST_MAKE_FOURCC ('g', '7', '2', '6'):
2829 gst_caps_new_simple ("audio/x-adpcm", "layout", G_TYPE_STRING, "g726",
2833 GST_WARNING ("Unknown codec '%s' please file a bug", codec);
2838 if (subcodec != NULL)
2839 g_strfreev (subcodec);
2844 * gst_codec_utils_caps_from_mime_codec:
2845 * @codecs_field: A mime codec string field
2847 * Converts a RFC 6381 compatible codec string to #GstCaps. More than one codec
2848 * string can be present (separated by `,`).
2850 * Registered codecs can be found at http://mp4ra.org/#/codecs
2852 * Returns: (transfer full) (nullable): The corresponding #GstCaps or %NULL
2857 gst_codec_utils_caps_from_mime_codec (const gchar * codecs_field)
2859 gchar **codecs = NULL;
2860 GstCaps *caps = NULL;
2863 g_return_val_if_fail (codecs_field != NULL, NULL);
2865 GST_LOG ("codecs_field '%s'", codecs_field);
2867 codecs = g_strsplit (codecs_field, ",", 0);
2868 if (codecs == NULL) {
2869 GST_WARNING ("Invalid 'codecs' field : '%s'", codecs_field);
2873 for (i = 0; codecs[i]; i++) {
2874 const gchar *codec = codecs[i];
2876 caps = gst_codec_utils_caps_from_mime_codec_single (codec);
2878 gst_caps_append (caps,
2879 gst_codec_utils_caps_from_mime_codec_single (codec));
2883 g_strfreev (codecs);
2884 GST_LOG ("caps %" GST_PTR_FORMAT, caps);