/* gstvp9parser.c
 *
 *  Copyright (C) 2013-2014 Intel Corporation
 *  Copyright (C) 2015 Intel Corporation
 *    Author: XuGuangxin<Guangxin.Xu@intel.com>
 *    Author: 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:gstvp9parser
 * @title: GstVp9Parser
 * @short_description: Convenience library for parsing vp9 video bitstream.
 *
 * For more details about the structures, you can refer to the
 * specifications:
 */

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

#include <string.h>
#include <stdlib.h>
#include <gst/base/gstbitreader.h>
#include "vp9utils.h"
#include "gstvp9parser.h"

#define MIN_TILE_WIDTH_B64 4
#define MAX_TILE_WIDTH_B64 64

/* order of sb64, where sb64 = 64x64 */
#define ALIGN_SB64(w) ((w + 63) >> 6)

GST_DEBUG_CATEGORY_STATIC (gst_vp9_parser_debug);
#define GST_CAT_DEFAULT gst_vp9_parser_debug

static gboolean initialized = FALSE;
#define INITIALIZE_DEBUG_CATEGORY \
  if (!initialized) { \
    GST_DEBUG_CATEGORY_INIT (gst_vp9_parser_debug, "codecparsers_vp9", 0, \
        "vp9 parser library"); \
    initialized = TRUE; \
  }

#define gst_vp9_read_bit(br) gst_bit_reader_get_bits_uint8_unchecked(br, 1)
#define gst_vp9_read_bits(br, bits) gst_bit_reader_get_bits_uint32_unchecked(br, bits)

#define GST_VP9_PARSER_GET_PRIVATE(parser)  ((GstVp9ParserPrivate *)(parser->priv))

typedef struct _ReferenceSize
{
  guint32 width;
  guint32 height;
} ReferenceSize;

typedef struct
{
  /* for loop filters */
  gint8 ref_deltas[GST_VP9_MAX_REF_LF_DELTAS];
  gint8 mode_deltas[GST_VP9_MAX_MODE_LF_DELTAS];

  guint8 segmentation_abs_delta;
  GstVp9SegmentationInfoData segmentation[GST_VP9_MAX_SEGMENTS];

  ReferenceSize reference[GST_VP9_REF_FRAMES];
} GstVp9ParserPrivate;

static gint32
gst_vp9_read_signed_bits (GstBitReader * br, int bits)
{
  const gint32 value = gst_vp9_read_bits (br, bits);
  return gst_vp9_read_bit (br) ? -value : value;
}

static gboolean
verify_frame_marker (GstBitReader * br)
{
  guint8 frame_marker = gst_vp9_read_bits (br, 2);
  if (frame_marker != GST_VP9_FRAME_MARKER) {
    GST_ERROR ("Invalid VP9 Frame Marker !");
    return FALSE;
  }
  return TRUE;
}

static gboolean
verify_sync_code (GstBitReader * const br)
{
  return (gst_vp9_read_bits (br, 24) == GST_VP9_SYNC_CODE);
}

static gboolean
parse_bitdepth_colorspace_sampling (GstVp9Parser * parser,
    GstBitReader * const br, GstVp9FrameHdr * frame_hdr)
{
  if (frame_hdr->profile > GST_VP9_PROFILE_1)
    parser->bit_depth =
        gst_vp9_read_bit (br) ? GST_VP9_BIT_DEPTH_12 : GST_VP9_BIT_DEPTH_10;
  else
    parser->bit_depth = GST_VP9_BIT_DEPTH_8;

  parser->color_space = gst_vp9_read_bits (br, 3);
  if (parser->color_space != GST_VP9_CS_SRGB) {
    parser->color_range = gst_vp9_read_bit (br);

    if (frame_hdr->profile == GST_VP9_PROFILE_1
        || frame_hdr->profile == GST_VP9_PROFILE_3) {

      parser->subsampling_x = gst_vp9_read_bit (br);
      parser->subsampling_y = gst_vp9_read_bit (br);

      if (parser->subsampling_x == 1 && parser->subsampling_y == 1) {
        GST_ERROR
            ("4:2:0 subsampling is not supported in profile_1 or profile_3");
        goto error;
      }

      if (gst_vp9_read_bit (br)) {
        GST_ERROR ("Reserved bit set!");
        goto error;
      }
    } else {
      parser->subsampling_y = parser->subsampling_x = 1;
    }
  } else {
    parser->color_range = GST_VP9_CR_FULL;

    if (frame_hdr->profile == GST_VP9_PROFILE_1
        || frame_hdr->profile == GST_VP9_PROFILE_3) {
      if (gst_vp9_read_bit (br)) {
        GST_ERROR ("Reserved bit set!");
        goto error;
      }
    } else {
      GST_ERROR
          ("4:4:4 subsampling is not supported in profile_0 and profile_2");
      goto error;
    }
  }
  return TRUE;

error:
  return FALSE;
}

