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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2112>
This commit is contained in:
Seungha Yang 2021-03-30 11:49:43 +09:00 committed by GStreamer Marge Bot
parent c36190cbda
commit 1f769839c0
6 changed files with 275 additions and 251 deletions

View 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");

View 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:

View 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

View 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;
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);

View 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,42 +232,21 @@ 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;
modified = TRUE;
}
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 (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)
if (frame_hdr->bit_depth == 10)
out_format = GST_VIDEO_FORMAT_P010_10LE;
else
out_format = GST_VIDEO_FORMAT_P016_LE;
@ -279,7 +258,6 @@ gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
}
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)) {
@ -294,8 +272,7 @@ gst_nv_vp9_dec_new_sequence (GstVp9Decoder * decoder,
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);
}

View 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));
}