codecs: vp9decoder: Port to GstVp9StatefulParser
authorSeungha Yang <seungha@centricular.com>
Tue, 30 Mar 2021 02:49:43 +0000 (11:49 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 7 Apr 2021 19:32:29 +0000 (19:32 +0000)
Use newly implemented VP9 parser. Since new GstVp9FrameHeader
struct holds all the information of the stream, baseclass will not
pass parser object to new_sequence() method anymore.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2112>

gst-libs/gst/codecs/gstvp9decoder.c
gst-libs/gst/codecs/gstvp9decoder.h
gst-libs/gst/codecs/gstvp9picture.h
sys/d3d11/gstd3d11vp9dec.cpp
sys/nvcodec/gstnvvp9dec.c
sys/va/gstvavp9dec.c

index e38ff4e..3e02672 100644 (file)
@@ -71,7 +71,7 @@ struct _GstVp9DecoderPrivate
 
   gboolean had_sequence;
 
-  GstVp9Parser *parser;
+  GstVp9StatefulParser *parser;
   GstVp9Dpb *dpb;
 
   gboolean wait_keyframe;
@@ -129,7 +129,7 @@ gst_vp9_decoder_start (GstVideoDecoder * decoder)
   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
   GstVp9DecoderPrivate *priv = self->priv;
 
-  priv->parser = gst_vp9_parser_new ();
+  priv->parser = gst_vp9_stateful_parser_new ();
   priv->dpb = gst_vp9_dpb_new ();
   priv->wait_keyframe = TRUE;
 
@@ -142,27 +142,16 @@ gst_vp9_decoder_stop (GstVideoDecoder * decoder)
   GstVp9Decoder *self = GST_VP9_DECODER (decoder);
   GstVp9DecoderPrivate *priv = self->priv;
 
-  if (self->input_state) {
-    gst_video_codec_state_unref (self->input_state);
-    self->input_state = NULL;
-  }
-
-  if (priv->parser) {
-    gst_vp9_parser_free (priv->parser);
-    priv->parser = NULL;
-  }
-
-  if (priv->dpb) {
-    gst_vp9_dpb_free (priv->dpb);
-    priv->dpb = NULL;
-  }
+  g_clear_pointer (&self->input_state, gst_video_codec_state_unref);
+  g_clear_pointer (&priv->parser, gst_vp9_stateful_parser_free);
+  g_clear_pointer (&priv->dpb, gst_vp9_dpb_free);
 
   return TRUE;
 }
 
 static gboolean
 gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
-    const GstVp9FrameHdr * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr)
 {
   GstVp9DecoderPrivate *priv = self->priv;
   gboolean ret = TRUE;
@@ -187,7 +176,7 @@ gst_vp9_decoder_check_codec_change (GstVp9Decoder * self,
 
     priv->had_sequence = TRUE;
     if (klass->new_sequence)
-      priv->had_sequence = klass->new_sequence (self, priv->parser, frame_hdr);
+      priv->had_sequence = klass->new_sequence (self, frame_hdr);
 
     ret = priv->had_sequence;
   }
@@ -276,7 +265,7 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
   GstVp9DecoderClass *klass = GST_VP9_DECODER_GET_CLASS (self);
   GstVp9DecoderPrivate *priv = self->priv;
   GstBuffer *in_buf = frame->input_buffer;
-  GstVp9FrameHdr frame_hdr;
+  GstVp9FrameHeader frame_hdr;
   GstVp9Picture *picture = NULL;
   GstVp9ParserResult pres;
   GstMapInfo map;
@@ -289,7 +278,7 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
     goto error;
   }
 
