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.
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e7dbd65315
Коммит
426067898c
+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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Ссылка в новой задаче
Block a user