/* GStreamer base utils library codec-specific utility functions
 * Copyright (C) 2010 Arun Raghavan <arun.raghavan@collabora.co.uk>
 *               2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
 *               2010 Collabora Multimedia
 *               2010 Nokia Corporation
 *               2013 Intel Corporation
 *               2015 Sebastian Dröge <sebastian@centricular.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstpbutilscodecutils
 * @title: Codec utilities
 * @short_description: Miscellaneous codec-specific utility functions
 *
 * Provides codec-specific ulility functions such as functions to provide the
 * codec profile and level in human-readable string form from header data.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "pbutils.h"
#include <gst/base/base.h>
#include <gst/tag/tag.h>

#include <string.h>

#define GST_SIMPLE_CAPS_HAS_NAME(caps,name) \
    gst_structure_has_name(gst_caps_get_structure((caps),0),(name))

#define GST_SIMPLE_CAPS_HAS_FIELD(caps,field) \
    gst_structure_has_field(gst_caps_get_structure((caps),0),(field))

static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000, 44100,
  32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
};

static const gchar *
digit_to_string (guint digit)
{
  static const char itoa[][2] = {
    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
  };

  if (G_LIKELY (digit < 10))
    return itoa[digit];
  else
    return NULL;
}

/**
 * gst_codec_utils_aac_get_sample_rate_from_index:
 * @sr_idx: Sample rate index as from the AudioSpecificConfig (MPEG-4
 *          container) or ADTS frame header
 *
 * Translates the sample rate index found in AAC headers to the actual sample
 * rate.
 *
 * Returns: The sample rate if @sr_idx is valid, 0 otherwise.
 */
guint
gst_codec_utils_aac_get_sample_rate_from_index (guint sr_idx)
{
  if (G_LIKELY (sr_idx < G_N_ELEMENTS (aac_sample_rates)))
    return aac_sample_rates[sr_idx];

  GST_WARNING ("Invalid sample rate index %u", sr_idx);
  return 0;
}

/**
 * gst_codec_utils_aac_get_index_from_sample_rate:
 * @rate: Sample rate
 *
 * Translates the sample rate to the index corresponding to it in AAC spec.
 *
 * Returns: The AAC index for this sample rate, -1 if the rate is not a
 * valid AAC sample rate.
 */
gint
gst_codec_utils_aac_get_index_from_sample_rate (guint rate)
{
  guint n;

  for (n = 0; n < G_N_ELEMENTS (aac_sample_rates); n++)
    if (aac_sample_rates[n] == rate)
      return n;

  GST_WARNING ("Invalid sample rate %u", rate);
  return -1;
}

/**
 * gst_codec_utils_aac_get_sample_rate:
 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
 *                as specified in the Elementary Stream Descriptor (esds)
 *                in ISO/IEC 14496-1.
 * @len: Length of @audio_config
 *
 * Translates the sample rate index found in AAC headers to the actual sample
 * rate.
 *
 * Returns: The sample rate if sr_idx is valid, 0 otherwise.
 *
 * Since 1.10
 */
guint
gst_codec_utils_aac_get_sample_rate (const guint8 * audio_config, guint len)
{
  guint rate_index;

  if (len < 2)
    return 0;

  rate_index = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7);
  return gst_codec_utils_aac_get_sample_rate_from_index (rate_index);
}

/**
 * gst_codec_utils_aac_get_channels:
 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
 *                as specified in the Elementary Stream Descriptor (esds)
 *                in ISO/IEC 14496-1.
 * @len: Length of @audio_config in bytes
 *
 * Returns the channels of the given AAC stream.
 *
 * Returns: The channels or 0 if the channel could not be determined.
 *
 * Since 1.10
 */
guint
gst_codec_utils_aac_get_channels (const guint8 * audio_config, guint len)
{
  guint channels;

  if (len < 2)
    return 0;

  channels = (audio_config[1] & 0x7f) >> 3;
  if (channels > 0 && channels < 7)
    return channels;
  else if (channels == 7)
    return 8;
  else
    return 0;
}

/**
 * gst_codec_utils_aac_get_profile:
 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
 *                as specified in the Elementary Stream Descriptor (esds)
 *                in ISO/IEC 14496-1.
 * @len: Length of @audio_config in bytes
 *
 * Returns the profile of the given AAC stream as a string. The profile is
 * determined using the AudioObjectType field which is in the first 5 bits of
 * @audio_config.
 *
 * > HE-AAC support has not yet been implemented.
 *
 * Returns: The profile as a const string and %NULL if the profile could not be
 * determined.
 */
const gchar *
gst_codec_utils_aac_get_profile (const guint8 * audio_config, guint len)
{
  guint profile;

  if (len < 1)
    return NULL;

  GST_MEMDUMP ("audio config", audio_config, len);

  profile = audio_config[0] >> 3;
  switch (profile) {
    case 1:
      return "main";
    case 2:
      return "lc";
    case 3:
      return "ssr";
    case 4:
      return "ltp";
    default:
      break;
  }

  GST_DEBUG ("Invalid profile idx: %u", profile);
  return NULL;
}

/**
 * gst_codec_utils_aac_get_level:
 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
 *                as specified in the Elementary Stream Descriptor (esds)
 *                in ISO/IEC 14496-1.
 * @len: Length of @audio_config in bytes
 *
 * Determines the level of a stream as defined in ISO/IEC 14496-3. For AAC LC
 * streams, the constraints from the AAC audio profile are applied. For AAC
 * Main, LTP, SSR and others, the Main profile is used.
 *
 * The @audio_config parameter follows the following format, starting from the
 * most significant bit of the first byte:
 *
 *   * Bit 0:4 contains the AudioObjectType
 *   * Bit 5:8 contains the sample frequency index (if this is 0xf, then the
 *     next 24 bits define the actual sample frequency, and subsequent
 *     fields are appropriately shifted).
 *   * Bit 9:12 contains the channel configuration
 *
 * > HE-AAC support has not yet been implemented.
 *
 * Returns: The level as a const string and %NULL if the level could not be
 * determined.
 */