-  pres = gst_vp9_parser_parse_frame_header (priv->parser, &frame_hdr,
+  pres = gst_vp9_stateful_parser_parse_frame_header (priv->parser, &frame_hdr,
       map.data, map.size);
 
   if (pres != GST_VP9_PARSER_OK) {
@@ -324,15 +313,15 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
   if (frame_hdr.show_existing_frame) {
     GstVp9Picture *pic_to_dup;
 
-    if (frame_hdr.frame_to_show >= GST_VP9_REF_FRAMES ||
-        !priv->dpb->pic_list[frame_hdr.frame_to_show]) {
-      GST_ERROR_OBJECT (self, "Invalid frame_to_show %d",
-          frame_hdr.frame_to_show);
+    if (frame_hdr.frame_to_show_map_idx >= GST_VP9_REF_FRAMES ||
+        !priv->dpb->pic_list[frame_hdr.frame_to_show_map_idx]) {
+      GST_ERROR_OBJECT (self, "Invalid frame_to_show_map_idx %d",
+          frame_hdr.frame_to_show_map_idx);
       goto unmap_and_error;
     }
 
     g_assert (klass->duplicate_picture);
-    pic_to_dup = priv->dpb->pic_list[frame_hdr.frame_to_show];
+    pic_to_dup = priv->dpb->pic_list[frame_hdr.frame_to_show_map_idx];
     picture = klass->duplicate_picture (self, pic_to_dup);
 
     if (!picture) {
@@ -346,13 +335,6 @@ gst_vp9_decoder_handle_frame (GstVideoDecoder * decoder,
     picture->data = map.data;
     picture->size = map.size;
 
-    picture->subsampling_x = priv->parser->subsampling_x;
-    picture->subsampling_y = priv->parser->subsampling_y;
-    picture->bit_depth = priv->parser->bit_depth;
-
-    memcpy (picture->segmentation, priv->parser->segmentation,
-        sizeof (priv->parser->segmentation));
-
     if (klass->new_picture) {
       if (!klass->new_picture (self, frame, picture)) {
         GST_ERROR_OBJECT (self, "new picture error");
index f25252f..f75085b 100644 (file)
@@ -23,7 +23,6 @@
 #include <gst/codecs/codecs-prelude.h>
 
 #include <gst/video/video.h>
-#include <gst/codecparsers/gstvp9parser.h>
 #include <gst/codecs/gstvp9picture.h>
 
 G_BEGIN_DECLS
@@ -85,8 +84,7 @@ struct _GstVp9DecoderClass
   GstVideoDecoderClass parent_class;
 
   gboolean        (*new_sequence)      (GstVp9Decoder * decoder,
-                                        const GstVp9Parser * parser,
-                                        const GstVp9FrameHdr * frame_hdr);
+                                        const GstVp9FrameHeader *frame_hdr);
 
   /**
    * GstVp9Decoder:new_picture:
index dc71202..29bcd18 100644 (file)
@@ -21,7 +21,7 @@
 #define __GST_VP9_PICTURE_H__
 
 #include <gst/codecs/codecs-prelude.h>
-#include <gst/codecparsers/gstvp9parser.h>
+#include <gst/codecs/gstvp9statefulparser.h>
 
 G_BEGIN_DECLS
 
@@ -40,12 +40,7 @@ struct _GstVp9Picture
   /* From GstVideoCodecFrame */
   guint32 system_frame_number;
 
-  GstVp9FrameHdr frame_hdr;
-
-  /* copied from parser */
-  gint subsampling_x;
-  gint subsampling_y;
-  guint bit_depth;
+  GstVp9FrameHeader frame_hdr;
 
   /* raw data and size (does not have ownership) */
   const guint8 * data;
@@ -53,8 +48,6 @@ struct _GstVp9Picture
 
   gpointer user_data;
   GDestroyNotify notify;
-
-  GstVp9Segmentation segmentation[GST_VP9_MAX_SEGMENTS];
 };
 
 GST_CODECS_API
index e01e89f..a1ae106 100644 (file)
@@ -137,7 +137,7 @@ static gboolean gst_d3d11_vp9_dec_flush (GstVideoDecoder * decoder);
 
 /* GstVp9Decoder */
 static gboolean gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr);
+    const GstVp9FrameHeader * frame_hdr);
 static gboolean gst_d3d11_vp9_dec_new_picture (GstVp9Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp9Picture * picture);
 static GstVp9Picture *gst_d3d11_vp9_dec_duplicate_picture (GstVp9Decoder *
@@ -356,7 +356,7 @@ gst_d3d11_vp9_dec_flush (GstVideoDecoder * decoder)
 
 static gboolean
 gst_d3d11_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr)
 {
   GstD3D11Vp9Dec *self = GST_D3D11_VP9_DEC (decoder);
   GstVideoInfo info;
@@ -529,15 +529,14 @@ static void
 gst_d3d11_vp9_dec_copy_frame_params (GstD3D11Vp9Dec * self,
     GstVp9Picture * picture, DXVA_PicParams_VP9 * params)
 {
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
 
   params->profile = frame_hdr->profile;
-
   params->frame_type = frame_hdr->frame_type;
   params->show_frame = frame_hdr->show_frame;
   params->error_resilient_mode = frame_hdr->error_resilient_mode;
-  params->subsampling_x = picture->subsampling_x;
-  params->subsampling_y = picture->subsampling_y;
+  params->subsampling_x = frame_hdr->subsampling_x;
+  params->subsampling_y = frame_hdr->subsampling_y;
   params->refresh_frame_context = frame_hdr->refresh_frame_context;
   params->frame_parallel_decoding_mode =
       frame_hdr->frame_parallel_decoding_mode;
@@ -551,12 +550,12 @@ gst_d3d11_vp9_dec_copy_frame_params (GstD3D11Vp9Dec * self,
 
   params->width = frame_hdr->width;
   params->height = frame_hdr->height;
-  params->BitDepthMinus8Luma = picture->bit_depth - 8;
-  params->BitDepthMinus8Chroma = picture->bit_depth - 8;
+  params->BitDepthMinus8Luma = frame_hdr->bit_depth - 8;
+  params->BitDepthMinus8Chroma = frame_hdr->bit_depth - 8;
 
-  params->interp_filter = frame_hdr->mcomp_filter_type;
-  params->log2_tile_cols = frame_hdr->log2_tile_columns;
-  params->log2_tile_rows = frame_hdr->log2_tile_rows;
+  params->interp_filter = frame_hdr->interpolation_filter;
+  params->log2_tile_cols = frame_hdr->tile_cols_log2;
+  params->log2_tile_rows = frame_hdr->tile_rows_log2;
 }
 
 static void
@@ -593,92 +592,103 @@ static void
 gst_d3d11_vp9_dec_copy_frame_refs (GstD3D11Vp9Dec * self,
     GstVp9Picture * picture, DXVA_PicParams_VP9 * params)
 {
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
   gint i;
 
   for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
-    params->frame_refs[i] =
-        params->ref_frame_map[frame_hdr->ref_frame_indices[i]];
+    params->frame_refs[i] = params->ref_frame_map[frame_hdr->ref_frame_idx[i]];
   }
 
-  for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
-    params->ref_frame_sign_bias[i + 1] = frame_hdr->ref_frame_sign_bias[i];
-  }
+  G_STATIC_ASSERT (G_N_ELEMENTS (params->ref_frame_sign_bias) ==
+      G_N_ELEMENTS (frame_hdr->ref_frame_sign_bias));
+  G_STATIC_ASSERT (sizeof (params->ref_frame_sign_bias) ==
+      sizeof (frame_hdr->ref_frame_sign_bias));
+  memcpy (params->ref_frame_sign_bias,
+      frame_hdr->ref_frame_sign_bias, sizeof (frame_hdr->ref_frame_sign_bias));
 }
 
 static void
 gst_d3d11_vp9_dec_copy_loop_filter_params (GstD3D11Vp9Dec * self,
     GstVp9Picture * picture, DXVA_PicParams_VP9 * params)
 {
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
-  const GstVp9LoopFilter *loopfilter = &frame_hdr->loopfilter;
-  gint i;
-
-  params->filter_level = loopfilter->filter_level;
-  params->sharpness_level = loopfilter->sharpness_level;
-  params->mode_ref_delta_enabled = loopfilter->mode_ref_delta_enabled;
-  params->mode_ref_delta_update = loopfilter->mode_ref_delta_update;
-
-  for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) {
-    params->ref_deltas[i] = loopfilter->ref_deltas[i];
-  }
-
-  for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) {
-    params->mode_deltas[i] = loopfilter->mode_deltas[i];
-  }
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9LoopFilterParams *lfp = &frame_hdr->loop_filter_params;
+
+  params->filter_level = lfp->loop_filter_level;
+  params->sharpness_level = lfp->loop_filter_sharpness;
+  params->mode_ref_delta_enabled = lfp->loop_filter_delta_enabled;
+  params->mode_ref_delta_update = lfp->loop_filter_delta_update;
+
+  G_STATIC_ASSERT (G_N_ELEMENTS (params->ref_deltas) ==
+      G_N_ELEMENTS (lfp->loop_filter_ref_deltas));
+  G_STATIC_ASSERT (sizeof (params->ref_deltas) ==
+      sizeof (lfp->loop_filter_ref_deltas));
+  memcpy (params->ref_deltas, lfp->loop_filter_ref_deltas,
+      sizeof (lfp->loop_filter_ref_deltas));
+
+  G_STATIC_ASSERT (G_N_ELEMENTS (params->mode_deltas) ==
+      G_N_ELEMENTS (lfp->loop_filter_mode_deltas));
+  G_STATIC_ASSERT (sizeof (params->mode_deltas) ==
+      sizeof (lfp->loop_filter_mode_deltas));
+  memcpy (params->mode_deltas, lfp->loop_filter_mode_deltas,
+      sizeof (lfp->loop_filter_mode_deltas));
 }
 
 static void
 gst_d3d11_vp9_dec_copy_quant_params (GstD3D11Vp9Dec * self,
     GstVp9Picture * picture, DXVA_PicParams_VP9 * params)
 {
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
-  const GstVp9QuantIndices *quant_indices = &frame_hdr->quant_indices;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9QuantizationParams *qp = &frame_hdr->quantization_params;
 
-  params->base_qindex = quant_indices->y_ac_qi;
-  params->y_dc_delta_q = quant_indices->y_dc_delta;
-  params->uv_dc_delta_q = quant_indices->uv_dc_delta;
-  params->uv_ac_delta_q = quant_indices->uv_ac_delta;
+  params->base_qindex = qp->base_q_idx;
+  params->y_dc_delta_q = qp->delta_q_y_dc;
+  params->uv_dc_delta_q = qp->delta_q_uv_dc;
+  params->uv_ac_delta_q = qp->delta_q_uv_ac;
 }
 
 static void
 gst_d3d11_vp9_dec_copy_segmentation_params (GstD3D11Vp9Dec * self,
     GstVp9Picture * picture, DXVA_PicParams_VP9 * params)
 {
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
-  const GstVp9SegmentationInfo *seg = &frame_hdr->segmentation;
-  gint i;
-
-  params->stVP9Segments.enabled = seg->enabled;
-  params->stVP9Segments.update_map = seg->update_map;
-  params->stVP9Segments.temporal_update = seg->temporal_update;
-  params->stVP9Segments.abs_delta = seg->abs_delta;
-
-  for (i = 0; i < GST_VP9_SEG_TREE_PROBS; i++)
-    params->stVP9Segments.tree_probs[i] = seg->tree_probs[i];
-
-  for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++)
-    params->stVP9Segments.pred_probs[i] = seg->pred_probs[i];
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9SegmentationParams *sp = &frame_hdr->segmentation_params;
+  gint i, j;
+
+  params->stVP9Segments.enabled = sp->segmentation_enabled;
+  params->stVP9Segments.update_map = sp->segmentation_update_map;
+  params->stVP9Segments.temporal_update = sp->segmentation_temporal_update;
+  params->stVP9Segments.abs_delta = sp->segmentation_abs_or_delta_update;
+
+  G_STATIC_ASSERT (G_N_ELEMENTS (params->stVP9Segments.tree_probs) ==
+      G_N_ELEMENTS (sp->segmentation_tree_probs));
+  G_STATIC_ASSERT (sizeof (params->stVP9Segments.tree_probs) ==
+      sizeof (sp->segmentation_tree_probs));
+  memcpy (params->stVP9Segments.tree_probs, sp->segmentation_tree_probs,
+      sizeof (sp->segmentation_tree_probs));
+
+  G_STATIC_ASSERT (G_N_ELEMENTS (params->stVP9Segments.pred_probs) ==
+      G_N_ELEMENTS (sp->segmentation_pred_prob));
+  G_STATIC_ASSERT (sizeof (params->stVP9Segments.pred_probs) ==
+      sizeof (sp->segmentation_pred_prob));
+
+  if (sp->segmentation_temporal_update) {
+    memcpy (params->stVP9Segments.pred_probs, sp->segmentation_pred_prob,
+        sizeof (params->stVP9Segments.pred_probs));
+  } else {
+    memset (params->stVP9Segments.pred_probs, 255,
+        sizeof (params->stVP9Segments.pred_probs));
+  }
 
   for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
-    params->stVP9Segments.feature_mask[i] = 0;
-
-    if (seg->data[i].alternate_quantizer_enabled)
-      params->stVP9Segments.feature_mask[i] |= (1 << 0);
-
-    if (seg->data[i].alternate_loop_filter_enabled)
-      params->stVP9Segments.feature_mask[i] |= (1 << 1);
-
-    if (seg->data[i].reference_frame_enabled)
-      params->stVP9Segments.feature_mask[i] |= (1 << 2);
-
-    if (seg->data[i].reference_skip)
-      params->stVP9Segments.feature_mask[i] |= (1 << 3);
-
-    params->stVP9Segments.feature_data[i][0] = seg->data[i].alternate_quantizer;
-    params->stVP9Segments.feature_data[i][1] =
-        seg->data[i].alternate_loop_filter;
-    params->stVP9Segments.feature_data[i][2] = seg->data[i].reference_frame;
+    params->stVP9Segments.feature_mask[i] =
+        (sp->feature_enabled[i][GST_VP9_SEG_LVL_ALT_Q] << 0) |
+        (sp->feature_enabled[i][GST_VP9_SEG_LVL_ALT_L] << 1) |
+        (sp->feature_enabled[i][GST_VP9_SEG_LVL_REF_FRAME] << 2) |
+        (sp->feature_enabled[i][GST_VP9_SEG_SEG_LVL_SKIP] << 3);
+
+    for (j = 0; j < 3; j++)
+      params->stVP9Segments.feature_data[i][j] = sp->feature_data[i][j];
     params->stVP9Segments.feature_data[i][3] = 0;
   }
 }
