/* Gstreamer H.265 bitstream parser
 * Copyright (C) 2012 Intel Corporation
 * Copyright (C) 2013 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
 *
 *  Contact: Sreerenj Balachandran <sreerenj.balachandran@intel.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:gsth265parser
 * @short_description: Convenience library for h265 video bitstream parsing.
 *
 * It offers you bitstream parsing in HEVC mode and non-HEVC mode. To identify
 * Nals in a bitstream and parse its headers, you should call:
 * <itemizedlist>
 *   <listitem>
 *      gst_h265_parser_identify_nalu() to identify the following nalu in
 *        non-HEVC bitstreams
 *   </listitem>
 *   <listitem>
 *      gst_h265_parser_identify_nalu_hevc() to identify the nalu in
 *        HEVC bitstreams
 *   </listitem>
 * </itemizedlist>
 *
 * Then, depending on the #GstH265NalUnitType of the newly parsed #GstH265NalUnit,
 * you should call the differents functions to parse the structure:
 * <itemizedlist>
 *   <listitem>
 *      From #GST_H265_NAL_SLICE_TRAIL_N to #GST_H265_NAL_SLICE_CRA_NUT: gst_h265_parser_parse_slice_hdr()
 *   </listitem>
 *   <listitem>
 *      #GST_H265_NAL_SEI: gst_h265_parser_parse_sei()
 *   </listitem>
 *   <listitem>
 *      #GST_H265_NAL_VPS: gst_h265_parser_parse_vps()
 *   </listitem>
 *   <listitem>
 *      #GST_H265_NAL_SPS: gst_h265_parser_parse_sps()
 *   </listitem>
 *   <listitem>
 *      #GST_H265_NAL_PPS: #gst_h265_parser_parse_pps()
 *   </listitem>
 *   <listitem>
 *      Any other: gst_h265_parser_parse_nal()
 *   </listitem>
 * </itemizedlist>
 *
 * Note: You should always call gst_h265_parser_parse_nal() if you don't
 * actually need #GstH265NalUnitType to be parsed for your personal use, in
 * order to guarantee that the #GstH265Parser is always up to date.
 *
 * For more details about the structures, look at the ITU-T H.265
 * specifications, you can download them from:
 *
 * <itemizedlist>
 *   <listitem>
 *     ITU-T H.265: http://www.itu.int/rec/T-REC-H.265
 *   </listitem>
 * </itemizedlist>
 */

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

#include "nalutils.h"
#include "gsth265parser.h"

#include <gst/base/gstbytereader.h>
#include <gst/base/gstbitreader.h>
#include <string.h>
#include <math.h>

GST_DEBUG_CATEGORY (h265_parser_debug);
#define GST_CAT_DEFAULT h265_parser_debug

static gboolean initialized = FALSE;
#define INITIALIZE_DEBUG_CATEGORY \
  if (!initialized) { \
    GST_DEBUG_CATEGORY_INIT (h265_parser_debug, "codecparsers_h265", 0, \
        "h265 parser library"); \
    initialized = TRUE; \
  }

/**** Default scaling_lists according to Table 7-5 and 7-6 *****/

/* Table 7-5 */
static const guint8 default_scaling_list0[16] = {
  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  16, 16, 16, 16
};

/*  Combined the values in Table  7-6 to make the calculation easier
 *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 0, 1 and 2
 *  Default scaling list of 32x32 matrix for matrixId = 0
 */
static const guint8 default_scaling_list1[64] = {
  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16,
  17, 16, 17, 18, 17, 18, 18, 17, 18, 21, 19, 20,
  21, 20, 19, 21, 24, 22, 22, 24, 24, 22, 22, 24,
  25, 25, 27, 30, 27, 25, 25, 29, 31, 35, 35, 31,
  29, 36, 41, 44, 41, 36, 47, 54, 54, 47, 65, 70,
  65, 88, 88, 115
};

/*  Combined the values in Table 7-6 to make the calculation easier
 *  Default scaling list of 8x8 and 16x16 matrices for matrixId = 3, 4 and 5
 *  Default scaling list of 32x32 matrix for matrixId = 1
 */
static const guint8 default_scaling_list2[64] = {
  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17,
  17, 17, 17, 18, 18, 18, 18, 18, 18, 20, 20, 20,
  20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24,
  25, 25, 25, 25, 25, 25, 25, 28, 28, 28, 28, 28,
  28, 33, 33, 33, 33, 33, 41, 41, 41, 41, 54, 54,
  54, 71, 71, 91
};

static const guint8 zigzag_4x4[16] = {
  0, 1, 4, 8,
  5, 2, 3, 6,
  9, 12, 13, 10,
  7, 11, 14, 15,
};

static const guint8 zigzag_8x8[64] = {
  0, 1, 8, 16, 9, 2, 3, 10,
  17, 24, 32, 25, 18, 11, 4, 5,
  12, 19, 26, 33, 40, 48, 41, 34,
  27, 20, 13, 6, 7, 14, 21, 28,
  35, 42, 49, 56, 57, 50, 43, 36,
  29, 22, 15, 23, 30, 37, 44, 51,
  58, 59, 52, 45, 38, 31, 39, 46,
  53, 60, 61, 54, 47, 55, 62, 63
};

static const guint8 uprightdiagonal_4x4[16] = {
  0, 4, 1, 8,
  5, 2, 12, 9,
  6, 3, 13, 10,
  7, 14, 11, 15
};

static const guint8 uprightdiagonal_8x8[64] = {
  0, 8, 1, 16, 9, 2, 24, 17,
  10, 3, 32, 25, 18, 11, 4, 40,
  33, 26, 19, 12, 5, 48, 41, 34,
  27, 20, 13, 6, 56, 49, 42, 35,
  28, 21, 14, 7, 57, 50, 43, 36,
  29, 22, 15, 58, 51, 44, 37, 30,
  23, 59, 52, 45, 38, 31, 60, 53,
  46, 39, 61, 54, 47, 62, 55, 63
};

typedef struct
{
  guint par_n, par_d;
} PAR;

/* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
static const PAR aspect_ratios[17] = {
  {0, 0},
  {1, 1},
  {12, 11},
  {10, 11},
  {16, 11},
  {40, 33},
  {24, 11},
  {20, 11},
  {32, 11},
  {80, 33},
  {18, 11},
  {15, 11},
  {64, 33},
  {160, 99},
  {4, 3},
  {3, 2},
  {2, 1}
};

/*****  Utils ****/
#define EXTENDED_SAR 255

static GstH265VPS *
gst_h265_parser_get_vps (GstH265Parser * parser, guint8 vps_id)
{
  GstH265VPS *vps;

  vps = &parser->vps[vps_id];

  if (vps->valid)
    return vps;

  return NULL;
}

static GstH265SPS *
gst_h265_parser_get_sps (GstH265Parser * parser, guint8 sps_id)
{
  GstH265SPS *sps;

  sps = &parser->sps[sps_id];

  if (sps->valid)
    return sps;

  return NULL;
}

static GstH265PPS *
gst_h265_parser_get_pps (GstH265Parser * parser, guint8 pps_id)
{
  GstH265PPS *pps;

  pps = &parser->pps[pps_id];

  if (pps->valid)
    return pps;

  return NULL;
}

static gboolean
gst_h265_parse_nalu_header (GstH265NalUnit * nalu)
{
  guint8 *data = nalu->data + nalu->offset;
  GstBitReader br;

  if (nalu->size < 2)
    return FALSE;

  gst_bit_reader_init (&br, data, nalu->size - nalu->offset);

  /* skip the forbidden_zero_bit */
  gst_bit_reader_skip_unchecked (&br, 1);

  nalu->type = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
  nalu->layer_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
  nalu->temporal_id_plus1 = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
  nalu->header_bytes = 2;

  return TRUE;
}

/****** Parsing functions *****/

static gboolean
gst_h265_parse_profile_tier_level (GstH265ProfileTierLevel * ptl,
    NalReader * nr, guint8 maxNumSubLayersMinus1)
{
  guint i, j;
  GST_DEBUG ("parsing \"ProfileTierLevel parameters\"");

  /* set default values for fields that might not be present in the
   * bitstream and have valid defaults */
  for (i = 0; i < maxNumSubLayersMinus1; i++)
    ptl->sub_layer_tier_flag[i] = 0;

  READ_UINT8 (nr, ptl->profile_space, 2);
  READ_UINT8 (nr, ptl->tier_flag, 1);
  READ_UINT8 (nr, ptl->profile_idc, 5);

  for (j = 0; j < 32; j++)
    READ_UINT8 (nr, ptl->profile_compatibility_flag[j], 1);

  READ_UINT8 (nr, ptl->progressive_source_flag, 1);
  READ_UINT8 (nr, ptl->interlaced_source_flag, 1);
  READ_UINT8 (nr, ptl->non_packed_constraint_flag, 1);
  READ_UINT8 (nr, ptl->frame_only_constraint_flag, 1);

  /* skip the reserved zero bits */
  if (!nal_reader_skip (nr, 44))
    goto error;

  READ_UINT8 (nr, ptl->level_idc, 8);
  for (j = 0; j < maxNumSubLayersMinus1; j++) {
    READ_UINT8 (nr, ptl->sub_layer_profile_present_flag[j], 1);
    READ_UINT8 (nr, ptl->sub_layer_level_present_flag[j], 1);
  }

  if (maxNumSubLayersMinus1 > 0) {
    for (i = maxNumSubLayersMinus1; i < 8; i++)
      if (!nal_reader_skip (nr, 2))
        goto error;
  }

  for (i = 0; i < maxNumSubLayersMinus1; i++) {
    if (ptl->sub_layer_profile_present_flag[i]) {
      READ_UINT8 (nr, ptl->sub_layer_profile_space[i], 2);
      READ_UINT8 (nr, ptl->sub_layer_tier_flag[i], 1);
      READ_UINT8 (nr, ptl->sub_layer_profile_idc[i], 5);

      for (j = 0; j < 32; j++)
        READ_UINT8 (nr, ptl->sub_layer_profile_compatibility_flag[i][j], 1);

      READ_UINT8 (nr, ptl->sub_layer_progressive_source_flag[i], 1);
      READ_UINT8 (nr, ptl->sub_layer_interlaced_source_flag[i], 1);
      READ_UINT8 (nr, ptl->sub_layer_non_packed_constraint_flag[i], 1);
      READ_UINT8 (nr, ptl->sub_layer_frame_only_constraint_flag[i], 1);

      if (!nal_reader_skip (nr, 44))
        goto error;
    }

    if (ptl->sub_layer_level_present_flag[i])
      READ_UINT8 (nr, ptl->sub_layer_level_idc[i], 8);
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"ProfileTierLevel Parameters\"");
  return FALSE;
}

static gboolean
gst_h265_parse_sub_layer_hrd_parameters (GstH265SubLayerHRDParams * sub_hrd,
    NalReader * nr, guint8 CpbCnt, guint8 sub_pic_hrd_params_present_flag)
{
  guint i;

  GST_DEBUG ("parsing \"SubLayer HRD Parameters\"");

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  for (i = 0; i <= CpbCnt; i++)
    sub_hrd->cbr_flag[i] = 0;

  for (i = 0; i <= CpbCnt; i++) {
    READ_UE_MAX (nr, sub_hrd->bit_rate_value_minus1[i], G_MAXUINT32 - 1);
    READ_UE_MAX (nr, sub_hrd->cpb_size_value_minus1[i], G_MAXUINT32 - 1);

    if (sub_pic_hrd_params_present_flag) {
      READ_UE_MAX (nr, sub_hrd->cpb_size_du_value_minus1[i], G_MAXUINT32 - 1);
      READ_UE_MAX (nr, sub_hrd->bit_rate_du_value_minus1[i], G_MAXUINT32 - 1);
    }

    READ_UINT8 (nr, sub_hrd->cbr_flag[i], 1);
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"SubLayerHRD Parameters \"");
  return FALSE;
}