const gchar *
gst_codec_utils_aac_get_level (const guint8 * audio_config, guint len)
{
  int profile, sr_idx, channel_config, rate;
  /* Number of single channel elements, channel pair elements, low frequency
   * elements, independently switched coupling channel elements, and
   * dependently switched coupling channel elements.
   *
   * Note: The 2 CCE types are ignored for now as they require us to actually
   * parse the first frame, and they are rarely found in actual streams.
   */
  int num_sce = 0, num_cpe = 0, num_lfe = 0, num_cce_indep = 0, num_cce_dep = 0;
  int num_channels;
  /* Processor and RAM Complexity Units (calculated and "reference" for single
   * channel) */
  int pcu, rcu, pcu_ref, rcu_ref;
  int ret = -1;

  g_return_val_if_fail (audio_config != NULL, NULL);

  if (len < 2)
    return NULL;

  GST_MEMDUMP ("audio config", audio_config, len);

  profile = audio_config[0] >> 3;
  /* FIXME: add support for sr_idx = 0xf */
  sr_idx = ((audio_config[0] & 0x7) << 1) | ((audio_config[1] & 0x80) >> 7);
  rate = gst_codec_utils_aac_get_sample_rate_from_index (sr_idx);
  channel_config = (audio_config[1] & 0x7f) >> 3;

  if (rate == 0)
    return NULL;

  switch (channel_config) {
    case 0:
      /* Channel config is defined in the AudioObjectType's SpecificConfig,
       * which requires some amount of digging through the headers. I only see
       * this done in the MPEG conformance streams - FIXME */
      GST_WARNING ("Found a stream with channel configuration in the "
          "AudioSpecificConfig. Please file a bug with a link to the media if "
          "possible.");
      return NULL;
    case 1:
      /* front center */
      num_sce = 1;
      break;
    case 2:
      /* front left and right */
      num_cpe = 1;
      break;
    case 3:
      /* front left, right, and center */
      num_sce = 1;
      num_cpe = 1;
      break;
    case 4:
      /* front left, right, and center; rear surround */
      num_sce = 2;
      num_cpe = 1;
      break;
    case 5:
      /* front left, right, and center; rear left and right surround */
      num_sce = 1;
      num_cpe = 2;
      break;
    case 6:
      /* front left, right, center and LFE; rear left and right surround */
      num_sce = 1;
      num_cpe = 2;
      break;
    case 7:
    case 12:
    case 14:
      /* front left, right, center and LFE; outside front left and right;
       * rear left and right surround */
      num_sce = 1;
      num_cpe = 3;
      num_lfe = 1;
      break;
    case 11:
      num_sce = 2;
      num_cpe = 2;
      num_lfe = 1;
      break;
    default:
      GST_WARNING ("Unknown channel config in header: %d", channel_config);
      return NULL;
  }

  switch (profile) {
    case 0:                    /* NULL */
      GST_WARNING ("profile 0 is not a valid profile");
      return NULL;
    case 2:                    /* LC */
      pcu_ref = 3;
      rcu_ref = 3;
      break;
    case 3:                    /* SSR */
      pcu_ref = 4;
      rcu_ref = 3;
      break;
    case 4:                    /* LTP */
      pcu_ref = 4;
      rcu_ref = 4;
      break;
    case 1:                    /* Main */
    default:
      /* Other than a couple of ER profiles, Main is the worst-case */
      pcu_ref = 5;
      rcu_ref = 5;
      break;
  }

  /* "fs_ref" is 48000 Hz for AAC Main/LC/SSR/LTP. SBR's fs_ref is defined as
   * 24000/48000 (in/out), for SBR streams. Actual support is a FIXME */

  pcu = ((float) rate / 48000) * pcu_ref *
      ((2 * num_cpe) + num_sce + num_lfe + num_cce_indep + (0.3 * num_cce_dep));

  rcu = ((float) rcu_ref) * (num_sce + (0.5 * num_lfe) + (0.5 * num_cce_indep) +
      (0.4 * num_cce_dep));

  if (num_cpe < 2)
    rcu += (rcu_ref + (rcu_ref - 1)) * num_cpe;
  else
    rcu += (rcu_ref + (rcu_ref - 1) * ((2 * num_cpe) - 1));

  num_channels = num_sce + (2 * num_cpe) + num_lfe;

  if (profile == 2) {
    /* AAC LC => return the level as per the 'AAC Profile' */
    if (num_channels <= 2 && rate <= 24000 && pcu <= 3 && rcu <= 5)
      ret = 1;
    else if (num_channels <= 2 && rate <= 48000 && pcu <= 6 && rcu <= 5)
      ret = 2;
    /* There is no level 3 for the AAC Profile */
    else if (num_channels <= 5 && rate <= 48000 && pcu <= 19 && rcu <= 15)
      ret = 4;
    else if (num_channels <= 5 && rate <= 96000 && pcu <= 38 && rcu <= 15)
      ret = 5;
    else if (num_channels <= 7 && rate <= 48000 && pcu <= 25 && rcu <= 19)
      ret = 6;
    else if (num_channels <= 7 && rate <= 96000 && pcu <= 50 && rcu <= 19)
      ret = 7;
  } else {
    /* Return the level as per the 'Main Profile' */
    if (pcu < 40 && rcu < 20)
      ret = 1;
    else if (pcu < 80 && rcu < 64)
      ret = 2;
    else if (pcu < 160 && rcu < 128)
      ret = 3;
    else if (pcu < 320 && rcu < 256)
      ret = 4;
  }

  if (ret == -1) {
    GST_WARNING ("couldn't determine level: profile=%u, rate=%u, "
        "channel_config=%u, pcu=%d,rcu=%d", profile, rate, channel_config, pcu,
        rcu);
    return NULL;
  } else {
    return digit_to_string (ret);
  }
}

/**
 * gst_codec_utils_aac_caps_set_level_and_profile:
 * @caps: the #GstCaps to which level and profile fields are to be added
 * @audio_config: (array length=len): a pointer to the AudioSpecificConfig
 *                as specified in the Elementary Stream Descriptor (esds)
 *                in ISO/IEC 14496-1. (See below for more details)
 * @len: Length of @audio_config in bytes
 *
 * Sets the level and profile on @caps if it can be determined from
 * @audio_config. See gst_codec_utils_aac_get_level() and
 * gst_codec_utils_aac_get_profile() for more details on the parameters.
 * @caps must be audio/mpeg caps with an "mpegversion" field of either 2 or 4.
 * If mpegversion is 4, the "base-profile" field is also set in @caps.
 *
 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
 */