static guint
parse_profile (GstBitReader * br)
{
  guint8 profile = gst_vp9_read_bit (br);
  profile |= gst_vp9_read_bit (br) << 1;
  if (profile > 2)
    profile += gst_vp9_read_bit (br);
  return profile;
}

static void
parse_frame_size (GstBitReader * br, guint32 * width, guint32 * height)
{
  const guint32 w = gst_vp9_read_bits (br, 16) + 1;
  const guint32 h = gst_vp9_read_bits (br, 16) + 1;
  *width = w;
  *height = h;
}

static void
parse_display_frame_size (GstBitReader * br, GstVp9FrameHdr * frame_hdr)
{
  frame_hdr->display_size_enabled = gst_vp9_read_bit (br);
  if (frame_hdr->display_size_enabled)
    parse_frame_size (br, &frame_hdr->display_width,
        &frame_hdr->display_height);
}

static void
parse_frame_size_from_refs (const GstVp9Parser * parser,
    GstVp9FrameHdr * frame_hdr, GstBitReader * br)
{
  gboolean found = FALSE;
  int i;
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);

  for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
    found = gst_vp9_read_bit (br);

    if (found) {
      guint8 idx = frame_hdr->ref_frame_indices[i];
      frame_hdr->width = priv->reference[idx].width;
      frame_hdr->height = priv->reference[idx].height;
      break;
    }
  }
  if (!found)
    parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);
}

static GstVp9InterpolationFilter
parse_interp_filter (GstBitReader * br)
{
  static const GstVp9InterpolationFilter filter_map[] = {
    GST_VP9_INTERPOLATION_FILTER_EIGHTTAP_SMOOTH,
    GST_VP9_INTERPOLATION_FILTER_EIGHTTAP,
    GST_VP9_INTERPOLATION_FILTER_EIGHTTAP_SHARP,
    GST_VP9_INTERPOLATION_FILTER_BILINEAR
  };

  return gst_vp9_read_bit (br) ? GST_VP9_INTERPOLATION_FILTER_SWITCHABLE :
      filter_map[gst_vp9_read_bits (br, 2)];
}

static void
parse_loopfilter (GstVp9LoopFilter * lf, GstBitReader * br)
{
  lf->filter_level = gst_vp9_read_bits (br, 6);
  lf->sharpness_level = gst_vp9_read_bits (br, 3);

  lf->mode_ref_delta_update = 0;

  lf->mode_ref_delta_enabled = gst_vp9_read_bit (br);
  if (lf->mode_ref_delta_enabled) {
    lf->mode_ref_delta_update = gst_vp9_read_bit (br);
    if (lf->mode_ref_delta_update) {
      int i;
      for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) {
        lf->update_ref_deltas[i] = gst_vp9_read_bit (br);
        if (lf->update_ref_deltas[i])
          lf->ref_deltas[i] = gst_vp9_read_signed_bits (br, 6);
      }

      for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) {
        lf->update_mode_deltas[i] = gst_vp9_read_bit (br);
        if (lf->update_mode_deltas[i])
          lf->mode_deltas[i] = gst_vp9_read_signed_bits (br, 6);
      }
    }
  }
}

static gint8
parse_delta_q (GstBitReader * br)
{
  return gst_vp9_read_bit (br) ? gst_vp9_read_signed_bits (br, 4) : 0;
}