@@ -878,7 +888,7 @@ gst_d3d11_vp9_dec_decode_picture (GstVp9Decoder * decoder,
   pic_params.CurrPic.Index7Bits = view_id;
   pic_params.uncompressed_header_size_byte_aligned =
       picture->frame_hdr.frame_header_length_in_bytes;
-  pic_params.first_partition_size = picture->frame_hdr.first_partition_size;
+  pic_params.first_partition_size = picture->frame_hdr.header_size_in_bytes;
   pic_params.StatusReportFeedbackNumber = 1;
 
   gst_d3d11_vp9_dec_copy_frame_params (self, picture, &pic_params);
index b987328..fb269e9 100644 (file)
@@ -74,7 +74,7 @@ static gboolean gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder,
 
 /* GstVp9Decoder */
 static gboolean gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr);
+    const GstVp9FrameHeader * frame_hdr);
 static gboolean gst_nv_vp9_dec_new_picture (GstVp9Decoder * decoder,
     GstVideoCodecFrame * frame, GstVp9Picture * picture);
 static GstVp9Picture *gst_nv_vp9_dec_duplicate_picture (GstVp9Decoder *
@@ -232,70 +232,47 @@ gst_nv_vp9_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
 
 static gboolean
 gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
-    const GstVp9Parser * parser, const GstVp9FrameHdr * frame_hdr)
+    const GstVp9FrameHeader * frame_hdr)
 {
   GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
-  gboolean modified = FALSE;
+  GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
+  GstVideoInfo info;
 
   GST_LOG_OBJECT (self, "new sequence");
 
-  if (self->width != frame_hdr->width || self->height != frame_hdr->height) {
-    if (self->decoder) {
-      GST_INFO_OBJECT (self, "resolution changed %dx%d -> %dx%d",
-          self->width, self->height, frame_hdr->width, frame_hdr->height);
-    }
+  self->width = frame_hdr->width;
+  self->height = frame_hdr->height;
 
-    self->width = frame_hdr->width;
-    self->height = frame_hdr->height;
-    modified = TRUE;
+  if (self->profile == GST_VP9_PROFILE_0) {
+    out_format = GST_VIDEO_FORMAT_NV12;
+  } else if (self->profile == GST_VP9_PROFILE_2) {
+    if (frame_hdr->bit_depth == 10)
+      out_format = GST_VIDEO_FORMAT_P010_10LE;
+    else
+      out_format = GST_VIDEO_FORMAT_P016_LE;
   }
 
-  if (self->profile != frame_hdr->profile) {
-    if (self->decoder) {
-      GST_INFO_OBJECT (self, "profile changed %d -> %d", self->profile,
-          frame_hdr->profile);
-    }
-
-    self->profile = frame_hdr->profile;
-    modified = TRUE;
+  if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
+    GST_ERROR_OBJECT (self, "Could not support profile %d", self->profile);
+    return FALSE;
   }
 
-  if (modified || !gst_nv_decoder_is_configured (self->decoder)) {
-    GstVideoInfo info;
-    GstVideoFormat out_format = GST_VIDEO_FORMAT_UNKNOWN;
-
-    if (self->profile == GST_VP9_PROFILE_0) {
-      out_format = GST_VIDEO_FORMAT_NV12;
-    } else if (self->profile == GST_VP9_PROFILE_2) {
-      if (parser->bit_depth == 10)
-        out_format = GST_VIDEO_FORMAT_P010_10LE;
-      else
-        out_format = GST_VIDEO_FORMAT_P016_LE;
-    }
-
-    if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
-      GST_ERROR_OBJECT (self, "Could not support profile %d", self->profile);
-      return FALSE;
-    }
-
-    gst_video_info_set_format (&info, out_format, self->width, self->height);
-
-    if (!gst_nv_decoder_configure (self->decoder,
-            cudaVideoCodec_VP9, &info, self->width, self->height,
-            NUM_OUTPUT_VIEW)) {
-      GST_ERROR_OBJECT (self, "Failed to configure decoder");
-      return FALSE;
-    }
+  gst_video_info_set_format (&info, out_format, self->width, self->height);
+  if (!gst_nv_decoder_configure (self->decoder,
+          cudaVideoCodec_VP9, &info, self->width, self->height,
+          NUM_OUTPUT_VIEW)) {
+    GST_ERROR_OBJECT (self, "Failed to configure decoder");
+    return FALSE;
+  }
 
-    if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
-      GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
-      return FALSE;
-    }
+  if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
+    GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
+    return FALSE;
+  }
 