gboolean
gst_codec_utils_aac_caps_set_level_and_profile (GstCaps * caps,
    const guint8 * audio_config, guint len)
{
  GstStructure *s;
  const gchar *level, *profile;
  int mpegversion = 0;

  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
  g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "audio/mpeg"), FALSE);
  g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_FIELD (caps, "mpegversion"), FALSE);
  g_return_val_if_fail (audio_config != NULL, FALSE);

  s = gst_caps_get_structure (caps, 0);

  gst_structure_get_int (s, "mpegversion", &mpegversion);
  g_return_val_if_fail (mpegversion == 2 || mpegversion == 4, FALSE);

  level = gst_codec_utils_aac_get_level (audio_config, len);

  if (level != NULL)
    gst_structure_set (s, "level", G_TYPE_STRING, level, NULL);

  profile = gst_codec_utils_aac_get_profile (audio_config, len);

  if (profile != NULL) {
    if (mpegversion == 4) {
      gst_structure_set (s, "base-profile", G_TYPE_STRING, profile,
          "profile", G_TYPE_STRING, profile, NULL);
    } else {
      gst_structure_set (s, "profile", G_TYPE_STRING, profile, NULL);
    }
  }

  GST_LOG ("profile : %s", (profile) ? profile : "---");
  GST_LOG ("level   : %s", (level) ? level : "---");

  return (level != NULL && profile != NULL);
}

/**
 * gst_codec_utils_h264_get_profile:
 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
 * @len: Length of the data available in @sps.
 *
 * Converts the profile indication (profile_idc) in the stream's
 * sequence parameter set into a string. The SPS is expected to have the
 * following format, as defined in the H.264 specification. The SPS is viewed
 * as a bitstream here, with bit 0 being the most significant bit of the first
 * byte.
 *
 * * Bit 0:7   - Profile indication
 * * Bit 8     - constraint_set0_flag
 * * Bit 9     - constraint_set1_flag
 * * Bit 10    - constraint_set2_flag
 * * Bit 11    - constraint_set3_flag
 * * Bit 12    - constraint_set3_flag
 * * Bit 13:15 - Reserved
 * * Bit 16:24 - Level indication
 *
 * Returns: The profile as a const string, or %NULL if there is an error.
 */
const gchar *
gst_codec_utils_h264_get_profile (const guint8 * sps, guint len)
{
  const gchar *profile = NULL;
  gint csf1, csf3, csf5;

  g_return_val_if_fail (sps != NULL, NULL);

  if (len < 2)
    return NULL;

  GST_MEMDUMP ("SPS", sps, len);

  csf1 = (sps[1] & 0x40) >> 6;
  csf3 = (sps[1] & 0x10) >> 4;
  csf5 = (sps[1] & 0x04) >> 2;

  switch (sps[0]) {
    case 66:
      if (csf1)
        profile = "constrained-baseline";
      else
        profile = "baseline";
      break;
    case 77:
      profile = "main";
      break;
    case 88:
      profile = "extended";
      break;
    case 100:
      profile = "high";
      break;
    case 110:
      if (csf3)
        profile = "high-10-intra";
      else
        profile = "high-10";
      break;
    case 122:
      if (csf3)
        profile = "high-4:2:2-intra";
      else
        profile = "high-4:2:2";
      break;
    case 244:
      if (csf3)
        profile = "high-4:4:4-intra";
      else
        profile = "high-4:4:4";
      break;
    case 44:
      profile = "cavlc-4:4:4-intra";
      break;
    case 118:
      profile = "multiview-high";
      break;
    case 128:
      profile = "stereo-high";
      break;
    case 83:
      if (csf5)
        profile = "scalable-constrained-baseline";
      else
        profile = "scalable-baseline";
      break;
    case 86:
      if (csf3)
        profile = "scalable-high-intra";
      else if (csf5)
        profile = "scalable-constrained-high";
      else
        profile = "scalable-high";
      break;
    default:
      return NULL;
  }

  return profile;
}

/**
 * gst_codec_utils_h264_get_level:
 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
 * @len: Length of the data available in @sps.
 *
 * Converts the level indication (level_idc) in the stream's
 * sequence parameter set into a string. The SPS is expected to have the
 * same format as for gst_codec_utils_h264_get_profile().
 *
 * Returns: The level as a const string, or %NULL if there is an error.
 */
const gchar *
gst_codec_utils_h264_get_level (const guint8 * sps, guint len)
{
  gint csf3;

  g_return_val_if_fail (sps != NULL, NULL);

  if (len < 3)
    return NULL;

  GST_MEMDUMP ("SPS", sps, len);

  csf3 = (sps[1] & 0x10) >> 4;

  if (sps[2] == 0)
    return NULL;
  else if ((sps[2] == 11 && csf3) || sps[2] == 9)
    return "1b";
  else if (sps[2] % 10 == 0)
    return digit_to_string (sps[2] / 10);
  else {
    switch (sps[2]) {
      case 11:
        return "1.1";
      case 12:
        return "1.2";
      case 13:
        return "1.3";
      case 21:
        return "2.1";
      case 22:
        return "2.2";
      case 31:
        return "3.1";
      case 32:
        return "3.2";
      case 41:
        return "4.1";
      case 42:
        return "4.2";
      case 51:
        return "5.1";
      case 52:
        return "5.2";
      default:
        return NULL;
    }
  }
}

/**
 * gst_codec_utils_h264_get_level_idc:
 * @level: A level string from caps
 *
 * Transform a level string from the caps into the level_idc
 *
 * Returns: the level_idc or 0 if the level is unknown
 */
guint8
gst_codec_utils_h264_get_level_idc (const gchar * level)
{
  g_return_val_if_fail (level != NULL, 0);

  if (!strcmp (level, "1"))
    return 10;
  else if (!strcmp (level, "1b"))
    return 9;
  else if (!strcmp (level, "1.1"))
    return 11;
  else if (!strcmp (level, "1.2"))
    return 12;
  else if (!strcmp (level, "1.3"))
    return 13;
  else if (!strcmp (level, "2"))
    return 20;
  else if (!strcmp (level, "2.1"))
    return 21;
  else if (!strcmp (level, "2.2"))
    return 22;
  else if (!strcmp (level, "3"))
    return 30;
  else if (!strcmp (level, "3.1"))
    return 31;
  else if (!strcmp (level, "3.2"))
    return 32;
  else if (!strcmp (level, "4"))
    return 40;
  else if (!strcmp (level, "4.1"))
    return 41;
  else if (!strcmp (level, "4.2"))
    return 42;
  else if (!strcmp (level, "5"))
    return 50;
  else if (!strcmp (level, "5.1"))
    return 51;
  else if (!strcmp (level, "5.2"))
    return 52;

  GST_WARNING ("Invalid level %s", level);
  return 0;
}