static gboolean
gst_h265_parse_hrd_parameters (GstH265HRDParams * hrd, NalReader * nr,
    guint8 commonInfPresentFlag, guint8 maxNumSubLayersMinus1)
{
  guint i;

  GST_DEBUG ("parsing \"HRD Parameters\"");

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  hrd->sub_pic_hrd_params_present_flag = 0;
  hrd->sub_pic_cpb_params_in_pic_timing_sei_flag = 0;
  hrd->initial_cpb_removal_delay_length_minus1 = 23;
  hrd->au_cpb_removal_delay_length_minus1 = 23;
  hrd->dpb_output_delay_length_minus1 = 23;
  for (i = 0; i <= maxNumSubLayersMinus1; i++) {
    hrd->fixed_pic_rate_general_flag[i] = 0;
    hrd->low_delay_hrd_flag[i] = 0;
    hrd->cpb_cnt_minus1[i] = 0;
  }

  if (commonInfPresentFlag) {
    READ_UINT8 (nr, hrd->nal_hrd_parameters_present_flag, 1);
    READ_UINT8 (nr, hrd->vcl_hrd_parameters_present_flag, 1);

    if (hrd->nal_hrd_parameters_present_flag
        || hrd->vcl_hrd_parameters_present_flag) {

      READ_UINT8 (nr, hrd->sub_pic_hrd_params_present_flag, 1);

      if (hrd->sub_pic_hrd_params_present_flag) {
        READ_UINT8 (nr, hrd->tick_divisor_minus2, 8);
        READ_UINT8 (nr, hrd->du_cpb_removal_delay_increment_length_minus1, 5);
        READ_UINT8 (nr, hrd->sub_pic_cpb_params_in_pic_timing_sei_flag, 1);
        READ_UINT8 (nr, hrd->dpb_output_delay_du_length_minus1, 5);
      }

      READ_UINT8 (nr, hrd->bit_rate_scale, 4);
      READ_UINT8 (nr, hrd->cpb_size_scale, 4);

      if (hrd->sub_pic_hrd_params_present_flag)
        READ_UINT8 (nr, hrd->cpb_size_du_scale, 4);

      READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
      READ_UINT8 (nr, hrd->au_cpb_removal_delay_length_minus1, 5);
      READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
    }
  }

  for (i = 0; i <= maxNumSubLayersMinus1; i++) {
    READ_UINT8 (nr, hrd->fixed_pic_rate_general_flag[i], 1);

    if (!hrd->fixed_pic_rate_general_flag[i]) {
      READ_UINT8 (nr, hrd->fixed_pic_rate_within_cvs_flag[i], 1);
    } else
      hrd->fixed_pic_rate_within_cvs_flag[i] = 1;

    if (hrd->fixed_pic_rate_within_cvs_flag[i]) {
      READ_UE_MAX (nr, hrd->elemental_duration_in_tc_minus1[i], 2047);
    } else
      READ_UINT8 (nr, hrd->low_delay_hrd_flag[i], 1);

    if (!hrd->low_delay_hrd_flag[i])
      READ_UE_MAX (nr, hrd->cpb_cnt_minus1[i], 31);

    if (hrd->nal_hrd_parameters_present_flag)
      if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
              [i], nr, hrd->cpb_cnt_minus1[i],
              hrd->sub_pic_hrd_params_present_flag))
        goto error;

    if (hrd->vcl_hrd_parameters_present_flag)
      if (!gst_h265_parse_sub_layer_hrd_parameters (&hrd->sublayer_hrd_params
              [i], nr, hrd->cpb_cnt_minus1[i],
              hrd->sub_pic_hrd_params_present_flag))
        goto error;
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"HRD Parameters\"");
  return FALSE;
}

static gboolean
gst_h265_parse_vui_parameters (GstH265SPS * sps, NalReader * nr)
{
  GstH265VUIParams *vui = &sps->vui_params;

  GST_DEBUG ("parsing \"VUI Parameters\"");

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  vui->aspect_ratio_idc = 0;
  vui->video_format = 5;
  vui->video_full_range_flag = 0;
  vui->colour_primaries = 2;
  vui->transfer_characteristics = 2;
  vui->matrix_coefficients = 2;
  vui->chroma_sample_loc_type_top_field = 0;
  vui->chroma_sample_loc_type_bottom_field = 0;
  vui->neutral_chroma_indication_flag = 0;
  vui->field_seq_flag = 0;
  vui->def_disp_win_left_offset = 0;
  vui->def_disp_win_right_offset = 0;
  vui->def_disp_win_top_offset = 0;
  vui->def_disp_win_bottom_offset = 0;
  vui->tiles_fixed_structure_flag = 0;
  vui->motion_vectors_over_pic_boundaries_flag = 1;
  vui->min_spatial_segmentation_idc = 0;
  vui->max_bytes_per_pic_denom = 2;
  vui->max_bits_per_min_cu_denom = 1;
  vui->log2_max_mv_length_horizontal = 15;
  vui->log2_max_mv_length_vertical = 15;
  vui->par_n = 0;
  vui->par_d = 0;

  if (sps && sps->profile_tier_level.progressive_source_flag
      && sps->profile_tier_level.interlaced_source_flag)
    vui->frame_field_info_present_flag = 1;
  else
    vui->frame_field_info_present_flag = 0;

  READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
  if (vui->aspect_ratio_info_present_flag) {
    READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
    if (vui->aspect_ratio_idc == EXTENDED_SAR) {
      READ_UINT16 (nr, vui->sar_width, 16);
      READ_UINT16 (nr, vui->sar_height, 16);
      vui->par_n = vui->sar_width;
      vui->par_d = vui->sar_height;
    } else if (vui->aspect_ratio_idc <= 16) {
      vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
      vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
    }
  }

  READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
  if (vui->overscan_info_present_flag)
    READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);

  READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
  if (vui->video_signal_type_present_flag) {

    READ_UINT8 (nr, vui->video_format, 3);
    READ_UINT8 (nr, vui->video_full_range_flag, 1);
    READ_UINT8 (nr, vui->colour_description_present_flag, 1);
    if (vui->colour_description_present_flag) {
      READ_UINT8 (nr, vui->colour_primaries, 8);
      READ_UINT8 (nr, vui->transfer_characteristics, 8);
      READ_UINT8 (nr, vui->matrix_coefficients, 8);
    }
  }

  READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
  if (vui->chroma_loc_info_present_flag) {
    READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
    READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
  }

  READ_UINT8 (nr, vui->neutral_chroma_indication_flag, 1);
  READ_UINT8 (nr, vui->field_seq_flag, 1);
  READ_UINT8 (nr, vui->frame_field_info_present_flag, 1);

  READ_UINT8 (nr, vui->default_display_window_flag, 1);
  if (vui->default_display_window_flag) {
    READ_UE (nr, vui->def_disp_win_left_offset);
    READ_UE (nr, vui->def_disp_win_right_offset);
    READ_UE (nr, vui->def_disp_win_top_offset);
    READ_UE (nr, vui->def_disp_win_bottom_offset);
  }

  READ_UINT8 (nr, vui->timing_info_present_flag, 1);
  if (vui->timing_info_present_flag) {
    READ_UINT32 (nr, vui->num_units_in_tick, 32);
    if (vui->num_units_in_tick == 0)
      GST_WARNING ("num_units_in_tick = 0 detected in stream "
          "(incompliant to H.265 E.2.1).");

    READ_UINT32 (nr, vui->time_scale, 32);
    if (vui->time_scale == 0)
      GST_WARNING ("time_scale = 0 detected in stream "
          "(incompliant to H.265 E.2.1).");

    READ_UINT8 (nr, vui->poc_proportional_to_timing_flag, 1);
    if (vui->poc_proportional_to_timing_flag)
      READ_UE_MAX (nr, vui->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);

    READ_UINT8 (nr, vui->hrd_parameters_present_flag, 1);
    if (vui->hrd_parameters_present_flag)
      if (!gst_h265_parse_hrd_parameters (&vui->hrd_params, nr, 1,
              sps->max_sub_layers_minus1))
        goto error;
  }

  READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
  if (vui->bitstream_restriction_flag) {
    READ_UINT8 (nr, vui->tiles_fixed_structure_flag, 1);
    READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
    READ_UINT8 (nr, vui->restricted_ref_pic_lists_flag, 1);
    READ_UE_MAX (nr, vui->min_spatial_segmentation_idc, 4096);
    READ_UE_MAX (nr, vui->max_bytes_per_pic_denom, 16);
    READ_UE_MAX (nr, vui->max_bits_per_min_cu_denom, 16);
    READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
    READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 15);
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"VUI Parameters\"");
  return FALSE;
}

static gboolean
get_scaling_list_params (GstH265ScalingList * dest_scaling_list,
    guint8 sizeId, guint8 matrixId, guint8 ** sl, guint8 * size,
    gint16 ** scaling_list_dc_coef_minus8)
{
  switch (sizeId) {
    case GST_H265_QUANT_MATIX_4X4:
      *sl = dest_scaling_list->scaling_lists_4x4[matrixId];
      if (size)
        *size = 16;
      break;
    case GST_H265_QUANT_MATIX_8X8:
      *sl = dest_scaling_list->scaling_lists_8x8[matrixId];
      if (size)
        *size = 64;
      break;
    case GST_H265_QUANT_MATIX_16X16:
      *sl = dest_scaling_list->scaling_lists_16x16[matrixId];
      if (size)
        *size = 64;
      if (scaling_list_dc_coef_minus8)
        *scaling_list_dc_coef_minus8 =
            dest_scaling_list->scaling_list_dc_coef_minus8_16x16;
      break;
    case GST_H265_QUANT_MATIX_32X32:
      *sl = dest_scaling_list->scaling_lists_32x32[matrixId];
      if (size)
        *size = 64;
      if (scaling_list_dc_coef_minus8)
        *scaling_list_dc_coef_minus8 =
            dest_scaling_list->scaling_list_dc_coef_minus8_32x32;
      break;
    default:
      return FALSE;
  }
  return TRUE;
}

static gboolean
get_default_scaling_lists (guint8 ** sl, guint8 sizeId, guint8 matrixId)
{
  switch (sizeId) {
    case GST_H265_QUANT_MATIX_4X4:
      memcpy (*sl, default_scaling_list0, 16);
      break;

    case GST_H265_QUANT_MATIX_8X8:
    case GST_H265_QUANT_MATIX_16X16:
      if (matrixId <= 2)
        memcpy (*sl, default_scaling_list1, 64);
      else
        memcpy (*sl, default_scaling_list2, 64);
      break;

    case GST_H265_QUANT_MATIX_32X32:
      if (matrixId == 0)
        memcpy (*sl, default_scaling_list1, 64);
      else
        memcpy (*sl, default_scaling_list2, 64);
      break;

    default:
      return FALSE;
      break;
  }
  return TRUE;
}