-    memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
+  memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
 
-    self->params.CodecSpecific.vp9.colorSpace = parser->color_space;
-  }
+  self->params.CodecSpecific.vp9.colorSpace = frame_hdr->color_space;
 
   return TRUE;
 }
@@ -366,10 +343,10 @@ gst_nv_vp9_dec_decode_picture (GstVp9Decoder * decoder,
     GstVp9Picture * picture, GstVp9Dpb * dpb)
 {
   GstNvVp9Dec *self = GST_NV_VP9_DEC (decoder);
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
-  const GstVp9LoopFilter *loopfilter = &frame_hdr->loopfilter;
-  const GstVp9SegmentationInfo *seg = &frame_hdr->segmentation;
-  const GstVp9QuantIndices *quant_indices = &frame_hdr->quant_indices;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9LoopFilterParams *lfp = &frame_hdr->loop_filter_params;
+  const GstVp9SegmentationParams *sp = &frame_hdr->segmentation_params;
+  const GstVp9QuantizationParams *qp = &frame_hdr->quantization_params;
   CUVIDPICPARAMS *params = &self->params;
   CUVIDVP9PICPARAMS *vp9_params = &params->CodecSpecific.vp9;
   GstNvDecoderFrame *frame;
@@ -384,14 +361,26 @@ gst_nv_vp9_dec_decode_picture (GstVp9Decoder * decoder,
       GST_VP9_MAX_MODE_LF_DELTAS);
   G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->mb_segment_tree_probs) ==
       GST_VP9_SEG_TREE_PROBS);