/**
 * gst_codec_utils_h264_caps_set_level_and_profile:
 * @caps: the #GstCaps to which the level and profile are to be added
 * @sps: (array length=len): Pointer to the sequence parameter set for the stream.
 * @len: Length of the data available in @sps.
 *
 * Sets the level and profile in @caps if it can be determined from @sps. See
 * gst_codec_utils_h264_get_level() and gst_codec_utils_h264_get_profile()
 * for more details on the parameters.
 *
 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
 */
gboolean
gst_codec_utils_h264_caps_set_level_and_profile (GstCaps * caps,
    const guint8 * sps, guint len)
{
  const gchar *level, *profile;

  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
  g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h264"), FALSE);
  g_return_val_if_fail (sps != NULL, FALSE);

  level = gst_codec_utils_h264_get_level (sps, len);

  if (level != NULL)
    gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);

  profile = gst_codec_utils_h264_get_profile (sps, len);

  if (profile != NULL)
    gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);

  GST_LOG ("profile : %s", (profile) ? profile : "---");
  GST_LOG ("level   : %s", (level) ? level : "---");

  return (level != NULL && profile != NULL);
}

/**
 * gst_codec_utils_h265_get_profile:
 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
 *   structure for the stream.
 * @len: Length of the data available in @profile_tier_level
 *
 * Converts the profile indication (general_profile_idc) in the stream's
 * profile_level_tier structure into a string. The profile_tier_level is
 * expected to have the following format, as defined in the H.265
 * specification. The profile_tier_level is viewed as a bitstream here,
 * with bit 0 being the most significant bit of the first byte.
 *
 * * Bit 0:1   - general_profile_space
 * * Bit 2     - general_tier_flag
 * * Bit 3:7   - general_profile_idc
 * * Bit 8:39  - gernal_profile_compatibility_flags
 * * Bit 40    - general_progressive_source_flag
 * * Bit 41    - general_interlaced_source_flag
 * * Bit 42    - general_non_packed_constraint_flag
 * * Bit 43    - general_frame_only_constraint_flag
 * * Bit 44:87 - general_reserved_zero_44bits
 * * Bit 88:95 - general_level_idc
 *
 * Returns: The profile as a const string, or %NULL if there is an error.
 *
 * Since 1.4
 */
const gchar *
gst_codec_utils_h265_get_profile (const guint8 * profile_tier_level, guint len)
{
  const gchar *profile = NULL;
  gint profile_idc;

  g_return_val_if_fail (profile_tier_level != NULL, NULL);

  if (len < 2)
    return NULL;

  GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);

  profile_idc = (profile_tier_level[0] & 0x1f);

  if (profile_idc == 1)
    profile = "main";
  else if (profile_idc == 2)
    profile = "main-10";
  else if (profile_idc == 3)
    profile = "main-still-picture";
  else
    profile = NULL;

  return profile;
}

/**
 * gst_codec_utils_h265_get_tier:
 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
 *   for the stream.
 * @len: Length of the data available in @profile_tier_level.
 *
 * Converts the tier indication (general_tier_flag) in the stream's
 * profile_tier_level structure into a string. The profile_tier_level
 * is expected to have the same format as for gst_codec_utils_h264_get_profile().
 *
 * Returns: The tier as a const string, or %NULL if there is an error.
 *
 * Since 1.4
 */
const gchar *
gst_codec_utils_h265_get_tier (const guint8 * profile_tier_level, guint len)
{
  const gchar *tier = NULL;
  gint tier_flag = 0;

  g_return_val_if_fail (profile_tier_level != NULL, NULL);

  if (len < 1)
    return NULL;

  GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);

  tier_flag = (profile_tier_level[0] & 0x20) >> 5;

  if (tier_flag)
    tier = "high";
  else
    tier = "main";

  return tier;
}

/**
 * gst_codec_utils_h265_get_level:
 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
 *   for the stream
 * @len: Length of the data available in @profile_tier_level.
 *
 * Converts the level indication (general_level_idc) in the stream's
 * profile_tier_level structure into a string. The profiel_tier_level is
 * expected to have the same format as for gst_codec_utils_h264_get_profile().
 *
 * Returns: The level as a const string, or %NULL if there is an error.
 *
 * Since 1.4
 */
const gchar *
gst_codec_utils_h265_get_level (const guint8 * profile_tier_level, guint len)
{
  g_return_val_if_fail (profile_tier_level != NULL, NULL);

  if (len < 12)
    return NULL;

  GST_MEMDUMP ("ProfileTierLevel", profile_tier_level, len);

  if (profile_tier_level[11] == 0)
    return NULL;
  else if (profile_tier_level[11] % 30 == 0)
    return digit_to_string (profile_tier_level[11] / 30);
  else {
    switch (profile_tier_level[11]) {
      case 63:
        return "2.1";
        break;
      case 93:
        return "3.1";
        break;
      case 123:
        return "4.1";
        break;
      case 153:
        return "5.1";
        break;
      case 156:
        return "5.2";
        break;
      case 183:
        return "6.1";
        break;
      case 186:
        return "6.2";
        break;
      default:
        return NULL;
    }
  }
}

/**
 * gst_codec_utils_h265_get_level_idc:
 * @level: A level string from caps
 *
 * Transform a level string from the caps into the level_idc
 *
 * Returns: the level_idc or 0 if the level is unknown
 *
 * Since 1.4
 */
guint8
gst_codec_utils_h265_get_level_idc (const gchar * level)
{
  g_return_val_if_fail (level != NULL, 0);

  if (!strcmp (level, "1"))
    return 30;
  else if (!strcmp (level, "2"))
    return 60;
  else if (!strcmp (level, "2.1"))
    return 63;
  else if (!strcmp (level, "3"))
    return 90;
  else if (!strcmp (level, "3.1"))
    return 93;
  else if (!strcmp (level, "4"))
    return 120;
  else if (!strcmp (level, "4.1"))
    return 123;
  else if (!strcmp (level, "5"))
    return 150;
  else if (!strcmp (level, "5.1"))
    return 153;
  else if (!strcmp (level, "5.2"))
    return 156;
  else if (!strcmp (level, "6"))
    return 180;
  else if (!strcmp (level, "6.1"))
    return 183;
  else if (!strcmp (level, "6.2"))
    return 186;

  GST_WARNING ("Invalid level %s", level);
  return 0;
}