static void
parse_quantization (GstVp9QuantIndices * quant_indices, GstBitReader * br)
{
  quant_indices->y_ac_qi = gst_vp9_read_bits (br, QINDEX_BITS);
  quant_indices->y_dc_delta = parse_delta_q (br);
  quant_indices->uv_dc_delta = parse_delta_q (br);
  quant_indices->uv_ac_delta = parse_delta_q (br);
}

static void
parse_segmentation (GstVp9SegmentationInfo * seg, GstBitReader * br)
{
  int i;

  seg->update_map = FALSE;
  seg->update_data = FALSE;

  seg->enabled = gst_vp9_read_bit (br);
  if (!seg->enabled)
    return;

  /* Segmentation map update */
  seg->update_map = gst_vp9_read_bit (br);
  if (seg->update_map) {
    for (i = 0; i < GST_VP9_SEG_TREE_PROBS; i++) {
      seg->update_tree_probs[i] = gst_vp9_read_bit (br);
      seg->tree_probs[i] = seg->update_tree_probs[i] ?
          gst_vp9_read_bits (br, 8) : GST_VP9_MAX_PROB;
    }

    seg->temporal_update = gst_vp9_read_bit (br);
    if (seg->temporal_update) {
      for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++) {
        seg->update_pred_probs[i] = gst_vp9_read_bit (br);
        seg->pred_probs[i] = seg->update_pred_probs[i] ?
            gst_vp9_read_bits (br, 8) : GST_VP9_MAX_PROB;
      }
    } else {
      for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++)
        seg->pred_probs[i] = GST_VP9_MAX_PROB;
    }
  }

  /* Segmentation data update */
  seg->update_data = gst_vp9_read_bit (br);

  if (seg->update_data) {
    /* clear all features */
    memset (seg->data, 0, sizeof (seg->data));

    seg->abs_delta = gst_vp9_read_bit (br);

    for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
      GstVp9SegmentationInfoData *seg_data = seg->data + i;
      guint8 data;

      /* SEG_LVL_ALT_Q */
      seg_data->alternate_quantizer_enabled = gst_vp9_read_bit (br);
      if (seg_data->alternate_quantizer_enabled) {
        data = gst_vp9_read_bits (br, 8);
        seg_data->alternate_quantizer = gst_vp9_read_bit (br) ? -data : data;
      }

      /* SEG_LVL_ALT_LF */
      seg_data->alternate_loop_filter_enabled = gst_vp9_read_bit (br);
      if (seg_data->alternate_loop_filter_enabled) {
        data = gst_vp9_read_bits (br, 6);
        seg_data->alternate_loop_filter = gst_vp9_read_bit (br) ? -data : data;
      }

      /* SEG_LVL_REF_FRAME */
      seg_data->reference_frame_enabled = gst_vp9_read_bit (br);
      if (seg_data->reference_frame_enabled) {
        seg_data->reference_frame = gst_vp9_read_bits (br, 2);
      }

      seg_data->reference_skip = gst_vp9_read_bit (br);
    }
  }
}

static guint32
get_max_lb_tile_cols (guint32 sb_cols)
{
  gint max_log2 = 1;
  while ((sb_cols >> max_log2) >= MIN_TILE_WIDTH_B64)
    ++max_log2;
  return max_log2 - 1;
}

static guint32
get_min_lb_tile_cols (guint32 sb_cols)
{
  gint min_log2 = 0;
  while ((MAX_TILE_WIDTH_B64 << min_log2) < sb_cols)
    ++min_log2;
  return min_log2;
}

