diff --git a/api/rocdecode.h b/api/rocdecode.h
index 70ead343aa..e9f1695737 100644
--- a/api/rocdecode.h
+++ b/api/rocdecode.h
@@ -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;
diff --git a/src/parser/avc_parser.cpp b/src/parser/avc_parser.cpp
index 1f79bc91e4..35e6c2ff29 100644
--- a/src/parser/avc_parser.cpp
+++ b/src/parser/avc_parser.cpp
@@ -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;
diff --git a/src/parser/avc_parser.h b/src/parser/avc_parser.h
index f4870f5ec3..a3e336e2b9 100644
--- a/src/parser/avc_parser.h
+++ b/src/parser/avc_parser.h
@@ -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 ParserResult
+ */
+ ParserResult SendPicForDecode();
+
/*! \brief Function to parse one picture bit stream received from the demuxer.
* \param [in] p_stream A pointer of uint8_t for the input stream to be parsed
* \param [in] pic_data_size Size of the input stream
diff --git a/src/parser/hevc_parser.cpp b/src/parser/hevc_parser.cpp
index 9dffcc8784..a3e48f5f32 100644
--- a/src/parser/hevc_parser.cpp
+++ b/src/parser/hevc_parser.cpp
@@ -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;
diff --git a/src/rocdecode/vaapi/vaapi_videodecoder.cpp b/src/rocdecode/vaapi/vaapi_videodecoder.cpp
index da659d5dee..eb435c86db 100644
--- a/src/rocdecode/vaapi/vaapi_videodecoder.cpp
+++ b/src/rocdecode/vaapi/vaapi_videodecoder.cpp
@@ -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;