/**
 * gst_codec_utils_h265_caps_set_level_tier_and_profile:
 * @caps: the #GstCaps to which the level, tier and profile are to be added
 * @profile_tier_level: (array length=len): Pointer to the profile_tier_level
 *   struct
 * @len: Length of the data available in @profile_tier_level.
 *
 * Sets the level, tier and profile in @caps if it can be determined from
 * @profile_tier_level. See gst_codec_utils_h265_get_level(),
 * gst_codec_utils_h265_get_tier() and gst_codec_utils_h265_get_profile()
 * for more details on the parameters.
 *
 * Returns: %TRUE if the level, tier, profile could be set, %FALSE otherwise.
 *
 * Since 1.4
 */
gboolean
gst_codec_utils_h265_caps_set_level_tier_and_profile (GstCaps * caps,
    const guint8 * profile_tier_level, guint len)
{
  const gchar *level, *tier, *profile;

  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
  g_return_val_if_fail (GST_SIMPLE_CAPS_HAS_NAME (caps, "video/x-h265"), FALSE);
  g_return_val_if_fail (profile_tier_level != NULL, FALSE);

  level = gst_codec_utils_h265_get_level (profile_tier_level, len);
  if (level != NULL)
    gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);

  tier = gst_codec_utils_h265_get_tier (profile_tier_level, len);
  if (tier != NULL)
    gst_caps_set_simple (caps, "tier", G_TYPE_STRING, tier, NULL);

  profile = gst_codec_utils_h265_get_profile (profile_tier_level, len);
  if (profile != NULL)
    gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);

  GST_LOG ("profile : %s", (profile) ? profile : "---");
  GST_LOG ("tier    : %s", (tier) ? tier : "---");
  GST_LOG ("level   : %s", (level) ? level : "---");

  return (level != NULL && tier != NULL && profile != NULL);
}

/**
 * gst_codec_utils_mpeg4video_get_profile:
 * @vis_obj_seq: (array length=len): Pointer to the visual object
 *   sequence for the stream.
 * @len: Length of the data available in @sps.
 *
 * Converts the profile indication in the stream's visual object sequence into
 * a string. @vis_obj_seq is expected to be the data following the visual
 * object sequence start code. Only the first byte
 * (profile_and_level_indication) is used.
 *
 * Returns: The profile as a const string, or NULL if there is an error.
 */
const gchar *
gst_codec_utils_mpeg4video_get_profile (const guint8 * vis_obj_seq, guint len)
{
  /* The profile/level codes are from 14496-2, table G-1, and the Wireshark
   * sources: epan/dissectors/packet-mp4ves.c */

  /* These are a direct mapping from the integer profile id -> string. Profiles
   * 0x6, 0xe and 0xf can correspond to more than one profile depending on the
   * second 4 bits of vis_obj_seq[0], so they are handled separately. */
  static const char *profiles[] = { "simple", "simple-scalable", "core",
    "main", "n-bit", "scalable", NULL, "basic-animated-texture", "hybrid",
    "advanced-real-time-simple", "core-scalable", "advanced-coding-efficiency",
    "advanced-core", "advanced-scalable-texture",
  };
  int profile_id, level_id;

  g_return_val_if_fail (vis_obj_seq != NULL, NULL);

  if (len < 1)
    return NULL;

  GST_MEMDUMP ("VOS", vis_obj_seq, len);

  profile_id = vis_obj_seq[0] >> 4;
  level_id = vis_obj_seq[0] & 0xf;

  GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);

  if (profile_id != 6 && profile_id < 0xe)
    return profiles[profile_id];

  if (profile_id != 0xf && level_id == 0)
    return NULL;

  switch (profile_id) {
    case 0x6:
      if (level_id < 3)
        return "simple-face";
      else if (level_id < 5)
        return "simple-fba";
      break;

    case 0xe:
      if (level_id < 5)
        return "simple-studio";
      else if (level_id < 9)
        return "core-studio";
      break;

    case 0xf:
      if (level_id < 6)
        return "advanced-simple";
      else if (level_id > 7 && level_id < 0xe)
        return "fine-granularity-scalable";
      break;
  }

  return NULL;
}

/**
 * gst_codec_utils_mpeg4video_get_level:
 * @vis_obj_seq: (array length=len): Pointer to the visual object
 *   sequence for the stream.
 * @len: Length of the data available in @sps.
 *
 * Converts the level indication in the stream's visual object sequence into
 * a string. @vis_obj_seq is expected to be the data following the visual
 * object sequence start code. Only the first byte
 * (profile_and_level_indication) is used.
 *
 * Returns: The level as a const string, or NULL if there is an error.
 */
const gchar *
gst_codec_utils_mpeg4video_get_level (const guint8 * vis_obj_seq, guint len)
{
  /* The profile/level codes are from 14496-2, table G-1, the Wireshark
   * sources: epan/dissectors/packet-mp4ves.c and the Xvid Sources:
   * src/xvid.h.
   * Levels 4a and 5 for SP were added in Amendment 2, level 6 in Amendment 4
   * (see Xvid sources vfw/config.c)
   *
   * Each profile has a different maximum level it defines. Some of them still
   * need special case handling, because not all levels start from 1, and the
   * Simple profile defines an intermediate level as well. */
  static const int level_max[] = { 6, 2, 2, 4, 2, 1, 2, 2, 2, 4, 3, 4, 2, 3, 4,
    5
  };
  int profile_id, level_id;

  g_return_val_if_fail (vis_obj_seq != NULL, NULL);

  if (len < 1)
    return NULL;

  GST_MEMDUMP ("VOS", vis_obj_seq, len);

  profile_id = vis_obj_seq[0] >> 4;
  level_id = vis_obj_seq[0] & 0xf;

  GST_LOG ("profile_id = %d, level_id = %d", profile_id, level_id);

  if (profile_id != 0xf && level_id == 0)
    return NULL;

  /* Let's do some validation of the level */
  switch (profile_id) {
    case 0x3:
      if (level_id == 1)
        return NULL;
      break;

    case 0x4:
      if (level_id != 2)
        return NULL;
      break;

    case 0x6:
      if (level_id > 5)
        return NULL;
      break;

    case 0xe:
      if (level_id > 9)
        return NULL;
      break;

    case 0xf:
      if (level_id == 6 || level_id == 7 || level_id > 0xd)
        return NULL;
      break;
  }

  if (profile_id == 0 && level_id == 8)
    /* Simple Profile / Level 0 */
    return "0";
  else if (profile_id == 0 && level_id == 9)
    /* Simple Profile / Level 0b */
    return "0b";
  else if (profile_id == 0 && level_id == 4)
    /* Simple Profile / Level 4a */
    return "4a";
  else if (profile_id == 0xf && level_id > 7)
    /* Fine Granularity Scalable Profile */
    return digit_to_string (level_id - 8);
  else if (level_id <= level_max[profile_id])
    /* Levels for all other cases */
    return digit_to_string (level_id);

  return NULL;
}