static gboolean
parse_tile_info (GstVp9FrameHdr * frame_hdr, GstBitReader * br)
{
  guint32 max_ones;
  const guint32 sb_cols = ALIGN_SB64 (frame_hdr->width);
  guint32 min_lb_tile_cols = get_min_lb_tile_cols (sb_cols);
  guint32 max_lb_tile_cols = get_max_lb_tile_cols (sb_cols);

  g_assert (min_lb_tile_cols <= max_lb_tile_cols);
  max_ones = max_lb_tile_cols - min_lb_tile_cols;

  /* columns */
  frame_hdr->log2_tile_columns = min_lb_tile_cols;
  while (max_ones-- && gst_vp9_read_bit (br))
    frame_hdr->log2_tile_columns++;

  if (frame_hdr->log2_tile_columns > 6) {
    GST_ERROR ("Invalid number of tile columns..!");
    return FALSE;
  }

  /* row */
  frame_hdr->log2_tile_rows = gst_vp9_read_bit (br);
  if (frame_hdr->log2_tile_rows)
    frame_hdr->log2_tile_rows += gst_vp9_read_bit (br);

  return TRUE;
}

static void
loop_filter_update (GstVp9Parser * parser, const GstVp9LoopFilter * lf)
{
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  int i;

  for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) {
    if (lf->update_ref_deltas[i])
      priv->ref_deltas[i] = lf->ref_deltas[i];
  }

  for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) {
    if (lf->update_mode_deltas[i])
      priv->mode_deltas[i] = lf->mode_deltas[i];
  }
}

static guint8
seg_get_base_qindex (const GstVp9Parser * parser,
    const GstVp9FrameHdr * frame_hdr, int segid)
{
  int seg_base = frame_hdr->quant_indices.y_ac_qi;
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  const GstVp9SegmentationInfoData *seg = priv->segmentation + segid;
  /* DEBUG("id = %d, seg_base = %d, seg enable = %d, alt eanble = %d, abs = %d, alt= %d\n",segid,
     seg_base, frame_hdr->segmentation.enabled, seg->alternate_quantizer_enabled, priv->segmentation_abs_delta,  seg->alternate_quantizer);
   */
  if (frame_hdr->segmentation.enabled && seg->alternate_quantizer_enabled) {
    if (priv->segmentation_abs_delta)
      seg_base = seg->alternate_quantizer;
    else
      seg_base += seg->alternate_quantizer;
  }
  return CLAMP (seg_base, 0, MAXQ);
}

static guint8
seg_get_filter_level (const GstVp9Parser * parser,
    const GstVp9FrameHdr * frame_hdr, int segid)
{
  int seg_filter = frame_hdr->loopfilter.filter_level;
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  const GstVp9SegmentationInfoData *seg = priv->segmentation + segid;

  if (frame_hdr->segmentation.enabled && seg->alternate_loop_filter_enabled) {
    if (priv->segmentation_abs_delta)
      seg_filter = seg->alternate_loop_filter;
    else
      seg_filter += seg->alternate_loop_filter;
  }
  return CLAMP (seg_filter, 0, GST_VP9_MAX_LOOP_FILTER);
}