static gboolean
gst_h265_parser_parse_scaling_lists (NalReader * nr,
    GstH265ScalingList * dest_scaling_list, gboolean use_default)
{
  guint8 sizeId;
  guint8 matrixId;
  guint8 scaling_list_pred_mode_flag = 0;
  guint8 scaling_list_pred_matrix_id_delta = 0;
  guint8 size, i;

  GST_DEBUG ("parsing scaling lists");

  for (sizeId = 0; sizeId < 4; sizeId++) {
    for (matrixId = 0; matrixId < ((sizeId == 3) ? 2 : 6); matrixId++) {
      gint16 *scaling_list_dc_coef_minus8 = NULL;
      guint8 *sl;

      if (!get_scaling_list_params (dest_scaling_list, sizeId, matrixId, &sl,
              &size, &scaling_list_dc_coef_minus8))
        goto error;

      /* use_default_scaling_matrices forcefully which means,
       * sps_scaling_list_enabled_flag=TRUE,
       * sps_scaling_list_data_present_flag=FALSE,
       * pps_scaling_list_data_present_falg=FALSE */
      if (use_default) {
        if (!get_default_scaling_lists (&sl, sizeId, matrixId))
          goto error;

        /* Inferring the value of scaling_list_dc_coef_minus8 */
        if (sizeId > 1)
          scaling_list_dc_coef_minus8[matrixId] = 8;

      } else {
        READ_UINT8 (nr, scaling_list_pred_mode_flag, 1);

        if (!scaling_list_pred_mode_flag) {
          guint8 refMatrixId;

          READ_UE_MAX (nr, scaling_list_pred_matrix_id_delta, matrixId);

          if (!scaling_list_pred_matrix_id_delta) {
            if (!get_default_scaling_lists (&sl, sizeId, matrixId))
              goto error;

            /* Inferring the value of scaling_list_dc_coef_minus8 */
            if (sizeId > 1)
              scaling_list_dc_coef_minus8[matrixId] = 8;

          } else {
            guint8 *temp_sl;

            refMatrixId = matrixId - scaling_list_pred_matrix_id_delta; /* 7-30 */

            if (!get_scaling_list_params (dest_scaling_list, sizeId,
                    refMatrixId, &temp_sl, NULL, NULL))
              goto error;

            for (i = 0; i < size; i++)
              sl[i] = temp_sl[i];       /* 7-31 */


            /* Inferring the value of scaling_list_dc_coef_minus8 */
            if (sizeId > 1)
              scaling_list_dc_coef_minus8[matrixId] =
                  scaling_list_dc_coef_minus8[refMatrixId];
          }
        } else {
          guint8 nextCoef = 8;
          gint8 scaling_list_delta_coef;

          if (sizeId > 1) {
            READ_SE_ALLOWED (nr, scaling_list_dc_coef_minus8[matrixId], -7,
                247);
            nextCoef = scaling_list_dc_coef_minus8[matrixId] + 8;
          }

          for (i = 0; i < size; i++) {
            READ_SE_ALLOWED (nr, scaling_list_delta_coef, -128, 127);
            nextCoef = (nextCoef + scaling_list_delta_coef) & 0xff;
            sl[i] = nextCoef;
          }
        }
      }
    }
  }

  return TRUE;

error:
  GST_WARNING ("error parsing scaling lists");
  return FALSE;
}

static gboolean
gst_h265_parser_parse_short_term_ref_pic_sets (GstH265ShortTermRefPicSet *
    stRPS, NalReader * nr, guint8 stRpsIdx, GstH265SPS * sps)
{
  guint8 num_short_term_ref_pic_sets;
  guint8 RefRpsIdx = 0;
  gint16 deltaRps = 0;
  guint8 use_delta_flag[16] = { 0 };
  guint8 used_by_curr_pic_flag[16] = { 0 };
  guint32 delta_poc_s0_minus1[16] = { 0 };
  guint32 delta_poc_s1_minus1[16] = { 0 };
  gint j, i = 0;
  gint dPoc;

  GST_DEBUG ("parsing \"ShortTermRefPicSetParameters\"");

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  stRPS->inter_ref_pic_set_prediction_flag = 0;
  stRPS->delta_idx_minus1 = 0;
  for (j = 0; j < 16; j++)
    use_delta_flag[j] = 1;

  num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;

  if (stRpsIdx != 0)
    READ_UINT8 (nr, stRPS->inter_ref_pic_set_prediction_flag, 1);

  if (stRPS->inter_ref_pic_set_prediction_flag) {
    GstH265ShortTermRefPicSet *RefRPS;

    if (stRpsIdx == num_short_term_ref_pic_sets)
      READ_UE_MAX (nr, stRPS->delta_idx_minus1, stRpsIdx - 1);

    READ_UINT8 (nr, stRPS->delta_rps_sign, 1);
    READ_UE_MAX (nr, stRPS->abs_delta_rps_minus1, 32767);

    RefRpsIdx = stRpsIdx - stRPS->delta_idx_minus1 - 1; /* 7-45 */
    deltaRps = (1 - 2 * stRPS->delta_rps_sign) * (stRPS->abs_delta_rps_minus1 + 1);     /* 7-46 */

    RefRPS = &sps->short_term_ref_pic_set[RefRpsIdx];

    for (j = 0; j <= RefRPS->NumDeltaPocs; j++) {
      READ_UINT8 (nr, used_by_curr_pic_flag[j], 1);
      if (!used_by_curr_pic_flag[j])
        READ_UINT8 (nr, use_delta_flag[j], 1);
    }

    /* 7-47: calcuate NumNegativePics, DeltaPocS0 and UsedByCurrPicS0 */
    i = 0;
    for (j = (RefRPS->NumPositivePics - 1); j >= 0; j--) {
      dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
      if (dPoc < 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
        stRPS->DeltaPocS0[i] = dPoc;
        stRPS->UsedByCurrPicS0[i++] =
            used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
      }
    }
    if (deltaRps < 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
      stRPS->DeltaPocS0[i] = deltaRps;
      stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
    }
    for (j = 0; j < RefRPS->NumNegativePics; j++) {
      dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
      if (dPoc < 0 && use_delta_flag[j]) {
        stRPS->DeltaPocS0[i] = dPoc;
        stRPS->UsedByCurrPicS0[i++] = used_by_curr_pic_flag[j];
      }
    }
    stRPS->NumNegativePics = i;

    /* 7-48: calcuate NumPositivePics, DeltaPocS1 and UsedByCurrPicS1 */
    i = 0;
    for (j = (RefRPS->NumNegativePics - 1); j >= 0; j--) {
      dPoc = RefRPS->DeltaPocS0[j] + deltaRps;
      if (dPoc > 0 && use_delta_flag[j]) {
        stRPS->DeltaPocS1[i] = dPoc;
        stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[j];
      }
    }
    if (deltaRps > 0 && use_delta_flag[RefRPS->NumDeltaPocs]) {
      stRPS->DeltaPocS1[i] = deltaRps;
      stRPS->UsedByCurrPicS1[i++] = used_by_curr_pic_flag[RefRPS->NumDeltaPocs];
    }
    for (j = 0; j < RefRPS->NumPositivePics; j++) {
      dPoc = RefRPS->DeltaPocS1[j] + deltaRps;
      if (dPoc > 0 && use_delta_flag[RefRPS->NumNegativePics + j]) {
        stRPS->DeltaPocS1[i] = dPoc;
        stRPS->UsedByCurrPicS1[i++] =
            used_by_curr_pic_flag[RefRPS->NumNegativePics + j];
      }
    }
    stRPS->NumPositivePics = i;

  } else {
    /* 7-49 */
    READ_UE_MAX (nr, stRPS->NumNegativePics,
        sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1]);

    /* 7-50 */
    READ_UE_MAX (nr, stRPS->NumPositivePics,
        (sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] -
            stRPS->NumNegativePics));

    for (i = 0; i < stRPS->NumNegativePics; i++) {
      READ_UE_MAX (nr, delta_poc_s0_minus1[i], 32767);
      /* 7-51 */
      READ_UINT8 (nr, stRPS->UsedByCurrPicS0[i], 1);

      if (i == 0) {
        /* 7-53 */
        stRPS->DeltaPocS0[i] = -(delta_poc_s0_minus1[i] + 1);
      } else {
        /* 7-55 */
        stRPS->DeltaPocS0[i] =
            stRPS->DeltaPocS0[i - 1] - (delta_poc_s0_minus1[i] + 1);
      }
    }

    for (j = 0; j < stRPS->NumPositivePics; j++) {
      READ_UE_MAX (nr, delta_poc_s1_minus1[j], 32767);

      /* 7-52 */
      READ_UINT8 (nr, stRPS->UsedByCurrPicS1[j], 1);

      if (j == 0) {
        /* 7-54 */
        stRPS->DeltaPocS1[j] = delta_poc_s1_minus1[j] + 1;
      } else {
        /* 7-56 */
        stRPS->DeltaPocS1[j] =
            stRPS->DeltaPocS1[j - 1] + (delta_poc_s1_minus1[j] + 1);
      }
    }

  }

  /* 7-57 */
  stRPS->NumDeltaPocs = stRPS->NumPositivePics + stRPS->NumNegativePics;

  return TRUE;

error:
  GST_WARNING ("error parsing \"ShortTermRefPicSet Parameters\"");
  return FALSE;
}

static gboolean
gst_h265_slice_parse_ref_pic_list_modification (GstH265SliceHdr * slice,
    NalReader * nr, gint NumPocTotalCurr)
{
  guint i;
  GstH265RefPicListModification *rpl_mod = &slice->ref_pic_list_modification;
  const guint n = ceil_log2 (NumPocTotalCurr);

  /* set default values */
  rpl_mod->ref_pic_list_modification_flag_l0 = 0;
  rpl_mod->ref_pic_list_modification_flag_l1 = 0;
  for (i = 0; i < slice->num_ref_idx_l0_active_minus1; i++)
    rpl_mod->list_entry_l0[i] = 0;
  for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
    rpl_mod->list_entry_l1[i] = 0;

  READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l0, 1);

  if (rpl_mod->ref_pic_list_modification_flag_l0) {
    for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
      READ_UINT32 (nr, rpl_mod->list_entry_l0[i], n);
      CHECK_ALLOWED_MAX (rpl_mod->list_entry_l0[i], (NumPocTotalCurr - 1));
    }
  }
  if (GST_H265_IS_B_SLICE (slice)) {
    READ_UINT8 (nr, rpl_mod->ref_pic_list_modification_flag_l1, 1);
    if (rpl_mod->ref_pic_list_modification_flag_l1)
      for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
        READ_UINT32 (nr, rpl_mod->list_entry_l1[i], n);
        CHECK_ALLOWED_MAX (rpl_mod->list_entry_l1[i], (NumPocTotalCurr - 1));
      }
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"Prediction weight table\"");
  return FALSE;
}

static gboolean
gst_h265_slice_parse_pred_weight_table (GstH265SliceHdr * slice, NalReader * nr)
{
  GstH265PredWeightTable *p;
  gint i, j;
  GstH265PPS *pps = slice->pps;
  GstH265SPS *sps = pps->sps;

  GST_DEBUG ("parsing \"Prediction weight table\"");

  p = &slice->pred_weight_table;

  READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);

  /* set default values */
  for (i = 0; i < G_N_ELEMENTS (p->chroma_weight_l0_flag); i++) {
    p->chroma_weight_l0_flag[i] = 0;
    p->luma_offset_l0[i] = 0;
  }

  if (GST_H265_IS_B_SLICE (slice)) {
    for (i = 0; i < G_N_ELEMENTS (p->luma_weight_l1_flag); i++) {
      p->chroma_weight_l1_flag[i] = 0;
      p->luma_offset_l1[i] = 0;
    }
  }

  if (sps->chroma_format_idc != 0) {
    READ_SE_ALLOWED (nr, p->delta_chroma_log2_weight_denom,
        (0 - p->luma_log2_weight_denom), (7 - p->luma_log2_weight_denom));
  }

  for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
    READ_UINT8 (nr, p->luma_weight_l0_flag[i], 1);

  if (sps->chroma_format_idc != 0)
    for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
      READ_UINT8 (nr, p->chroma_weight_l0_flag[i], 1);

  for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
    if (p->luma_weight_l0_flag[i]) {
      READ_SE_ALLOWED (nr, p->delta_luma_weight_l0[i], -128, 127);
      READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
    }
    if (p->chroma_weight_l0_flag[i])
      for (j = 0; j < 2; j++) {
        READ_SE_ALLOWED (nr, p->delta_chroma_weight_l0[i][j], -128, 127);
        READ_SE_ALLOWED (nr, p->delta_chroma_offset_l0[i][j], -512, 511);
      }
  }

  if (GST_H265_IS_B_SLICE (slice)) {
    for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
      READ_UINT8 (nr, p->luma_weight_l1_flag[i], 1);
    if (sps->chroma_format_idc != 0)
      for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
        READ_UINT8 (nr, p->chroma_weight_l1_flag[i], 1);

    for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
      if (p->luma_weight_l1_flag[i]) {
        READ_SE_ALLOWED (nr, p->delta_luma_weight_l1[i], -128, 127);
        READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
      }
      if (p->chroma_weight_l1_flag[i])
        for (j = 0; j < 2; j++) {
          READ_SE_ALLOWED (nr, p->delta_chroma_weight_l1[i][j], -128, 127);
          READ_SE_ALLOWED (nr, p->delta_chroma_offset_l1[i][j], -512, 511);
        }
    }
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"Prediction weight table\"");
  return FALSE;
}