/**
 * gst_codec_utils_mpeg4video_caps_set_level_and_profile:
 * @caps: the #GstCaps to which the level and profile are to be added
 * @vis_obj_seq: (array length=len): Pointer to the visual object
 *   sequence for the stream.
 * @len: Length of the data available in @sps.
 *
 * Sets the level and profile in @caps if it can be determined from
 * @vis_obj_seq. See gst_codec_utils_mpeg4video_get_level() and
 * gst_codec_utils_mpeg4video_get_profile() for more details on the
 * parameters.
 *
 * Returns: %TRUE if the level and profile could be set, %FALSE otherwise.
 */
gboolean
gst_codec_utils_mpeg4video_caps_set_level_and_profile (GstCaps * caps,
    const guint8 * vis_obj_seq, guint len)
{
  const gchar *profile, *level;

  g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
  g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), FALSE);
  g_return_val_if_fail (vis_obj_seq != NULL, FALSE);

  profile = gst_codec_utils_mpeg4video_get_profile (vis_obj_seq, len);

  if (profile != NULL)
    gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);

  level = gst_codec_utils_mpeg4video_get_level (vis_obj_seq, len);

  if (level != NULL)
    gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);

  GST_LOG ("profile : %s", (profile) ? profile : "---");
  GST_LOG ("level   : %s", (level) ? level : "---");

  return (profile != NULL && level != NULL);
}

/**
 * gst_codec_utils_opus_parse_caps:
 * @caps: the #GstCaps to parse the data from
 * @rate: (out): the sample rate
 * @channels: (out): the number of channels
 * @channel_mapping_family: (out): the channel mapping family
 * @stream_count: (out): the number of independent streams
 * @coupled_count: (out): the number of stereo streams
 * @channel_mapping: (out) (array fixed-size=256): the mapping between the streams
 *
 * Parses Opus caps and fills the different fields with defaults if possible.
 *
 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
 *
 * Since: 1.8
 */
gboolean
gst_codec_utils_opus_parse_caps (GstCaps * caps,
    guint32 * rate,
    guint8 * channels,
    guint8 * channel_mapping_family,
    guint8 * stream_count, guint8 * coupled_count, guint8 channel_mapping[256])
{
  GstStructure *s;
  gint c, f, sc, cc;
  const GValue *va, *v;

  g_return_val_if_fail (caps != NULL, FALSE);
  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
  g_return_val_if_fail (!gst_caps_is_empty (caps), FALSE);

  s = gst_caps_get_structure (caps, 0);

  g_return_val_if_fail (gst_structure_has_name (s, "audio/x-opus"), FALSE);
  g_return_val_if_fail (gst_structure_has_field_typed (s,
          "channel-mapping-family", G_TYPE_INT), FALSE);

  if (rate) {
    gint r;

    if (gst_structure_get_int (s, "rate", &r))
      *rate = r;
    else
      *rate = 48000;
  }

  gst_structure_get_int (s, "channel-mapping-family", &f);
  if (channel_mapping_family)
    *channel_mapping_family = f;

  if (!gst_structure_get_int (s, "channels", &c)) {
    if (f == 0)
      c = 2;
    else
      return FALSE;
  }

  if (channels)
    *channels = c;

  /* RTP mapping */
  if (f == 0) {
    if (c > 2)
      return FALSE;

    if (stream_count)
      *stream_count = 1;
    if (coupled_count)
      *coupled_count = c == 2 ? 1 : 0;

    if (channel_mapping) {
      channel_mapping[0] = 0;
      channel_mapping[1] = 1;
    }

    return TRUE;
  }

  if (!gst_structure_get_int (s, "stream-count", &sc))
    return FALSE;
  if (stream_count)
    *stream_count = sc;

  if (!gst_structure_get_int (s, "coupled-count", &cc))
    return FALSE;
  if (coupled_count)
    *coupled_count = cc;

  va = gst_structure_get_value (s, "channel-mapping");
  if (!va || !G_VALUE_HOLDS (va, GST_TYPE_ARRAY))
    return FALSE;

  if (gst_value_array_get_size (va) != c)
    return FALSE;

  if (channel_mapping) {
    gint i;

    for (i = 0; i < c; i++) {
      gint cm;

      v = gst_value_array_get_value (va, i);

      if (!G_VALUE_HOLDS (v, G_TYPE_INT))
        return FALSE;

      cm = g_value_get_int (v);
      if (cm < 0 || cm > 255)
        return FALSE;

      channel_mapping[i] = cm;
    }
  }

  return TRUE;
}

/**
 * gst_codec_utils_opus_create_caps:
 * @rate: the sample rate
 * @channels: the number of channels
 * @channel_mapping_family: the channel mapping family
 * @stream_count: the number of independent streams
 * @coupled_count: the number of stereo streams
 * @channel_mapping: (allow-none) (array): the mapping between the streams
 *
 * Creates Opus caps from the given parameters.
 *
 * Returns: The #GstCaps, or %NULL if the parameters would lead to
 * invalid Opus caps.
 *
 * Since: 1.8
 */
