@ -29,8 +29,13 @@
# include "vaapi_decode.h"
typedef struct VAAPIDecodePictureHEVC {
# if VA_CHECK_VERSION(1, 2, 0)
VAPictureParameterBufferHEVCExtension pic_param ;
VASliceParameterBufferHEVCExtension last_slice_param ;
# else
VAPictureParameterBufferHEVC pic_param ;
VASliceParameterBufferHEVC last_slice_param ;
# endif
const uint8_t * last_buffer ;
size_t last_size ;
@ -117,11 +122,13 @@ static int vaapi_hevc_start_frame(AVCodecContext *avctx,
const HEVCPPS * pps = h - > ps . pps ;
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_param = ( VAPictureParameterBufferHEVC ) {
* pic_param = ( VAPictureParameterBufferHEVC ) {
. pic_width_in_luma_samples = sps - > width ,
. pic_height_in_luma_samples = sps - > height ,
. 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_reference_frames ( h , & pic - > pic_param ) ;
fill_vaapi_pic ( & pic_param - > CurrPic , h - > ref , 0 ) ;
fill_vaapi_reference_frames ( h , pic_param ) ;
if ( pps - > tiles_enabled_flag ) {
pic - > 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_columns_minus1 = pps - > num_tile_columns - 1 ;
pic_param - > num_tile_rows_minus1 = pps - > num_tile_rows - 1 ;
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 + + )
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 ) {
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 {
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 ,
VAPictureParameterBufferType ,
& pic - > pic_param , sizeof ( pic - > pic_param ) ) ;
& pic - > pic_param , pic_param_size ) ;
if ( err < 0 )
goto fail ;
@ -255,12 +294,16 @@ static int vaapi_hevc_end_frame(AVCodecContext *avctx)
{
const HEVCContext * h = avctx - > priv_data ;
VAAPIDecodePictureHEVC * pic = h - > ref - > hwaccel_picture_private ;
VASliceParameterBufferHEVC * last_slice_param = ( VASliceParameterBufferHEVC * ) & pic - > last_slice_param ;
int ret ;
int slice_param_size = avctx - > profile = = FF_PROFILE_HEVC_REXT ?
sizeof ( pic - > last_slice_param ) : sizeof ( VASliceParameterBufferHEVC ) ;
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 ,
& pic - > last_slice_param , sizeof ( pic - > last_slice_param ) ,
& pic - > last_slice_param , slice_param_size ,
pic - > last_buffer , pic - > last_size ) ;
if ( ret < 0 )
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 )
{
VAAPIDecodePictureHEVC * pic = h - > ref - > hwaccel_picture_private ;
VAPictureParameterBufferHEVC * pp = & pic - > pic_param ;
VAPictureParameterBufferHEVC * pp = ( VAPictureParameterBufferHEVC * ) & pic - > pic_param ;
uint8_t i ;
if ( ! frame )
@ -353,6 +396,10 @@ static int vaapi_hevc_decode_slice(AVCodecContext *avctx,
const HEVCContext * h = avctx - > priv_data ;
const SliceHeader * sh = & h - > sh ;
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 ) ?
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 ) {
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 = NULL ;
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_offset = 0 ,
. 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 + + ) {
RefPicList * rpl = & h - > ref - > refPicList [ list_idx ] ;
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_size = size ;