+  G_STATIC_ASSERT (sizeof (vp9_params->mb_segment_tree_probs) ==
+      sizeof (sp->segmentation_tree_probs));
+  G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->segment_pred_probs) ==
+      GST_VP9_PREDICTION_PROBS);
+  G_STATIC_ASSERT (sizeof (vp9_params->segment_pred_probs) ==
+      sizeof (sp->segmentation_pred_prob));
   G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->refFrameSignBias) ==
       GST_VP9_REFS_PER_FRAME + 1);
+  G_STATIC_ASSERT (sizeof (vp9_params->refFrameSignBias) ==
+      sizeof (frame_hdr->ref_frame_sign_bias));
   G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->activeRefIdx) ==
       GST_VP9_REFS_PER_FRAME);
   G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->segmentFeatureEnable) ==
       GST_VP9_MAX_SEGMENTS);
+  G_STATIC_ASSERT (sizeof (vp9_params->segmentFeatureEnable) ==
+      sizeof (sp->feature_enabled));
   G_STATIC_ASSERT (G_N_ELEMENTS (vp9_params->segmentFeatureData) ==
       GST_VP9_MAX_SEGMENTS);
+  G_STATIC_ASSERT (sizeof (vp9_params->segmentFeatureData) ==
+      sizeof (sp->feature_data));
 
   GST_LOG_OBJECT (self, "Decode picture, size %" G_GSIZE_FORMAT, picture->size);
 
@@ -428,9 +417,9 @@ gst_nv_vp9_dec_decode_picture (GstVp9Decoder * decoder,
     }
   }
 
-  vp9_params->LastRefIdx = ref_frame_map[frame_hdr->ref_frame_indices[0]];
-  vp9_params->GoldenRefIdx = ref_frame_map[frame_hdr->ref_frame_indices[1]];
-  vp9_params->AltRefIdx = ref_frame_map[frame_hdr->ref_frame_indices[2]];
+  vp9_params->LastRefIdx = ref_frame_map[frame_hdr->ref_frame_idx[0]];
+  vp9_params->GoldenRefIdx = ref_frame_map[frame_hdr->ref_frame_idx[1]];
+  vp9_params->AltRefIdx = ref_frame_map[frame_hdr->ref_frame_idx[2]];
 
   vp9_params->profile = frame_hdr->profile;
   vp9_params->frameContextIdx = frame_hdr->frame_context_idx;