static GstH265ParserResult
gst_h265_parser_parse_buffering_period (GstH265Parser * parser,
    GstH265BufferingPeriod * per, NalReader * nr)
{
  GstH265SPS *sps;
  guint8 sps_id;
  guint i;
  guint n;

  GST_DEBUG ("parsing \"Buffering period\"");

  READ_UE_MAX (nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);
  sps = gst_h265_parser_get_sps (parser, sps_id);
  if (!sps) {
    GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
        sps_id);
    return GST_H265_PARSER_BROKEN_LINK;
  }
  per->sps = sps;

  /* set default values if not present */
  per->irap_cpb_params_present_flag = 0;
  per->cpb_delay_offset = 0;
  per->dpb_delay_offset = 0;

  if (sps->vui_parameters_present_flag) {
    GstH265VUIParams *vui = &sps->vui_params;
    GstH265HRDParams *hrd = &vui->hrd_params;

    if (!hrd->sub_pic_hrd_params_present_flag)
      READ_UINT8 (nr, per->irap_cpb_params_present_flag, 1);

    if (per->irap_cpb_params_present_flag) {
      READ_UINT8 (nr, per->cpb_delay_offset,
          (hrd->au_cpb_removal_delay_length_minus1 + 1));
      READ_UINT8 (nr, per->dpb_delay_offset,
          (hrd->dpb_output_delay_length_minus1 + 1));
    }

    n = hrd->initial_cpb_removal_delay_length_minus1 + 1;

    READ_UINT8 (nr, per->concatenation_flag, 1);
    READ_UINT8 (nr, per->au_cpb_removal_delay_delta_minus1,
        (hrd->au_cpb_removal_delay_length_minus1 + 1));

    if (hrd->nal_hrd_parameters_present_flag) {
      for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
        READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[i], n);
        READ_UINT8 (nr, per->nal_initial_cpb_removal_offset[i], n);
        if (hrd->sub_pic_hrd_params_present_flag
            || per->irap_cpb_params_present_flag) {
          READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_delay[i], n);
          READ_UINT8 (nr, per->nal_initial_alt_cpb_removal_offset[i], n);
        }
      }
    }

    if (hrd->vcl_hrd_parameters_present_flag) {
      for (i = 0; i <= hrd->cpb_cnt_minus1[i]; i++) {
        READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[i], n);
        READ_UINT8 (nr, per->vcl_initial_cpb_removal_offset[i], n);
        if (hrd->sub_pic_hrd_params_present_flag
            || per->irap_cpb_params_present_flag) {
          READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_delay[i], n);
          READ_UINT8 (nr, per->vcl_initial_alt_cpb_removal_offset[i], n);
        }
      }
    }

  }
  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Buffering period\"");
  return GST_H265_PARSER_ERROR;
}

static GstH265ParserResult
gst_h265_parser_parse_pic_timing (GstH265Parser * parser,
    GstH265PicTiming * tim, NalReader * nr)
{
  GstH265ProfileTierLevel *profile_tier_level;
  guint i;

  GST_DEBUG ("parsing \"Picture timing\"");
  if (!parser->last_sps || !parser->last_sps->valid) {
    GST_WARNING ("didn't get the associated sequence paramater set for the "
        "current access unit");
    goto error;
  }

  profile_tier_level = &parser->last_sps->profile_tier_level;

  /* set default values */
  tim->pic_struct = 0;
  if (!profile_tier_level->progressive_source_flag
      && profile_tier_level->interlaced_source_flag)
    tim->source_scan_type = 0;
  else if (profile_tier_level->progressive_source_flag
      && !profile_tier_level->interlaced_source_flag)
    tim->source_scan_type = 1;
  else
    tim->source_scan_type = 2;

  if (parser->last_sps->vui_parameters_present_flag) {
    GstH265VUIParams *vui = &parser->last_sps->vui_params;

    if (vui->frame_field_info_present_flag) {
      READ_UINT8 (nr, tim->pic_struct, 4);
      READ_UINT8 (nr, tim->source_scan_type, 2);
      READ_UINT8 (nr, tim->duplicate_flag, 1);
    } else {
      /* set default values */
      tim->pic_struct = 0;
    }

    if (vui->hrd_parameters_present_flag) {
      GstH265HRDParams *hrd = &vui->hrd_params;

      READ_UINT8 (nr, tim->au_cpb_removal_delay_minus1,
          (hrd->au_cpb_removal_delay_length_minus1 + 1));
      READ_UINT8 (nr, tim->pic_dpb_output_delay,
          (hrd->dpb_output_delay_length_minus1 + 1));

      if (hrd->sub_pic_hrd_params_present_flag)
        READ_UINT8 (nr, tim->pic_dpb_output_du_delay,
            (hrd->dpb_output_delay_du_length_minus1 + 1));

      if (hrd->sub_pic_hrd_params_present_flag
          && hrd->sub_pic_cpb_params_in_pic_timing_sei_flag) {
        READ_UE (nr, tim->num_decoding_units_minus1);

        READ_UINT8 (nr, tim->du_common_cpb_removal_delay_flag, 1);
        if (tim->du_common_cpb_removal_delay_flag)
          READ_UINT8 (nr, tim->du_common_cpb_removal_delay_increment_minus1,
              (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));

        tim->num_nalus_in_du_minus1 =
            g_new0 (guint32, (tim->num_decoding_units_minus1 + 1));
        tim->du_cpb_removal_delay_increment_minus1 =
            g_new0 (guint8, (tim->num_decoding_units_minus1 + 1));

        for (i = 0; i <= (tim->num_decoding_units_minus1 + 1); i++) {
          READ_UE (nr, tim->num_nalus_in_du_minus1[i]);

          if (!tim->du_common_cpb_removal_delay_flag
              && (i < tim->num_decoding_units_minus1))
            READ_UINT8 (nr, tim->du_cpb_removal_delay_increment_minus1[i],
                (hrd->du_cpb_removal_delay_increment_length_minus1 + 1));
        }
      }
    }
  }
  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Picture timing\"");
  return GST_H265_PARSER_ERROR;
}

/******** API *************/

/**
 * gst_h265_parser_new:
 *
 * Creates a new #GstH265Parser. It should be freed with
 * gst_h265_parser_free after use.
 *
 * Returns: a new #GstH265Parser
 */
GstH265Parser *
gst_h265_parser_new (void)
{
  GstH265Parser *parser;

  parser = g_slice_new0 (GstH265Parser);
  INITIALIZE_DEBUG_CATEGORY;

  return parser;
}

/**
 * gst_h265_parser_free:
 * @parser: the #GstH265Parser to free
 *
 * Frees @parser and sets it to %NULL
 */
void
gst_h265_parser_free (GstH265Parser * parser)
{
  g_slice_free (GstH265Parser, parser);
  parser = NULL;
}

/**
 * gst_h265_parser_identify_nalu_unchecked:
 * @parser: a #GstH265Parser
 * @data: The data to parse
 * @offset: the offset from which to parse @data
 * @size: the size of @data
 * @nalu: The #GstH265NalUnit where to store parsed nal headers
 *
 * Parses @data and fills @nalu from the next nalu data from @data.
 *
 * This differs from @gst_h265_parser_identify_nalu in that it doesn't
 * check whether the packet is complete or not.
 *
 * Note: Only use this function if you already know the provided @data
 * is a complete NALU, else use @gst_h265_parser_identify_nalu.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_identify_nalu_unchecked (GstH265Parser * parser,
    const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
{
  gint off1;

  if (size < offset + 4) {
    GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
        ", offset %u", size, offset);
    return GST_H265_PARSER_ERROR;
  }

  off1 = scan_for_start_codes (data + offset, size - offset);

  if (off1 < 0) {
    GST_DEBUG ("No start code prefix in this buffer");
    return GST_H265_PARSER_NO_NAL;
  }

  if (offset + off1 == size - 1) {
    GST_DEBUG ("Missing data to identify nal unit");

    return GST_H265_PARSER_ERROR;
  }

  nalu->sc_offset = offset + off1;

  /* sc might have 2 or 3 0-bytes */
  if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
    nalu->sc_offset--;

  nalu->offset = offset + off1 + 3;
  nalu->data = (guint8 *) data;
  nalu->size = size - nalu->offset;

  if (!gst_h265_parse_nalu_header (nalu)) {
    GST_WARNING ("error parsing \"NAL unit header\"");
    nalu->size = 0;
    return GST_H265_PARSER_BROKEN_DATA;
  }

  nalu->valid = TRUE;

  if (nalu->type == GST_H265_NAL_EOS || nalu->type == GST_H265_NAL_EOB) {
    GST_DEBUG ("end-of-seq or end-of-stream nal found");
    nalu->size = 2;
    return GST_H265_PARSER_OK;
  }

  return GST_H265_PARSER_OK;
}

/**
 * gst_h265_parser_identify_nalu:
 * @parser: a #GstH265Parser
 * @data: The data to parse
 * @offset: the offset from which to parse @data
 * @size: the size of @data
 * @nalu: The #GstH265NalUnit where to store parsed nal headers
 *
 * Parses @data and fills @nalu from the next nalu data from @data
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_identify_nalu (GstH265Parser * parser,
    const guint8 * data, guint offset, gsize size, GstH265NalUnit * nalu)
{
  GstH265ParserResult res;
  gint off2;

  res =
      gst_h265_parser_identify_nalu_unchecked (parser, data, offset, size,
      nalu);

  if (res != GST_H265_PARSER_OK || nalu->size == 2)
    goto beach;

  off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
  if (off2 < 0) {
    GST_DEBUG ("Nal start %d, No end found", nalu->offset);

    return GST_H265_PARSER_NO_NAL_END;
  }

  /* Mini performance improvement:
   * We could have a way to store how many 0s were skipped to avoid
   * parsing them again on the next NAL */
  while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
    off2--;

  nalu->size = off2;
  if (nalu->size < 3)
    return GST_H265_PARSER_BROKEN_DATA;

  GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);

beach:
  return res;
}