GstCaps *
gst_codec_utils_opus_create_caps (guint32 rate,
    guint8 channels,
    guint8 channel_mapping_family,
    guint8 stream_count, guint8 coupled_count, const guint8 * channel_mapping)
{
  GstCaps *caps = NULL;
  GValue va = G_VALUE_INIT;
  GValue v = G_VALUE_INIT;
  gint i;

  if (rate == 0)
    rate = 48000;

  if (channel_mapping_family == 0) {
    if (channels > 2) {
      GST_ERROR ("Invalid channels count for channel_mapping_family 0: %d",
          channels);
      goto done;
    }

    if (stream_count > 1) {
      GST_ERROR ("Invalid stream count for channel_mapping_family 0: %d",
          stream_count);
      goto done;
    }

    if (coupled_count > 1) {
      GST_ERROR ("Invalid coupled count for channel_mapping_family 0: %d",
          coupled_count);
      goto done;
    }

    if (channels == 0)
      channels = 2;

    if (stream_count == 0)
      stream_count = 1;

    if (coupled_count == 0)
      coupled_count = channels == 2 ? 1 : 0;

    return gst_caps_new_simple ("audio/x-opus",
        "rate", G_TYPE_INT, rate,
        "channels", G_TYPE_INT, channels,
        "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
        "stream-count", G_TYPE_INT, stream_count,
        "coupled-count", G_TYPE_INT, coupled_count, NULL);
  }

  if (channels == 0) {
    GST_ERROR ("Invalid channels count: %d", channels);
    goto done;
  }

  if (stream_count == 0) {
    GST_ERROR ("Invalid stream count: %d", stream_count);
    goto done;
  }

  if (coupled_count > stream_count) {
    GST_ERROR ("Coupled count %d > stream count: %d", coupled_count,
        stream_count);
    goto done;
  }

  if (channel_mapping == NULL) {
    GST_ERROR
        ("A non NULL channel-mapping is needed for channel_mapping_family != 0");
    goto done;
  }

  caps = gst_caps_new_simple ("audio/x-opus",
      "rate", G_TYPE_INT, rate,
      "channels", G_TYPE_INT, channels,
      "channel-mapping-family", G_TYPE_INT, channel_mapping_family,
      "stream-count", G_TYPE_INT, stream_count,
      "coupled-count", G_TYPE_INT, coupled_count, NULL);

  g_value_init (&va, GST_TYPE_ARRAY);
  g_value_init (&v, G_TYPE_INT);
  for (i = 0; i < channels; i++) {
    g_value_set_int (&v, channel_mapping[i]);
    gst_value_array_append_value (&va, &v);
  }
  gst_structure_set_value (gst_caps_get_structure (caps, 0), "channel-mapping",
      &va);
  g_value_unset (&va);
  g_value_unset (&v);

done:
  return caps;
}

/*
 * (really really) FIXME: move into core (dixit tpm)
 */
/*
 * _gst_caps_set_buffer_array:
 * @caps: (transfer full): a #GstCaps
 * @field: field in caps to set
 * @buf: header buffers
 *
 * Adds given buffers to an array of buffers set as the given @field
 * on the given @caps.  List of buffer arguments must be NULL-terminated.
 *
 * Returns: (transfer full): input caps with a streamheader field added, or NULL
 *     if some error occurred
 */
static GstCaps *
_gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
    GstBuffer * buf, ...)
{
  GstStructure *structure = NULL;
  va_list va;
  GValue array = { 0 };
  GValue value = { 0 };

  g_return_val_if_fail (caps != NULL, NULL);
  g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
  g_return_val_if_fail (field != NULL, NULL);

  caps = gst_caps_make_writable (caps);
  structure = gst_caps_get_structure (caps, 0);

  g_value_init (&array, GST_TYPE_ARRAY);

  va_start (va, buf);
  /* put buffers in a fixed list */
  while (buf) {
    g_assert (gst_buffer_is_writable (buf));

    /* mark buffer */
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);

    g_value_init (&value, GST_TYPE_BUFFER);
    buf = gst_buffer_copy (buf);
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
    gst_value_set_buffer (&value, buf);
    gst_buffer_unref (buf);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);

    buf = va_arg (va, GstBuffer *);
  }
  va_end (va);

  gst_structure_set_value (structure, field, &array);
  g_value_unset (&array);

  return caps;
}

/**
 * gst_codec_utils_opus_create_caps_from_header:
 * @header: OpusHead header
 * @comments: (allow-none): Comment header or NULL
 *
 * Creates Opus caps from the given OpusHead @header and comment header
 * @comments.
 *
 * Returns: The #GstCaps.
 *
 * Since: 1.8
 */
GstCaps *
gst_codec_utils_opus_create_caps_from_header (GstBuffer * header,
    GstBuffer * comments)
{
  GstCaps *caps;
  guint32 rate;
  guint8 channels;
  guint8 channel_mapping_family;
  guint8 stream_count;
  guint8 coupled_count;
  guint8 channel_mapping[256];
  GstBuffer *dummy_comments = NULL;

  g_return_val_if_fail (GST_IS_BUFFER (header), NULL);
  g_return_val_if_fail (comments == NULL || GST_IS_BUFFER (comments), NULL);

  if (!gst_codec_utils_opus_parse_header (header, &rate, &channels,
          &channel_mapping_family, &stream_count, &coupled_count,
          channel_mapping, NULL, NULL))
    return NULL;

  if (!(caps =
          gst_codec_utils_opus_create_caps (rate, channels,
              channel_mapping_family, stream_count, coupled_count,
              channel_mapping)))
    return NULL;

  if (!comments) {
    GstTagList *tags = gst_tag_list_new_empty ();
    dummy_comments =
        gst_tag_list_to_vorbiscomment_buffer (tags, (const guint8 *) "OpusTags",
        8, NULL);
    gst_tag_list_unref (tags);
  }
  _gst_caps_set_buffer_array (caps, "streamheader", header,
      comments ? comments : dummy_comments, NULL);

  if (dummy_comments)
    gst_buffer_unref (dummy_comments);

  return caps;
}

/**
 * gst_codec_utils_opus_create_header:
 * @rate: the sample rate
 * @channels: the number of channels
 * @channel_mapping_family: the channel mapping family
 * @stream_count: the number of independent streams
 * @coupled_count: the number of stereo streams
 * @channel_mapping: (allow-none) (array): the mapping between the streams
 * @pre_skip: Pre-skip in 48kHz samples or 0
 * @output_gain: Output gain or 0
 *
 * Creates OpusHead header from the given parameters.
 *
 * Returns: The #GstBuffer containing the OpusHead.
 *
 * Since: 1.8
 */
