/* 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
 * @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 (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;
}