/**
 * gst_h265_parser_identify_nalu_hevc:
 * @parser: a #GstH265Parser
 * @data: The data to parse, must be the beging of the Nal unit
 * @offset: the offset from which to parse @data
 * @size: the size of @data
 * @nal_length_size: the size in bytes of the HEVC nal length prefix.
 * @nalu: The #GstH265NalUnit where to store parsed nal headers
 *
 * Parses @data and sets @nalu.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_identify_nalu_hevc (GstH265Parser * parser,
    const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
    GstH265NalUnit * nalu)
{
  GstBitReader br;

  if (size < offset + nal_length_size) {
    GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
        ", offset %u", size, offset);
    return GST_H265_PARSER_ERROR;
  }

  size = size - offset;
  gst_bit_reader_init (&br, data + offset, size);

  nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
      nal_length_size * 8);
  nalu->sc_offset = offset;
  nalu->offset = offset + nal_length_size;

  if (size < nalu->size + nal_length_size) {
    nalu->size = 0;

    return GST_H265_PARSER_NO_NAL_END;
  }

  nalu->data = (guint8 *) data;

  if (!gst_h265_parse_nalu_header (nalu)) {
    GST_WARNING ("error parsing \"NAL unit header\"");
    nalu->size = 0;
    return GST_H265_PARSER_BROKEN_DATA;
  }

  if (nalu->size < 2)
    return GST_H265_PARSER_BROKEN_DATA;

  nalu->valid = TRUE;

  return GST_H265_PARSER_OK;
}

/**
 * gst_h265_parser_parse_nal:
 * @parser: a #GstH265Parser
 * @nalu: The #GstH265NalUnit to parse
 *
 * This function should be called in the case one doesn't need to
 * parse a specific structure. It is necessary to do so to make
 * sure @parser is up to date.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_nal (GstH265Parser * parser, GstH265NalUnit * nalu)
{
  GstH265VPS vps;
  GstH265SPS sps;
  GstH265PPS pps;

  switch (nalu->type) {
    case GST_H265_NAL_VPS:
      return gst_h265_parser_parse_vps (parser, nalu, &vps);
      break;
    case GST_H265_NAL_SPS:
      return gst_h265_parser_parse_sps (parser, nalu, &sps, FALSE);
      break;
    case GST_H265_NAL_PPS:
      return gst_h265_parser_parse_pps (parser, nalu, &pps);
  }

  return GST_H265_PARSER_OK;
}

/**
 * gst_h265_parser_parse_vps:
 * @parser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
 * @vps: The #GstH265VPS to fill.
 *
 * Parses @data, and fills the @vps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_vps (GstH265Parser * parser, GstH265NalUnit * nalu,
    GstH265VPS * vps)
{
  GstH265ParserResult res = gst_h265_parse_vps (nalu, vps);

  if (res == GST_H265_PARSER_OK) {
    GST_DEBUG ("adding video parameter set with id: %d to array", vps->id);

    parser->vps[vps->id] = *vps;
    parser->last_vps = &parser->vps[vps->id];
  }

  return res;
}

/**
 * gst_h265_parse_vps:
 * @nalu: The #GST_H265_NAL_VPS #GstH265NalUnit to parse
 * @sps: The #GstH265VPS to fill.
 *
 * Parses @data, and fills the @vps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
{
  NalReader nr;
  guint i, j;

  INITIALIZE_DEBUG_CATEGORY;
  GST_DEBUG ("parsing VPS");

  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
      nalu->size - nalu->header_bytes);

  memset (&vps->profile_tier_level, 0, sizeof (vps->profile_tier_level));
  memset (&vps->hrd_params, 0, sizeof (vps->hrd_params));
  vps->cprms_present_flag = 1;

  READ_UINT8 (&nr, vps->id, 4);

  /* skip reserved_three_2bits */
  if (!nal_reader_skip (&nr, 2))
    goto error;

  READ_UINT8 (&nr, vps->max_layers_minus1, 6);
  READ_UINT8 (&nr, vps->max_sub_layers_minus1, 3);
  READ_UINT8 (&nr, vps->temporal_id_nesting_flag, 1);

  /* skip reserved_0xffff_16bits */
  if (!nal_reader_skip (&nr, 16))
    goto error;

  if (!gst_h265_parse_profile_tier_level (&vps->profile_tier_level, &nr,
          vps->max_sub_layers_minus1))
    goto error;

  READ_UINT8 (&nr, vps->sub_layer_ordering_info_present_flag, 1);

  for (i =
      (vps->sub_layer_ordering_info_present_flag ? 0 :
          vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
    READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
    READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
        vps->max_dec_pic_buffering_minus1[i]);
    READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
  }
  /* setting default values if vps->sub_layer_ordering_info_present_flag is zero */
  if (!vps->sub_layer_ordering_info_present_flag && vps->max_sub_layers_minus1) {
    for (i = 0; i <= (vps->max_sub_layers_minus1 - 1); i++) {
      vps->max_dec_pic_buffering_minus1[i] =
          vps->max_dec_pic_buffering_minus1[vps->max_sub_layers_minus1];
      vps->max_num_reorder_pics[i] =
          vps->max_num_reorder_pics[vps->max_sub_layers_minus1];
      vps->max_latency_increase_plus1[i] =
          vps->max_latency_increase_plus1[vps->max_sub_layers_minus1];
    }
  }

  READ_UINT8 (&nr, vps->max_layer_id, 6);
  CHECK_ALLOWED_MAX (vps->max_layer_id, 0);

  READ_UE_MAX (&nr, vps->num_layer_sets_minus1, 1023);
  CHECK_ALLOWED_MAX (vps->num_layer_sets_minus1, 0);

  for (i = 1; i <= vps->num_layer_sets_minus1; i++)
    for (j = 0; j <= vps->max_layer_id; j++)
      nal_reader_skip (&nr, 1);

  READ_UINT8 (&nr, vps->timing_info_present_flag, 1);

  if (vps->timing_info_present_flag) {
    READ_UINT32 (&nr, vps->num_units_in_tick, 32);
    READ_UINT32 (&nr, vps->time_scale, 32);
    READ_UINT8 (&nr, vps->poc_proportional_to_timing_flag, 1);

    if (vps->poc_proportional_to_timing_flag)
      READ_UE_MAX (&nr, vps->num_ticks_poc_diff_one_minus1, G_MAXUINT32 - 1);

    READ_UE_MAX (&nr, vps->num_hrd_parameters, 1024);
    CHECK_ALLOWED_MAX (vps->num_hrd_parameters, 1);

    if (vps->num_hrd_parameters) {
      READ_UE_MAX (&nr, vps->hrd_layer_set_idx, 1023);
      CHECK_ALLOWED_MAX (vps->hrd_layer_set_idx, 0);

      if (!gst_h265_parse_hrd_parameters (&vps->hrd_params, &nr,
              vps->cprms_present_flag, vps->max_sub_layers_minus1))
        goto error;
    }
  }
  READ_UINT8 (&nr, vps->vps_extension, 1);
  vps->valid = TRUE;

  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Video parameter set\"");
  vps->valid = FALSE;
  return GST_H265_PARSER_ERROR;
}

/**
 * gst_h265_parser_parse_sps:
 * @parser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
 * @sps: The #GstH265SPS to fill.
 * @parse_vui_params: Whether to parse the vui_params or not
 *
 * Parses @data, and fills the @sps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
    GstH265SPS * sps, gboolean parse_vui_params)
{
  GstH265ParserResult res =
      gst_h265_parse_sps (parser, nalu, sps, parse_vui_params);

  if (res == GST_H265_PARSER_OK) {
    GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);

    parser->sps[sps->id] = *sps;
    parser->last_sps = &parser->sps[sps->id];
  }

  return res;
}

/**
 * gst_h265_parse_sps:
 * parser: The #GstH265Parser
 * @nalu: The #GST_H265_NAL_SPS #GstH265NalUnit to parse
 * @sps: The #GstH265SPS to fill.
 * @parse_vui_params: Whether to parse the vui_params or not
 *
 * Parses @data, and fills the @sps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
    GstH265SPS * sps, gboolean parse_vui_params)
{
  NalReader nr;
  GstH265VPS *vps;
  guint8 vps_id;
  guint i;
  guint subwc[] = { 1, 2, 2, 1, 1 };
  guint subhc[] = { 1, 2, 1, 1, 1 };
  GstH265VUIParams *vui = NULL;

  INITIALIZE_DEBUG_CATEGORY;
  GST_DEBUG ("parsing SPS");

  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
      nalu->size - nalu->header_bytes);

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  memset (&sps->profile_tier_level, 0, sizeof (sps->profile_tier_level));
  memset (sps->short_term_ref_pic_set, 0, sizeof (sps->short_term_ref_pic_set));
  sps->scaling_list_data_present_flag = 0;
  sps->separate_colour_plane_flag = 0;
  sps->conf_win_left_offset = 0;
  sps->conf_win_right_offset = 0;
  sps->conf_win_top_offset = 0;
  sps->conf_win_bottom_offset = 0;
  sps->pcm_loop_filter_disabled_flag = 0;

  READ_UINT8 (&nr, vps_id, 4);
  vps = gst_h265_parser_get_vps (parser, vps_id);
  if (!vps) {
    GST_DEBUG ("couldn't find associated video parameter set with id: %d",
        vps_id);
  }
  sps->vps = vps;

  READ_UINT8 (&nr, sps->max_sub_layers_minus1, 3);
  READ_UINT8 (&nr, sps->temporal_id_nesting_flag, 1);

  if (!gst_h265_parse_profile_tier_level (&sps->profile_tier_level, &nr,
          sps->max_sub_layers_minus1))
    goto error;

  READ_UE_MAX (&nr, sps->id, GST_H265_MAX_SPS_COUNT - 1);

  READ_UE_MAX (&nr, sps->chroma_format_idc, 3);
  if (sps->chroma_format_idc == 3)
    READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);

  READ_UE_ALLOWED (&nr, sps->pic_width_in_luma_samples, 1, 16888);
  READ_UE_ALLOWED (&nr, sps->pic_height_in_luma_samples, 1, 16888);

  READ_UINT8 (&nr, sps->conformance_window_flag, 1);
  if (sps->conformance_window_flag) {
    READ_UE (&nr, sps->conf_win_left_offset);
    READ_UE (&nr, sps->conf_win_right_offset);
    READ_UE (&nr, sps->conf_win_top_offset);
    READ_UE (&nr, sps->conf_win_bottom_offset);
  }

  READ_UE_MAX (&nr, sps->bit_depth_luma_minus8, 6);
  READ_UE_MAX (&nr, sps->bit_depth_chroma_minus8, 6);
  READ_UE_MAX (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);

  READ_UINT8 (&nr, sps->sub_layer_ordering_info_present_flag, 1);
  for (i =
      (sps->sub_layer_ordering_info_present_flag ? 0 :
          sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
    READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
    READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
        sps->max_dec_pic_buffering_minus1[i]);
    READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
  }
  /* setting default values if sps->sub_layer_ordering_info_present_flag is zero */
  if (!sps->sub_layer_ordering_info_present_flag && sps->max_sub_layers_minus1) {
    for (i = 0; i <= (sps->max_sub_layers_minus1 - 1); i++) {
      sps->max_dec_pic_buffering_minus1[i] =
          sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1];
      sps->max_num_reorder_pics[i] =
          sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
      sps->max_latency_increase_plus1[i] =
          sps->max_latency_increase_plus1[sps->max_sub_layers_minus1];
    }
  }

  /* The limits are calculted based on the profile_tier_level constraint
   * in Annex-A: CtbLog2SizeY = 4 to 6 */
  READ_UE_MAX (&nr, sps->log2_min_luma_coding_block_size_minus3, 3);
  READ_UE_MAX (&nr, sps->log2_diff_max_min_luma_coding_block_size, 6);
  READ_UE_MAX (&nr, sps->log2_min_transform_block_size_minus2, 3);
  READ_UE_MAX (&nr, sps->log2_diff_max_min_transform_block_size, 3);
  READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_inter, 4);
  READ_UE_MAX (&nr, sps->max_transform_hierarchy_depth_intra, 4);

  READ_UINT8 (&nr, sps->scaling_list_enabled_flag, 1);
  if (sps->scaling_list_enabled_flag) {
    READ_UINT8 (&nr, sps->scaling_list_data_present_flag, 1);

    if (sps->scaling_list_data_present_flag)
      if (!gst_h265_parser_parse_scaling_lists (&nr, &sps->scaling_list, FALSE))
        goto error;
  }

  READ_UINT8 (&nr, sps->amp_enabled_flag, 1);
  READ_UINT8 (&nr, sps->sample_adaptive_offset_enabled_flag, 1);
  READ_UINT8 (&nr, sps->pcm_enabled_flag, 1);

  if (sps->pcm_enabled_flag) {
    READ_UINT8 (&nr, sps->pcm_sample_bit_depth_luma_minus1, 4);
    READ_UINT8 (&nr, sps->pcm_sample_bit_depth_chroma_minus1, 4);
    READ_UE_MAX (&nr, sps->log2_min_pcm_luma_coding_block_size_minus3, 2);
    READ_UE_MAX (&nr, sps->log2_diff_max_min_pcm_luma_coding_block_size, 2);
    READ_UINT8 (&nr, sps->pcm_loop_filter_disabled_flag, 1);
  }

  READ_UE_MAX (&nr, sps->num_short_term_ref_pic_sets, 64);
  for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
    if (!gst_h265_parser_parse_short_term_ref_pic_sets
        (&sps->short_term_ref_pic_set[i], &nr, i, sps))
      goto error;

  READ_UINT8 (&nr, sps->long_term_ref_pics_present_flag, 1);
  if (sps->long_term_ref_pics_present_flag) {
    READ_UE_MAX (&nr, sps->num_long_term_ref_pics_sps, 32);
    for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
      READ_UINT16 (&nr, sps->lt_ref_pic_poc_lsb_sps[i],
          sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
      READ_UINT8 (&nr, sps->used_by_curr_pic_lt_sps_flag[i], 1);
    }
  }

  READ_UINT8 (&nr, sps->temporal_mvp_enabled_flag, 1);
  READ_UINT8 (&nr, sps->strong_intra_smoothing_enabled_flag, 1);
  READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);

  if (sps->vui_parameters_present_flag && parse_vui_params) {
    if (!gst_h265_parse_vui_parameters (sps, &nr))
      goto error;
    vui = &sps->vui_params;
  }

  READ_UINT8 (&nr, sps->sps_extension_flag, 1);

  /* calculate ChromaArrayType */
  if (sps->separate_colour_plane_flag)
    sps->chroma_array_type = 0;
  else
    sps->chroma_array_type = sps->chroma_format_idc;

  /* Calculate  width and height */
  sps->width = sps->pic_width_in_luma_samples;
  sps->height = sps->pic_height_in_luma_samples;
  if (sps->width < 0 || sps->height < 0) {
    GST_WARNING ("invalid width/height in SPS");
    goto error;
  }

  if (sps->conformance_window_flag) {
    const guint crop_unit_x = subwc[sps->chroma_format_idc];
    const guint crop_unit_y = subhc[sps->chroma_format_idc];

    sps->crop_rect_width = sps->width -
        (sps->conf_win_left_offset + sps->conf_win_right_offset) * crop_unit_x;
    sps->crop_rect_height = sps->height -
        (sps->conf_win_top_offset + sps->conf_win_bottom_offset) * crop_unit_y;
    sps->crop_rect_x = sps->conf_win_left_offset * crop_unit_x;
    sps->crop_rect_y = sps->conf_win_top_offset * crop_unit_y;

    GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
        sps->crop_rect_y, sps->crop_rect_width, sps->crop_rect_height);
  }

  sps->fps_num = 0;
  sps->fps_den = 1;

  if (vui && vui->timing_info_present_flag) {
    /* derive framerate for progressive stream if the pic_struct
     * syntax element is not present in picture timing SEI messages */
    /* Fixme: handle other cases also */
    if (parse_vui_params && vui->timing_info_present_flag
        && !vui->field_seq_flag && !vui->frame_field_info_present_flag) {
      sps->fps_num = vui->time_scale;
      sps->fps_den = vui->num_units_in_tick;
      GST_LOG ("framerate %d/%d", sps->fps_num, sps->fps_den);
    }
  } else {
    GST_LOG ("No VUI, unknown framerate");
  }

  sps->valid = TRUE;

  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Sequence parameter set\"");
  sps->valid = FALSE;
  return GST_H265_PARSER_ERROR;
}

