1 /* GStreamer base utils library codec-specific utility functions
2 * Copyright (C) 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
3 * 2010 Collabora Multimedia
4 * 2010 Nokia Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 * SECTION:gstpbutilscodecutils
24 * @short_description: Miscellaneous codec-specific utility functions
28 * Provides codec-specific ulility functions such as functions to provide the
29 * codec profile and level in human-readable string form from header data.
42 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
43 gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
45 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
46 gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
49 digit_to_string (guint digit)
51 static const char itoa[][2] = {
52 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
55 if (G_LIKELY (digit < 10))
62 * gst_codec_utils_aac_get_sample_rate_from_index:
63 * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
64 * container) or ADTS frame header
66 * Translates the sample rate index found in AAC headers to the actual sample
69 * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
74 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
76 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
77 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
80 if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
81 return aac_sample_rates[sr_idx];
83 GST_WARNING ("Invalid sample rate index %u", sr_idx);
88 * gst_codec_utils_aac_get_profile:
89 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
90 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see
91 * gst_codec_utils_aac_get_level() for a more details).
92 * @len: Length of @audio_config in bytes
94 * Returns the profile of the given AAC stream as a string. The profile is
95 * determined using the AudioObjectType field which is in the first 5 bits of
99 * HE-AAC support has not yet been implemented.
102 * Returns: The profile as a const string and %NULL if the profile could not be
108 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
115 GST_MEMDUMP ("audio config", audio_config, len);
117 profile = audio_config[0] >> 3;
131 GST_DEBUG ("Invalid profile idx: %u", profile);
136 * gst_codec_utils_aac_get_level:
137 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
138 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.
139 * @len: Length of @audio_config in bytes
141 * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
142 * streams, the constraints from the AAC audio profile are applied. For AAC
143 * Main, LTP, SSR and others, the Main profile is used.
145 * The @audio_config parameter follows the following format, starting from the
146 * most significant bit of the first byte:
150 * Bit 0:4 contains the AudioObjectType
153 * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
154 * next 24 bits define the actual sample frequency, and subsequent
155 * fields are appropriately shifted).
158 * Bit 9:12 contains the channel configuration
163 * HE-AAC support has not yet been implemented.
166 * Returns: The level as a const string and %NULL if the level could not be
172 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
174 int profile, sr_idx, channel_config, rate;
175 /* Number of single channel elements, channel pair elements, low frequency
176 * elements, independently switched coupling channel elements, and
177 * dependently switched coupling channel elements.
179 * Note: The 2 CCE types are ignored for now as they require us to actually
180 * parse the first frame, and they are rarely found in actual streams.
182 int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
184 /* Processor and RAM Complexity Units (calculated and "reference" for single
186 int pcu, rcu, pcu_ref, rcu_ref;
189 g_return_val_if_fail (audio_config != NULL, NULL);
194 GST_MEMDUMP ("audio config", audio_config, len);
196 profile = audio_config[0] >> 3;
197 /* FIXME: add support for sr_idx = 0xf */
198 sr_idx = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7);
199 rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
200 channel_config = (audio_config[1] & 0x7f) >> 3;
205 switch (channel_config) {
207 /* Channel config is defined in the AudioObjectType's SpecificConfig,
208 * which requires some amount of digging through the headers. I only see
209 * this done in the MPEG conformance streams - FIXME */
210 GST_WARNING ("Found a stream with channel configuration in the "
211 "AudioSpecificConfig. Please file a bug with a link to the media if "
219 /* front left and right */
223 /* front left, right, and center */
228 /* front left, right, and center; rear surround */
233 /* front left, right, and center; rear left and right surround */
238 /* front left, right, center and LFE; rear left and right surround */
243 /* front left, right, center and LFE; outside front left and right;
244 * rear left and right surround */
250 GST_WARNING ("Unknown channel config in header: %d", channel_config);
256 GST_WARNING ("profile 0 is not a valid profile");
272 /* Other than a couple of ER profiles, Main is the worst-case */
278 /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
279 * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
281 pcu = ((float) rate / 48000) * pcu_ref *
282 ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
284 rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
285 (0.4 * num_cce_dep));
288 rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
290 rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
292 num_channels = num_sce + (2 * num_cpe) + num_lfe;
295 /* AAC LC => return the level as per the 'AAC Profile' */
296 if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
298 else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
300 /* There is no level 3 for the AAC Profile */
301 else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
303 else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
306 /* Return the level as per the 'Main Profile' */
307 if (pcu < 40 && rcu < 20)
309 else if (pcu < 80 && rcu < 64)
311 else if (pcu < 160 && rcu < 128)
313 else if (pcu < 320 && rcu < 256)
318 GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
319 "channel_config=%u, pcu=%d,rcu=%d", profile, rate, channel_config, pcu,
323 return digit_to_string (ret);
328 * gst_codec_utils_aac_caps_set_level_and_profile:
329 * @caps: the #GstCaps to which level and profile fields are to be added
330 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
331 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see
332 * below for a more details).
333 * @len: Length of @audio_config in bytes
335 * Sets the level and profile on @caps if it can be determined from
336 * @audio_config. See gst_codec_utils_aac_get_level() and
337 * gst_codec_utils_aac_get_profile() for more details on the parameters.
338 * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
339 * If mpegversion is 4, the "base-profile" field is also set in @caps.
341 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
346 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
347 const guint8 * audio_config, guint len)
350 const gchar *level, *profile;
353 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
354 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
355 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
356 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
357 g_return_val_if_fail (audio_config != NULL, FALSE);
359 s = gst_caps_get_structure (caps, 0);
361 gst_structure_get_int (s, "mpegversion", &mpegversion);
362 g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
364 level = gst_codec_utils_aac_get_level (audio_config, len);
367 gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
369 profile = gst_codec_utils_aac_get_profile (audio_config, len);
371 if (profile != NULL) {
372 if (mpegversion == 4) {
373 gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
374 "profile", G_TYPE_STRING, profile, NULL);
376 gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
380 GST_LOG ("profile : %s", (profile) ? profile : "---");
381 GST_LOG ("level : %s", (level) ? level : "---");
383 return (level != NULL && profile != NULL);
387 * gst_codec_utils_h264_get_profile:
388 * @sps: Pointer to the sequence parameter set for the stream.
389 * @len: Length of the data available in @sps.
391 * Converts the profile indication (profile_idc) in the stream's
392 * sequence parameter set into a string. The SPS is expected to have the
393 * following format, as defined in the H.264 specification. The SPS is viewed
394 * as a bitstream here, with bit 0 being the most significant bit of the first
398 * <listitem><para>Bit 0:7 - Profile indication</para></listitem>
399 * <listitem><para>Bit 8 - constraint_set0_flag</para></listitem>
400 * <listitem><para>Bit 9 - constraint_set1_flag</para></listitem>
401 * <listitem><para>Bit 10 - constraint_set2_flag</para></listitem>
402 * <listitem><para>Bit 11 - constraint_set3_flag</para></listitem>
403 * <listitem><para>Bit 12 - constraint_set3_flag</para></listitem>
404 * <listitem><para>Bit 13:15 - Reserved</para></listitem>
405 * <listitem><para>Bit 16:24 - Level indication</para></listitem>
408 * Returns: The profile as a const string, or %NULL if there is an error.
413 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
415 const gchar *profile = NULL;
418 g_return_val_if_fail (sps != NULL, NULL);
423 GST_MEMDUMP ("SPS", sps, len);
425 csf1 = (sps[1] & 0x40) >> 6;
426 csf3 = (sps[1] & 0x10) >> 4;
431 profile = "constrained-baseline";
433 profile = "baseline";
439 profile = "extended";
446 profile = "high-10-intra";
452 profile = "high-4:2:2-intra";
454 profile = "high-4:2:2";
458 profile = "high-4:4:4-intra";
460 profile = "high-4:4:4";
463 profile = "cavlc-4:4:4-intra";
473 * gst_codec_utils_h264_get_level:
474 * @sps: Pointer to the sequence parameter set for the stream.
475 * @len: Length of the data available in @sps.
477 * Converts the level indication (level_idc) in the stream's
478 * sequence parameter set into a string. The SPS is expected to have the
479 * same format as for gst_codec_utils_h264_get_profile().
481 * Returns: The level as a const string, or %NULL if there is an error.
486 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
490 g_return_val_if_fail (sps != NULL, NULL);
495 GST_MEMDUMP ("SPS", sps, len);
497 csf3 = (sps[1] & 0x10) >> 4;
499 if (sps[2] == 11 && csf3)
501 else if (sps[2] % 10 == 0)
502 return digit_to_string (sps[2] / 10);
532 * gst_codec_utils_h264_get_level_idc:
533 * @level: A level string from caps
535 * Transform a level string from the caps into the level_idc
537 * Returns: the level_idc or 0 if the level is unknown
542 gst_codec_utils_h264_get_level_idc (const gchar * level)
544 g_return_val_if_fail (level != NULL, 0);
546 if (!strcmp (level, "1"))
548 else if (!strcmp (level, "1b"))
550 else if (!strcmp (level, "1.1"))
552 else if (!strcmp (level, "1.2"))
554 else if (!strcmp (level, "1.3"))
556 else if (!strcmp (level, "2"))
558 else if (!strcmp (level, "2.1"))
560 else if (!strcmp (level, "2.2"))
562 else if (!strcmp (level, "3"))
564 else if (!strcmp (level, "3.1"))
566 else if (!strcmp (level, "3.2"))
568 else if (!strcmp (level, "4"))
570 else if (!strcmp (level, "4.1"))
572 else if (!strcmp (level, "4.2"))
574 else if (!strcmp (level, "5"))
576 else if (!strcmp (level, "5.1"))
579 GST_WARNING ("Invalid level %s", level);
584 * gst_codec_utils_h264_caps_set_level_and_profile:
585 * @caps: the #GstCaps to which the level and profile are to be added
586 * @sps: Pointer to the sequence parameter set for the stream.
587 * @len: Length of the data available in @sps.
589 * Sets the level and profile in @caps if it can be determined from @sps. See
590 * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
591 * for more details on the parameters.
593 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
598 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
599 const guint8 * sps, guint len)
601 const gchar *level, *profile;
603 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
604 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
605 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
606 g_return_val_if_fail (sps != NULL, FALSE);
608 level = gst_codec_utils_h264_get_level (sps, len);
611 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
613 profile = gst_codec_utils_h264_get_profile (sps, len);
616 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
618 GST_LOG ("profile : %s", (profile) ? profile : "---");
619 GST_LOG ("level : %s", (level) ? level : "---");
621 return (level != NULL && profile != NULL);
625 * gst_codec_utils_mpeg4video_get_profile:
626 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
627 * @len: Length of the data available in @sps.
629 * Converts the profile indication in the stream's visual object sequence into
630 * a string. @vis_obj_seq is expected to be the data following the visual
631 * object sequence start code. Only the first byte
632 * (profile_and_level_indication) is used.
634 * Returns: The profile as a const string, or NULL if there is an error.
639 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
641 /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
642 * sources: epan/dissectors/packet-mp4ves.c */
644 /* These are a direct mapping from the integer profile id -> string. Profiles
645 * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
646 * second 4 bits of vis_obj_seq[0], so they are handled separately. */
647 static const char *profiles[] = { "simple", "simple-scalable", "core",
648 "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
649 "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
650 "advanced-core", "advanced-scalable-texture",
652 int profile_id, level_id;
654 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
659 GST_MEMDUMP ("VOS", vis_obj_seq, len);
661 profile_id = vis_obj_seq[0] >> 4;
662 level_id = vis_obj_seq[0] & 0xf;
664 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
666 if (profile_id != 6 && profile_id < 0xe)
667 return profiles[profile_id];
669 if (profile_id != 0xf && level_id == 0)
672 switch (profile_id) {
675 return "simple-face";
676 else if (level_id < 5)
682 return "simple-studio";
683 else if (level_id < 9)
684 return "core-studio";
689 return "advanced-simple";
690 else if (level_id > 7 && level_id < 0xe)
691 return "fine-granularity-scalable";
699 * gst_codec_utils_mpeg4video_get_level:
700 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
701 * @len: Length of the data available in @sps.
703 * Converts the level indication in the stream's visual object sequence into
704 * a string. @vis_obj_seq is expected to be the data following the visual
705 * object sequence start code. Only the first byte
706 * (profile_and_level_indication) is used.
708 * Returns: The level as a const string, or NULL if there is an error.
713 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
715 /* The profile/level codes are from 14496-2, table G-1, the Wireshark
716 * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
718 * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
719 * (see Xvid sources vfw/config.c)
721 * Each profile has a different maximum level it defines. Some of them still
722 * need special case handling, because not all levels start from 1, and the
723 * Simple profile defines an intermediate level as well. */
724 static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
727 int profile_id, level_id;
729 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
734 GST_MEMDUMP ("VOS", vis_obj_seq, len);
736 profile_id = vis_obj_seq[0] >> 4;
737 level_id = vis_obj_seq[0] & 0xf;
739 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
741 if (profile_id != 0xf && level_id == 0)
744 /* Let's do some validation of the level */
745 switch (profile_id) {
767 if (level_id == 6 || level_id == 7 || level_id > 0xd)
772 if (profile_id == 0 && level_id == 8)
773 /* Simple Profile / Level 0 */
775 else if (profile_id == 0 && level_id == 9)
776 /* Simple Profile / Level 0b */
778 else if (profile_id == 0 && level_id == 4)
779 /* Simple Profile / Level 4a */
781 else if (profile_id == 0xf && level_id > 7)
782 /* Fine Granularity Scalable Profile */
783 return digit_to_string (level_id - 8);
784 else if (level_id <= level_max[profile_id])
785 /* Levels for all other cases */
786 return digit_to_string (level_id);
792 * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
793 * @caps: the #GstCaps to which the level and profile are to be added
794 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
795 * @len: Length of the data available in @sps.
797 * Sets the level and profile in @caps if it can be determined from
798 * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
799 * gst_codec_utils_mpeg4video_get_profile() for more details on the
802 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
807 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
808 const guint8 * vis_obj_seq, guint len)
810 const gchar *profile, *level;
812 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
813 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
814 g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
816 profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
819 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
821 level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
824 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
826 GST_LOG ("profile : %s", (profile) ? profile : "---");
827 GST_LOG ("level : %s", (level) ? level : "---");
829 return (profile != NULL && level != NULL);