mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
lavc/vaapi_hevc: extend parameter buffer to ParameterBufferHEVCExtension
Extend ParameterBufferHEVC to ParameterBufferHEVCExtension for both VAPicture and VASlice. Pass Range Extension flags to support the decode for HEVC REXT. Signed-off-by: Linjie Fu <linjie.fu@intel.com>
This commit is contained in:
parent
f4cd4017bf
commit
aa6b2e1604
@ -29,8 +29,13 @@
|
|||||||
#include "vaapi_decode.h"
|
#include "vaapi_decode.h"
|
||||||
|
|
||||||
typedef struct VAAPIDecodePictureHEVC {
|
typedef struct VAAPIDecodePictureHEVC {
|
||||||
|
#if VA_CHECK_VERSION(1, 2, 0)
|
||||||
|
VAPictureParameterBufferHEVCExtension pic_param;
|
||||||
|
VASliceParameterBufferHEVCExtension last_slice_param;
|
||||||
|
#else
|
||||||
VAPictureParameterBufferHEVC pic_param;
|
VAPictureParameterBufferHEVC pic_param;
|
||||||
VASliceParameterBufferHEVC last_slice_param;
|
VASliceParameterBufferHEVC last_slice_param;
|
||||||
|
#endif
|
||||||
const uint8_t *last_buffer;
|
const uint8_t *last_buffer;
|
||||||
size_t last_size;
|
size_t last_size;
|
||||||
|
|
||||||
@ -117,11 +122,13 @@ static int vaapi_hevc_start_frame(AVCodecContext *avctx,
|
|||||||
const HEVCPPS *pps = h->ps.pps;
|
const HEVCPPS *pps = h->ps.pps;
|
||||||
|
|
||||||
const ScalingList *scaling_list = NULL;
|
const ScalingList *scaling_list = NULL;
|
||||||
int err, i;
|
int pic_param_size, err, i;
|
||||||
|
|
||||||
|
VAPictureParameterBufferHEVC *pic_param = (VAPictureParameterBufferHEVC *)&pic->pic_param;
|
||||||
|
|
||||||
pic->pic.output_surface = ff_vaapi_get_surface_id(h->ref->frame);
|
pic->pic.output_surface = ff_vaapi_get_surface_id(h->ref->frame);
|
||||||
|
|
||||||
pic->pic_param = (VAPictureParameterBufferHEVC) {
|
*pic_param = (VAPictureParameterBufferHEVC) {
|
||||||
.pic_width_in_luma_samples = sps->width,
|
.pic_width_in_luma_samples = sps->width,
|
||||||
.pic_height_in_luma_samples = sps->height,
|
.pic_height_in_luma_samples = sps->height,
|
||||||
.log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3,
|
.log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3,
|
||||||
@ -188,29 +195,61 @@ static int vaapi_hevc_start_frame(AVCodecContext *avctx,
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
fill_vaapi_pic(&pic->pic_param.CurrPic, h->ref, 0);
|
fill_vaapi_pic(&pic_param->CurrPic, h->ref, 0);
|
||||||
fill_vaapi_reference_frames(h, &pic->pic_param);
|
fill_vaapi_reference_frames(h, pic_param);
|
||||||
|
|
||||||
if (pps->tiles_enabled_flag) {
|
if (pps->tiles_enabled_flag) {
|
||||||
pic->pic_param.num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
pic_param->num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||||
pic->pic_param.num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
pic_param->num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||||
|
|
||||||
for (i = 0; i < pps->num_tile_columns; i++)
|
for (i = 0; i < pps->num_tile_columns; i++)
|
||||||
pic->pic_param.column_width_minus1[i] = pps->column_width[i] - 1;
|
pic_param->column_width_minus1[i] = pps->column_width[i] - 1;
|
||||||
|
|
||||||
for (i = 0; i < pps->num_tile_rows; i++)
|
for (i = 0; i < pps->num_tile_rows; i++)
|
||||||
pic->pic_param.row_height_minus1[i] = pps->row_height[i] - 1;
|
pic_param->row_height_minus1[i] = pps->row_height[i] - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
|
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
|
||||||
pic->pic_param.st_rps_bits = h->sh.short_term_ref_pic_set_size;
|
pic_param->st_rps_bits = h->sh.short_term_ref_pic_set_size;
|
||||||
} else {
|
} else {
|
||||||
pic->pic_param.st_rps_bits = 0;
|
pic_param->st_rps_bits = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if VA_CHECK_VERSION(1, 2, 0)
|
||||||
|
if (avctx->profile == FF_PROFILE_HEVC_REXT) {
|
||||||
|
pic->pic_param.rext = (VAPictureParameterBufferHEVCRext) {
|
||||||
|
.range_extension_pic_fields.bits = {
|
||||||
|
.transform_skip_rotation_enabled_flag = sps->transform_skip_rotation_enabled_flag,
|
||||||
|
.transform_skip_context_enabled_flag = sps->transform_skip_context_enabled_flag,
|
||||||
|
.implicit_rdpcm_enabled_flag = sps->implicit_rdpcm_enabled_flag,
|
||||||
|
.explicit_rdpcm_enabled_flag = sps->explicit_rdpcm_enabled_flag,
|
||||||
|
.extended_precision_processing_flag = sps->extended_precision_processing_flag,
|
||||||
|
.intra_smoothing_disabled_flag = sps->intra_smoothing_disabled_flag,
|
||||||
|
.high_precision_offsets_enabled_flag = sps->high_precision_offsets_enabled_flag,
|
||||||
|
.persistent_rice_adaptation_enabled_flag = sps->persistent_rice_adaptation_enabled_flag,
|
||||||
|
.cabac_bypass_alignment_enabled_flag = sps->cabac_bypass_alignment_enabled_flag,
|
||||||
|
.cross_component_prediction_enabled_flag = pps->cross_component_prediction_enabled_flag,
|
||||||
|
.chroma_qp_offset_list_enabled_flag = pps->chroma_qp_offset_list_enabled_flag,
|
||||||
|
},
|
||||||
|
.diff_cu_chroma_qp_offset_depth = pps->diff_cu_chroma_qp_offset_depth,
|
||||||
|
.chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1,
|
||||||
|
.log2_sao_offset_scale_luma = pps->log2_sao_offset_scale_luma,
|
||||||
|
.log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma,
|
||||||
|
.log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size - 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
pic->pic_param.rext.cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
pic->pic_param.rext.cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
pic_param_size = avctx->profile == FF_PROFILE_HEVC_REXT ?
|
||||||
|
sizeof(pic->pic_param) : sizeof(VAPictureParameterBufferHEVC);
|
||||||
|
|
||||||
err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
|
err = ff_vaapi_decode_make_param_buffer(avctx, &pic->pic,
|
||||||
VAPictureParameterBufferType,
|
VAPictureParameterBufferType,
|
||||||
&pic->pic_param, sizeof(pic->pic_param));
|
&pic->pic_param, pic_param_size);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -255,12 +294,16 @@ static int vaapi_hevc_end_frame(AVCodecContext *avctx)
|
|||||||
{
|
{
|
||||||
const HEVCContext *h = avctx->priv_data;
|
const HEVCContext *h = avctx->priv_data;
|
||||||
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
||||||
|
VASliceParameterBufferHEVC *last_slice_param = (VASliceParameterBufferHEVC *)&pic->last_slice_param;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
int slice_param_size = avctx->profile == FF_PROFILE_HEVC_REXT ?
|
||||||
|
sizeof(pic->last_slice_param) : sizeof(VASliceParameterBufferHEVC);
|
||||||
|
|
||||||
if (pic->last_size) {
|
if (pic->last_size) {
|
||||||
pic->last_slice_param.LongSliceFlags.fields.LastSliceOfPic = 1;
|
last_slice_param->LongSliceFlags.fields.LastSliceOfPic = 1;
|
||||||
ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
|
ret = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
|
||||||
&pic->last_slice_param, sizeof(pic->last_slice_param),
|
&pic->last_slice_param, slice_param_size,
|
||||||
pic->last_buffer, pic->last_size);
|
pic->last_buffer, pic->last_size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -330,7 +373,7 @@ static void fill_pred_weight_table(const HEVCContext *h,
|
|||||||
static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame)
|
static uint8_t get_ref_pic_index(const HEVCContext *h, const HEVCFrame *frame)
|
||||||
{
|
{
|
||||||
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
||||||
VAPictureParameterBufferHEVC *pp = &pic->pic_param;
|
VAPictureParameterBufferHEVC *pp = (VAPictureParameterBufferHEVC *)&pic->pic_param;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
if (!frame)
|
if (!frame)
|
||||||
@ -353,6 +396,10 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
|
|||||||
const HEVCContext *h = avctx->priv_data;
|
const HEVCContext *h = avctx->priv_data;
|
||||||
const SliceHeader *sh = &h->sh;
|
const SliceHeader *sh = &h->sh;
|
||||||
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
VAAPIDecodePictureHEVC *pic = h->ref->hwaccel_picture_private;
|
||||||
|
VASliceParameterBufferHEVC *last_slice_param = (VASliceParameterBufferHEVC *)&pic->last_slice_param;
|
||||||
|
|
||||||
|
int slice_param_size = avctx->profile == FF_PROFILE_HEVC_REXT ?
|
||||||
|
sizeof(pic->last_slice_param) : sizeof(VASliceParameterBufferHEVC);
|
||||||
|
|
||||||
int nb_list = (sh->slice_type == HEVC_SLICE_B) ?
|
int nb_list = (sh->slice_type == HEVC_SLICE_B) ?
|
||||||
2 : (sh->slice_type == HEVC_SLICE_I ? 0 : 1);
|
2 : (sh->slice_type == HEVC_SLICE_I ? 0 : 1);
|
||||||
@ -361,7 +408,7 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
|
|||||||
|
|
||||||
if (!sh->first_slice_in_pic_flag) {
|
if (!sh->first_slice_in_pic_flag) {
|
||||||
err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
|
err = ff_vaapi_decode_make_slice_buffer(avctx, &pic->pic,
|
||||||
&pic->last_slice_param, sizeof(pic->last_slice_param),
|
&pic->last_slice_param, slice_param_size,
|
||||||
pic->last_buffer, pic->last_size);
|
pic->last_buffer, pic->last_size);
|
||||||
pic->last_buffer = NULL;
|
pic->last_buffer = NULL;
|
||||||
pic->last_size = 0;
|
pic->last_size = 0;
|
||||||
@ -371,7 +418,7 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pic->last_slice_param = (VASliceParameterBufferHEVC) {
|
*last_slice_param = (VASliceParameterBufferHEVC) {
|
||||||
.slice_data_size = size,
|
.slice_data_size = size,
|
||||||
.slice_data_offset = 0,
|
.slice_data_offset = 0,
|
||||||
.slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
|
.slice_data_flag = VA_SLICE_DATA_FLAG_ALL,
|
||||||
@ -404,16 +451,35 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
memset(pic->last_slice_param.RefPicList, 0xFF, sizeof(pic->last_slice_param.RefPicList));
|
memset(last_slice_param->RefPicList, 0xFF, sizeof(last_slice_param->RefPicList));
|
||||||
|
|
||||||
for (list_idx = 0; list_idx < nb_list; list_idx++) {
|
for (list_idx = 0; list_idx < nb_list; list_idx++) {
|
||||||
RefPicList *rpl = &h->ref->refPicList[list_idx];
|
RefPicList *rpl = &h->ref->refPicList[list_idx];
|
||||||
|
|
||||||
for (i = 0; i < rpl->nb_refs; i++)
|
for (i = 0; i < rpl->nb_refs; i++)
|
||||||
pic->last_slice_param.RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->ref[i]);
|
last_slice_param->RefPicList[list_idx][i] = get_ref_pic_index(h, rpl->ref[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_pred_weight_table(h, sh, &pic->last_slice_param);
|
fill_pred_weight_table(h, sh, last_slice_param);
|
||||||
|
|
||||||
|
#if VA_CHECK_VERSION(1, 2, 0)
|
||||||
|
if (avctx->profile == FF_PROFILE_HEVC_REXT) {
|
||||||
|
pic->last_slice_param.rext = (VASliceParameterBufferHEVCRext) {
|
||||||
|
.slice_ext_flags.bits = {
|
||||||
|
.cu_chroma_qp_offset_enabled_flag = sh->cu_chroma_qp_offset_enabled_flag,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(pic->last_slice_param.rext.luma_offset_l0, pic->last_slice_param.base.luma_offset_l0,
|
||||||
|
sizeof(pic->last_slice_param.base.luma_offset_l0));
|
||||||
|
memcpy(pic->last_slice_param.rext.luma_offset_l1, pic->last_slice_param.base.luma_offset_l1,
|
||||||
|
sizeof(pic->last_slice_param.base.luma_offset_l1));
|
||||||
|
memcpy(pic->last_slice_param.rext.ChromaOffsetL0, pic->last_slice_param.base.ChromaOffsetL0,
|
||||||
|
sizeof(pic->last_slice_param.base.ChromaOffsetL0));
|
||||||
|
memcpy(pic->last_slice_param.rext.ChromaOffsetL1, pic->last_slice_param.base.ChromaOffsetL1,
|
||||||
|
sizeof(pic->last_slice_param.base.ChromaOffsetL1));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
pic->last_buffer = buffer;
|
pic->last_buffer = buffer;
|
||||||
pic->last_size = size;
|
pic->last_size = size;
|
||||||
|
Loading…
Reference in New Issue
Block a user