/**
 * gst_h265_parse_pps:
 * @parser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
 * @pps: The #GstH265PPS to fill.
 *
 * Parses @data, and fills the @pps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parse_pps (GstH265Parser * parser, GstH265NalUnit * nalu,
    GstH265PPS * pps)
{
  NalReader nr;
  GstH265SPS *sps;
  gint sps_id;
  gint qp_bd_offset;
  guint32 CtbSizeY, MinCbLog2SizeY, CtbLog2SizeY;
  guint8 i;

  INITIALIZE_DEBUG_CATEGORY;
  GST_DEBUG ("parsing PPS");

  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
      nalu->size - nalu->header_bytes);

  READ_UE_MAX (&nr, pps->id, GST_H265_MAX_PPS_COUNT - 1);
  READ_UE_MAX (&nr, sps_id, GST_H265_MAX_SPS_COUNT - 1);

  sps = gst_h265_parser_get_sps (parser, sps_id);
  if (!sps) {
    GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
        sps_id);
    return GST_H265_PARSER_BROKEN_LINK;
  }
  pps->sps = sps;
  qp_bd_offset = 6 * sps->bit_depth_luma_minus8;

  MinCbLog2SizeY = sps->log2_min_luma_coding_block_size_minus3 + 3;
  CtbLog2SizeY = MinCbLog2SizeY + sps->log2_diff_max_min_luma_coding_block_size;
  CtbSizeY = 1 << CtbLog2SizeY;
  pps->PicHeightInCtbsY =
      ceil ((gdouble) sps->pic_height_in_luma_samples / (gdouble) CtbSizeY);
  pps->PicWidthInCtbsY =
      ceil ((gdouble) sps->pic_width_in_luma_samples / (gdouble) CtbSizeY);

  /* set default values for fields that might not be present in the bitstream
     and have valid defaults */
  pps->diff_cu_qp_delta_depth = 0;
  pps->num_tile_columns_minus1 = 0;
  pps->num_tile_rows_minus1 = 0;
  pps->uniform_spacing_flag = 1;
  pps->loop_filter_across_tiles_enabled_flag = 1;
  pps->deblocking_filter_override_enabled_flag = 0;
  pps->deblocking_filter_disabled_flag = 0;
  pps->beta_offset_div2 = 0;
  pps->tc_offset_div2 = 0;

  READ_UINT8 (&nr, pps->dependent_slice_segments_enabled_flag, 1);
  READ_UINT8 (&nr, pps->output_flag_present_flag, 1);
  READ_UINT8 (&nr, pps->num_extra_slice_header_bits, 3);
  READ_UINT8 (&nr, pps->sign_data_hiding_enabled_flag, 1);
  READ_UINT8 (&nr, pps->cabac_init_present_flag, 1);

  READ_UE_MAX (&nr, pps->num_ref_idx_l0_default_active_minus1, 14);
  READ_UE_MAX (&nr, pps->num_ref_idx_l1_default_active_minus1, 14);
  READ_SE_ALLOWED (&nr, pps->init_qp_minus26, -(26 + qp_bd_offset), 25);

  READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
  READ_UINT8 (&nr, pps->transform_skip_enabled_flag, 1);

  READ_UINT8 (&nr, pps->cu_qp_delta_enabled_flag, 1);
  if (pps->cu_qp_delta_enabled_flag)
    READ_UE_MAX (&nr, pps->diff_cu_qp_delta_depth,
        sps->log2_diff_max_min_luma_coding_block_size);

  READ_SE_ALLOWED (&nr, pps->cb_qp_offset, -12, 12);
  READ_SE_ALLOWED (&nr, pps->cr_qp_offset, -12, 12);

  READ_UINT8 (&nr, pps->slice_chroma_qp_offsets_present_flag, 1);
  READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
  READ_UINT8 (&nr, pps->weighted_bipred_flag, 1);
  READ_UINT8 (&nr, pps->transquant_bypass_enabled_flag, 1);
  READ_UINT8 (&nr, pps->tiles_enabled_flag, 1);
  READ_UINT8 (&nr, pps->entropy_coding_sync_enabled_flag, 1);

  if (pps->tiles_enabled_flag) {
    READ_UE_ALLOWED (&nr, pps->num_tile_columns_minus1, 0, 19);
    READ_UE_ALLOWED (&nr, pps->num_tile_rows_minus1, 0, 21);

    READ_UINT8 (&nr, pps->uniform_spacing_flag, 1);
    /* 6.5.1, 6-4, 6-5, 7.4.3.3.1 */
    if (pps->uniform_spacing_flag) {
      guint8 num_col = pps->num_tile_columns_minus1 + 1;
      guint8 num_row = pps->num_tile_rows_minus1 + 1;
      for (i = 0; i < num_col; i++) {
        pps->column_width_minus1[i] =
            ((i + 1) * pps->PicWidthInCtbsY / num_col
            - i * pps->PicWidthInCtbsY / num_col) - 1;
      }
      for (i = 0; i < num_row; i++) {
        pps->row_height_minus1[i] =
            ((i + 1) * pps->PicHeightInCtbsY / num_row
            - i * pps->PicHeightInCtbsY / num_row) - 1;
      }
    } else {
      pps->column_width_minus1[pps->num_tile_columns_minus1] =
          pps->PicWidthInCtbsY - 1;
      for (i = 0; i < pps->num_tile_columns_minus1; i++) {
        READ_UE (&nr, pps->column_width_minus1[i]);
        pps->column_width_minus1[pps->num_tile_columns_minus1] -=
            (pps->column_width_minus1[i] + 1);
      }

      pps->row_height_minus1[pps->num_tile_rows_minus1] =
          pps->PicHeightInCtbsY - 1;
      for (i = 0; i < pps->num_tile_rows_minus1; i++) {
        READ_UE (&nr, pps->row_height_minus1[i]);
        pps->row_height_minus1[pps->num_tile_rows_minus1] -=
            (pps->row_height_minus1[i] + 1);
      }
    }
    READ_UINT8 (&nr, pps->loop_filter_across_tiles_enabled_flag, 1);
  }

  READ_UINT8 (&nr, pps->loop_filter_across_slices_enabled_flag, 1);

  READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
  if (pps->deblocking_filter_control_present_flag) {
    READ_UINT8 (&nr, pps->deblocking_filter_override_enabled_flag, 1);

    READ_UINT8 (&nr, pps->deblocking_filter_disabled_flag, 1);
    if (!pps->deblocking_filter_disabled_flag) {
      READ_SE_ALLOWED (&nr, pps->beta_offset_div2, -6, 6);
      READ_SE_ALLOWED (&nr, pps->tc_offset_div2, -6, +6);
    }
  }

  READ_UINT8 (&nr, pps->scaling_list_data_present_flag, 1);
  if (pps->scaling_list_data_present_flag)
    if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, FALSE))
      goto error;
  if (sps->scaling_list_enabled_flag && !sps->scaling_list_data_present_flag
      && !pps->scaling_list_data_present_flag)
    if (!gst_h265_parser_parse_scaling_lists (&nr, &pps->scaling_list, TRUE))
      goto error;

  READ_UINT8 (&nr, pps->lists_modification_present_flag, 1);
  READ_UE_MAX (&nr, pps->log2_parallel_merge_level_minus2, 4);
  READ_UINT8 (&nr, pps->slice_segment_header_extension_present_flag, 1);
  READ_UINT8 (&nr, pps->pps_extension_flag, 1);

  pps->valid = TRUE;
  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Picture parameter set\"");
  pps->valid = FALSE;
  return GST_H265_PARSER_ERROR;
}