@@ -438,65 +427,57 @@ gst_nv_vp9_dec_decode_picture (GstVp9Decoder * decoder,
   vp9_params->showFrame = frame_hdr->show_frame;
   vp9_params->errorResilient = frame_hdr->error_resilient_mode;
   vp9_params->frameParallelDecoding = frame_hdr->frame_parallel_decoding_mode;
-  vp9_params->subSamplingX = picture->subsampling_x;
-  vp9_params->subSamplingY = picture->subsampling_y;
+  vp9_params->subSamplingX = frame_hdr->subsampling_x;
+  vp9_params->subSamplingY = frame_hdr->subsampling_y;
   vp9_params->intraOnly = frame_hdr->intra_only;
   vp9_params->allow_high_precision_mv = frame_hdr->allow_high_precision_mv;
   vp9_params->refreshEntropyProbs = frame_hdr->refresh_frame_context;
-  vp9_params->bitDepthMinus8Luma = picture->bit_depth - 8;
-  vp9_params->bitDepthMinus8Chroma = picture->bit_depth - 8;
+  vp9_params->bitDepthMinus8Luma = frame_hdr->bit_depth - 8;
+  vp9_params->bitDepthMinus8Chroma = frame_hdr->bit_depth - 8;
 
-  vp9_params->loopFilterLevel = loopfilter->filter_level;
-  vp9_params->loopFilterSharpness = loopfilter->sharpness_level;
-  vp9_params->modeRefLfEnabled = loopfilter->mode_ref_delta_enabled;
+  vp9_params->loopFilterLevel = lfp->loop_filter_level;
+  vp9_params->loopFilterSharpness = lfp->loop_filter_sharpness;
+  vp9_params->modeRefLfEnabled = lfp->loop_filter_delta_enabled;
 
-  vp9_params->log2_tile_columns = frame_hdr->log2_tile_columns;
-  vp9_params->log2_tile_rows = frame_hdr->log2_tile_rows;
+  vp9_params->log2_tile_columns = frame_hdr->tile_cols_log2;
+  vp9_params->log2_tile_rows = frame_hdr->tile_rows_log2;
 
-  vp9_params->segmentEnabled = seg->enabled;
-  vp9_params->segmentMapUpdate = seg->update_map;
-  vp9_params->segmentMapTemporalUpdate = seg->temporal_update;
-  vp9_params->segmentFeatureMode = seg->abs_delta;
+  vp9_params->segmentEnabled = sp->segmentation_enabled;
+  vp9_params->segmentMapUpdate = sp->segmentation_update_map;
+  vp9_params->segmentMapTemporalUpdate = sp->segmentation_temporal_update;
+  vp9_params->segmentFeatureMode = sp->segmentation_abs_or_delta_update;
 
-  vp9_params->qpYAc = quant_indices->y_ac_qi;
-  vp9_params->qpYDc = quant_indices->y_dc_delta;
-  vp9_params->qpChDc = quant_indices->uv_dc_delta;
-  vp9_params->qpChAc = quant_indices->uv_ac_delta;
+  vp9_params->qpYAc = qp->base_q_idx;
+  vp9_params->qpYDc = qp->delta_q_y_dc;
+  vp9_params->qpChDc = qp->delta_q_uv_dc;
+  vp9_params->qpChAc = qp->delta_q_uv_ac;
 
   vp9_params->resetFrameContext = frame_hdr->reset_frame_context;
-  vp9_params->mcomp_filter_type = frame_hdr->mcomp_filter_type;
+  vp9_params->mcomp_filter_type = frame_hdr->interpolation_filter;
   vp9_params->frameTagSize = frame_hdr->frame_header_length_in_bytes;
-  vp9_params->offsetToDctParts = frame_hdr->first_partition_size;
+  vp9_params->offsetToDctParts = frame_hdr->header_size_in_bytes;
 
   for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++)
-    vp9_params->mbRefLfDelta[i] = loopfilter->ref_deltas[i];
+    vp9_params->mbRefLfDelta[i] = lfp->loop_filter_ref_deltas[i];
 
   for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++)
-    vp9_params->mbModeLfDelta[i] = loopfilter->mode_deltas[i];
+    vp9_params->mbModeLfDelta[i] = lfp->loop_filter_mode_deltas[i];
 
-  for (i = 0; i < GST_VP9_SEG_TREE_PROBS; i++)
-    vp9_params->mb_segment_tree_probs[i] = seg->tree_probs[i];
+  memcpy (vp9_params->mb_segment_tree_probs, sp->segmentation_tree_probs,
+      sizeof (sp->segmentation_tree_probs));
+  memcpy (vp9_params->segment_pred_probs, sp->segmentation_pred_prob,
+      sizeof (sp->segmentation_pred_prob));
+  memcpy (vp9_params->refFrameSignBias, frame_hdr->ref_frame_sign_bias,
+      sizeof (frame_hdr->ref_frame_sign_bias));
 
-  vp9_params->refFrameSignBias[0] = 0;
   for (i = 0; i < GST_VP9_REFS_PER_FRAME; i++) {
-    vp9_params->refFrameSignBias[i + 1] = frame_hdr->ref_frame_sign_bias[i];
-    vp9_params->activeRefIdx[i] = frame_hdr->ref_frame_indices[i];
+    vp9_params->activeRefIdx[i] = frame_hdr->ref_frame_idx[i];
   }
 
-  for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
-    vp9_params->segmentFeatureEnable[i][0] =
-        seg->data[i].alternate_quantizer_enabled;
-    vp9_params->segmentFeatureEnable[i][1] =
-        seg->data[i].alternate_loop_filter_enabled;
-    vp9_params->segmentFeatureEnable[i][2] =
-        seg->data[i].reference_frame_enabled;
-    vp9_params->segmentFeatureEnable[i][3] = seg->data[i].reference_skip;
-
-    vp9_params->segmentFeatureData[i][0] = seg->data[i].alternate_quantizer;
-    vp9_params->segmentFeatureData[i][1] = seg->data[i].alternate_loop_filter;
-    vp9_params->segmentFeatureData[i][2] = seg->data[i].reference_frame;
-    vp9_params->segmentFeatureData[i][3] = 0;
-  }
+  memcpy (vp9_params->segmentFeatureEnable, sp->feature_enabled,
+      sizeof (sp->feature_enabled));
+  memcpy (vp9_params->segmentFeatureData, sp->feature_data,
+      sizeof (sp->feature_data));
 
   return gst_nv_decoder_decode_picture (self->decoder, &self->params);
 }
index a4dc3f7..7a88f87 100644 (file)
@@ -144,8 +144,8 @@ _get_profile (GstVaVp9Dec * self, GstVP9Profile profile)
 }
 
 static gboolean
