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.
40 #define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
41 gst_structure_has_name(gst_caps_get_structure((caps),0),(name))
43 #define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
44 gst_structure_has_field(gst_caps_get_structure((caps),0),(field))
47 digit_to_string (guint digit)
49 static const char itoa[][2] = {
50 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
53 if (G_LIKELY (digit < 10))
60 * gst_codec_utils_aac_get_sample_rate_from_index:
61 * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
62 * container) or ADTS frame header
64 * Translates the sample rate index found in AAC headers to the actual sample
67 * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
72 gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
74 static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
75 32000, 24000, 22050, 16000, 12000, 11025, 8000
78 if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
79 return aac_sample_rates[sr_idx];
81 GST_WARNING ("Invalid sample rate index %u", sr_idx);
86 * gst_codec_utils_aac_get_profile:
87 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
88 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see
89 * gst_codec_utils_aac_get_level() for a more details).
90 * @len: Length of @audio_config in bytes
92 * Returns the profile of the given AAC stream as a string. The profile is
93 * determined using the AudioObjectType field which is in the first 5 bits of
97 * HE-AAC support has not yet been implemented.
100 * Returns: The profile as a const string and %NULL if the profile could not be
106 gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
113 GST_MEMDUMP ("audio config", audio_config, len);
115 profile = audio_config[0] >> 3;
129 GST_DEBUG ("Invalid profile idx: %u", profile);
134 * gst_codec_utils_aac_get_level:
135 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
136 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1.
137 * @len: Length of @audio_config in bytes
139 * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
140 * streams, the constraints from the AAC audio profile are applied. For AAC
141 * Main, LTP, SSR and others, the Main profile is used.
143 * The @audio_config parameter follows the following format, starting from the
144 * most significant bit of the first byte:
148 * Bit 0:4 contains the AudioObjectType
151 * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
152 * next 24 bits define the actual sample frequency, and subsequent
153 * fields are appropriately shifted).
156 * Bit 9:12 contains the channel configuration
161 * HE-AAC support has not yet been implemented.
164 * Returns: The level as a const string and %NULL if the level could not be
170 gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
172 int profile, sr_idx, channel_config, rate;
173 /* Number of single channel elements, channel pair elements, low frequency
174 * elements, independently switched coupling channel elements, and
175 * dependently switched coupling channel elements.
177 * Note: The 2 CCE types are ignored for now as they require us to actually
178 * parse the first frame, and they are rarely found in actual streams.
180 int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
182 /* Processor and RAM Complexity Units (calculated and "reference" for single
184 int pcu, rcu, pcu_ref, rcu_ref;
187 g_return_val_if_fail (audio_config != NULL, NULL);
192 GST_MEMDUMP ("audio config", audio_config, len);
194 profile = audio_config[0] >> 3;
195 /* FIXME: add support for sr_idx = 0xf */
196 sr_idx = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7);
197 rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
198 channel_config = (audio_config[1] & 0x7f) >> 3;
203 switch (channel_config) {
205 /* Channel config is defined in the AudioObjectType's SpecificConfig,
206 * which requires some amount of digging through the headers. I only see
207 * this done in the MPEG conformance streams - FIXME */
208 GST_WARNING ("Found a stream with channel configuration in the "
209 "AudioSpecificConfig. Please file a bug with a link to the media if "
217 /* front left and right */
221 /* front left, right, and center */
226 /* front left, right, and center; rear surround */
231 /* front left, right, and center; rear left and right surround */
236 /* front left, right, center and LFE; rear left and right surround */
241 /* front left, right, center and LFE; outside front left and right;
242 * rear left and right surround */
248 GST_WARNING ("Unknown channel config in header: %d", channel_config);
254 GST_WARNING ("profile 0 is not a valid profile");
270 /* Other than a couple of ER profiles, Main is the worst-case */
276 /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
277 * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */
279 pcu = ((float) rate / 48000) * pcu_ref *
280 ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));
282 rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
283 (0.4 * num_cce_dep));
286 rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
288 rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));
290 num_channels = num_sce + (2 * num_cpe) + num_lfe;
293 /* AAC LC => return the level as per the 'AAC Profile' */
294 if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
296 else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
298 /* There is no level 3 for the AAC Profile */
299 else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
301 else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
304 /* Return the level as per the 'Main Profile' */
305 if (pcu < 40 && rcu < 20)
307 else if (pcu < 80 && rcu < 64)
309 else if (pcu < 160 && rcu < 128)
311 else if (pcu < 320 && rcu < 256)
316 GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
317 "channel_config=%u, pcu=%d,rcu=%d", profile, rate, channel_config, pcu,
321 return digit_to_string (ret);
326 * gst_codec_utils_aac_caps_set_level_and_profile:
327 * @caps: the #GstCaps to which level and profile fields are to be added
328 * @audio_config: a pointer to the AudioSpecificConfig as specified in the
329 * Elementary Stream Descriptor (esds) in ISO/IEC 14496-1 (see
330 * below for a more details).
331 * @len: Length of @audio_config in bytes
333 * Sets the level and profile on @caps if it can be determined from
334 * @audio_config. See gst_codec_utils_aac_get_level() and
335 * gst_codec_utils_aac_get_profile() for more details on the parameters.
336 * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
337 * If mpegversion is 4, the "base-profile" field is also set in @caps.
339 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
344 gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
345 const guint8 * audio_config, guint len)
348 const gchar *level, *profile;
351 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
352 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
353 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
354 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
355 g_return_val_if_fail (audio_config != NULL, FALSE);
357 s = gst_caps_get_structure (caps, 0);
359 gst_structure_get_int (s, "mpegversion", &mpegversion);
360 g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);
362 level = gst_codec_utils_aac_get_level (audio_config, len);
365 gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);
367 profile = gst_codec_utils_aac_get_profile (audio_config, len);
369 if (profile != NULL) {
370 if (mpegversion == 4) {
371 gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
372 "profile", G_TYPE_STRING, profile, NULL);
374 gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
378 GST_LOG ("profile : %s", (profile) ? profile : "---");
379 GST_LOG ("level : %s", (level) ? level : "---");
381 return (level != NULL && profile != NULL);
385 * gst_codec_utils_h264_get_profile:
386 * @sps: Pointer to the sequence parameter set for the stream.
387 * @len: Length of the data available in @sps.
389 * Converts the profile indication (profile_idc) in the stream's
390 * sequence parameter set into a string. The SPS is expected to have the
391 * following format, as defined in the H.264 specification. The SPS is viewed
392 * as a bitstream here, with bit 0 being the most significant bit of the first
396 * <listitem><para>Bit 0:7 - Profile indication</para></listitem>
397 * <listitem><para>Bit 8 - constraint_set0_flag</para></listitem>
398 * <listitem><para>Bit 9 - constraint_set1_flag</para></listitem>
399 * <listitem><para>Bit 10 - constraint_set2_flag</para></listitem>
400 * <listitem><para>Bit 11 - constraint_set3_flag</para></listitem>
401 * <listitem><para>Bit 12 - constraint_set3_flag</para></listitem>
402 * <listitem><para>Bit 13:15 - Reserved</para></listitem>
403 * <listitem><para>Bit 16:24 - Level indication</para></listitem>
406 * Returns: The profile as a const string, or %NULL if there is an error.
411 gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
413 const gchar *profile = NULL;
416 g_return_val_if_fail (sps != NULL, NULL);
421 GST_MEMDUMP ("SPS", sps, len);
423 csf1 = (sps[1] & 0x40) >> 6;
424 csf3 = (sps[1] & 0x10) >> 4;
429 profile = "constrained-baseline";
431 profile = "baseline";
437 profile = "extended";
444 profile = "high-10-intra";
450 profile = "high-4:2:2-intra";
452 profile = "high-4:2:2";
456 profile = "high-4:4:4-intra";
458 profile = "high-4:4:4";
461 profile = "cavlc-4:4:4-intra";
471 * gst_codec_utils_h264_get_level:
472 * @sps: Pointer to the sequence parameter set for the stream.
473 * @len: Length of the data available in @sps.
475 * Converts the level indication (level_idc) in the stream's
476 * sequence parameter set into a string. The SPS is expected to have the
477 * same format as for gst_codec_utils_h264_get_profile().
479 * Returns: The level as a const string, or %NULL if there is an error.
484 gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
488 g_return_val_if_fail (sps != NULL, NULL);
493 GST_MEMDUMP ("SPS", sps, len);
495 csf3 = (sps[1] & 0x10) >> 4;
497 if (sps[2] == 11 && csf3)
499 else if (sps[2] % 10 == 0)
500 return digit_to_string (sps[2] / 10);
530 * gst_codec_utils_h264_caps_set_level_and_profile:
531 * @caps: the #GstCaps to which the level and profile are to be added
532 * @sps: Pointer to the sequence parameter set for the stream.
533 * @len: Length of the data available in @sps.
535 * Sets the level and profile in @caps if it can be determined from @sps. See
536 * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
537 * for more details on the parameters.
539 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
544 gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
545 const guint8 * sps, guint len)
547 const gchar *level, *profile;
549 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
550 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
551 g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
552 g_return_val_if_fail (sps != NULL, FALSE);
554 level = gst_codec_utils_h264_get_level (sps, len);
557 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
559 profile = gst_codec_utils_h264_get_profile (sps, len);
562 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
564 GST_LOG ("profile : %s", (profile) ? profile : "---");
565 GST_LOG ("level : %s", (level) ? level : "---");
567 return (level != NULL && profile != NULL);
571 * gst_codec_utils_mpeg4video_get_profile:
572 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
573 * @len: Length of the data available in @sps.
575 * Converts the profile indication in the stream's visual object sequence into
576 * a string. @vis_obj_seq is expected to be the data following the visual
577 * object sequence start code. Only the first byte
578 * (profile_and_level_indication) is used.
580 * Returns: The profile as a const string, or NULL if there is an error.
585 gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
587 /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
588 * sources: epan/dissectors/packet-mp4ves.c */
590 /* These are a direct mapping from the integer profile id -> string. Profiles
591 * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
592 * second 4 bits of vis_obj_seq[0], so they are handled separately. */
593 static const char *profiles[] = { "simple", "simple-scalable", "core",
594 "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
595 "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
596 "advanced-core", "advanced-scalable-texture",
598 int profile_id, level_id;
600 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
605 GST_MEMDUMP ("VOS", vis_obj_seq, len);
607 profile_id = vis_obj_seq[0] >> 4;
608 level_id = vis_obj_seq[0] & 0xf;
610 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
612 if (profile_id != 6 && profile_id < 0xe)
613 return profiles[profile_id];
615 if (profile_id != 0xf && level_id == 0)
618 switch (profile_id) {
621 return "simple-face";
622 else if (level_id < 5)
628 return "simple-studio";
629 else if (level_id < 9)
630 return "core-studio";
635 return "advanced-simple";
636 else if (level_id > 7 && level_id < 0xe)
637 return "fine-granularity-scalable";
645 * gst_codec_utils_mpeg4video_get_level:
646 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
647 * @len: Length of the data available in @sps.
649 * Converts the level indication in the stream's visual object sequence into
650 * a string. @vis_obj_seq is expected to be the data following the visual
651 * object sequence start code. Only the first byte
652 * (profile_and_level_indication) is used.
654 * Returns: The level as a const string, or NULL if there is an error.
659 gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
661 /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
662 * sources: epan/dissectors/packet-mp4ves.c
664 * Each profile has a different maximum level it defines. Some of them still
665 * need special case handling, because not all levels start from 1, and the
666 * Simple profile defines an intermediate level as well. */
667 static const int level_max[] = { 3, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
670 int profile_id, level_id;
672 g_return_val_if_fail (vis_obj_seq != NULL, NULL);
677 GST_MEMDUMP ("VOS", vis_obj_seq, len);
679 profile_id = vis_obj_seq[0] >> 4;
680 level_id = vis_obj_seq[0] & 0xf;
682 GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);
684 if (profile_id != 0xf && level_id == 0)
687 /* Let's do some validation of the level */
688 switch (profile_id) {
710 if (level_id == 7 && level_id > 0xd)
715 if (profile_id == 0 && level_id == 8)
716 /* Simple Profile / Level 0 */
718 else if (profile_id == 0 && level_id == 9)
719 /* Simple Profile / Level 0b */
721 else if (level_id <= level_max[profile_id])
722 /* Levels for all other cases */
723 return digit_to_string (level_id);
729 * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
730 * @caps: the #GstCaps to which the level and profile are to be added
731 * @vis_obj_seq: Pointer to the visual object sequence for the stream.
732 * @len: Length of the data available in @sps.
734 * Sets the level and profile in @caps if it can be determined from
735 * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
736 * gst_codec_utils_mpeg4video_get_profile() for more details on the
739 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
744 gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
745 const guint8 * vis_obj_seq, guint len)
747 const gchar *profile, *level;
749 g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
750 g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
751 g_return_val_if_fail (vis_obj_seq != NULL, FALSE);
753 profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);
756 gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
758 level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);
761 gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
763 GST_LOG ("profile : %s", (profile) ? profile : "---");
764 GST_LOG ("level : %s", (level) ? level : "---");
766 return (profile != NULL && level != NULL);