/**
 * gst_h265_parser_parse_pps:
 * @parser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_PPS #GstH265NalUnit to parse
 * @pps: The #GstH265PPS to fill.
 *
 * Parses @data, and fills the @pps structure.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_pps (GstH265Parser * parser,
    GstH265NalUnit * nalu, GstH265PPS * pps)
{
  GstH265ParserResult res = gst_h265_parse_pps (parser, nalu, pps);
  if (res == GST_H265_PARSER_OK) {
    GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);

    parser->pps[pps->id] = *pps;
    parser->last_pps = &parser->pps[pps->id];
  }

  return res;
}

/**
 * gst_h265_parser_parse_slice_hdr:
 * @parser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_SLICE #GstH265NalUnit to parse
 * @slice: The #GstH265SliceHdr to fill.
 *
 * Parses @data, and fills the @slice structure.
 * The resulting @slice_hdr structure shall be deallocated with
 * gst_h265_slice_hdr_free() when it is no longer needed
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
    GstH265NalUnit * nalu, GstH265SliceHdr * slice)
{
  NalReader nr;
  gint pps_id;
  GstH265PPS *pps;
  GstH265SPS *sps;
  guint i;
  GstH265ShortTermRefPicSet *stRPS = NULL;
  guint32 UsedByCurrPicLt[16];
  guint32 PicSizeInCtbsY;
  gint NumPocTotalCurr = 0;

  if (!nalu->size) {
    GST_DEBUG ("Invalid Nal Unit");
    return GST_H265_PARSER_ERROR;
  }

  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
      nalu->size - nalu->header_bytes);

  GST_DEBUG ("parsing \"Slice header\", slice type");

  READ_UINT8 (&nr, slice->first_slice_segment_in_pic_flag, 1);

  if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP
      && nalu->type <= RESERVED_IRAP_NAL_TYPE_MAX)
    READ_UINT8 (&nr, slice->no_output_of_prior_pics_flag, 1);

  READ_UE_MAX (&nr, pps_id, GST_H265_MAX_PPS_COUNT - 1);
  pps = gst_h265_parser_get_pps (parser, pps_id);
  if (!pps) {
    GST_WARNING
        ("couldn't find associated picture parameter set with id: %d", pps_id);
    return GST_H265_PARSER_BROKEN_LINK;
  }

  slice->pps = pps;
  sps = pps->sps;
  if (!sps) {
    GST_WARNING
        ("couldn't find associated sequence parameter set with id: %d",
        pps->id);
    return GST_H265_PARSER_BROKEN_LINK;
  }

  PicSizeInCtbsY = pps->PicWidthInCtbsY * pps->PicHeightInCtbsY;
  /* set default values for fields that might not be present in the bitstream
   * and have valid defaults */
  slice->dependent_slice_segment_flag = 0;
  slice->segment_address = 0;
  slice->pic_output_flag = 1;
  slice->pic_order_cnt_lsb = 0;
  slice->short_term_ref_pic_set_idx = 0;
  slice->num_long_term_sps = 0;
  slice->num_long_term_pics = 0;
  for (i = 0; i < 16; i++) {
    slice->lt_idx_sps[i] = 0;
    slice->delta_poc_msb_cycle_lt[i] = 0;
  }
  slice->temporal_mvp_enabled_flag = 0;
  slice->sao_luma_flag = 0;
  slice->sao_chroma_flag = 0;
  slice->cabac_init_flag = 0;
  slice->collocated_from_l0_flag = 1;
  slice->cb_qp_offset = 0;
  slice->cr_qp_offset = 0;
  slice->deblocking_filter_override_flag = 0;
  slice->deblocking_filter_disabled_flag = 0;
  slice->beta_offset_div2 = pps->beta_offset_div2;
  slice->tc_offset_div2 = pps->tc_offset_div2;
  slice->loop_filter_across_slices_enabled_flag =
      pps->loop_filter_across_slices_enabled_flag;
  slice->num_entry_point_offsets = 0;
  slice->entry_point_offset_minus1 = NULL;

  if (!slice->first_slice_segment_in_pic_flag) {
    const guint n = ceil_log2 (PicSizeInCtbsY);

    if (pps->dependent_slice_segments_enabled_flag)
      READ_UINT8 (&nr, slice->dependent_slice_segment_flag, 1);
    /* sice_segment_address parsing */
    READ_UINT32 (&nr, slice->segment_address, n);
  }

  if (!slice->dependent_slice_segment_flag) {
    for (i = 0; i < pps->num_extra_slice_header_bits; i++)
      nal_reader_skip (&nr, 1);
    READ_UE_MAX (&nr, slice->type, 63);


    if (pps->output_flag_present_flag)
      READ_UINT8 (&nr, slice->pic_output_flag, 1);
    if (sps->separate_colour_plane_flag == 1)
      READ_UINT8 (&nr, slice->colour_plane_id, 2);

    if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL)
        && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) {
      READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
          (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));

      READ_UINT8 (&nr, slice->short_term_ref_pic_set_sps_flag, 1);
      if (!slice->short_term_ref_pic_set_sps_flag) {
        if (!gst_h265_parser_parse_short_term_ref_pic_sets
            (&slice->short_term_ref_pic_sets, &nr,
                sps->num_short_term_ref_pic_sets, sps))
          goto error;
      } else if (sps->num_short_term_ref_pic_sets > 1) {
        const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
        READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
        CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
            sps->num_short_term_ref_pic_sets - 1);
      }

      if (sps->long_term_ref_pics_present_flag) {
        guint32 limit;

        if (sps->num_long_term_ref_pics_sps > 0)
          READ_UE_MAX (&nr, slice->num_long_term_sps,
              sps->num_long_term_ref_pics_sps);

        READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
        limit = slice->num_long_term_sps + slice->num_long_term_pics;
        for (i = 0; i < limit; i++) {
          if (i < slice->num_long_term_sps) {
            if (sps->num_long_term_ref_pics_sps > 1) {
              const guint n = ceil_log2 (sps->num_long_term_ref_pics_sps);
              READ_UINT8 (&nr, slice->lt_idx_sps[i], n);
            }
          } else {
            READ_UINT32 (&nr, slice->poc_lsb_lt[i],
                (sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
            READ_UINT8 (&nr, slice->used_by_curr_pic_lt_flag[i], 1);
          }

          /* calculate UsedByCurrPicLt */
          if (i < slice->num_long_term_sps)
            UsedByCurrPicLt[i] =
                sps->used_by_curr_pic_lt_sps_flag[slice->lt_idx_sps[i]];
          else
            UsedByCurrPicLt[i] = slice->used_by_curr_pic_lt_flag[i];
          READ_UINT8 (&nr, slice->delta_poc_msb_present_flag[i], 1);
          if (slice->delta_poc_msb_present_flag[i])
            READ_UE (&nr, slice->delta_poc_msb_cycle_lt[i]);
        }
      }
      if (sps->temporal_mvp_enabled_flag)
        READ_UINT8 (&nr, slice->temporal_mvp_enabled_flag, 1);
    }

    if (sps->sample_adaptive_offset_enabled_flag) {
      READ_UINT8 (&nr, slice->sao_luma_flag, 1);
      READ_UINT8 (&nr, slice->sao_chroma_flag, 1);
    }

    if (GST_H265_IS_B_SLICE (slice) || GST_H265_IS_P_SLICE (slice)) {
      READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);

      if (slice->num_ref_idx_active_override_flag) {
        READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 14);
        if (GST_H265_IS_B_SLICE (slice))
          READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 14);
      } else {
        /*set default values */
        slice->num_ref_idx_l0_active_minus1 =
            pps->num_ref_idx_l0_default_active_minus1;
        slice->num_ref_idx_l1_active_minus1 =
            pps->num_ref_idx_l1_default_active_minus1;
      }

      /* calculate NumPocTotalCurr */
      if (slice->short_term_ref_pic_set_sps_flag)
        stRPS = &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
      else
        stRPS = &slice->short_term_ref_pic_sets;

      for (i = 0; i < stRPS->NumNegativePics; i++)
        if (stRPS->UsedByCurrPicS0[i])
          NumPocTotalCurr++;
      for (i = 0; i < stRPS->NumPositivePics; i++)
        if (stRPS->UsedByCurrPicS1[i])
          NumPocTotalCurr++;
      for (i = 0;
          i < (slice->num_long_term_sps + slice->num_long_term_pics); i++)
        if (UsedByCurrPicLt[i])
          NumPocTotalCurr++;
      slice->NumPocTotalCurr = NumPocTotalCurr;

      if (pps->lists_modification_present_flag) {
        if (NumPocTotalCurr > 1)
          if (!gst_h265_slice_parse_ref_pic_list_modification (slice, &nr,
                  NumPocTotalCurr))
            goto error;
      }

      if (GST_H265_IS_B_SLICE (slice))
        READ_UINT8 (&nr, slice->mvd_l1_zero_flag, 1);
      if (pps->cabac_init_present_flag)
        READ_UINT8 (&nr, slice->cabac_init_flag, 1);
      if (slice->temporal_mvp_enabled_flag) {
        if (GST_H265_IS_B_SLICE (slice))
          READ_UINT8 (&nr, slice->collocated_from_l0_flag, 1);

        if ((slice->collocated_from_l0_flag
                && slice->num_ref_idx_l0_active_minus1 > 0)
            || (!slice->collocated_from_l0_flag
                && slice->num_ref_idx_l1_active_minus1 > 0)) {

          /*fixme: add optimization */
          if ((GST_H265_IS_P_SLICE (slice))
              || ((GST_H265_IS_B_SLICE (slice))
                  && (slice->collocated_from_l0_flag))) {
            READ_UE_MAX (&nr, slice->collocated_ref_idx,
                slice->num_ref_idx_l0_active_minus1);
          } else if ((GST_H265_IS_B_SLICE (slice))
              && (!slice->collocated_from_l0_flag)) {
            READ_UE_MAX (&nr, slice->collocated_ref_idx,
                slice->num_ref_idx_l1_active_minus1);
          }
        }
      }
      if ((pps->weighted_pred_flag && GST_H265_IS_P_SLICE (slice)) ||
          (pps->weighted_bipred_flag && GST_H265_IS_B_SLICE (slice)))
        if (!gst_h265_slice_parse_pred_weight_table (slice, &nr))
          goto error;
      READ_UE_MAX (&nr, slice->five_minus_max_num_merge_cand, 4);
    }

    READ_SE_ALLOWED (&nr, slice->qp_delta, -87, 77);
    if (pps->slice_chroma_qp_offsets_present_flag) {
      READ_SE_ALLOWED (&nr, slice->cb_qp_offset, -12, 12);
      READ_SE_ALLOWED (&nr, slice->cr_qp_offset, -12, 12);
    }

    if (pps->deblocking_filter_override_enabled_flag)
      READ_UINT8 (&nr, slice->deblocking_filter_override_flag, 1);
    if (slice->deblocking_filter_override_flag) {
      READ_UINT8 (&nr, slice->deblocking_filter_disabled_flag, 1);
      if (!slice->deblocking_filter_disabled_flag) {
        READ_SE_ALLOWED (&nr, slice->beta_offset_div2, -6, 6);
        READ_SE_ALLOWED (&nr, slice->tc_offset_div2, -6, 6);
      }
    }

    if (pps->loop_filter_across_slices_enabled_flag &&
        (slice->sao_luma_flag || slice->sao_chroma_flag ||
            !slice->deblocking_filter_disabled_flag))
      READ_UINT8 (&nr, slice->loop_filter_across_slices_enabled_flag, 1);
  }

  if (pps->tiles_enabled_flag || pps->entropy_coding_sync_enabled_flag) {
    guint32 offset_max;

    if (!pps->tiles_enabled_flag && pps->entropy_coding_sync_enabled_flag)
      offset_max = pps->PicHeightInCtbsY - 1;
    else if (pps->tiles_enabled_flag && !pps->entropy_coding_sync_enabled_flag)
      offset_max =
          (pps->num_tile_columns_minus1 + 1) * (pps->num_tile_rows_minus1 + 1) -
          1;
    else
      offset_max =
          (pps->num_tile_columns_minus1 + 1) * pps->PicHeightInCtbsY - 1;

    READ_UE_MAX (&nr, slice->num_entry_point_offsets, offset_max);
    if (slice->num_entry_point_offsets > 0) {
      READ_UE_MAX (&nr, slice->offset_len_minus1, 31);
      slice->entry_point_offset_minus1 =
          g_new0 (guint32, slice->num_entry_point_offsets);
      for (i = 0; i < slice->num_entry_point_offsets; i++)
        READ_UINT32 (&nr, slice->entry_point_offset_minus1[i],
            (slice->offset_len_minus1 + 1));
    }
  }

  if (pps->slice_segment_header_extension_present_flag) {
    guint16 slice_segment_header_extension_length;
    READ_UE_MAX (&nr, slice_segment_header_extension_length, 256);
    for (i = 0; i < slice_segment_header_extension_length; i++)
      if (!nal_reader_skip (&nr, 8))
        goto error;
  }

  /* Skip the byte alignment bits */
  if (!nal_reader_skip (&nr, 1))
    goto error;
  while (!nal_reader_is_byte_aligned (&nr)) {
    if (!nal_reader_skip (&nr, 1))
      goto error;
  }

  slice->header_size = nal_reader_get_pos (&nr);
  slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);

  return GST_H265_PARSER_OK;