-gst_va_vp9_new_sequence (GstVp9Decoder * decoder, const GstVp9Parser * parser,
-    const GstVp9FrameHdr * frame_hdr)
+gst_va_vp9_new_sequence (GstVp9Decoder * decoder,
+    const GstVp9FrameHeader * frame_hdr)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaVp9Dec *self = GST_VA_VP9_DEC (decoder);
@@ -163,8 +163,8 @@ gst_va_vp9_new_sequence (GstVp9Decoder * decoder, const GstVp9Parser * parser,
     return FALSE;
   }
 
-  rt_format = _get_rtformat (self, frame_hdr->profile, parser->bit_depth,
-      parser->subsampling_x, parser->subsampling_y);
+  rt_format = _get_rtformat (self, frame_hdr->profile, frame_hdr->bit_depth,
+      frame_hdr->subsampling_x, frame_hdr->subsampling_y);
   if (rt_format == 0)
     return FALSE;
 
@@ -227,9 +227,9 @@ _fill_param (GstVp9Decoder * decoder, GstVp9Picture * picture, GstVp9Dpb * dpb)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaDecodePicture *va_pic;
-  const GstVp9FrameHdr *frame_hdr = &picture->frame_hdr;
-  const GstVp9LoopFilter *loopfilter = &frame_hdr->loopfilter;
-  const GstVp9SegmentationInfo *seg = &frame_hdr->segmentation;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9LoopFilterParams *lfp = &frame_hdr->loop_filter_params;
+  const GstVp9SegmentationParams *sp = &frame_hdr->segmentation_params;
   VADecPictureParameterBufferVP9 pic_param;
   guint i;
 
@@ -239,59 +239,58 @@ _fill_param (GstVp9Decoder * decoder, GstVp9Picture * picture, GstVp9Dpb * dpb)
     .frame_height = base->height,
 
     .pic_fields.bits = {
-      .subsampling_x = picture->subsampling_x,
-      .subsampling_y = picture->subsampling_x,
+      .subsampling_x = frame_hdr->subsampling_x,
+      .subsampling_y = frame_hdr->subsampling_x,
       .frame_type = frame_hdr->frame_type,
       .show_frame = frame_hdr->show_frame,
       .error_resilient_mode = frame_hdr->error_resilient_mode,
       .intra_only = frame_hdr->intra_only,
-      .allow_high_precision_mv = (frame_hdr->frame_type == GST_VP9_KEY_FRAME) ?
-          0 : frame_hdr->allow_high_precision_mv,
-      .mcomp_filter_type = frame_hdr->mcomp_filter_type,
+      .allow_high_precision_mv = frame_hdr->allow_high_precision_mv,
+      .mcomp_filter_type = frame_hdr->interpolation_filter,
       .frame_parallel_decoding_mode = frame_hdr->frame_parallel_decoding_mode,
       .reset_frame_context = frame_hdr->reset_frame_context,
       .refresh_frame_context = frame_hdr->refresh_frame_context,
       .frame_context_idx = frame_hdr->frame_context_idx,
 
-      .segmentation_enabled = seg->enabled,
-      .segmentation_temporal_update = seg->temporal_update,
-      .segmentation_update_map = seg->update_map,
+      .segmentation_enabled = sp->segmentation_enabled,
+      .segmentation_temporal_update = sp->segmentation_temporal_update,
+      .segmentation_update_map = sp->segmentation_update_map,
 
       .last_ref_frame =
-          frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_LAST - 1],
+          frame_hdr->ref_frame_idx[GST_VP9_REF_FRAME_LAST - 1],
       .last_ref_frame_sign_bias =
-          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_LAST - 1],
+          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_LAST],
       .golden_ref_frame =
-          frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_GOLDEN - 1],
+          frame_hdr->ref_frame_idx[GST_VP9_REF_FRAME_GOLDEN - 1],
       .golden_ref_frame_sign_bias =
-          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_GOLDEN - 1],
+          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_GOLDEN],
       .alt_ref_frame =
-          frame_hdr->ref_frame_indices[GST_VP9_REF_FRAME_ALTREF - 1],
+          frame_hdr->ref_frame_idx[GST_VP9_REF_FRAME_ALTREF - 1],
       .alt_ref_frame_sign_bias =
-          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_ALTREF - 1],
+          frame_hdr->ref_frame_sign_bias[GST_VP9_REF_FRAME_ALTREF],
 
       .lossless_flag = frame_hdr->lossless_flag,
     },
 
-    .filter_level = loopfilter->filter_level,
-    .sharpness_level = loopfilter->sharpness_level,
-    .log2_tile_rows = frame_hdr->log2_tile_rows,
-    .log2_tile_columns = frame_hdr->log2_tile_columns,
+    .filter_level = lfp->loop_filter_level,
+    .sharpness_level = lfp->loop_filter_sharpness,
+    .log2_tile_rows = frame_hdr->tile_rows_log2,
+    .log2_tile_columns = frame_hdr->tile_cols_log2,
 
     .frame_header_length_in_bytes = frame_hdr->frame_header_length_in_bytes,
-    .first_partition_size = frame_hdr->first_partition_size,
+    .first_partition_size = frame_hdr->header_size_in_bytes,
 
     .profile = frame_hdr->profile,
-    .bit_depth = picture->bit_depth
+    .bit_depth = frame_hdr->bit_depth
   };
   /* *INDENT-ON* */
 
-  memcpy (pic_param.mb_segment_tree_probs, seg->tree_probs,
-      sizeof (seg->tree_probs));
+  memcpy (pic_param.mb_segment_tree_probs, sp->segmentation_tree_probs,
+      sizeof (sp->segmentation_tree_probs));
 
