AVC: Added decode picture callback from parser to decoder and VAAPI decode submission. (#190)

* * rocDecode/AVC: Added decode picture callback from parser to decoder and VAAPI decode submission.

* * rocDecode/AVC: Minor changes based on code review comments.

* * rocDecode/AVC: Removed a redundant line.

* * rocDecode/AVC: Condensed several lines based on code review feedback.
Этот коммит содержится в:
jeffqjiangNew
2024-01-23 20:30:29 -05:00
коммит произвёл GitHub
родитель e7dbd65315
Коммит 426067898c
5 изменённых файлов: 460 добавлений и 111 удалений
+166 -108
Просмотреть файл
@@ -261,26 +261,27 @@ typedef struct _RocdecReconfigureDecoderInfo {
} RocdecReconfigureDecoderInfo;
/*********************************************************/
//! \struct RocdecH264Picture
//! \struct RocdecAvcPicture
//! \ingroup group_amd_rocdecode
//! H.264 Picture Entry
//! This structure is used in RocdecH264PicParams structure
//! AVC/H.264 Picture Entry
//! This structure is used in RocdecAvcPicParams structure
/*********************************************************/
typedef struct _RocdecH264Picture {
int PicIdx; /**< picture index of reference frame */
int FrameIdx; /**< frame_num(int16_t-term) or LongTermFrameIdx(long-term) */
uint32_t RefFlags; /**< See below for definitions */
int TopFieldOrderCnt; /**< field order count of top field */
int BottomFieldOrderCnt; /**< field order count of bottom field */
} RocdecH264Picture;
typedef struct _RocdecAvcPicture {
int PicIdx; /**< picture index of reference frame */
uint32_t FrameIdx; /**< frame_num(int16_t-term) or LongTermFrameIdx(long-term) */
uint32_t Flags; /**< See below for definitions */
int32_t TopFieldOrderCnt; /**< field order count of top field */
int32_t BottomFieldOrderCnt; /**< field order count of bottom field */
uint32_t reserved[4];
} RocdecAvcPicture;
/* flags in RocdecH264Picture could be OR of the following */
#define RocdecH264Picture_FLAGS_INVALID 0x00000001
#define RocdecH264Picture_FLAGS_TOP_FIELD 0x00000002
#define RocdecH264Picture_FLAGS_BOTTOM_FIELD 0x00000004
#define RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE 0x00000008
#define RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE 0x00000010
#define RocdecH264Picture_FLAGS_NON_EXISTING 0x00000020
/* flags in RocdecAvcPicture could be OR of the following */
#define RocdecH264Picture_FLAGS_INVALID 0x00000001
#define RocdecH264Picture_FLAGS_TOP_FIELD 0x00000002
#define RocdecH264Picture_FLAGS_BOTTOM_FIELD 0x00000004
#define RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE 0x00000008
#define RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE 0x00000010
#define RocdecH264Picture_FLAGS_NON_EXISTING 0x00000020
/*********************************************************/
//! \struct RocdecHEVCPicture
@@ -403,15 +404,25 @@ typedef struct _RocdecMpeg2PicParams {
} RocdecMpeg2PicParams;
/***********************************************************/
//! \struct RocdecH264PicParams placeholder
//! \struct RocdecVc1PicParams placeholder
//! \ingroup group_amd_rocdecode
//! H.264 picture parameters
//! This structure is used in RocdecH264PicParams structure
//! This structure is configured similar to VA-API VAPictureParameterBufferH264 structure
//! JPEG picture parameters
//! This structure is used in RocdecVc1PicParams structure
/***********************************************************/
typedef struct _RocdecH264PicParams {
RocdecH264Picture cur_pic;
RocdecH264Picture dpb[16]; /* in DPB */
typedef struct _RocdecVc1PicParams {
int Reserved;
} RocdecVc1PicParams;
/***********************************************************/
//! \struct RocdecAvcPicParams placeholder
//! \ingroup group_amd_rocdecode
//! AVC picture parameters
//! This structure is used in RocdecAvcPicParams structure
//! This structure is configured to be the same as VA-API VAPictureParameterBufferH264 structure
/***********************************************************/
typedef struct _RocdecAvcPicParams {
RocdecAvcPicture curr_pic;
RocdecAvcPicture ref_frames[16]; /* in DPB */
uint16_t picture_width_in_mbs_minus1;
uint16_t picture_height_in_mbs_minus1;
uint8_t bit_depth_luma_minus8;
@@ -432,7 +443,16 @@ typedef struct _RocdecH264PicParams {
uint32_t delta_pic_order_always_zero_flag : 1;
} bits;
uint32_t value;
} sps_fields;
} seq_fields;
// FMO/ASO
uint8_t num_slice_groups_minus1;
uint8_t slice_group_map_type;
uint16_t slice_group_change_rate_minus1;
int8_t pic_init_qp_minus26;
int8_t pic_init_qs_minus26;
int8_t chroma_qp_index_offset;
int8_t second_chroma_qp_index_offset;
union {
struct {
uint32_t entropy_coding_mode_flag : 1;
@@ -447,86 +467,79 @@ typedef struct _RocdecH264PicParams {
uint32_t reference_pic_flag : 1; /* nal_ref_idc != 0 */
} bits;
uint32_t value;
} pps_fields;
// FMO/ASO
uint8_t num_slice_groups_minus1;
uint8_t slice_group_map_type;
uint16_t slice_group_change_rate_minus1;
int8_t pic_init_qp_minus26;
int8_t pic_init_qs_minus26;
int8_t chroma_qp_index_offset;
int8_t second_chroma_qp_index_offset;
} pic_fields;
uint16_t frame_num;
uint8_t num_ref_idx_l0_default_active_minus1;
uint8_t num_ref_idx_l1_default_active_minus1;
// Quantization Matrices (raster-order)
uint8_t scaling_list_4x4[6][16];
uint8_t scaling_list_8x8[2][64];
// SVC/MVC : Not supported in this version
// union
// {
// ROCDECH264MVCEXT mvcext;
// ROCDECH264SVCEXT svcext;
// };
uint32_t Reserved[12];
} RocdecH264PicParams;
uint32_t Reserved[8];
} RocdecAvcPicParams;
/***********************************************************/
//! \struct RocdecHevcIQMatrix
//! \struct RocdecAvcSliceParams placeholder
//! \ingroup group_amd_rocdecode
//! HEVC IQMatrix
//! This structure is sent once per frame,
//! and only when scaling_list_enabled_flag = 1.
//! When sps_scaling_list_data_present_flag = 0, app still
//! needs to send in this structure with default matrix values.
//! This structure is used in RocdecHevcQMatrix structure
//! AVC slice parameter buffer
//! This structure is configured to be the same as VA-API VASliceParameterBufferH264 structure
/***********************************************************/
typedef struct _RocdecHevcIQMatrix {
typedef struct _RocdecAvcSliceParams {
uint32_t slice_data_size; // slice size in bytes
uint32_t slice_data_offset; // byte offset of the current slice in the slice data buffer
uint32_t slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX defintions */
/**
* \brief 4x4 scaling,
* correspongs i = 0, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 15, inclusive.
* \brief Bit offset from NAL Header Unit to the begining of slice_data().
*
* This bit offset is relative to and includes the NAL unit byte
* and represents the number of bits parsed in the slice_header()
* after the removal of any emulation prevention bytes in
* there. However, the slice data buffer passed to the hardware is
* the original bitstream, thus including any emulation prevention
* bytes.
*/
uint8_t ScalingList4x4[6][16];
/**
* \brief 8x8 scaling,
* correspongs i = 1, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList8x8[6][64];
/**
* \brief 16x16 scaling,
* correspongs i = 2, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList16x16[6][64];
/**
* \brief 32x32 scaling,
* correspongs i = 3, MatrixID is in the range of 0 to 1,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList32x32[2][64];
/**
* \brief DC values of the 16x16 scaling lists,
* corresponds to HEVC spec syntax
* scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
* with sizeID = 2 and matrixID in the range of 0 to 5, inclusive.
*/
uint8_t ScalingListDC16x16[6];
/**
* \brief DC values of the 32x32 scaling lists,
* corresponds to HEVC spec syntax
* scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
* with sizeID = 3 and matrixID in the range of 0 to 1, inclusive.
*/
uint8_t ScalingListDC32x32[2];
uint16_t slice_data_bit_offset;
uint32_t reserved[4];
} RocdecHevcIQMatrix;
uint16_t first_mb_in_slice;
uint8_t slice_type;
uint8_t direct_spatial_mv_pred_flag;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint8_t cabac_init_idc;
int8_t slice_qp_delta;
uint8_t disable_deblocking_filter_idc;
int8_t slice_alpha_c0_offset_div2;
int8_t slice_beta_offset_div2;
RocdecAvcPicture ref_pic_list_0[32]; // 8.2.4.2
RocdecAvcPicture ref_pic_list_1[32]; // 8.2.4.2
uint8_t luma_log2_weight_denom;
uint8_t chroma_log2_weight_denom;
uint8_t luma_weight_l0_flag;
int16_t luma_weight_l0[32];
int16_t luma_offset_l0[32];
uint8_t chroma_weight_l0_flag;
int16_t chroma_weight_l0[32][2];
int16_t chroma_offset_l0[32][2];
uint8_t luma_weight_l1_flag;
int16_t luma_weight_l1[32];
int16_t luma_offset_l1[32];
uint8_t chroma_weight_l1_flag;
int16_t chroma_weight_l1[32][2];
int16_t chroma_offset_l1[32][2];
uint32_t va_reserved[4];
} RocdecAvcSliceParams;
/***********************************************************/
//! \struct RocdecAvcIQMatrix placeholder
//! \ingroup group_amd_rocdecode
//! AVC Inverse Quantization Matrix
//! This structure is configured to be the same as VA-API VAIQMatrixBufferH264 structure
/***********************************************************/
typedef struct _RocdecAvcIQMatrix {
/** \brief 4x4 scaling list, in raster scan order. */
uint8_t scaling_list_4x4[6][16];
/** \brief 8x8 scaling list, in raster scan order. */
uint8_t scaling_list_8x8[2][64];
/** \brief Reserved bytes for future use, must be zero */
uint32_t va_reserved[4];
} RocdecAvcIQMatrix;
/***********************************************************/
//! \struct RocdecHevcPicParams
@@ -535,7 +548,7 @@ typedef struct _RocdecHevcIQMatrix {
//! This structure is used in RocdecHevcPicParams structure
/***********************************************************/
typedef struct _RocdecHevcPicParams {
RocdecHEVCPicture cur_pic;
RocdecHEVCPicture curr_pic;
RocdecHEVCPicture ref_frames[15]; /* reference frame list in DPB */
uint16_t picture_width_in_luma_samples;
uint16_t picture_height_in_luma_samples;
@@ -649,16 +662,6 @@ typedef struct _RocdecHevcPicParams {
uint32_t reserved[8];
} RocdecHevcPicParams;
/***********************************************************/
//! \struct RocdecVc1PicParams placeholder
//! \ingroup group_amd_rocdecode
//! JPEG picture parameters
//! This structure is used in RocdecVc1PicParams structure
/***********************************************************/
typedef struct _RocdecVc1PicParams {
int Reserved;
} RocdecVc1PicParams;
/***********************************************************/
//! \struct RocdecHevcSliceParams
//! \ingroup group_amd_rocdecode
@@ -746,6 +749,59 @@ typedef struct _RocdecHevcSliceParams {
uint32_t reserved[2];
} RocdecHevcSliceParams;
/***********************************************************/
//! \struct RocdecHevcIQMatrix
//! \ingroup group_amd_rocdecode
//! HEVC IQMatrix
//! This structure is sent once per frame,
//! and only when scaling_list_enabled_flag = 1.
//! When sps_scaling_list_data_present_flag = 0, app still
//! needs to send in this structure with default matrix values.
//! This structure is used in RocdecHevcQMatrix structure
/***********************************************************/
typedef struct _RocdecHevcIQMatrix {
/**
* \brief 4x4 scaling,
* correspongs i = 0, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 15, inclusive.
*/
uint8_t ScalingList4x4[6][16];
/**
* \brief 8x8 scaling,
* correspongs i = 1, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList8x8[6][64];
/**
* \brief 16x16 scaling,
* correspongs i = 2, MatrixID is in the range of 0 to 5,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList16x16[6][64];
/**
* \brief 32x32 scaling,
* correspongs i = 3, MatrixID is in the range of 0 to 1,
* inclusive. And j is in the range of 0 to 63, inclusive.
*/
uint8_t ScalingList32x32[2][64];
/**
* \brief DC values of the 16x16 scaling lists,
* corresponds to HEVC spec syntax
* scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
* with sizeID = 2 and matrixID in the range of 0 to 5, inclusive.
*/
uint8_t ScalingListDC16x16[6];
/**
* \brief DC values of the 32x32 scaling lists,
* corresponds to HEVC spec syntax
* scaling_list_dc_coef_minus8[ sizeID - 2 ][ matrixID ] + 8
* with sizeID = 3 and matrixID in the range of 0 to 1, inclusive.
*/
uint8_t ScalingListDC32x32[2];
uint32_t reserved[4];
} RocdecHevcIQMatrix;
/******************************************************************************************/
//! \struct _RocdecPicParams
//! \ingroup group_amd_rocdecode
@@ -773,7 +829,7 @@ typedef struct _RocdecPicParams {
// IN: Codec-specific data
union {
RocdecMpeg2PicParams mpeg2; /**< Also used for MPEG-1 */
RocdecH264PicParams h264;
RocdecAvcPicParams avc;
RocdecHevcPicParams hevc;
RocdecVc1PicParams vc1;
RocdecJPEGPicParams jpeg;
@@ -782,11 +838,13 @@ typedef struct _RocdecPicParams {
union {
// Todo: Add slice params defines for other codecs.
RocdecAvcSliceParams avc;
RocdecHevcSliceParams hevc;
} slice_params;
union {
// Todo: Added IQ matrix defines for other codecs.
RocdecAvcIQMatrix avc;
RocdecHevcIQMatrix hevc;
} iq_matrix;
} RocdecPicParams;
+223
Просмотреть файл
@@ -55,6 +55,13 @@ rocDecStatus AvcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
}
new_sps_activated_ = false;
}
// Decode the picture
if (SendPicForDecode() != PARSER_OK) {
ERR(STR("Failed to decode!"));
return ROCDEC_RUNTIME_ERROR;
}
pic_count_++;
} else if (!(p_data->flags & ROCDEC_PKT_ENDOFSTREAM)) {
// If no payload and EOS is not set, treated as invalid.
@@ -275,6 +282,222 @@ ParserResult AvcVideoParser::NotifyNewSps(AvcSeqParameterSet *p_sps) {
}
}
ParserResult AvcVideoParser::SendPicForDecode() {
int i, j;
AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_];
AvcPicParameterSet *p_pps = &pps_list_[active_pps_id_];
AvcSliceHeader *p_slice_header = &slice_header_0_;
dec_pic_params_ = {0};
dec_pic_params_.PicWidth = pic_width_;
dec_pic_params_.PicHeight = pic_height_;
dec_pic_params_.CurrPicIdx = curr_pic_.pic_idx;
dec_pic_params_.field_pic_flag = p_slice_header->field_pic_flag;
dec_pic_params_.bottom_field_flag = p_slice_header->bottom_field_flag;
if (p_slice_header->field_pic_flag) {
dec_pic_params_.second_field = (pic_count_ & 1) ? 1 : 0;
} else {
dec_pic_params_.second_field = 1;
}
dec_pic_params_.nBitstreamDataLen = pic_stream_data_size_;
dec_pic_params_.pBitstreamData = pic_stream_data_ptr_;
dec_pic_params_.nNumSlices = slice_num_;
dec_pic_params_.pSliceDataOffsets = nullptr;
dec_pic_params_.ref_pic_flag = slice_nal_unit_header_.nal_ref_idc;
dec_pic_params_.intra_pic_flag = p_slice_header->slice_type == kAvcSliceTypeI || p_slice_header->slice_type == kAvcSliceTypeI_7 || p_slice_header->slice_type == kAvcSliceTypeSI || p_slice_header->slice_type == kAvcSliceTypeSI_9;
// Set up the picture parameter buffer
RocdecAvcPicParams *p_pic_param = &dec_pic_params_.pic_params.avc;
// Current picture
p_pic_param->curr_pic.PicIdx = curr_pic_.pic_idx;
if (curr_pic_.is_reference == kUsedForLongTerm) {
p_pic_param->curr_pic.FrameIdx = curr_pic_.long_term_pic_num;
} else {
p_pic_param->curr_pic.FrameIdx = curr_pic_.frame_num;
}
p_pic_param->curr_pic.Flags = 0;
if (curr_pic_.pic_structure != kFrame) {
p_pic_param->curr_pic.Flags |= curr_pic_.pic_structure == kBottomField ? RocdecH264Picture_FLAGS_BOTTOM_FIELD : RocdecH264Picture_FLAGS_TOP_FIELD;
}
if (curr_pic_.is_reference != kUnusedForReference) {
p_pic_param->curr_pic.Flags |= curr_pic_.is_reference == kUsedForShortTerm ? RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE : RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE;
}
p_pic_param->curr_pic.TopFieldOrderCnt = curr_pic_.top_field_order_cnt;
p_pic_param->curr_pic.BottomFieldOrderCnt = curr_pic_.bottom_field_order_cnt;
// Reference pictures
int buf_index = 0;
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference != kUnusedForReference) {
p_pic_param->ref_frames[buf_index].PicIdx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_pic_param->ref_frames[buf_index].FrameIdx = p_ref_pic->long_term_pic_num;
} else {
p_pic_param->ref_frames[buf_index].FrameIdx = p_ref_pic->frame_num;
}
p_pic_param->ref_frames[buf_index].Flags = 0;
if (p_ref_pic->pic_structure != kFrame) {
p_pic_param->ref_frames[buf_index].Flags |= p_ref_pic->pic_structure == kBottomField ? RocdecH264Picture_FLAGS_BOTTOM_FIELD : RocdecH264Picture_FLAGS_TOP_FIELD;
}
p_pic_param->ref_frames[buf_index].Flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE : RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE;
buf_index++;
}
}
for (i = buf_index; i < AVC_MAX_DPB_FRAMES; i++) {
p_pic_param->ref_frames[i].PicIdx = 0xFF;
}
p_pic_param->picture_width_in_mbs_minus1 = p_sps->pic_width_in_mbs_minus1;
p_pic_param->picture_height_in_mbs_minus1 = (2 - p_sps->frame_mbs_only_flag) * (p_sps->pic_height_in_map_units_minus1 + 1) - 1;
p_pic_param->bit_depth_luma_minus8 = p_sps->bit_depth_luma_minus8;
p_pic_param->bit_depth_chroma_minus8 = p_sps->bit_depth_chroma_minus8;
p_pic_param->num_ref_frames = p_sps->max_num_ref_frames;
p_pic_param->seq_fields.bits.chroma_format_idc = p_sps->chroma_format_idc;
p_pic_param->seq_fields.bits.residual_colour_transform_flag = p_sps->separate_colour_plane_flag;
p_pic_param->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = p_sps->gaps_in_frame_num_value_allowed_flag;
p_pic_param->seq_fields.bits.frame_mbs_only_flag = p_sps->frame_mbs_only_flag;
p_pic_param->seq_fields.bits.mb_adaptive_frame_field_flag = p_sps->mb_adaptive_frame_field_flag;
p_pic_param->seq_fields.bits.direct_8x8_inference_flag = p_sps->direct_8x8_inference_flag;
p_pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = p_sps->level_idc >= 31; // A.3.3.2
p_pic_param->seq_fields.bits.log2_max_frame_num_minus4 = p_sps->log2_max_frame_num_minus4;
p_pic_param->seq_fields.bits.pic_order_cnt_type = p_sps->pic_order_cnt_type;
p_pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = p_sps->log2_max_pic_order_cnt_lsb_minus4;
p_pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = p_sps->delta_pic_order_always_zero_flag;
p_pic_param->pic_init_qp_minus26 = p_pps->pic_init_qp_minus26;
p_pic_param->pic_init_qs_minus26 = p_pps->pic_init_qs_minus26;
p_pic_param->chroma_qp_index_offset = p_pps->chroma_qp_index_offset;
p_pic_param->second_chroma_qp_index_offset = p_pps->second_chroma_qp_index_offset;
p_pic_param->pic_fields.bits.entropy_coding_mode_flag = p_pps->entropy_coding_mode_flag;
p_pic_param->pic_fields.bits.weighted_pred_flag = p_pps->weighted_pred_flag;
p_pic_param->pic_fields.bits.weighted_bipred_idc = p_pps->weighted_bipred_idc;
p_pic_param->pic_fields.bits.transform_8x8_mode_flag = p_pps->transform_8x8_mode_flag;
p_pic_param->pic_fields.bits.field_pic_flag = p_slice_header->field_pic_flag;
p_pic_param->pic_fields.bits.constrained_intra_pred_flag = p_pps->constrained_intra_pred_flag;
p_pic_param->pic_fields.bits.pic_order_present_flag = p_pps->bottom_field_pic_order_in_frame_present_flag;
p_pic_param->pic_fields.bits.deblocking_filter_control_present_flag = p_pps->deblocking_filter_control_present_flag;
p_pic_param->pic_fields.bits.redundant_pic_cnt_present_flag = p_pps->redundant_pic_cnt_present_flag;
p_pic_param->pic_fields.bits.reference_pic_flag = slice_nal_unit_header_.nal_ref_idc != 0;
p_pic_param->frame_num = p_slice_header->frame_num;
// Set up slice parameters
RocdecAvcSliceParams *p_slice_param = &dec_pic_params_.slice_params.avc;
p_slice_param->slice_data_size = pic_stream_data_size_;
p_slice_param->slice_data_offset = 0;
p_slice_param->slice_data_flag = 0; // VA_SLICE_DATA_FLAG_ALL;
p_slice_param->slice_data_bit_offset = 0;
p_slice_param->first_mb_in_slice = p_slice_header->first_mb_in_slice;
p_slice_param->slice_type = p_slice_header->slice_type;
p_slice_param->direct_spatial_mv_pred_flag = p_slice_header->direct_spatial_mv_pred_flag;
p_slice_param->num_ref_idx_l0_active_minus1 = p_slice_header->num_ref_idx_l0_active_minus1;
p_slice_param->num_ref_idx_l1_active_minus1 = p_slice_header->num_ref_idx_l1_active_minus1;
p_slice_param->cabac_init_idc = p_slice_header->cabac_init_idc;
p_slice_param->slice_qp_delta = p_slice_header->slice_qp_delta;
p_slice_param->disable_deblocking_filter_idc = p_slice_header->disable_deblocking_filter_idc;
p_slice_param->slice_alpha_c0_offset_div2 = p_slice_header->slice_alpha_c0_offset_div2;
p_slice_param->slice_beta_offset_div2 = p_slice_header->slice_beta_offset_div2;
p_slice_param->luma_log2_weight_denom = p_slice_header->pred_weight_table.luma_log2_weight_denom;
p_slice_param->chroma_log2_weight_denom = p_slice_header->pred_weight_table.chroma_log2_weight_denom;
// Ref lists
for (i = 0; i < dpb_buffer_.num_short_term + dpb_buffer_.num_long_term; i++) {
AvcPicture *p_ref_pic = &ref_list_0_[i];
if (p_ref_pic->is_reference != kUnusedForReference) {
p_slice_param->ref_pic_list_0[i].PicIdx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_0[i].FrameIdx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_0[i].FrameIdx = p_ref_pic->frame_num;
}
p_slice_param->ref_pic_list_0[i].Flags = 0;
if (p_ref_pic->pic_structure != kFrame) {
p_slice_param->ref_pic_list_0[i].Flags |= p_ref_pic->pic_structure == kBottomField ? RocdecH264Picture_FLAGS_BOTTOM_FIELD : RocdecH264Picture_FLAGS_TOP_FIELD;
}
p_slice_param->ref_pic_list_0[i].Flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE : RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE;
}
}
if (p_slice_header->slice_type == kAvcSliceTypeB || p_slice_header->slice_type == kAvcSliceTypeB_6 ) {
AvcPicture *p_ref_pic = &ref_list_1_[i];
if (p_ref_pic->is_reference != kUnusedForReference) {
p_slice_param->ref_pic_list_1[i].PicIdx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_1[i].FrameIdx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_1[i].FrameIdx = p_ref_pic->frame_num;
}
p_slice_param->ref_pic_list_1[i].Flags = 0;
if (p_ref_pic->pic_structure != kFrame) {
p_slice_param->ref_pic_list_1[i].Flags |= p_ref_pic->pic_structure == kBottomField ? RocdecH264Picture_FLAGS_BOTTOM_FIELD : RocdecH264Picture_FLAGS_TOP_FIELD;
}
p_slice_param->ref_pic_list_1[i].Flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecH264Picture_FLAGS_SHORT_TERM_REFERENCE : RocdecH264Picture_FLAGS_LONG_TERM_REFERENCE;
}
}
// Prediction weight table
// Note luma_weight_l0_flag should be an array. Set it using the first one in the table.
p_slice_param->luma_weight_l0_flag = p_slice_header->pred_weight_table.weight_factor[0].luma_weight_l0_flag;
for (i = 0; i <= p_slice_header->num_ref_idx_l0_active_minus1; i++) {
p_slice_param->luma_weight_l0[i] = p_slice_header->pred_weight_table.weight_factor[i].luma_weight_l0;
p_slice_param->luma_offset_l0[i] = p_slice_header->pred_weight_table.weight_factor[i].luma_offset_l0;
}
// Note chroma_weight_l0_flag should be an array. Set it using the first one in the table.
p_slice_param->chroma_weight_l0_flag = p_slice_header->pred_weight_table.weight_factor[0].chroma_weight_l0_flag;
for (i = 0; i <= p_slice_header->num_ref_idx_l0_active_minus1; i++) {
for (j = 0; j < 2; j++) {
p_slice_param->chroma_weight_l0[i][j] = p_slice_header->pred_weight_table.weight_factor[i].chroma_weight_l0[j];
p_slice_param->chroma_offset_l0[i][j] = p_slice_header->pred_weight_table.weight_factor[i].chroma_offset_l0[j];
}
}
if (p_slice_header->slice_type == kAvcSliceTypeB || p_slice_header->slice_type == kAvcSliceTypeB_6 ) {
// Note luma_weight_l1_flag should be an array. Set it using the first one in the table.
p_slice_param->luma_weight_l1_flag = p_slice_header->pred_weight_table.weight_factor[0].luma_weight_l1_flag;
for (i = 0; i <= p_slice_header->num_ref_idx_l1_active_minus1; i++) {
p_slice_param->luma_weight_l1[i] = p_slice_header->pred_weight_table.weight_factor[i].luma_weight_l1;
p_slice_param->luma_offset_l1[i] = p_slice_header->pred_weight_table.weight_factor[i].luma_offset_l1;
}
// Note chroma_weight_l0_flag should be an array. Set it using the first one in the table.
p_slice_param->chroma_weight_l1_flag = p_slice_header->pred_weight_table.weight_factor[0].chroma_weight_l1_flag;
for (i = 0; i <= p_slice_header->num_ref_idx_l1_active_minus1; i++) {
for (j = 0; j < 2; j++) {
p_slice_param->chroma_weight_l1[i][j] = p_slice_header->pred_weight_table.weight_factor[i].chroma_weight_l1[j];
p_slice_param->chroma_offset_l1[i][j] = p_slice_header->pred_weight_table.weight_factor[i].chroma_offset_l1[j];
}
}
}
// Set up scaling lists
RocdecAvcIQMatrix *p_iq_matrix = &dec_pic_params_.iq_matrix.avc;
for (i = 0; i < 6; i++) {
for (j = 0; j < 16; j++) {
p_iq_matrix->scaling_list_4x4[i][j] = p_pps->scaling_list_4x4[i][j];
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 64; j++) {
p_iq_matrix->scaling_list_8x8[i][j] = p_pps->scaling_list_8x8[i][j];
}
}
if (pfn_decode_picture_cb_(parser_params_.pUserData, &dec_pic_params_) == 0) {
ERR("Decode error occurred.");
return PARSER_FAIL;
} else {
return PARSER_OK;
}
}
AvcNalUnitHeader AvcVideoParser::ParseNalUnitHeader(uint8_t header_byte) {
size_t bit_offset = 0;
AvcNalUnitHeader nal_header;
+39
Просмотреть файл
@@ -54,10 +54,41 @@ public:
protected:
enum PictureStructure {
kFrame,
kTopField,
kBottomField
};
enum AvcRefMarking {
kUnusedForReference = 0,
kUsedForShortTerm = 1,
kUsedForLongTerm = 2
};
typedef struct {
int pic_idx; // picture index or id
PictureStructure pic_structure;
int32_t pic_order_cnt;
int32_t top_field_order_cnt;
int32_t bottom_field_order_cnt;
int32_t frame_num;
int32_t frame_num_wrap; // FrameNumWrap
int32_t pic_num; // PicNum
int32_t long_term_pic_num; // LongTermPicNum
uint32_t long_term_frame_idx; // LongTermFrameIdx: long term reference frame/field identifier
uint32_t is_reference;
} AvcPicture;
/*! \brief Decoded picture buffer
*/
typedef struct{
uint32_t dpb_size; // DPB buffer size in number of frames
uint32_t num_short_term; // numShortTerm;
uint32_t num_long_term; // numLongTerm;
AvcPicture frame_buffer_list[AVC_MAX_DPB_FRAMES];
} DecodedPictureBuffer;
AvcNalUnitHeader nal_unit_header_;
@@ -75,7 +106,10 @@ protected:
int curr_ref_pic_bottom_field_;
// DPB
AvcPicture curr_pic_;
DecodedPictureBuffer dpb_buffer_;
AvcPicture ref_list_0_[AVC_MAX_REF_FRAME_NUM];
AvcPicture ref_list_1_[AVC_MAX_REF_FRAME_NUM];
/*! \brief Function to notify decoder about video format change (new SPS) through callback
* \param [in] p_sps Pointer to the current active SPS
@@ -83,6 +117,11 @@ protected:
*/
ParserResult NotifyNewSps(AvcSeqParameterSet *p_sps);
/*! \brief Function to fill the decode parameters and call back decoder to decode a picture
* \return <tt>ParserResult</tt>
*/
ParserResult SendPicForDecode();
/*! \brief Function to parse one picture bit stream received from the demuxer.
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] pic_data_size Size of the input stream
+2 -2
Просмотреть файл
@@ -287,8 +287,8 @@ int HevcVideoParser::SendPicForDecode() {
RocdecHevcPicParams *pic_param_ptr = &dec_pic_params_.pic_params.hevc;
// Current picture
pic_param_ptr->cur_pic.PicIdx = curr_pic_info_.pic_idx;
pic_param_ptr->cur_pic.POC = curr_pic_info_.pic_order_cnt;
pic_param_ptr->curr_pic.PicIdx = curr_pic_info_.pic_idx;
pic_param_ptr->curr_pic.POC = curr_pic_info_.pic_order_cnt;
// Reference pictures
ref_idx = 0;
+30 -1
Просмотреть файл
@@ -212,7 +212,7 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
// Upload data buffers
switch (decoder_create_info_.CodecType) {
case rocDecVideoCodec_HEVC: {
pPicParams->pic_params.hevc.cur_pic.PicIdx = curr_surface_id;
pPicParams->pic_params.hevc.curr_pic.PicIdx = curr_surface_id;
for (int i = 0; i < 15; i++) {
if (pPicParams->pic_params.hevc.ref_frames[i].PicIdx != 0xFF) {
if (pPicParams->pic_params.hevc.ref_frames[i].PicIdx >= va_surface_ids_.size() || pPicParams->pic_params.hevc.ref_frames[i].PicIdx < 0) {
@@ -233,6 +233,7 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
slice_params_ptr = (void*)&pPicParams->slice_params.hevc;
slice_params_size = sizeof(RocdecHevcSliceParams);
if ((pic_params_size != sizeof(VAPictureParameterBufferHEVC)) || (scaling_list_enabled && (iq_matrix_size != sizeof(VAIQMatrixBufferHEVC))) ||
(slice_params_size != sizeof(VASliceParameterBufferHEVC))) {
ERR("HEVC data_buffer parameter_size not matching vaapi parameter buffer size!");
@@ -241,6 +242,34 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
break;
}
case rocDecVideoCodec_H264: {
pPicParams->pic_params.avc.curr_pic.PicIdx = curr_surface_id;
for (int i = 0; i < 16; i++) {
if (pPicParams->pic_params.avc.ref_frames[i].PicIdx != 0xFF) {
if (pPicParams->pic_params.avc.ref_frames[i].PicIdx >= va_surface_ids_.size() || pPicParams->pic_params.avc.ref_frames[i].PicIdx < 0) {
ERR("Reference frame index exceeded the VAAPI surface pool limit.");
return ROCDEC_INVALID_PARAMETER;
}
pPicParams->pic_params.avc.ref_frames[i].PicIdx = va_surface_ids_[pPicParams->pic_params.avc.ref_frames[i].PicIdx];
}
}
pic_params_ptr = (void*)&pPicParams->pic_params.avc;
pic_params_size = sizeof(RocdecAvcPicParams);
scaling_list_enabled = true;
iq_matrix_ptr = (void*)&pPicParams->iq_matrix.avc;
iq_matrix_size = sizeof(RocdecAvcIQMatrix);
slice_params_ptr = (void*)&pPicParams->slice_params.avc;
slice_params_size = sizeof(RocdecAvcSliceParams);
if ((pic_params_size != sizeof(VAPictureParameterBufferH264)) || (iq_matrix_size != sizeof(VAIQMatrixBufferH264)) || (slice_params_size != sizeof(VASliceParameterBufferH264))) {
ERR("AVC data_buffer parameter_size not matching vaapi parameter buffer size!");
return ROCDEC_RUNTIME_ERROR;
}
break;
}
default: {
ERR("ERROR: the codec type is not supported!");
return ROCDEC_NOT_SUPPORTED;