GstBuffer *
gst_codec_utils_opus_create_header (guint32 rate,
    guint8 channels,
    guint8 channel_mapping_family,
    guint8 stream_count,
    guint8 coupled_count,
    const guint8 * channel_mapping, guint16 pre_skip, gint16 output_gain)
{
  GstBuffer *buffer;
  GstByteWriter bw;
  gboolean hdl = TRUE;

  if (rate == 0)
    rate = 48000;

  if (channel_mapping_family == 0) {
    g_return_val_if_fail (channels <= 2, NULL);
    if (channels == 0)
      channels = 2;

    g_return_val_if_fail (stream_count == 0 || stream_count == 1, NULL);
    if (stream_count == 0)
      stream_count = 1;

    g_return_val_if_fail (coupled_count == 0 || coupled_count == 1, NULL);
    if (coupled_count == 0)
      coupled_count = channels == 2 ? 1 : 0;

    channel_mapping = NULL;
  } else {
    g_return_val_if_fail (channels > 0, NULL);
    g_return_val_if_fail (stream_count > 0, NULL);
    g_return_val_if_fail (coupled_count <= stream_count, NULL);
    g_return_val_if_fail (channel_mapping != NULL, NULL);
  }

  gst_byte_writer_init (&bw);
  /* See http://wiki.xiph.org/OggOpus */
  hdl &= gst_byte_writer_put_data (&bw, (const guint8 *) "OpusHead", 8);
  hdl &= gst_byte_writer_put_uint8 (&bw, 0x01); /* version number */
  hdl &= gst_byte_writer_put_uint8 (&bw, channels);
  hdl &= gst_byte_writer_put_uint16_le (&bw, pre_skip);
  hdl &= gst_byte_writer_put_uint32_le (&bw, rate);
  hdl &= gst_byte_writer_put_uint16_le (&bw, output_gain);
  hdl &= gst_byte_writer_put_uint8 (&bw, channel_mapping_family);
  if (channel_mapping_family > 0) {
    hdl &= gst_byte_writer_put_uint8 (&bw, stream_count);
    hdl &= gst_byte_writer_put_uint8 (&bw, coupled_count);
    hdl &= gst_byte_writer_put_data (&bw, channel_mapping, channels);
  }

  if (!hdl) {
    GST_WARNING ("Error creating header");
    return NULL;
  }

  buffer = gst_byte_writer_reset_and_get_buffer (&bw);
  GST_BUFFER_OFFSET (buffer) = 0;
  GST_BUFFER_OFFSET_END (buffer) = 0;

  return buffer;
}

/**
 * gst_codec_utils_opus_parse_header:
 * @header: the OpusHead #GstBuffer
 * @rate: (out): the sample rate
 * @channels: (out): the number of channels
 * @channel_mapping_family: (out): the channel mapping family
 * @stream_count: (out): the number of independent streams
 * @coupled_count: (out): the number of stereo streams
 * @channel_mapping: (out) (array fixed-size=256): the mapping between the streams
 * @pre_skip: (out): Pre-skip in 48kHz samples or 0
 * @output_gain: (out): Output gain or 0
 *
 * Parses the OpusHead header.
 *
 * Returns: %TRUE if parsing was successful, %FALSE otherwise.
 *
 * Since: 1.8
 */
gboolean
gst_codec_utils_opus_parse_header (GstBuffer * header,
    guint32 * rate,
    guint8 * channels,
    guint8 * channel_mapping_family,
    guint8 * stream_count,
    guint8 * coupled_count,
    guint8 channel_mapping[256], guint16 * pre_skip, gint16 * output_gain)
{
  GstByteReader br;
  GstMapInfo map;
  gboolean ret = TRUE;
  guint8 c, f, version;

  g_return_val_if_fail (GST_IS_BUFFER (header), FALSE);
  g_return_val_if_fail (gst_buffer_get_size (header) >= 19, FALSE);

  if (!gst_buffer_map (header, &map, GST_MAP_READ))
    return FALSE;
  gst_byte_reader_init (&br, map.data, map.size);
  /* See http://wiki.xiph.org/OggOpus */
  if (memcmp (gst_byte_reader_get_data_unchecked (&br, 8), "OpusHead", 8) != 0) {
    ret = FALSE;
    goto done;
  }
  version = gst_byte_reader_get_uint8_unchecked (&br);
  if (version == 0x00)
    GST_ERROR ("Opus Header version is wrong, should be 0x01 and not 0x00");
  else if (version != 0x01) {
    ret = FALSE;
    goto done;
  }

  c = gst_byte_reader_get_uint8_unchecked (&br);
  if (channels)
    *channels = c;

  if (pre_skip)
    *pre_skip = gst_byte_reader_get_uint16_le_unchecked (&br);
  else
    gst_byte_reader_skip_unchecked (&br, 2);

  if (rate)
    *rate = gst_byte_reader_get_uint32_le_unchecked (&br);
  else
    gst_byte_reader_skip_unchecked (&br, 4);

  if (output_gain)
    *output_gain = gst_byte_reader_get_uint16_le_unchecked (&br);
  else
    gst_byte_reader_skip_unchecked (&br, 2);

  f = gst_byte_reader_get_uint8_unchecked (&br);
  if (channel_mapping_family)
    *channel_mapping_family = f;
  if (f == 0 && c <= 2) {
    if (stream_count)
      *stream_count = 1;
    if (coupled_count)
      *coupled_count = c == 2 ? 1 : 0;
    if (channel_mapping) {
      channel_mapping[0] = 0;
      channel_mapping[1] = 1;
    }

    goto done;
  }

  if (gst_byte_reader_get_remaining (&br) < 2 + c) {
    ret = FALSE;
    goto done;
  }

  if (stream_count)
    *stream_count = gst_byte_reader_get_uint8_unchecked (&br);
  else
    gst_byte_reader_skip_unchecked (&br, 1);

  if (coupled_count)
    *coupled_count = gst_byte_reader_get_uint8_unchecked (&br);
  else
    gst_byte_reader_skip_unchecked (&br, 1);

  if (channel_mapping)
    memcpy (channel_mapping, gst_byte_reader_get_data_unchecked (&br, c), c);

done:
  gst_buffer_unmap (header, &map);

  return ret;
}