error:
  GST_WARNING ("error parsing \"Slice header\"");

  gst_h265_slice_hdr_free (slice);

  return GST_H265_PARSER_ERROR;
}

static gboolean
nal_reader_has_more_data_in_payload (NalReader * nr,
    guint32 payload_start_pos_bit, guint32 payloadSize)
{
  if (nal_reader_is_byte_aligned (nr) &&
      (nal_reader_get_pos (nr) == (payload_start_pos_bit + 8 * payloadSize)))
    return FALSE;

  return TRUE;
}

static GstH265ParserResult
gst_h265_parser_parse_sei_message (GstH265Parser * parser,
    guint8 nal_type, NalReader * nr, GstH265SEIMessage * sei)
{
  guint32 payloadSize;
  guint8 payload_type_byte, payload_size_byte;
  guint remaining, payload_size;
  guint32 payload_start_pos_bit;
  GstH265ParserResult res = GST_H265_PARSER_OK;

  GST_DEBUG ("parsing \"Sei message\"");

  sei->payloadType = 0;
  do {
    READ_UINT8 (nr, payload_type_byte, 8);
    sei->payloadType += payload_type_byte;
  } while (payload_type_byte == 0xff);
  payloadSize = 0;
  do {
    READ_UINT8 (nr, payload_size_byte, 8);
    payloadSize += payload_size_byte;
  }
  while (payload_size_byte == 0xff);

  remaining = nal_reader_get_remaining (nr);
  payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;

  payload_start_pos_bit = nal_reader_get_pos (nr);
  GST_DEBUG
      ("SEI message received: payloadType  %u, payloadSize = %u bytes",
      sei->payloadType, payload_size);

  if (nal_type == GST_H265_NAL_PREFIX_SEI) {
    switch (sei->payloadType) {
      case GST_H265_SEI_BUF_PERIOD:
        /* size not set; might depend on emulation_prevention_three_byte */
        res = gst_h265_parser_parse_buffering_period (parser,
            &sei->payload.buffering_period, nr);
        break;
      case GST_H265_SEI_PIC_TIMING:
        /* size not set; might depend on emulation_prevention_three_byte */
        res = gst_h265_parser_parse_pic_timing (parser,
            &sei->payload.pic_timing, nr);
        break;
      default:
        /* Just consume payloadSize bytes, which does not account for
           emulation prevention bytes */
        if (!nal_reader_skip_long (nr, payload_size))
          goto error;
        res = GST_H265_PARSER_OK;
        break;
    }
  } else if (nal_type == GST_H265_NAL_SUFFIX_SEI) {
    switch (sei->payloadType) {
      default:
        /* Just consume payloadSize bytes, which does not account for
           emulation prevention bytes */
        if (!nal_reader_skip_long (nr, payload_size))
          goto error;
        res = GST_H265_PARSER_OK;
        break;
    }
  }

  /* Not parsing the reserved_payload_extension, but it shouldn't be
   * an issue because of 1: There shall not be any reserved_payload_extension
   * present in bitstreams conforming to the specification.2. Even though
   * it is present, the size will be less than total PayloadSize since the
   * size of reserved_payload_extension is supposed to be
   * 8 * payloadSize - nEarlierBits - nPayloadZeroBits -1 which means the
   * the current implementation will still skip all unnecessary bits correctly.
   * In theory, we can have a more optimized implementation by skipping the
   * data left in PayLoadSize without out individually checking for each bits,
   * since the totoal size will be always less than payloadSize*/
  if (nal_reader_has_more_data_in_payload (nr, payload_start_pos_bit,
          payloadSize)) {
    /* Skip the byte alignment bits */
    if (!nal_reader_skip (nr, 1))
      goto error;
    while (!nal_reader_is_byte_aligned (nr)) {
      if (!nal_reader_skip (nr, 1))
        goto error;
    }
  }

  return res;

error:
  GST_WARNING ("error parsing \"Sei message\"");
  return GST_H265_PARSER_ERROR;
}

/**
 * gst_h265_slice_hdr_copy:
 * @dst_slice: The destination #GstH265SliceHdr to copy into
 * @src_slice: The source #GstH265SliceHdr to copy from
 *
 * Copies @src_slice into @dst_slice
 *
 * Returns: %TRUE if everything went fine, %FALSE otherwise
 */
gboolean
gst_h265_slice_hdr_copy (GstH265SliceHdr * dst_slice,
    const GstH265SliceHdr * src_slice)
{
  guint i;

  g_return_val_if_fail (dst_slice != NULL, FALSE);
  g_return_val_if_fail (src_slice != NULL, FALSE);

  gst_h265_slice_hdr_free (dst_slice);

  *dst_slice = *src_slice;

  if (dst_slice->num_entry_point_offsets > 0) {
    dst_slice->entry_point_offset_minus1 =
        g_new0 (guint32, dst_slice->num_entry_point_offsets);
    for (i = 0; i < dst_slice->num_entry_point_offsets; i++)
      dst_slice->entry_point_offset_minus1[i] =
          src_slice->entry_point_offset_minus1[i];
  }

  return TRUE;
}

/**
 * gst_h265_slice_hdr_free:
 * slice_hdr: The #GstH265SliceHdr to free
 *
 * Frees @slice_hdr fields.
 */
void
gst_h265_slice_hdr_free (GstH265SliceHdr * slice_hdr)
{
  g_return_if_fail (slice_hdr != NULL);

  if (slice_hdr->num_entry_point_offsets > 0)
    g_free (slice_hdr->entry_point_offset_minus1);
  slice_hdr->entry_point_offset_minus1 = 0;
}

/**
 * gst_h265_sei_copy:
 * @dst_sei: The destination #GstH265SEIMessage to copy into
 * @src_sei: The source #GstH265SEIMessage to copy from
 *
 * Copies @src_sei into @dst_sei
 *
 * Returns: %TRUE if everything went fine, %FALSE otherwise
 */
gboolean
gst_h265_sei_copy (GstH265SEIMessage * dst_sei,
    const GstH265SEIMessage * src_sei)
{
  guint i;

  g_return_val_if_fail (dst_sei != NULL, FALSE);
  g_return_val_if_fail (src_sei != NULL, FALSE);

  gst_h265_sei_free (dst_sei);

  *dst_sei = *src_sei;

  if (dst_sei->payloadType == GST_H265_SEI_PIC_TIMING) {
    GstH265PicTiming *dst_pic_timing = &dst_sei->payload.pic_timing;
    const GstH265PicTiming *src_pic_timing = &src_sei->payload.pic_timing;

    if (dst_pic_timing->num_decoding_units_minus1 > 0) {
      dst_pic_timing->num_nalus_in_du_minus1 =
          g_new0 (guint32, (dst_pic_timing->num_decoding_units_minus1 + 1));
      dst_pic_timing->du_cpb_removal_delay_increment_minus1 =
          g_new0 (guint8, (dst_pic_timing->num_decoding_units_minus1 + 1));

      for (i = 0; i <= dst_pic_timing->num_decoding_units_minus1; i++) {
        dst_pic_timing->num_nalus_in_du_minus1[i] =
            src_pic_timing->num_nalus_in_du_minus1[i];
        dst_pic_timing->du_cpb_removal_delay_increment_minus1[i] =
            src_pic_timing->du_cpb_removal_delay_increment_minus1[i];
      }
    }
  }

  return TRUE;
}

/**
 * gst_h265_sei_free:
 * sei: The #GstH265SEIMessage to free
 *
 * Frees @sei fields.
 */
void
gst_h265_sei_free (GstH265SEIMessage * sei)
{
  g_return_if_fail (sei != NULL);

  if (sei->payloadType == GST_H265_SEI_PIC_TIMING) {
    GstH265PicTiming *pic_timing = &sei->payload.pic_timing;
    if (pic_timing->num_decoding_units_minus1 > 0) {
      g_free (pic_timing->num_nalus_in_du_minus1);
      g_free (pic_timing->du_cpb_removal_delay_increment_minus1);
    }
    pic_timing->num_nalus_in_du_minus1 = 0;
    pic_timing->du_cpb_removal_delay_increment_minus1 = 0;
  }
}

/**
 * gst_h265_parser_parse_sei:
 * @nalparser: a #GstH265Parser
 * @nalu: The #GST_H265_NAL_SEI #GstH265NalUnit to parse
 * @messages: The GArray of #GstH265SEIMessage to fill. The caller must free it when done.
 *
 * Parses @data, create and fills the @messages array.
 *
 * Returns: a #GstH265ParserResult
 */
GstH265ParserResult
gst_h265_parser_parse_sei (GstH265Parser * nalparser, GstH265NalUnit * nalu,
    GArray ** messages)
{
  NalReader nr;
  GstH265SEIMessage sei;
  GstH265ParserResult res;

  GST_DEBUG ("parsing SEI nal");
  nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
      nalu->size - nalu->header_bytes);
  *messages = g_array_new (FALSE, FALSE, sizeof (GstH265SEIMessage));
  g_array_set_clear_func (*messages, (GDestroyNotify) gst_h265_sei_free);

  do {
    res = gst_h265_parser_parse_sei_message (nalparser, nalu->type, &nr, &sei);
    if (res == GST_H265_PARSER_OK)
      g_array_append_val (*messages, sei);
    else
      break;
  } while (nal_reader_has_more_data (&nr));

  return res;
}


/**
 * gst_h265_quant_matrix_4x4_get_zigzag_from_raster:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from raster scan order to
 * zigzag scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
    const guint8 quant[16])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 16; i++)
    out_quant[i] = quant[zigzag_4x4[i]];
}

/**
 * gst_h265_quant_matrix_4x4_get_raster_from_zigzag:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from zigzag scan order to
 * raster scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
    const guint8 quant[16])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 16; i++)
    out_quant[zigzag_4x4[i]] = quant[i];
}

/**
 * gst_h265_quant_matrix_8x8_get_zigzag_from_raster:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from raster scan order to
 * zigzag scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[i] = quant[zigzag_8x8[i]];
}

/**
 * gst_h265_quant_matrix_8x8_get_raster_from_zigzag:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from zigzag scan order to
 * raster scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[zigzag_8x8[i]] = quant[i];
}

/**
 * gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from raster scan order to
 * uprightdiagonal scan order and store the resulting factors
 * into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_4x4_get_uprightdiagonal_from_raster (guint8 out_quant[16],
    const guint8 quant[16])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 16; i++)
    out_quant[i] = quant[uprightdiagonal_4x4[i]];
}

/**
 * gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from uprightdiagonal scan order to
 * raster scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_4x4_get_raster_from_uprightdiagonal (guint8 out_quant[16],
    const guint8 quant[16])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 16; i++)
    out_quant[uprightdiagonal_4x4[i]] = quant[i];
}

/**
 * gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from raster scan order to
 * uprightdiagonal scan order and store the resulting factors
 * into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_8x8_get_uprightdiagonal_from_raster (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[i] = quant[uprightdiagonal_8x8[i]];
}

/**
 * gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal:
 * @out_quant: (out): The resulting quantization matrix
 * @quant: The source quantization matrix
 *
 * Converts quantization matrix @quant from uprightdiagonal scan order to
 * raster scan order and store the resulting factors into @out_quant.
 *
 * Note: it is an error to pass the same table in both @quant and
 * @out_quant arguments.
 *
 * Since: 1.6
 */
void
gst_h265_quant_matrix_8x8_get_raster_from_uprightdiagonal (guint8 out_quant[64],
    const guint8 quant[64])
{
  guint i;

  g_return_if_fail (out_quant != quant);

  for (i = 0; i < 64; i++)
    out_quant[uprightdiagonal_8x8[i]] = quant[i];
}