/*save segmentation info from frame header to parser*/
static void
segmentation_save (GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
{
  const GstVp9SegmentationInfo *info = &frame_hdr->segmentation;
  if (!info->enabled)
    return;

  if (info->update_map) {
    g_assert (G_N_ELEMENTS (parser->mb_segment_tree_probs) ==
        G_N_ELEMENTS (info->tree_probs));
    g_assert (G_N_ELEMENTS (parser->segment_pred_probs) ==
        G_N_ELEMENTS (info->pred_probs));
    memcpy (parser->mb_segment_tree_probs, info->tree_probs,
        sizeof (info->tree_probs));
    memcpy (parser->segment_pred_probs, info->pred_probs,
        sizeof (info->pred_probs));
  }

  if (info->update_data) {
    GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
    priv->segmentation_abs_delta = info->abs_delta;
    g_assert (G_N_ELEMENTS (priv->segmentation) == G_N_ELEMENTS (info->data));
    memcpy (priv->segmentation, info->data, sizeof (info->data));
  }
}

static void
segmentation_update (GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
{
  int i = 0;
  const GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  const GstVp9LoopFilter *lf = &frame_hdr->loopfilter;
  const GstVp9QuantIndices *quant_indices = &frame_hdr->quant_indices;
  int default_filter = lf->filter_level;
  const int scale = 1 << (default_filter >> 5);

  segmentation_save (parser, frame_hdr);

  for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
    guint8 q = seg_get_base_qindex (parser, frame_hdr, i);

    GstVp9Segmentation *seg = parser->segmentation + i;
    const GstVp9SegmentationInfoData *info = priv->segmentation + i;

    seg->luma_dc_quant_scale =
        gst_vp9_dc_quant (q, quant_indices->y_dc_delta, parser->bit_depth);
    seg->luma_ac_quant_scale = gst_vp9_ac_quant (q, 0, parser->bit_depth);
    seg->chroma_dc_quant_scale =
        gst_vp9_dc_quant (q, quant_indices->uv_dc_delta, parser->bit_depth);
    seg->chroma_ac_quant_scale =
        gst_vp9_ac_quant (q, quant_indices->uv_ac_delta, parser->bit_depth);

    if (lf->filter_level) {
      guint8 filter = seg_get_filter_level (parser, frame_hdr, i);

      if (!lf->mode_ref_delta_enabled) {
        memset (seg->filter_level, filter, sizeof (seg->filter_level));
      } else {
        int ref, mode;
        const int intra_filter =
            filter + priv->ref_deltas[GST_VP9_REF_FRAME_INTRA] * scale;
        seg->filter_level[GST_VP9_REF_FRAME_INTRA][0] =
            CLAMP (intra_filter, 0, GST_VP9_MAX_LOOP_FILTER);
        for (ref = GST_VP9_REF_FRAME_LAST; ref < GST_VP9_REF_FRAME_MAX; ++ref) {
          for (mode = 0; mode < GST_VP9_MAX_MODE_LF_DELTAS; ++mode) {
            const int inter_filter = filter + priv->ref_deltas[ref] * scale
                + priv->mode_deltas[mode] * scale;
            seg->filter_level[ref][mode] =
                CLAMP (inter_filter, 0, GST_VP9_MAX_LOOP_FILTER);
          }
        }
      }
    }
    seg->reference_frame_enabled = info->reference_frame_enabled;;
    seg->reference_frame = info->reference_frame;
    seg->reference_skip = info->reference_skip;
  }
}

static void
reference_update (GstVp9Parser * parser, const GstVp9FrameHdr * const frame_hdr)
{
  guint8 flag = 1;
  guint8 refresh_frame_flags;
  int i;
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  ReferenceSize *reference = priv->reference;
  if (frame_hdr->frame_type == GST_VP9_KEY_FRAME) {
    refresh_frame_flags = 0xff;
  } else {
    refresh_frame_flags = frame_hdr->refresh_frame_flags;
  }
  for (i = 0; i < GST_VP9_REF_FRAMES; i++) {
    if (refresh_frame_flags & flag) {
      reference[i].width = frame_hdr->width;
      reference[i].height = frame_hdr->height;
    }
    flag <<= 1;
  }
}

static inline int
frame_is_intra_only (const GstVp9FrameHdr * frame_hdr)
{
  return frame_hdr->frame_type == GST_VP9_KEY_FRAME || frame_hdr->intra_only;
}

static void
set_default_lf_deltas (GstVp9Parser * parser)
{
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);
  priv->ref_deltas[GST_VP9_REF_FRAME_INTRA] = 1;
  priv->ref_deltas[GST_VP9_REF_FRAME_LAST] = 0;
  priv->ref_deltas[GST_VP9_REF_FRAME_GOLDEN] = -1;
  priv->ref_deltas[GST_VP9_REF_FRAME_ALTREF] = -1;

  priv->mode_deltas[0] = 0;
  priv->mode_deltas[1] = 0;
}

static void
set_default_segmentation_info (GstVp9Parser * parser)
{
  GstVp9ParserPrivate *priv = GST_VP9_PARSER_GET_PRIVATE (parser);

  memset (priv->segmentation, 0, sizeof (priv->segmentation));

  priv->segmentation_abs_delta = FALSE;
}

static void
setup_past_independence (GstVp9Parser * parser,
    GstVp9FrameHdr * const frame_hdr)
{
  set_default_lf_deltas (parser);
  set_default_segmentation_info (parser);

  memset (frame_hdr->ref_frame_sign_bias, 0,
      sizeof (frame_hdr->ref_frame_sign_bias));
}