-  if (seg->temporal_update) {
-    memcpy (pic_param.segment_pred_probs, seg->pred_probs,
-        sizeof (seg->pred_probs));
+  if (sp->segmentation_temporal_update) {
+    memcpy (pic_param.segment_pred_probs, sp->segmentation_pred_prob,
+        sizeof (sp->segmentation_pred_prob));
   } else {
     memset (pic_param.segment_pred_probs, 255,
         sizeof (pic_param.segment_pred_probs));
@@ -320,7 +319,11 @@ _fill_slice (GstVp9Decoder * decoder, GstVp9Picture * picture)
 {
   GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
   GstVaDecodePicture *va_pic;
-  const GstVp9Segmentation *seg = picture->segmentation;
+  const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr;
+  const GstVp9LoopFilterParams *lfp = &frame_hdr->loop_filter_params;
+  const GstVp9QuantizationParams *qp = &frame_hdr->quantization_params;
+  const GstVp9SegmentationParams *sp = &frame_hdr->segmentation_params;
+  guint8 n_shift = lfp->loop_filter_level >> 5;
   VASliceParameterBufferVP9 slice_param;
   guint i;
 
@@ -333,22 +336,79 @@ _fill_slice (GstVp9Decoder * decoder, GstVp9Picture * picture)
   /* *INDENT-ON* */
 
   for (i = 0; i < GST_VP9_MAX_SEGMENTS; i++) {
+    gint16 luma_dc_quant_scale;
+    gint16 luma_ac_quant_scale;
+    gint16 chroma_dc_quant_scale;
+    gint16 chroma_ac_quant_scale;
+    guint8 qindex;
+    guint8 lvl_lookup[GST_VP9_MAX_REF_LF_DELTAS][GST_VP9_MAX_MODE_LF_DELTAS];
+    guint lvl_seg = lfp->loop_filter_level;
+
+    /* 8.6.1 Dequantization functions */
+    qindex = gst_vp9_get_qindex (sp, qp, i);
+    luma_dc_quant_scale =
+        gst_vp9_get_dc_quant (qindex, qp->delta_q_y_dc, frame_hdr->bit_depth);
+    luma_ac_quant_scale =
+        gst_vp9_get_ac_quant (qindex, 0, frame_hdr->bit_depth);
+    chroma_dc_quant_scale =
+        gst_vp9_get_dc_quant (qindex, qp->delta_q_uv_dc, frame_hdr->bit_depth);
+    chroma_ac_quant_scale =
+        gst_vp9_get_ac_quant (qindex, qp->delta_q_uv_ac, frame_hdr->bit_depth);
+
+    if (!lfp->loop_filter_level) {
+      memset (lvl_lookup, 0, sizeof (lvl_lookup));
+    } else {
+      /* 8.8.1 Loop filter frame init process */
+      if (gst_vp9_seg_feature_active (sp, i, GST_VP9_SEG_LVL_ALT_L)) {
+        if (sp->segmentation_abs_or_delta_update) {
+          lvl_seg = sp->feature_data[i][GST_VP9_SEG_LVL_ALT_L];
+        } else {
+          lvl_seg += sp->feature_data[i][GST_VP9_SEG_LVL_ALT_L];
+        }
+
+        lvl_seg = CLAMP (lvl_seg, 0, GST_VP9_MAX_LOOP_FILTER);
+      }
+
+      if (!lfp->loop_filter_delta_enabled) {
+        memset (lvl_lookup, lvl_seg, sizeof (lvl_lookup));
+      } else {
+        guint8 ref, mode;
+        guint intra_lvl = lvl_seg +
+            (((guint) lfp->loop_filter_ref_deltas[GST_VP9_REF_FRAME_INTRA]) <<
+            n_shift);
+
+        lvl_lookup[GST_VP9_REF_FRAME_INTRA][0] =
+            CLAMP (intra_lvl, 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++) {
+            intra_lvl = lvl_seg + (lfp->loop_filter_ref_deltas[ref] << n_shift)
+                + (lfp->loop_filter_mode_deltas[mode] << n_shift);
+            lvl_lookup[ref][mode] =
+                CLAMP (intra_lvl, 0, GST_VP9_MAX_LOOP_FILTER);
+          }
+        }
+      }
+    }
+
     /* *INDENT-OFF* */
     slice_param.seg_param[i] = (VASegmentParameterVP9) {
         .segment_flags.fields = {
-            .segment_reference_enabled = seg[i].reference_frame_enabled,
-            .segment_reference = seg[i].reference_frame,
-            .segment_reference_skipped = seg[i].reference_skip,
+            .segment_reference_enabled =
+                sp->feature_enabled[i][GST_VP9_SEG_LVL_REF_FRAME],
+            .segment_reference =
+                sp->feature_data[i][GST_VP9_SEG_LVL_REF_FRAME],
+            .segment_reference_skipped =
+                sp->feature_enabled[i][GST_VP9_SEG_SEG_LVL_SKIP],
          },
 
-        .luma_dc_quant_scale = seg[i].luma_dc_quant_scale,
-        .luma_ac_quant_scale = seg[i].luma_ac_quant_scale,
-        .chroma_dc_quant_scale = seg[i].chroma_dc_quant_scale,
-        .chroma_ac_quant_scale = seg[i].chroma_ac_quant_scale,
+        .luma_dc_quant_scale = luma_dc_quant_scale,
+        .luma_ac_quant_scale = luma_ac_quant_scale,
+        .chroma_dc_quant_scale = chroma_dc_quant_scale,
+        .chroma_ac_quant_scale = chroma_ac_quant_scale,
     };
     /* *INDENT-ON* */
 
-    memcpy (slice_param.seg_param[i].filter_level, seg[i].filter_level,
+    memcpy (slice_param.seg_param[i].filter_level, lvl_lookup,
         sizeof (slice_param.seg_param[i].filter_level));
   }