From 1f769839c09b38745f0b7c9aac127ea5432804f6 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Tue, 30 Mar 2021 11:49:43 +0900 Subject: [PATCH] codecs: vp9decoder: Port to GstVp9StatefulParser 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: --- gst-libs/gst/codecs/gstvp9decoder.c | 46 +++---- gst-libs/gst/codecs/gstvp9decoder.h | 4 +- gst-libs/gst/codecs/gstvp9picture.h | 11 +- sys/d3d11/gstd3d11vp9dec.cpp | 140 +++++++++++---------- sys/nvcodec/gstnvvp9dec.c | 183 +++++++++++++--------------- sys/va/gstvavp9dec.c | 142 ++++++++++++++------- 6 files changed, 275 insertions(+), 251 deletions(-) diff --git a/gst-libs/gst/codecs/gstvp9decoder.c b/gst-libs/gst/codecs/gstvp9decoder.c index e38ff4e74d..3e02672c90 100644 --- a/gst-libs/gst/codecs/gstvp9decoder.c +++ b/gst-libs/gst/codecs/gstvp9decoder.c @@ -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"); diff --git a/gst-libs/gst/codecs/gstvp9decoder.h b/gst-libs/gst/codecs/gstvp9decoder.h index f25252f5df..f75085bf89 100644 --- a/gst-libs/gst/codecs/gstvp9decoder.h +++ b/gst-libs/gst/codecs/gstvp9decoder.h @@ -23,7 +23,6 @@ #include #include -#include #include 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: diff --git a/gst-libs/gst/codecs/gstvp9picture.h b/gst-libs/gst/codecs/gstvp9picture.h index dc71202769..29bcd18a06 100644 --- a/gst-libs/gst/codecs/gstvp9picture.h +++ b/gst-libs/gst/codecs/gstvp9picture.h @@ -21,7 +21,7 @@ #define __GST_VP9_PICTURE_H__ #include -#include +#include 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 diff --git a/sys/d3d11/gstd3d11vp9dec.cpp b/sys/d3d11/gstd3d11vp9dec.cpp index e01e89fc44..a1ae106e13 100644 --- a/sys/d3d11/gstd3d11vp9dec.cpp +++ b/sys/d3d11/gstd3d11vp9dec.cpp @@ -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; + const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr; + const GstVp9LoopFilterParams *lfp = &frame_hdr->loop_filter_params; - 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; + 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; - for (i = 0; i < GST_VP9_MAX_REF_LF_DELTAS; i++) { - params->ref_deltas[i] = loopfilter->ref_deltas[i]; - } + 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)); - for (i = 0; i < GST_VP9_MAX_MODE_LF_DELTAS; i++) { - params->mode_deltas[i] = loopfilter->mode_deltas[i]; - } + 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; + const GstVp9FrameHeader *frame_hdr = &picture->frame_hdr; + const GstVp9SegmentationParams *sp = &frame_hdr->segmentation_params; + gint i, j; - 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; + 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; - for (i = 0; i < GST_VP9_SEG_TREE_PROBS; i++) - params->stVP9Segments.tree_probs[i] = seg->tree_probs[i]; + 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)); - for (i = 0; i < GST_VP9_PREDICTION_PROBS; i++) - params->stVP9Segments.pred_probs[i] = seg->pred_probs[i]; + 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; + 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); - 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; + 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); diff --git a/sys/nvcodec/gstnvvp9dec.c b/sys/nvcodec/gstnvvp9dec.c index b987328bee..fb269e9f4f 100644 --- a/sys/nvcodec/gstnvvp9dec.c +++ b/sys/nvcodec/gstnvvp9dec.c @@ -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,71 +232,48 @@ 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; - } - - 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)); - - self->params.CodecSpecific.vp9.colorSpace = parser->color_space; + 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; + } + + memset (&self->params, 0, sizeof (CUVIDPICPARAMS)); + + 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 = ¶ms->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); } diff --git a/sys/va/gstvavp9dec.c b/sys/va/gstvavp9dec.c index a4dc3f72a2..7a88f877f3 100644 --- a/sys/va/gstvavp9dec.c +++ b/sys/va/gstvavp9dec.c @@ -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)); }