static void
gst_vp9_parser_reset (GstVp9Parser * parser)
{
  GstVp9ParserPrivate *priv = parser->priv;

  parser->priv = NULL;
  memset (parser->mb_segment_tree_probs, 0,
      sizeof (parser->mb_segment_tree_probs));
  memset (parser->segment_pred_probs, 0, sizeof (parser->segment_pred_probs));
  memset (parser->segmentation, 0, sizeof (parser->segmentation));

  memset (priv, 0, sizeof (GstVp9ParserPrivate));
  parser->priv = priv;
}

static GstVp9ParserResult
gst_vp9_parser_update (GstVp9Parser * parser, GstVp9FrameHdr * const frame_hdr)
{
  if (frame_hdr->frame_type == GST_VP9_KEY_FRAME)
    gst_vp9_parser_reset (parser);

  if (frame_is_intra_only (frame_hdr) || frame_hdr->error_resilient_mode)
    setup_past_independence (parser, frame_hdr);

  loop_filter_update (parser, &frame_hdr->loopfilter);
  segmentation_update (parser, frame_hdr);
  reference_update (parser, frame_hdr);

  return GST_VP9_PARSER_OK;
}


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

/**
 * gst_vp9_parser_new:
 *
 * Creates a new #GstVp9Parser. It should be freed with
 * gst_vp9_parser_free() after use.
 *
 * Returns: a new #GstVp9Parser
 *
 * Since: 1.8
 */
GstVp9Parser *
gst_vp9_parser_new (void)
{
  GstVp9Parser *parser;
  GstVp9ParserPrivate *priv;

  INITIALIZE_DEBUG_CATEGORY;
  GST_DEBUG ("Create VP9 Parser");

  parser = g_slice_new0 (GstVp9Parser);
  if (!parser)
    return NULL;

  priv = g_slice_new0 (GstVp9ParserPrivate);
  if (!priv)
    return NULL;

  parser->priv = priv;

  return parser;
}

/**
 * gst_vp9_parser_free:
 * @parser: the #GstVp9Parser to free
 *
 * Frees @parser.
 *
 * Since: 1.8
 */
void
gst_vp9_parser_free (GstVp9Parser * parser)
{
  if (parser) {
    if (parser->priv) {
      g_slice_free (GstVp9ParserPrivate, parser->priv);
      parser->priv = NULL;
    }
    g_slice_free (GstVp9Parser, parser);
  }
}

/**
 * gst_vp9_parser_parse_frame_header:
 * @parser: The #GstVp9Parser
 * @frame_hdr: The #GstVp9FrameHdr to fill
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses the VP9 bitstream contained in @data, and fills in @frame_hdr
 * with the information. The @size argument represent the whole frame size.
 *
 * Returns: a #GstVp9ParserResult
 *
 * Since: 1.8
 */
