From c29d7bf0077a9f5fa6a5df39a6f9ec7bd175f8ab Mon Sep 17 00:00:00 2001 From: "Liu, Chunjuan" Date: Mon, 22 Jan 2024 09:12:28 +0800 Subject: [PATCH] Add VVC decode LibVA interface. Signed-off-by: Liu, Chunjuan --- va/va.h | 6 +- va/va_dec_vvc.h | 165 +++++++++++++++++++++++++++++++----------------- va/va_trace.c | 14 ++-- 3 files changed, 120 insertions(+), 65 deletions(-) diff --git a/va/va.h b/va/va.h index 78a8d5b14..64306fdc8 100644 --- a/va/va.h +++ b/va/va.h @@ -5283,7 +5283,11 @@ typedef struct _VAPictureVVC { #define VA_PICTURE_VVC_INVALID 0x00000001 /** \brief Long term reference picture */ #define VA_PICTURE_VVC_LONG_TERM_REFERENCE 0x00000002 -/** \brief Unavailable reference picture */ +/** \brief Unavailable reference picture + * This flag indicates the situation that the process of + * "generating unavailable reference pictures" (spec section 8.3.4) + * is required. + */ #define VA_PICTURE_VVC_UNAVAILABLE_REFERENCE 0x00000004 typedef enum { diff --git a/va/va_dec_vvc.h b/va/va_dec_vvc.h index 73ea2631f..bbd403994 100644 --- a/va/va_dec_vvc.h +++ b/va/va_dec_vvc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Intel Corporation. All Rights Reserved. + * Copyright (c) 2024 Intel Corporation. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -52,7 +52,7 @@ extern "C" { */ typedef struct _VAWeightedPredInfo { /** \brief Weighted Prediction parameters. - * All the parameters are VVC syntax. + * All the parameters except reserved bytes are VVC syntax. */ uint8_t luma_log2_weight_denom; int8_t delta_chroma_log2_weight_denom; @@ -81,6 +81,9 @@ typedef struct _VAWeightedPredInfo { * This structure conveys picture level parameters and should be sent once * per frame. * + * Host decoder is required to send in a buffer of VAPictureParameterBufferVVC + * as the first va buffer for each frame. + * */ typedef struct _VAPictureParameterBufferVVC { /** \brief buffer description of decoded current picture @@ -102,7 +105,11 @@ typedef struct _VAPictureParameterBufferVVC { uint8_t sps_log2_ctu_size_minus5; uint8_t sps_log2_min_luma_coding_block_size_minus2; uint8_t sps_log2_transform_skip_max_size_minus2; - int8_t ChromaQpTable[3][112]; + /** \brief chroma QP mapping table. + * ChromaQpTable[][] corresponds to VVC spec variable with the same name. + * It is derived according to formula (57) in VVC spec section 7.4.3.4. + */ + int8_t ChromaQpTable[3][111]; uint8_t sps_six_minus_max_num_merge_cand; uint8_t sps_five_minus_max_num_subblock_merge_cand; uint8_t sps_max_num_merge_cand_minus_max_num_gpm_cand; @@ -173,9 +180,25 @@ typedef struct _VAPictureParameterBufferVVC { /** \brief picture level parameters. * All the parameters except reserved bytes are VVC syntax or spec variables. */ + /** \brief number of vertical virtual boundaries on the picture. + * NumVerVirtualBoundaries corresponds to VVC spec variable with the same name. + * It is derived according to formula (78) in VVC spec section 7.4.3.8. + */ uint8_t NumVerVirtualBoundaries; + /** \brief number of horizontal virtual boundaries on the picture. + * NumHorVirtualBoundaries corresponds to VVC spec variable with the same name. + * It is derived according to formula (80) in VVC spec section 7.4.3.8. + */ uint8_t NumHorVirtualBoundaries; + /** \brief location of the vertical virtual boundary in units of luma samples. + * VirtualBoundaryPosX[] corresponds to VVC spec variable with the same name. + * It is derived according to formula (79) in VVC spec section 7.4.3.8. + */ uint16_t VirtualBoundaryPosX[3]; + /** \brief location of the horizontal virtual boundary in units of luma samples. + * VirtualBoundaryPosY[] corresponds to VVC spec variable with the same name. + * It is derived according to formula (81) in VVC spec section 7.4.3.8. + */ uint16_t VirtualBoundaryPosY[3]; int32_t pps_scaling_win_left_offset; @@ -279,7 +302,9 @@ typedef struct _VAPictureParameterBufferVVC { union { struct { /** \brief Flag to indicate if current picture is an intra picture. - * Takes value 1 when all the slices are intra slices, 0 otherwise. + * Takes value 1 when all slices of current picture are intra slices. + * Takes value 0 when some slices of current picture may not be + * intra slices. */ uint32_t IntraPicFlag : 1; // [0..1] /** \brief Reserved for future use, must be zero */ @@ -328,7 +353,7 @@ typedef struct _VASliceParameterBufferVVC { */ uint32_t slice_data_byte_offset; /** \brief index into ReferenceFrames[] - * RefPicList[][] corresponds to VVC variable with the same name. + * RefPicList[][] corresponds to VVC spec variable with the same name. * Value range [0..14, 0xFF], where 0xFF indicates invalid entry. */ uint8_t RefPicList[2][15]; @@ -341,7 +366,7 @@ typedef struct _VASliceParameterBufferVVC { * And it is the spec variable with the same name. */ uint16_t sh_subpic_id; - /* parameters below are VVC syntax. */ + /* parameters below are VVC syntax or spec variables. */ uint16_t sh_slice_address; uint16_t sh_num_tiles_in_slice_minus1; uint8_t sh_slice_type; @@ -350,9 +375,21 @@ typedef struct _VASliceParameterBufferVVC { uint8_t sh_alf_aps_id_chroma; uint8_t sh_alf_cc_cb_aps_id; uint8_t sh_alf_cc_cr_aps_id; - uint8_t sh_num_ref_idx_active_minus1[2]; + /** + * \brief NumRefIdxActive[i] - 1 specifies the maximum reference index + * for RPL i that may be used to decode the slice. When NumRefIdxActive[i] + * is equal to 0, no reference index for RPL i is used to decode the slice. + * NumRefIdxActive[] corresponds to VVC spec variable with the same name. + * It is derived according to formula (138) in VVC spec section 7.4.8. + */ + uint8_t NumRefIdxActive[2]; uint8_t sh_collocated_ref_idx; - /* VVC spec variable indicating quantization parameter for the slice. */ + /** + * \brief initial value of the QpY quantization parameter for the slice. + * SliceQpY corresponds to VVC spec variable with the same name. + * It is derived according to formula (86) in VVC spec section 7.4.3.8 + * and formula (139) in VVC Spec section 7.4.8. + */ int8_t SliceQpY; /* parameters below are VVC syntax. */ int8_t sh_cb_qp_offset; @@ -403,9 +440,11 @@ typedef struct _VASliceParameterBufferVVC { /** * \brief VVC Scaling List Data Structure * - * Host decoder sends in a buffer surface of array of VVC Scaling Lists. - * The surface buffer may contain 1 to 8 VAScalingListVVC data structures. - * Driver may store the data internally. Host decode may choose not to + * Host decoder sends in an array of VVC Scaling Lists through one or multiple + * buffers which may contain 1 to 8 VAScalingListVVC data structures in total. + * Each buffer contains an integer number of VAScalingListVVC data structures + * with no gap in between. + * Driver may store the data internally. Host decoder may choose not to * send the same scaling list data for each frame. When a VAScalingListVVC * structure carries a same value of aps_adaptation_parameter_set_id * as a previously stored structure, driver should override the old structure @@ -445,15 +484,17 @@ typedef struct _VAScalingListVVC { /** * \brief VVC Adaptive Loop Filter Data Structure * - * Host decoder sends in a buffer surface of array of VVC ALF sets. - * The surface buffer may contain 1 to 8 VAAlfDataVVC data structures. - * Driver may store the data internally. Host decode may choose not to + * Host decoder sends in an array of VVC ALF sets through one or multiple + * buffers which may contain 1 to 8 VAAlfDataVVC data structures in total. + * Each buffer contains an integer number of VAAlfDataVVC data structures + * with no gap in between. + * Driver may store the data internally. Host decoder may choose not to * send the same ALF data for each frame. When a VAAlfDataVVC structure * carries a same value of aps_adaptation_parameter_set_id as a previously * stored structure, driver should override the old structure * with values in the new structure. * VAAlfBufferType is used to send this buffer. -*/ + */ typedef struct _VAAlfDataVVC { /** * \brief VVC Adaptive Loop Filter parameters. @@ -462,7 +503,7 @@ typedef struct _VAAlfDataVVC { uint8_t aps_adaptation_parameter_set_id; uint8_t alf_luma_num_filters_signalled_minus1; uint8_t alf_luma_coeff_delta_idx[25]; - int8_t AlfCoeffL[25][12]; + int8_t filtCoeff[25][12]; uint8_t alf_luma_clip_idx[25][12]; uint8_t alf_chroma_num_alt_filters_minus1; int8_t AlfCoeffC[8][6]; @@ -496,9 +537,11 @@ typedef struct _VAAlfDataVVC { /** * \brief VVC Luma Mapping with Chroma Scaling Data Structure * - * Host decoder sends in a buffer surface of array of VVC LMCS sets. - * The surface buffer may contain 1 to 4 VALmcsDataVVC data structures. - * Driver may store the data internally. Host decode may choose not to + * Host decoder sends in an array of VVC LMCS sets through one or multiple + * buffers which may contain 1 to 4 VALmcsDataVVC data structures in total. + * Each buffer contains an integer number of VALmcsDataVVC data structures + * with no gap in between. + * Driver may store the data internally. Host decoder may choose not to * send the same LMCS data for each frame. When a VALmcsDataVVC structure * carries a same value of aps_adaptation_parameter_set_id as a previously * stored structure, driver should override the old structure @@ -523,13 +566,12 @@ typedef struct _VALmcsDataVVC { /** * \brief VVC SubPicture Data Structure * - * Host decoder sends in a data buffer of array of VVC SubPic sets. - * The Subpic sets are laid out sequentially in the order of indices - * from 0 to sps_num_subpics_minus1 according to the bitstream with - * no gap in between. The number of element should equal to - * sps_num_subpics_minus1 + 1. - * App should allocate enough buffer size to hold - * all the SubPic data. + * Host decoder sends in an array of VVC SubPic sets through one or + * multiple buffers which contain sps_num_subpics_minus1 + 1 + * VASubPicVVC data structures in total. Each buffer contains + * an integer number of VASubPicVVC data structures with no gap in between. + * The Subpic sets are sent sequentially in the order of indices + * from 0 to sps_num_subpics_minus1 according to the bitstream. * VASubPicBufferType is used to send this buffer. */ typedef struct _VASubPicVVC { @@ -564,42 +606,52 @@ typedef struct _VASubPicVVC { * \brief data buffer of tile widths and heights. * VATileBufferType is used to send this buffer. * - * The buffer is filled with number of pps_num_exp_tile_columns_minus1 + 1 - * tile column widths of pps_tile_column_width_minus1[i], starting - * from buffer beginning. Then it is followed by number of - * pps_num_exp_tile_rows_minus1 + 1 of tile row heights of - * pps_tile_row_height_minus1[i]. No gaps in between. - * Each element is formatted as - uint16_t tile_dimension; + * Host decoder sends in number of pps_num_exp_tile_columns_minus1 + 1 + * tile column widths of pps_tile_column_width_minus1[i], followed by + * number of pps_num_exp_tile_rows_minus1 + 1 of tile row heights of + * pps_tile_row_height_minus1[i], through one or multiple buffers. + * Each tile width or height is formatted as + uint16_t tile_dimension; + * Each buffer contains an integer number of tile_dimension with + * no gap in between. + * The buffers with type VATileBufferType should be submitted for each + * picture. And driver will derive the tile structure from it. * When pps_num_exp_tile_columns_minus1 + pps_num_exp_tile_rows_minus1 equals 0, - * this surface is still submitted by app to driver. - * For each picture, this surface should be submitted once. - * And driver will derive the tile structure from it. + * this buffer is still submitted by app to driver. */ /** - * \brief VVC SliceStruct Data Structure - * - * Host decoder sends in a data buffer of array of SliceStruct sets. - * The buffer contains only the "explicit" slices parsed from PPS - * header. - * Each element is described by VASliceStructVVC data structures. - * And they are laid out sequentially in the order of - * ascending slice indices according to the spec with no gap in between. - * And the buffer size is large enough to hold all SliceStruct elements. - * When pps_rect_slice_flag or there are no explicit slices, - * this surface is not submitted by app to driver. Otherwise, for each picture, - * this surface should be submitted once. - * App should populate the data entries regardless of values of - * pps_single_slice_per_subpic_flag or sps_subpic_info_present_flag. - * - * VASliceStructBufferType is used to send this buffer. - */ + * \brief VVC SliceStruct Data Structure + * + * Host decoder sends in an array of SliceStruct sets through one or multiple + * buffers. These SliceStruct sets contain only the "explicit" slices parsed + * from PPS header. + * Each SliceStruct set is described by VASliceStructVVC data structure. + * Each buffer contains an integer number of VASliceStructVVC data structures, + * which are laid out sequentially in the order of + * ascending slice indices according to the spec with no gap in between. + * + * When pps_rect_slice_flag equals 0 or there are no explicit slices, + * this buffer is not submitted by app to driver. Otherwise, for each picture, + * this buffer should be submitted. + * + * Note: When pps_slice_width_in_tiles_minus1 + pps_slice_height_in_tiles_minus1 + * equals 0, if the sum of pps_exp_slice_height_in_ctus_minus1 + 1 of all those + * slices with same SliceTopLeftTileIdx value is less than the height of tile + * SliceTopLeftTileIdx in unit of CTUs, driver should derive the rest slices in + * that tile according to equation (21) in spec section 6.5.1. And VASliceStructVVC + * for these (derived) slices are not passed in to LibVA by App. + * + * App should populate the data entries regardless of values of + * pps_single_slice_per_subpic_flag or sps_subpic_info_present_flag. + * + * VASliceStructBufferType is used to send this buffer. + */ typedef struct _VASliceStructVVC { /** \brief the tile index of which the starting CTU (top-left) of * the slice belongs to. The tile index is in raster scan order. - * Same syntax varible as in VVC spec. + * Same syntax variable as in VVC spec. */ uint16_t SliceTopLeftTileIdx; /* plus 1 specifies the width of the rectangular slice in units @@ -616,9 +668,8 @@ typedef struct _VASliceStructVVC { * If pps_slice_width_in_tiles_minus1 + pps_slice_height_in_tiles_minus1 > 0, * set this value to 0. * If pps_slice_width_in_tiles_minus1 + pps_slice_height_in_tiles_minus1 == 0, - * and if there is only one slice in tile (pps_num_exp_slices_in_tile == 0), - * set this value to the number of CTU rows of the tile minus 1. - * Otherwise (pps_num_exp_slices_in_tile != 0), set the value equal to + * and if there is only one slice in tile, set this value to the number of + * CTU rows of the tile minus 1, otherwise, set the value equal to * corresponding pps_exp_slice_height_in_ctus_minus1 from bitstream. */ uint16_t pps_exp_slice_height_in_ctus_minus1; diff --git a/va/va_trace.c b/va/va_trace.c index 8597acd35..7745b5d87 100644 --- a/va/va_trace.c +++ b/va/va_trace.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2009-2023 Intel Corporation. All Rights Reserved. + * Copyright (c) 2009-2024 Intel Corporation. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -2356,10 +2356,10 @@ static void va_TraceVAPictureParameterBufferVVC( va_TraceMsg(trace_ctx, "\tsps_log2_min_luma_coding_block_size_minus2 = %d\n", p->sps_log2_min_luma_coding_block_size_minus2); va_TraceMsg(trace_ctx, "\tsps_log2_transform_skip_max_size_minus2 = %d\n", p->sps_log2_transform_skip_max_size_minus2); - va_TraceMsg(trace_ctx, "\tChromaQpTable[3][112] =\n"); + va_TraceMsg(trace_ctx, "\tChromaQpTable[3][111] =\n"); va_TraceMsg(trace_ctx, ""); for (i = 0; i < 3; i++) { - for (j = 0; j < 112; j++) { + for (j = 0; j < 111; j++) { va_TracePrint(trace_ctx, "\t%d", p->ChromaQpTable[i][j]); if ((j + 1) % 8 == 0) TRACE_NEWLINE(); @@ -2634,10 +2634,10 @@ static void va_TraceVASliceParameterBufferVVC( va_TraceMsg(trace_ctx, "\tsh_alf_cc_cb_aps_id = %d\n", p->sh_alf_cc_cb_aps_id); va_TraceMsg(trace_ctx, "\tsh_alf_cc_cr_aps_id = %d\n", p->sh_alf_cc_cr_aps_id); - va_TraceMsg(trace_ctx, "\tsh_num_ref_idx_active_minus1[2]=\n"); + va_TraceMsg(trace_ctx, "\tNumRefIdxActive[2]=\n"); va_TraceMsg(trace_ctx, ""); for (i = 0; i < 2; i++) { - va_TracePrint(trace_ctx, "\t%d", p->sh_num_ref_idx_active_minus1[i]); + va_TracePrint(trace_ctx, "\t%d", p->NumRefIdxActive[i]); } va_TracePrint(trace_ctx, "\n"); @@ -2894,11 +2894,11 @@ static void va_TraceVAAlfBufferVVC( } va_TracePrint(trace_ctx, "\n"); - va_TraceMsg(trace_ctx, "\tAlfCoeffL[25][12]=\n"); + va_TraceMsg(trace_ctx, "\tfiltCoeff[25][12]=\n"); va_TraceMsg(trace_ctx, ""); for (i = 0; i < 25; i++) { for (j = 0; j < 12; j++) { - va_TracePrint(trace_ctx, "\t%d", p->AlfCoeffL[i][j]); + va_TracePrint(trace_ctx, "\t%d", p->filtCoeff[i][j]); if ((j + 1) % 8 == 0) TRACE_NEWLINE(); }