GstVp9ParserResult
gst_vp9_parser_parse_frame_header (GstVp9Parser * parser,
    GstVp9FrameHdr * frame_hdr, const guint8 * data, gsize size)
{
  GstBitReader bit_reader;
  GstBitReader *br = &bit_reader;

  gst_bit_reader_init (br, data, size);
  memset (frame_hdr, 0, sizeof (*frame_hdr));

  /* Parsing Uncompressed Data Chunk */

  if (!verify_frame_marker (br))
    goto error;

  frame_hdr->profile = parse_profile (br);
  if (frame_hdr->profile > GST_VP9_PROFILE_UNDEFINED) {
    GST_ERROR ("Stream has undefined VP9  profile !");
    goto error;
  }

  frame_hdr->show_existing_frame = gst_vp9_read_bit (br);
  if (frame_hdr->show_existing_frame) {
    frame_hdr->frame_to_show = gst_vp9_read_bits (br, GST_VP9_REF_FRAMES_LOG2);
    return GST_VP9_PARSER_OK;
  }

  frame_hdr->frame_type = gst_vp9_read_bit (br);
  frame_hdr->show_frame = gst_vp9_read_bit (br);
  frame_hdr->error_resilient_mode = gst_vp9_read_bit (br);

  if (frame_hdr->frame_type == GST_VP9_KEY_FRAME) {

    if (!verify_sync_code (br)) {
      GST_ERROR ("Invalid VP9 Key-frame sync code !");
      goto error;
    }

    if (!parse_bitdepth_colorspace_sampling (parser, br, frame_hdr)) {
      GST_ERROR ("Failed to parse color_space/bit_depth info !");
      goto error;
    }

    parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);

    parse_display_frame_size (br, frame_hdr);

  } else {
    frame_hdr->intra_only = frame_hdr->show_frame ? 0 : gst_vp9_read_bit (br);
    frame_hdr->reset_frame_context = frame_hdr->error_resilient_mode ?
        0 : gst_vp9_read_bits (br, 2);

    if (frame_hdr->intra_only) {

      if (!verify_sync_code (br)) {
        GST_ERROR ("Invalid VP9 sync code in intra-only frame !");
        goto error;
      }

      if (frame_hdr->profile > GST_VP9_PROFILE_0) {
        if (!parse_bitdepth_colorspace_sampling (parser, br, frame_hdr)) {
          GST_ERROR ("Failed to parse color_space/bit_depth info !");
          goto error;
        }
      } else {
        parser->color_space = GST_VP9_CS_BT_601;
        parser->color_range = GST_VP9_CR_LIMITED;
        parser->subsampling_y = parser->subsampling_x = 1;
        parser->bit_depth = GST_VP9_BIT_DEPTH_8;
      }

      frame_hdr->refresh_frame_flags =
          gst_vp9_read_bits (br, GST_VP9_REF_FRAMES);
      parse_frame_size (br, &frame_hdr->width, &frame_hdr->height);
      parse_display_frame_size (br, frame_hdr);

    } else {
      int i;
      frame_hdr->refresh_frame_flags =
          gst_vp9_read_bits (br, GST_VP9_REF_FRAMES);

      for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
        frame_hdr->ref_frame_indices[i] =
            gst_vp9_read_bits (br, GST_VP9_REF_FRAMES_LOG2);
        frame_hdr->ref_frame_sign_bias[i] = gst_vp9_read_bit (br);
      }

      parse_frame_size_from_refs (parser, frame_hdr, br);
      parse_display_frame_size (br, frame_hdr);

      frame_hdr->allow_high_precision_mv = gst_vp9_read_bit (br);
      frame_hdr->mcomp_filter_type = parse_interp_filter (br);
    }
  }

  frame_hdr->refresh_frame_context =
      frame_hdr->error_resilient_mode ? 0 : gst_vp9_read_bit (br);
  frame_hdr->frame_parallel_decoding_mode =
      frame_hdr->error_resilient_mode ? 1 : gst_vp9_read_bit (br);
  frame_hdr->frame_context_idx =
      gst_vp9_read_bits (br, GST_VP9_FRAME_CONTEXTS_LOG2);

  /* loopfilter header  */
  parse_loopfilter (&frame_hdr->loopfilter, br);

  /* quantization header */
  parse_quantization (&frame_hdr->quant_indices, br);
  /* set lossless_flag */
  frame_hdr->lossless_flag = frame_hdr->quant_indices.y_ac_qi == 0 &&
      frame_hdr->quant_indices.y_dc_delta == 0 &&
      frame_hdr->quant_indices.uv_dc_delta == 0
      && frame_hdr->quant_indices.uv_ac_delta == 0;

  /* segmentation header */
  parse_segmentation (&frame_hdr->segmentation, br);

  /* tile header */
  if (!parse_tile_info (frame_hdr, br)) {
    GST_ERROR ("Failed to parse tile info...!");
    goto error;
  }

  /* size of the rest of the header */
  frame_hdr->first_partition_size = gst_vp9_read_bits (br, 16);
  if (!frame_hdr->first_partition_size) {
    GST_ERROR ("Failed to parse the first partition size...!");
    goto error;
  }

  frame_hdr->frame_header_length_in_bytes =
      (gst_bit_reader_get_pos (br) + 7) / 8;
  return gst_vp9_parser_update (parser, frame_hdr);

error:
  return GST_VP9_PARSER_ERROR;
}
