Implemented proper slice parameter buffer submission for multiple slice streams. (#226)

* * rocDecode: Implemented proper slice parameter buffer submission for multiple slice streams.
 - We were submitting single slice parameter buffer for multiple slice streams. This works for other APIs but not for VAAPI, which requires to send slice parameter buffer once per slice.
 - At step 1, all the multi-slice structures are fixed sized (256). Will make them dynamic in the next step.
 - With this change, all 135 HEVC conformance streams now pass.

* * rocDecode: Multiple slice change step 2: make the fixed size slice info structure lists dynamic.

* * rocDecode: Minor changes in comments. No functional changes.

* *rocDecode: Changed INIT_SLICE_PARAM_LIST_NUM from 256 back to 16. 256 was set during debug process.

* * rocDecode: Add suggest changes from code review.

* * rocDecode: Moved slice_params_buf_id_ initialization to class VaapiVideoDecoder declaration, as suggested by code review.
このコミットが含まれているのは:
jeffqjiangNew
2024-02-09 15:09:49 -05:00
committed by GitHub
コミット 00127f16f1
7個のファイルの変更298行の追加256行の削除
+5 -4
ファイルの表示
@@ -805,8 +805,7 @@ typedef struct _RocdecPicParams {
uint32_t bitstream_data_len; /**< IN: Number of bytes in bitstream data buffer */
const uint8_t *bitstream_data; /**< IN: Ptr to bitstream data for this picture (slice-layer) */
uint32_t num_slices; /**< IN: Number of slices in this picture */
const uint32_t *slice_data_offsets; /**< IN: num_slices entries, contains offset of each slice within
the bitstream data buffer */
int ref_pic_flag; /**< IN: This picture is a reference picture */
int intra_pic_flag; /**< IN: This picture is entirely intra coded */
uint32_t reserved[30]; /**< Reserved for future use */
@@ -821,10 +820,12 @@ typedef struct _RocdecPicParams {
uint32_t codec_reserved[256];
} pic_params;
/*! \brief Variable size array. The user should allocate one slice param struct for each slice.
*/
union {
// Todo: Add slice params defines for other codecs.
RocdecAvcSliceParams avc;
RocdecHevcSliceParams hevc;
RocdecAvcSliceParams *avc;
RocdecHevcSliceParams *hevc;
} slice_params;
union {
+5 -6
ファイルの表示
@@ -92,7 +92,7 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
curr_start_code_offset_ = 0;
next_start_code_offset_ = 0;
slice_num_ = 0;
num_slices_ = 0;
sei_message_count_ = 0;
sei_payload_size_ = 0;
@@ -132,7 +132,7 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 4), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
// For each picture, only parse the first slice header
if (slice_num_ == 0) {
if (num_slices_ == 0) {
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_;
@@ -168,7 +168,7 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
// Find a free buffer in DPB for the current picture
FindFreeBufInDpb();
}
slice_num_++;
num_slices_++;
break;
}
@@ -334,8 +334,7 @@ ParserResult AvcVideoParser::SendPicForDecode() {
dec_pic_params_.bitstream_data_len = pic_stream_data_size_;
dec_pic_params_.bitstream_data = pic_stream_data_ptr_;
dec_pic_params_.num_slices = slice_num_;
dec_pic_params_.slice_data_offsets = nullptr;
dec_pic_params_.num_slices = num_slices_;
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;
@@ -423,7 +422,7 @@ ParserResult AvcVideoParser::SendPicForDecode() {
p_pic_param->frame_num = p_slice_header->frame_num;
// Set up slice parameters
RocdecAvcSliceParams *p_slice_param = &dec_pic_params_.slice_params.avc;
RocdecAvcSliceParams *p_slice_param = dec_pic_params_.slice_params.avc; // Todo
p_slice_param->slice_data_size = pic_stream_data_size_;
p_slice_param->slice_data_offset = 0;
+242 -226
ファイルの表示
@@ -44,8 +44,9 @@ HevcVideoParser::HevcVideoParser() {
m_vps_ = AllocStruct<HevcVideoParamSet>(MAX_VPS_COUNT);
m_sps_ = AllocStruct<HevcSeqParamSet>(MAX_SPS_COUNT);
m_pps_ = AllocStruct<HevcPicParamSet>(MAX_PPS_COUNT);
m_sh_ = AllocStruct<HevcSliceSegHeader>(1);
m_sh_copy_ = AllocStruct<HevcSliceSegHeader>(1);
slice_info_list_.assign(INIT_SLICE_LIST_NUM, {0});
slice_param_list_.assign(INIT_SLICE_LIST_NUM, {0});
sei_rbsp_buf_ = nullptr;
sei_rbsp_buf_size_ = 0;
@@ -134,9 +135,6 @@ HevcVideoParser::~HevcVideoParser() {
if (m_pps_) {
delete [] m_pps_;
}
if (m_sh_) {
delete m_sh_;
}
if (m_sh_copy_) {
delete m_sh_copy_;
}
@@ -274,11 +272,10 @@ int HevcVideoParser::SendPicForDecode() {
dec_pic_params_.bitstream_data_len = pic_stream_data_size_;
dec_pic_params_.bitstream_data = pic_stream_data_ptr_;
dec_pic_params_.num_slices = slice_num_;
dec_pic_params_.slice_data_offsets = nullptr; // Todo: do we need this? Remove if not.
dec_pic_params_.num_slices = num_slices_;
dec_pic_params_.ref_pic_flag = 1; // HEVC decoded picture is always marked as short term at first.
dec_pic_params_.intra_pic_flag = m_sh_->slice_type == HEVC_SLICE_TYPE_I ? 1 : 0;
dec_pic_params_.intra_pic_flag = slice_info_list_[0].slice_header.slice_type == HEVC_SLICE_TYPE_I ? 1 : 0;
// Todo: field_pic_flag, bottom_field_flag, second_field, ref_pic_flag, and intra_pic_flag seems to be associated with AVC/H.264.
// Do we need them for general purpose? Reomve if not.
@@ -361,7 +358,7 @@ int HevcVideoParser::SendPicForDecode() {
pic_param_ptr->pic_fields.bits.loop_filter_across_tiles_enabled_flag = pps_ptr->loop_filter_across_tiles_enabled_flag;
pic_param_ptr->pic_fields.bits.pcm_loop_filter_disabled_flag = sps_ptr->pcm_loop_filter_disabled_flag;
pic_param_ptr->pic_fields.bits.no_pic_reordering_flag = sps_ptr->sps_max_num_reorder_pics[0] ? 0 : 1;
pic_param_ptr->pic_fields.bits.no_bi_pred_flag = m_sh_->slice_type == HEVC_SLICE_TYPE_B ? 0 : 1;
pic_param_ptr->pic_fields.bits.no_bi_pred_flag = slice_info_list_[0].slice_header.slice_type == HEVC_SLICE_TYPE_B ? 0 : 1;
pic_param_ptr->sps_max_dec_pic_buffering_minus1 = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1]; // HighestTid
pic_param_ptr->bit_depth_luma_minus8 = sps_ptr->bit_depth_luma_minus8;
@@ -406,7 +403,7 @@ int HevcVideoParser::SendPicForDecode() {
pic_param_ptr->slice_parsing_fields.bits.slice_segment_header_extension_present_flag = pps_ptr->slice_segment_header_extension_present_flag;
pic_param_ptr->slice_parsing_fields.bits.rap_pic_flag = IsIrapPic(&slice_nal_unit_header_) ? 1 : 0;
pic_param_ptr->slice_parsing_fields.bits.idr_pic_flag = IsIdrPic(&slice_nal_unit_header_) ? 1 : 0;
pic_param_ptr->slice_parsing_fields.bits.intra_pic_flag = m_sh_->slice_type == HEVC_SLICE_TYPE_I ? 1 : 0;
pic_param_ptr->slice_parsing_fields.bits.intra_pic_flag = slice_info_list_[0].slice_header.slice_type == HEVC_SLICE_TYPE_I ? 1 : 0;
pic_param_ptr->log2_max_pic_order_cnt_lsb_minus4 = sps_ptr->log2_max_pic_order_cnt_lsb_minus4;
pic_param_ptr->num_short_term_ref_pic_sets = sps_ptr->num_short_term_ref_pic_sets;
@@ -417,104 +414,113 @@ int HevcVideoParser::SendPicForDecode() {
pic_param_ptr->pps_tc_offset_div2 = pps_ptr->pps_tc_offset_div2;
pic_param_ptr->num_extra_slice_header_bits = pps_ptr->num_extra_slice_header_bits;
pic_param_ptr->st_rps_bits = m_sh_->short_term_ref_pic_set_size;
pic_param_ptr->st_rps_bits = slice_info_list_[0].slice_header.short_term_ref_pic_set_size;
/// Fill slice parameters
RocdecHevcSliceParams *slice_params_ptr = &dec_pic_params_.slice_params.hevc;
// Resize if needed
if (num_slices_ > slice_param_list_.size()) {
slice_param_list_.resize(num_slices_, {0});
}
for (int slice_index = 0; slice_index < num_slices_; slice_index++) {
RocdecHevcSliceParams *slice_params_ptr = &slice_param_list_[slice_index];
HevcSliceInfo *p_slice_info = &slice_info_list_[slice_index];
HevcSliceSegHeader *p_slice_header = &p_slice_info->slice_header;
// We put all slices into one slice data buffer.
slice_params_ptr->slice_data_size = pic_stream_data_size_;
slice_params_ptr->slice_data_offset = 0; // point to the start code
slice_params_ptr->slice_data_flag = 0x00; // VA_SLICE_DATA_FLAG_ALL;
slice_params_ptr->slice_data_byte_offset = 0; // VCN consumes from the start code
slice_params_ptr->slice_segment_address = m_sh_->slice_segment_address;
// We put all slices into one slice data buffer.
slice_params_ptr->slice_data_size = p_slice_info->slice_data_size;
slice_params_ptr->slice_data_offset = p_slice_info->slice_data_offset; // point to the start code
slice_params_ptr->slice_data_flag = 0x00; // VA_SLICE_DATA_FLAG_ALL;
slice_params_ptr->slice_data_byte_offset = 0; // VCN consumes from the start code
slice_params_ptr->slice_segment_address = p_slice_header->slice_segment_address;
// Ref lists
memset(slice_params_ptr->ref_pic_list, 0xFF, sizeof(slice_params_ptr->ref_pic_list));
if (m_sh_->slice_type != HEVC_SLICE_TYPE_I) {
for (i = 0; i <= m_sh_->num_ref_idx_l0_active_minus1; i++) {
int idx = ref_pic_list_0_[i]; // pic_idx of the ref pic
for (j = 0; j < 15; j++) {
if (pic_param_ptr->ref_frames[j].pic_idx == idx) {
break;
}
}
if (j == 15) {
ERR("Could not find matching pic in ref_frames list. The slice type is P/B, and the idx from the ref_pic_list_0_ is: " + TOSTR(idx));
return PARSER_FAIL;
} else {
slice_params_ptr->ref_pic_list[0][i] = j;
}
}
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
for (i = 0; i <= m_sh_->num_ref_idx_l1_active_minus1; i++) {
int idx = ref_pic_list_1_[i]; // pic_idx of the ref pic
// Ref lists
memset(slice_params_ptr->ref_pic_list, 0xFF, sizeof(slice_params_ptr->ref_pic_list));
if (p_slice_header->slice_type != HEVC_SLICE_TYPE_I) {
for (i = 0; i <= p_slice_header->num_ref_idx_l0_active_minus1; i++) {
int idx = p_slice_info->ref_pic_list_0_[i]; // pic_idx of the ref pic
for (j = 0; j < 15; j++) {
if (pic_param_ptr->ref_frames[j].pic_idx == idx) {
break;
}
}
if (j == 15) {
ERR("Could not find matching pic in ref_frames list. The slice type is B, and the idx from the ref_pic_list_1_ is: " + TOSTR(idx));
ERR("Could not find matching pic in ref_frames list. The slice type is P/B, and the idx from the ref_pic_list_0_ is: " + TOSTR(idx));
return PARSER_FAIL;
} else {
slice_params_ptr->ref_pic_list[1][i] = j;
slice_params_ptr->ref_pic_list[0][i] = j;
}
}
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
for (i = 0; i <= p_slice_header->num_ref_idx_l1_active_minus1; i++) {
int idx = p_slice_info->ref_pic_list_1_[i]; // pic_idx of the ref pic
for (j = 0; j < 15; j++) {
if (pic_param_ptr->ref_frames[j].pic_idx == idx) {
break;
}
}
if (j == 15) {
ERR("Could not find matching pic in ref_frames list. The slice type is B, and the idx from the ref_pic_list_1_ is: " + TOSTR(idx));
return PARSER_FAIL;
} else {
slice_params_ptr->ref_pic_list[1][i] = j;
}
}
}
}
}
slice_params_ptr->long_slice_flags.fields.last_slice_of_pic = 1;
slice_params_ptr->long_slice_flags.fields.dependent_slice_segment_flag = m_sh_->dependent_slice_segment_flag;
slice_params_ptr->long_slice_flags.fields.slice_type = m_sh_->slice_type;
slice_params_ptr->long_slice_flags.fields.color_plane_id = m_sh_->colour_plane_id;
slice_params_ptr->long_slice_flags.fields.slice_sao_luma_flag = m_sh_->slice_sao_luma_flag;
slice_params_ptr->long_slice_flags.fields.slice_sao_chroma_flag = m_sh_->slice_sao_chroma_flag;
slice_params_ptr->long_slice_flags.fields.mvd_l1_zero_flag = m_sh_->mvd_l1_zero_flag;
slice_params_ptr->long_slice_flags.fields.cabac_init_flag = m_sh_->cabac_init_flag;
slice_params_ptr->long_slice_flags.fields.slice_temporal_mvp_enabled_flag = m_sh_->slice_temporal_mvp_enabled_flag;
slice_params_ptr->long_slice_flags.fields.slice_deblocking_filter_disabled_flag = m_sh_->slice_deblocking_filter_disabled_flag;
slice_params_ptr->long_slice_flags.fields.collocated_from_l0_flag = m_sh_->collocated_from_l0_flag;
slice_params_ptr->long_slice_flags.fields.slice_loop_filter_across_slices_enabled_flag = m_sh_->slice_loop_filter_across_slices_enabled_flag;
slice_params_ptr->long_slice_flags.fields.last_slice_of_pic = (slice_index == num_slices_ - 1) ? 1 : 0;
slice_params_ptr->long_slice_flags.fields.dependent_slice_segment_flag = p_slice_header->dependent_slice_segment_flag;
slice_params_ptr->long_slice_flags.fields.slice_type = p_slice_header->slice_type;
slice_params_ptr->long_slice_flags.fields.color_plane_id = p_slice_header->colour_plane_id;
slice_params_ptr->long_slice_flags.fields.slice_sao_luma_flag = p_slice_header->slice_sao_luma_flag;
slice_params_ptr->long_slice_flags.fields.slice_sao_chroma_flag = p_slice_header->slice_sao_chroma_flag;
slice_params_ptr->long_slice_flags.fields.mvd_l1_zero_flag = p_slice_header->mvd_l1_zero_flag;
slice_params_ptr->long_slice_flags.fields.cabac_init_flag = p_slice_header->cabac_init_flag;
slice_params_ptr->long_slice_flags.fields.slice_temporal_mvp_enabled_flag = p_slice_header->slice_temporal_mvp_enabled_flag;
slice_params_ptr->long_slice_flags.fields.slice_deblocking_filter_disabled_flag = p_slice_header->slice_deblocking_filter_disabled_flag;
slice_params_ptr->long_slice_flags.fields.collocated_from_l0_flag = p_slice_header->collocated_from_l0_flag;
slice_params_ptr->long_slice_flags.fields.slice_loop_filter_across_slices_enabled_flag = p_slice_header->slice_loop_filter_across_slices_enabled_flag;
slice_params_ptr->collocated_ref_idx = m_sh_->collocated_ref_idx;
slice_params_ptr->num_ref_idx_l0_active_minus1 = m_sh_->num_ref_idx_l0_active_minus1;
slice_params_ptr->num_ref_idx_l1_active_minus1 = m_sh_->num_ref_idx_l1_active_minus1;
slice_params_ptr->slice_qp_delta = m_sh_->slice_qp_delta;
slice_params_ptr->slice_cb_qp_offset = m_sh_->slice_cb_qp_offset;
slice_params_ptr->slice_cr_qp_offset = m_sh_->slice_cr_qp_offset;
slice_params_ptr->slice_beta_offset_div2 = m_sh_->slice_beta_offset_div2;
slice_params_ptr->slice_tc_offset_div2 = m_sh_->slice_tc_offset_div2;
slice_params_ptr->collocated_ref_idx = p_slice_header->collocated_ref_idx;
slice_params_ptr->num_ref_idx_l0_active_minus1 = p_slice_header->num_ref_idx_l0_active_minus1;
slice_params_ptr->num_ref_idx_l1_active_minus1 = p_slice_header->num_ref_idx_l1_active_minus1;
slice_params_ptr->slice_qp_delta = p_slice_header->slice_qp_delta;
slice_params_ptr->slice_cb_qp_offset = p_slice_header->slice_cb_qp_offset;
slice_params_ptr->slice_cr_qp_offset = p_slice_header->slice_cr_qp_offset;
slice_params_ptr->slice_beta_offset_div2 = p_slice_header->slice_beta_offset_div2;
slice_params_ptr->slice_tc_offset_div2 = p_slice_header->slice_tc_offset_div2;
if ((pps_ptr->weighted_pred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_P) || (pps_ptr->weighted_bipred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_B)) {
slice_params_ptr->luma_log2_weight_denom = m_sh_->pred_weight_table.luma_log2_weight_denom;
slice_params_ptr->delta_chroma_log2_weight_denom = m_sh_->pred_weight_table.delta_chroma_log2_weight_denom;
for (i = 0; i < m_sh_->num_ref_idx_l0_active_minus1; i++) {
slice_params_ptr->delta_luma_weight_l0[i] = m_sh_->pred_weight_table.delta_luma_weight_l0[i];
slice_params_ptr->luma_offset_l0[i] = m_sh_->pred_weight_table.luma_offset_l0[i];
slice_params_ptr->delta_chroma_weight_l0[i][0] = m_sh_->pred_weight_table.delta_chroma_weight_l0[i][0];
slice_params_ptr->delta_chroma_weight_l0[i][1] = m_sh_->pred_weight_table.delta_chroma_weight_l0[i][1];
slice_params_ptr->chroma_offset_l0[i][0] = m_sh_->pred_weight_table.chroma_offset_l0[i][0];
slice_params_ptr->chroma_offset_l0[i][1] = m_sh_->pred_weight_table.chroma_offset_l0[i][1];
}
if ((pps_ptr->weighted_pred_flag && p_slice_header->slice_type == HEVC_SLICE_TYPE_P) || (pps_ptr->weighted_bipred_flag && p_slice_header->slice_type == HEVC_SLICE_TYPE_B)) {
slice_params_ptr->luma_log2_weight_denom = p_slice_header->pred_weight_table.luma_log2_weight_denom;
slice_params_ptr->delta_chroma_log2_weight_denom = p_slice_header->pred_weight_table.delta_chroma_log2_weight_denom;
for (i = 0; i < p_slice_header->num_ref_idx_l0_active_minus1; i++) {
slice_params_ptr->delta_luma_weight_l0[i] = p_slice_header->pred_weight_table.delta_luma_weight_l0[i];
slice_params_ptr->luma_offset_l0[i] = p_slice_header->pred_weight_table.luma_offset_l0[i];
slice_params_ptr->delta_chroma_weight_l0[i][0] = p_slice_header->pred_weight_table.delta_chroma_weight_l0[i][0];
slice_params_ptr->delta_chroma_weight_l0[i][1] = p_slice_header->pred_weight_table.delta_chroma_weight_l0[i][1];
slice_params_ptr->chroma_offset_l0[i][0] = p_slice_header->pred_weight_table.chroma_offset_l0[i][0];
slice_params_ptr->chroma_offset_l0[i][1] = p_slice_header->pred_weight_table.chroma_offset_l0[i][1];
}
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
for (i = 0; i < m_sh_->num_ref_idx_l1_active_minus1; i++) {
slice_params_ptr->delta_luma_weight_l1[i] = m_sh_->pred_weight_table.delta_luma_weight_l1[i];
slice_params_ptr->luma_offset_l1[i] = m_sh_->pred_weight_table.luma_offset_l1[i];
slice_params_ptr->delta_chroma_weight_l1[i][0] = m_sh_->pred_weight_table.delta_chroma_weight_l1[i][0];
slice_params_ptr->delta_chroma_weight_l1[i][1] = m_sh_->pred_weight_table.delta_chroma_weight_l1[i][1];
slice_params_ptr->chroma_offset_l1[i][0] = m_sh_->pred_weight_table.chroma_offset_l1[i][0];
slice_params_ptr->chroma_offset_l1[i][1] = m_sh_->pred_weight_table.chroma_offset_l1[i][1];
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
for (i = 0; i < p_slice_header->num_ref_idx_l1_active_minus1; i++) {
slice_params_ptr->delta_luma_weight_l1[i] = p_slice_header->pred_weight_table.delta_luma_weight_l1[i];
slice_params_ptr->luma_offset_l1[i] = p_slice_header->pred_weight_table.luma_offset_l1[i];
slice_params_ptr->delta_chroma_weight_l1[i][0] = p_slice_header->pred_weight_table.delta_chroma_weight_l1[i][0];
slice_params_ptr->delta_chroma_weight_l1[i][1] = p_slice_header->pred_weight_table.delta_chroma_weight_l1[i][1];
slice_params_ptr->chroma_offset_l1[i][0] = p_slice_header->pred_weight_table.chroma_offset_l1[i][0];
slice_params_ptr->chroma_offset_l1[i][1] = p_slice_header->pred_weight_table.chroma_offset_l1[i][1];
}
}
}
}
slice_params_ptr->five_minus_max_num_merge_cand = m_sh_->five_minus_max_num_merge_cand;
slice_params_ptr->num_entry_point_offsets = m_sh_->num_entry_point_offsets;
slice_params_ptr->entry_offset_to_subset_array = 0; // don't care
slice_params_ptr->slice_data_num_emu_prevn_bytes = 0; // don't care
slice_params_ptr->five_minus_max_num_merge_cand = p_slice_header->five_minus_max_num_merge_cand;
slice_params_ptr->num_entry_point_offsets = p_slice_header->num_entry_point_offsets;
slice_params_ptr->entry_offset_to_subset_array = 0; // don't care
slice_params_ptr->slice_data_num_emu_prevn_bytes = 0; // don't care
}
dec_pic_params_.slice_params.hevc = slice_param_list_.data();
/// Fill scaling lists
if (sps_ptr->scaling_list_enabled_flag) {
@@ -572,7 +578,7 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
curr_start_code_offset_ = 0;
next_start_code_offset_ = 0;
slice_num_ = 0;
num_slices_ = 0;
sei_message_count_ = 0;
sei_payload_size_ = 0;
@@ -627,22 +633,30 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
case NAL_UNIT_CODED_SLICE_RADL_R:
case NAL_UNIT_CODED_SLICE_RASL_N:
case NAL_UNIT_CODED_SLICE_RASL_R: {
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_;
// Resize slice info list if needed
if ((num_slices_ + 1) > slice_info_list_.size()) {
slice_info_list_.resize(num_slices_ + 1, {0});
}
slice_info_list_[num_slices_].slice_data_offset = curr_start_code_offset_;
slice_info_list_[num_slices_].slice_data_size = nal_unit_size_;
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
// For each picture, only parse the first slice header
if (slice_num_ == 0) {
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_;
HevcSliceSegHeader *p_slice_header = &slice_info_list_[num_slices_].slice_header;
ParseSliceHeader(rbsp_buf_, rbsp_size_, p_slice_header);
// Start decode process
if (num_slices_ == 0) {
// Use the data directly from demuxer without copying
pic_stream_data_ptr_ = pic_data_buffer_ptr_ + curr_start_code_offset_;
// Picture stream data size is calculated as the diff between the frame end and the first slice offset.
// This is to consider the possibility of non-slice NAL units between slices.
pic_stream_data_size_ = pic_data_size - curr_start_code_offset_;
ParseSliceHeader(rbsp_buf_, rbsp_size_);
// Start decode process
if (IsIrapPic(&slice_nal_unit_header_)) {
if (IsIdrPic(&slice_nal_unit_header_) || IsBlaPic(&slice_nal_unit_header_) || pic_count_ == 0 || first_pic_after_eos_nal_unit_) {
no_rasl_output_flag_ = 1;
@@ -658,7 +672,7 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
if (IsRaslPic(&slice_nal_unit_header_) && no_rasl_output_flag_ == 1) {
curr_pic_info_.pic_output_flag = 0;
} else {
curr_pic_info_.pic_output_flag = m_sh_->pic_output_flag;
curr_pic_info_.pic_output_flag = p_slice_header->pic_output_flag;
}
// Get POC. 8.3.1.
@@ -666,12 +680,14 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
// Decode RPS. 8.3.2.
DecodeRps();
}
// Construct ref lists. 8.3.4.
if(m_sh_->slice_type != HEVC_SLICE_TYPE_I) {
ConstructRefPicLists();
}
// Construct ref lists. 8.3.4.
if(p_slice_header->slice_type != HEVC_SLICE_TYPE_I) {
ConstructRefPicLists(&slice_info_list_[num_slices_]);
}
if (num_slices_ == 0) {
// C.5.2.2. Mark output buffers. (After 8.3.2.)
if (MarkOutputPictures() != PARSER_OK) {
return PARSER_FAIL;
@@ -682,7 +698,7 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
return PARSER_FAIL;
}
}
slice_num_++;
num_slices_++;
break;
}
@@ -1519,22 +1535,22 @@ void HevcVideoParser::ParsePps(uint8_t *nalu, size_t size) {
#endif // DBGINFO
}
bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header) {
HevcPicParamSet *pps_ptr = nullptr;
HevcSeqParamSet *sps_ptr = nullptr;
size_t offset = 0;
HevcSliceSegHeader temp_sh;
memset(m_sh_, 0, sizeof(HevcSliceSegHeader));
memset(p_slice_header, 0, sizeof(HevcSliceSegHeader));
memset(&temp_sh, 0, sizeof(temp_sh));
temp_sh.first_slice_segment_in_pic_flag = m_sh_->first_slice_segment_in_pic_flag = Parser::GetBit(nalu, offset);
temp_sh.first_slice_segment_in_pic_flag = p_slice_header->first_slice_segment_in_pic_flag = Parser::GetBit(nalu, offset);
if (IsIrapPic(&slice_nal_unit_header_)) {
temp_sh.no_output_of_prior_pics_flag = m_sh_->no_output_of_prior_pics_flag = Parser::GetBit(nalu, offset);
temp_sh.no_output_of_prior_pics_flag = p_slice_header->no_output_of_prior_pics_flag = Parser::GetBit(nalu, offset);
}
// Set active VPS, SPS and PPS for the current slice
m_active_pps_id_ = Parser::ExpGolomb::ReadUe(nalu, offset);
temp_sh.slice_pic_parameter_set_id = m_sh_->slice_pic_parameter_set_id = m_active_pps_id_;
temp_sh.slice_pic_parameter_set_id = p_slice_header->slice_pic_parameter_set_id = m_active_pps_id_;
pps_ptr = &m_pps_[m_active_pps_id_];
if (m_active_sps_id_ != pps_ptr->pps_seq_parameter_set_id) {
m_active_sps_id_ = pps_ptr->pps_seq_parameter_set_id;
@@ -1572,38 +1588,36 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
}
}
if (!m_sh_->first_slice_segment_in_pic_flag) {
if (!p_slice_header->first_slice_segment_in_pic_flag) {
if (pps_ptr->dependent_slice_segments_enabled_flag) {
temp_sh.dependent_slice_segment_flag = m_sh_->dependent_slice_segment_flag = Parser::GetBit(nalu, offset);
temp_sh.dependent_slice_segment_flag = p_slice_header->dependent_slice_segment_flag = Parser::GetBit(nalu, offset);
}
int bits_slice_segment_address = (int)ceilf(log2f((float)pic_size_in_ctbs_y_));
temp_sh.slice_segment_address = m_sh_->slice_segment_address = Parser::ReadBits(nalu, offset, bits_slice_segment_address);
temp_sh.slice_segment_address = p_slice_header->slice_segment_address = Parser::ReadBits(nalu, offset, bits_slice_segment_address);
}
if (!m_sh_->dependent_slice_segment_flag) {
if (!p_slice_header->dependent_slice_segment_flag) {
for (int i = 0; i < pps_ptr->num_extra_slice_header_bits; i++) {
m_sh_->slice_reserved_flag[i] = Parser::GetBit(nalu, offset);
p_slice_header->slice_reserved_flag[i] = Parser::GetBit(nalu, offset);
}
m_sh_->slice_type = Parser::ExpGolomb::ReadUe(nalu, offset);
p_slice_header->slice_type = Parser::ExpGolomb::ReadUe(nalu, offset);
if (pps_ptr->output_flag_present_flag) {
m_sh_->pic_output_flag = Parser::GetBit(nalu, offset);
p_slice_header->pic_output_flag = Parser::GetBit(nalu, offset);
} else {
m_sh_->pic_output_flag = 1; // default value
p_slice_header->pic_output_flag = 1; // default value
}
if (sps_ptr->separate_colour_plane_flag) {
m_sh_->colour_plane_id = Parser::ReadBits(nalu, offset, 2);
p_slice_header->colour_plane_id = Parser::ReadBits(nalu, offset, 2);
}
if (slice_nal_unit_header_.nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_W_RADL && slice_nal_unit_header_.nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_N_LP) {
//length of slice_pic_order_cnt_lsb is log2_max_pic_order_cnt_lsb_minus4 + 4 bits.
m_sh_->slice_pic_order_cnt_lsb = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4));
p_slice_header->slice_pic_order_cnt_lsb = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4));
m_sh_->short_term_ref_pic_set_sps_flag = Parser::GetBit(nalu, offset);
p_slice_header->short_term_ref_pic_set_sps_flag = Parser::GetBit(nalu, offset);
int32_t pos = offset;
if (!m_sh_->short_term_ref_pic_set_sps_flag) {
ParseShortTermRefPicSet(&m_sh_->st_rps, sps_ptr->num_short_term_ref_pic_sets, sps_ptr->num_short_term_ref_pic_sets, sps_ptr->st_rps, nalu, size, offset);
if (!p_slice_header->short_term_ref_pic_set_sps_flag) {
ParseShortTermRefPicSet(&p_slice_header->st_rps, sps_ptr->num_short_term_ref_pic_sets, sps_ptr->num_short_term_ref_pic_sets, sps_ptr->st_rps, nalu, size, offset);
} else {
if (sps_ptr->num_short_term_ref_pic_sets > 1) {
int num_bits = 0;
@@ -1611,88 +1625,88 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
num_bits++;
}
if (num_bits > 0) {
m_sh_->short_term_ref_pic_set_idx = Parser::ReadBits(nalu, offset, num_bits);
p_slice_header->short_term_ref_pic_set_idx = Parser::ReadBits(nalu, offset, num_bits);
}
} else {
m_sh_->short_term_ref_pic_set_idx = 0;
p_slice_header->short_term_ref_pic_set_idx = 0;
}
// Copy the SPS RPS to slice RPS
m_sh_->st_rps = sps_ptr->st_rps[m_sh_->short_term_ref_pic_set_idx];
p_slice_header->st_rps = sps_ptr->st_rps[p_slice_header->short_term_ref_pic_set_idx];
}
m_sh_->short_term_ref_pic_set_size = offset - pos;
p_slice_header->short_term_ref_pic_set_size = offset - pos;
if (sps_ptr->long_term_ref_pics_present_flag) {
if (sps_ptr->num_long_term_ref_pics_sps > 0) {
m_sh_->num_long_term_sps = Parser::ExpGolomb::ReadUe(nalu, offset);
p_slice_header->num_long_term_sps = Parser::ExpGolomb::ReadUe(nalu, offset);
}
m_sh_->num_long_term_pics = Parser::ExpGolomb::ReadUe(nalu, offset);
p_slice_header->num_long_term_pics = Parser::ExpGolomb::ReadUe(nalu, offset);
int bits_for_ltrp_in_sps = 0;
while (sps_ptr->num_long_term_ref_pics_sps > (1 << bits_for_ltrp_in_sps)) {
bits_for_ltrp_in_sps++;
}
m_sh_->lt_rps.num_of_pics = m_sh_->num_long_term_sps + m_sh_->num_long_term_pics;
for (int i = 0; i < (m_sh_->num_long_term_sps + m_sh_->num_long_term_pics); i++) {
if (i < m_sh_->num_long_term_sps) {
p_slice_header->lt_rps.num_of_pics = p_slice_header->num_long_term_sps + p_slice_header->num_long_term_pics;
for (int i = 0; i < (p_slice_header->num_long_term_sps + p_slice_header->num_long_term_pics); i++) {
if (i < p_slice_header->num_long_term_sps) {
if (sps_ptr->num_long_term_ref_pics_sps > 1) {
if( bits_for_ltrp_in_sps > 0) {
m_sh_->lt_idx_sps[i] = Parser::ReadBits(nalu, offset, bits_for_ltrp_in_sps);
m_sh_->lt_rps.pocs[i] = sps_ptr->lt_rps.pocs[m_sh_->lt_idx_sps[i]]; // PocLsbLt[]
m_sh_->lt_rps.used_by_curr_pic[i] = sps_ptr->lt_rps.used_by_curr_pic[m_sh_->lt_idx_sps[i]]; // UsedByCurrPicLt[]
p_slice_header->lt_idx_sps[i] = Parser::ReadBits(nalu, offset, bits_for_ltrp_in_sps);
p_slice_header->lt_rps.pocs[i] = sps_ptr->lt_rps.pocs[p_slice_header->lt_idx_sps[i]]; // PocLsbLt[]
p_slice_header->lt_rps.used_by_curr_pic[i] = sps_ptr->lt_rps.used_by_curr_pic[p_slice_header->lt_idx_sps[i]]; // UsedByCurrPicLt[]
}
}
} else {
m_sh_->poc_lsb_lt[i] = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4));
m_sh_->used_by_curr_pic_lt_flag[i] = Parser::GetBit(nalu, offset);
m_sh_->lt_rps.pocs[i] = m_sh_->poc_lsb_lt[i]; // PocLsbLt[]
m_sh_->lt_rps.used_by_curr_pic[i] = m_sh_->used_by_curr_pic_lt_flag[i]; // UsedByCurrPicLt[]
p_slice_header->poc_lsb_lt[i] = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4));
p_slice_header->used_by_curr_pic_lt_flag[i] = Parser::GetBit(nalu, offset);
p_slice_header->lt_rps.pocs[i] = p_slice_header->poc_lsb_lt[i]; // PocLsbLt[]
p_slice_header->lt_rps.used_by_curr_pic[i] = p_slice_header->used_by_curr_pic_lt_flag[i]; // UsedByCurrPicLt[]
}
int delta_poc_msb_cycle_lt = 0;
m_sh_->delta_poc_msb_present_flag[i] = Parser::GetBit(nalu, offset);
if (m_sh_->delta_poc_msb_present_flag[i]) {
p_slice_header->delta_poc_msb_present_flag[i] = Parser::GetBit(nalu, offset);
if (p_slice_header->delta_poc_msb_present_flag[i]) {
// Store DeltaPocMsbCycleLt in delta_poc_msb_cycle_lt for later use
delta_poc_msb_cycle_lt = Parser::ExpGolomb::ReadUe(nalu, offset);
}
if ( i == 0 || i == m_sh_->num_long_term_sps) {
m_sh_->delta_poc_msb_cycle_lt[i] = delta_poc_msb_cycle_lt;
if ( i == 0 || i == p_slice_header->num_long_term_sps) {
p_slice_header->delta_poc_msb_cycle_lt[i] = delta_poc_msb_cycle_lt;
} else {
m_sh_->delta_poc_msb_cycle_lt[i] = delta_poc_msb_cycle_lt + m_sh_->delta_poc_msb_cycle_lt[i - 1];
p_slice_header->delta_poc_msb_cycle_lt[i] = delta_poc_msb_cycle_lt + p_slice_header->delta_poc_msb_cycle_lt[i - 1];
}
}
}
if (sps_ptr->sps_temporal_mvp_enabled_flag) {
m_sh_->slice_temporal_mvp_enabled_flag = Parser::GetBit(nalu, offset);
p_slice_header->slice_temporal_mvp_enabled_flag = Parser::GetBit(nalu, offset);
}
}
int chroma_array_type = sps_ptr->separate_colour_plane_flag ? 0 : sps_ptr->chroma_format_idc; // ChromaArrayType
if (sps_ptr->sample_adaptive_offset_enabled_flag) {
m_sh_->slice_sao_luma_flag = Parser::GetBit(nalu, offset);
p_slice_header->slice_sao_luma_flag = Parser::GetBit(nalu, offset);
if (chroma_array_type)
{
m_sh_->slice_sao_chroma_flag = Parser::GetBit(nalu, offset);
p_slice_header->slice_sao_chroma_flag = Parser::GetBit(nalu, offset);
}
}
if (m_sh_->slice_type != HEVC_SLICE_TYPE_I) {
m_sh_->num_ref_idx_active_override_flag = Parser::GetBit(nalu, offset);
if (m_sh_->num_ref_idx_active_override_flag) {
m_sh_->num_ref_idx_l0_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
m_sh_->num_ref_idx_l1_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
if (p_slice_header->slice_type != HEVC_SLICE_TYPE_I) {
p_slice_header->num_ref_idx_active_override_flag = Parser::GetBit(nalu, offset);
if (p_slice_header->num_ref_idx_active_override_flag) {
p_slice_header->num_ref_idx_l0_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
p_slice_header->num_ref_idx_l1_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
}
} else {
m_sh_->num_ref_idx_l0_active_minus1 = pps_ptr->num_ref_idx_l0_default_active_minus1;
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
m_sh_->num_ref_idx_l1_active_minus1 = pps_ptr->num_ref_idx_l1_default_active_minus1;
p_slice_header->num_ref_idx_l0_active_minus1 = pps_ptr->num_ref_idx_l0_default_active_minus1;
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
p_slice_header->num_ref_idx_l1_active_minus1 = pps_ptr->num_ref_idx_l1_default_active_minus1;
}
}
// 7.3.6.2 Reference picture list modification
// Calculate NumPicTotalCurr
num_pic_total_curr_ = 0;
HevcShortTermRps *st_rps_ptr = &m_sh_->st_rps;
HevcShortTermRps *st_rps_ptr = &p_slice_header->st_rps;
for (int i = 0; i < st_rps_ptr->num_negative_pics; i++) {
if (st_rps_ptr->used_by_curr_pic_s0[i]) {
num_pic_total_curr_++;
@@ -1704,7 +1718,7 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
}
}
HevcLongTermRps *lt_rps_ptr = &m_sh_->lt_rps;
HevcLongTermRps *lt_rps_ptr = &p_slice_header->lt_rps;
// Check the combined list
for (int i = 0; i < lt_rps_ptr->num_of_pics; i++) {
if (lt_rps_ptr->used_by_curr_pic[i]) {
@@ -1719,78 +1733,78 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
list_entry_bits++;
}
m_sh_->ref_pic_list_modification_flag_l0 = Parser::GetBit(nalu, offset);
if (m_sh_->ref_pic_list_modification_flag_l0) {
for (int i = 0; i <= m_sh_->num_ref_idx_l0_active_minus1; i++) {
m_sh_->list_entry_l0[i] = Parser::ReadBits(nalu, offset, list_entry_bits);
p_slice_header->ref_pic_list_modification_flag_l0 = Parser::GetBit(nalu, offset);
if (p_slice_header->ref_pic_list_modification_flag_l0) {
for (int i = 0; i <= p_slice_header->num_ref_idx_l0_active_minus1; i++) {
p_slice_header->list_entry_l0[i] = Parser::ReadBits(nalu, offset, list_entry_bits);
}
}
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
m_sh_->ref_pic_list_modification_flag_l1 = Parser::GetBit(nalu, offset);
if (m_sh_->ref_pic_list_modification_flag_l1) {
for (int i = 0; i <= m_sh_->num_ref_idx_l1_active_minus1; i++) {
m_sh_->list_entry_l1[i] = Parser::ReadBits(nalu, offset, list_entry_bits);
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
p_slice_header->ref_pic_list_modification_flag_l1 = Parser::GetBit(nalu, offset);
if (p_slice_header->ref_pic_list_modification_flag_l1) {
for (int i = 0; i <= p_slice_header->num_ref_idx_l1_active_minus1; i++) {
p_slice_header->list_entry_l1[i] = Parser::ReadBits(nalu, offset, list_entry_bits);
}
}
}
}
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
m_sh_->mvd_l1_zero_flag = Parser::GetBit(nalu, offset);
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
p_slice_header->mvd_l1_zero_flag = Parser::GetBit(nalu, offset);
}
if (pps_ptr->cabac_init_present_flag) {
m_sh_->cabac_init_flag = Parser::GetBit(nalu, offset);
p_slice_header->cabac_init_flag = Parser::GetBit(nalu, offset);
}
if (m_sh_->slice_temporal_mvp_enabled_flag) {
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
m_sh_->collocated_from_l0_flag = Parser::GetBit(nalu, offset);
if (p_slice_header->slice_temporal_mvp_enabled_flag) {
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
p_slice_header->collocated_from_l0_flag = Parser::GetBit(nalu, offset);
}
if ((m_sh_->collocated_from_l0_flag && m_sh_->num_ref_idx_l0_active_minus1 > 0) || (!m_sh_->collocated_from_l0_flag && m_sh_->num_ref_idx_l1_active_minus1 > 0)) {
m_sh_->collocated_ref_idx = Parser::ExpGolomb::ReadUe(nalu, offset);
if ((p_slice_header->collocated_from_l0_flag && p_slice_header->num_ref_idx_l0_active_minus1 > 0) || (!p_slice_header->collocated_from_l0_flag && p_slice_header->num_ref_idx_l1_active_minus1 > 0)) {
p_slice_header->collocated_ref_idx = Parser::ExpGolomb::ReadUe(nalu, offset);
}
}
if ((pps_ptr->weighted_pred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_P) || (pps_ptr->weighted_bipred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_B)) {
ParsePredWeightTable(m_sh_, chroma_array_type, nalu, offset);
if ((pps_ptr->weighted_pred_flag && p_slice_header->slice_type == HEVC_SLICE_TYPE_P) || (pps_ptr->weighted_bipred_flag && p_slice_header->slice_type == HEVC_SLICE_TYPE_B)) {
ParsePredWeightTable(p_slice_header, chroma_array_type, nalu, offset);
}
m_sh_->five_minus_max_num_merge_cand = Parser::ExpGolomb::ReadUe(nalu, offset);
p_slice_header->five_minus_max_num_merge_cand = Parser::ExpGolomb::ReadUe(nalu, offset);
}
m_sh_->slice_qp_delta = Parser::ExpGolomb::ReadSe(nalu, offset);
p_slice_header->slice_qp_delta = Parser::ExpGolomb::ReadSe(nalu, offset);
if (pps_ptr->pps_slice_chroma_qp_offsets_present_flag) {
m_sh_->slice_cb_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset);
m_sh_->slice_cr_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset);
p_slice_header->slice_cb_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset);
p_slice_header->slice_cr_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset);
}
if (pps_ptr->chroma_qp_offset_list_enabled_flag) {
m_sh_->cu_chroma_qp_offset_enabled_flag = Parser::GetBit(nalu, offset);
p_slice_header->cu_chroma_qp_offset_enabled_flag = Parser::GetBit(nalu, offset);
}
if (pps_ptr->deblocking_filter_override_enabled_flag) {
m_sh_->deblocking_filter_override_flag = Parser::GetBit(nalu, offset);
p_slice_header->deblocking_filter_override_flag = Parser::GetBit(nalu, offset);
}
if (m_sh_->deblocking_filter_override_flag) {
m_sh_->slice_deblocking_filter_disabled_flag = Parser::GetBit(nalu, offset);
if ( !m_sh_->slice_deblocking_filter_disabled_flag ) {
m_sh_->slice_beta_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset);
m_sh_->slice_tc_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset);
if (p_slice_header->deblocking_filter_override_flag) {
p_slice_header->slice_deblocking_filter_disabled_flag = Parser::GetBit(nalu, offset);
if ( !p_slice_header->slice_deblocking_filter_disabled_flag ) {
p_slice_header->slice_beta_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset);
p_slice_header->slice_tc_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset);
}
}
if (pps_ptr->pps_loop_filter_across_slices_enabled_flag && (m_sh_->slice_sao_luma_flag || m_sh_->slice_sao_chroma_flag ||
!m_sh_->slice_deblocking_filter_disabled_flag)) {
m_sh_->slice_loop_filter_across_slices_enabled_flag = Parser::GetBit(nalu, offset);
if (pps_ptr->pps_loop_filter_across_slices_enabled_flag && (p_slice_header->slice_sao_luma_flag || p_slice_header->slice_sao_chroma_flag ||
!p_slice_header->slice_deblocking_filter_disabled_flag)) {
p_slice_header->slice_loop_filter_across_slices_enabled_flag = Parser::GetBit(nalu, offset);
}
memcpy(m_sh_copy_, m_sh_, sizeof(HevcSliceSegHeader));
memcpy(m_sh_copy_, p_slice_header, sizeof(HevcSliceSegHeader));
} else {
//dependant slice
memcpy(m_sh_, m_sh_copy_, sizeof(HevcSliceSegHeader));
m_sh_->first_slice_segment_in_pic_flag = temp_sh.first_slice_segment_in_pic_flag;
m_sh_->no_output_of_prior_pics_flag = temp_sh.no_output_of_prior_pics_flag;
m_sh_->slice_pic_parameter_set_id = temp_sh.slice_pic_parameter_set_id;
m_sh_->dependent_slice_segment_flag = temp_sh.dependent_slice_segment_flag;
m_sh_->slice_segment_address = temp_sh.slice_segment_address;
memcpy(p_slice_header, m_sh_copy_, sizeof(HevcSliceSegHeader));
p_slice_header->first_slice_segment_in_pic_flag = temp_sh.first_slice_segment_in_pic_flag;
p_slice_header->no_output_of_prior_pics_flag = temp_sh.no_output_of_prior_pics_flag;
p_slice_header->slice_pic_parameter_set_id = temp_sh.slice_pic_parameter_set_id;
p_slice_header->dependent_slice_segment_flag = temp_sh.dependent_slice_segment_flag;
p_slice_header->slice_segment_address = temp_sh.slice_segment_address;
}
if (pps_ptr->tiles_enabled_flag || pps_ptr->entropy_coding_sync_enabled_flag) {
int max_num_entry_point_offsets; // 7.4.7.1
@@ -1801,16 +1815,16 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
} else {
max_num_entry_point_offsets = (pps_ptr->num_tile_columns_minus1 + 1) * pic_height_in_ctbs_y_ - 1;
}
m_sh_->num_entry_point_offsets = Parser::ExpGolomb::ReadUe(nalu, offset);
if (m_sh_->num_entry_point_offsets > max_num_entry_point_offsets) {
m_sh_->num_entry_point_offsets = max_num_entry_point_offsets;
p_slice_header->num_entry_point_offsets = Parser::ExpGolomb::ReadUe(nalu, offset);
if (p_slice_header->num_entry_point_offsets > max_num_entry_point_offsets) {
p_slice_header->num_entry_point_offsets = max_num_entry_point_offsets;
}
#if 0 // do not parse syntax parameters that are not used by HW decode
if (m_sh_->num_entry_point_offsets) {
m_sh_->offset_len_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < m_sh_->num_entry_point_offsets; i++) {
m_sh_->entry_point_offset_minus1[i] = Parser::ReadBits(nalu, offset, m_sh_->offset_len_minus1 + 1);
if (p_slice_header->num_entry_point_offsets) {
p_slice_header->offset_len_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < p_slice_header->num_entry_point_offsets; i++) {
p_slice_header->entry_point_offset_minus1[i] = Parser::ReadBits(nalu, offset, p_slice_header->offset_len_minus1 + 1);
}
}
#endif
@@ -1818,15 +1832,15 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
#if 0 // do not parse syntax parameters that are not used by HW decode
if (pps_ptr->slice_segment_header_extension_present_flag) {
m_sh_->slice_segment_header_extension_length = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < m_sh_->slice_segment_header_extension_length; i++) {
m_sh_->slice_segment_header_extension_data_byte[i] = Parser::ReadBits(nalu, offset, 8);
p_slice_header->slice_segment_header_extension_length = Parser::ExpGolomb::ReadUe(nalu, offset);
for (int i = 0; i < p_slice_header->slice_segment_header_extension_length; i++) {
p_slice_header->slice_segment_header_extension_data_byte[i] = Parser::ReadBits(nalu, offset, 8);
}
}
#endif
#if DBGINFO
PrintSliceSegHeader(m_sh_);
PrintSliceSegHeader(p_slice_header);
#endif // DBGINFO
return false;
@@ -1917,6 +1931,7 @@ bool HevcVideoParser::IsRefPic(HevcNalUnitHeader *nal_header_ptr) {
}
void HevcVideoParser::CalculateCurrPoc() {
HevcSliceSegHeader *p_slice_header = &slice_info_list_[0].slice_header;
// Record decode order count
curr_pic_info_.decode_order_count = pic_count_;
if (IsIdrPic(&slice_nal_unit_header_)) {
@@ -1931,19 +1946,19 @@ void HevcVideoParser::CalculateCurrPoc() {
if (IsIrapPic(&slice_nal_unit_header_) && no_rasl_output_flag_ == 1) {
poc_msb = 0;
} else {
if ((m_sh_->slice_pic_order_cnt_lsb < curr_pic_info_.prev_poc_lsb) && ((curr_pic_info_.prev_poc_lsb - m_sh_->slice_pic_order_cnt_lsb) >= (max_poc_lsb / 2))) {
if ((p_slice_header->slice_pic_order_cnt_lsb < curr_pic_info_.prev_poc_lsb) && ((curr_pic_info_.prev_poc_lsb - p_slice_header->slice_pic_order_cnt_lsb) >= (max_poc_lsb / 2))) {
poc_msb = curr_pic_info_.prev_poc_msb + max_poc_lsb;
} else if ((m_sh_->slice_pic_order_cnt_lsb > curr_pic_info_.prev_poc_lsb) && ((m_sh_->slice_pic_order_cnt_lsb - curr_pic_info_.prev_poc_lsb) > (max_poc_lsb / 2))) {
} else if ((p_slice_header->slice_pic_order_cnt_lsb > curr_pic_info_.prev_poc_lsb) && ((p_slice_header->slice_pic_order_cnt_lsb - curr_pic_info_.prev_poc_lsb) > (max_poc_lsb / 2))) {
poc_msb = curr_pic_info_.prev_poc_msb - max_poc_lsb;
} else {
poc_msb = curr_pic_info_.prev_poc_msb;
}
}
curr_pic_info_.pic_order_cnt = poc_msb + m_sh_->slice_pic_order_cnt_lsb;
curr_pic_info_.slice_pic_order_cnt_lsb = m_sh_->slice_pic_order_cnt_lsb;
curr_pic_info_.pic_order_cnt = poc_msb + p_slice_header->slice_pic_order_cnt_lsb;
curr_pic_info_.slice_pic_order_cnt_lsb = p_slice_header->slice_pic_order_cnt_lsb;
if ((slice_nal_unit_header_.nuh_temporal_id_plus1 - 1) == 0 && IsRefPic(&slice_nal_unit_header_) && !IsRaslPic(&slice_nal_unit_header_) && !IsRadlPic(&slice_nal_unit_header_)) {
curr_pic_info_.prev_poc_lsb = m_sh_->slice_pic_order_cnt_lsb;
curr_pic_info_.prev_poc_lsb = p_slice_header->slice_pic_order_cnt_lsb;
curr_pic_info_.prev_poc_msb = poc_msb;
}
}
@@ -1954,6 +1969,7 @@ void HevcVideoParser::DecodeRps() {
int curr_delta_poc_msb_present_flag[HEVC_MAX_NUM_REF_PICS] = {0}; // CurrDeltaPocMsbPresentFlag
int foll_delta_poc_msb_present_flag[HEVC_MAX_NUM_REF_PICS] = {0}; // FollDeltaPocMsbPresentFlag
int max_poc_lsb = 1 << (m_sps_[m_active_sps_id_].log2_max_pic_order_cnt_lsb_minus4 + 4); // MaxPicOrderCntLsb
HevcSliceSegHeader *p_slice_header = &slice_info_list_[0].slice_header;
// When the current picture is an IRAP picture with NoRaslOutputFlag equal to 1, all reference pictures with
// nuh_layer_id equal to currPicLayerId currently in the DPB (if any) are marked as "unused for reference".
@@ -1975,7 +1991,7 @@ void HevcVideoParser::DecodeRps() {
memset(poc_lt_curr_, 0, sizeof(int32_t) * HEVC_MAX_NUM_REF_PICS);
memset(poc_lt_foll_, 0, sizeof(int32_t) * HEVC_MAX_NUM_REF_PICS);
} else {
HevcShortTermRps *rps_ptr = &m_sh_->st_rps;
HevcShortTermRps *rps_ptr = &p_slice_header->st_rps;
for (i = 0, j = 0, k = 0; i < rps_ptr->num_negative_pics; i++) {
if (rps_ptr->used_by_curr_pic_s0[i]) {
poc_st_curr_before_[j++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc_s0[i];
@@ -1995,19 +2011,19 @@ void HevcVideoParser::DecodeRps() {
num_poc_st_curr_after_ = j;
num_poc_st_foll_ = k;
HevcLongTermRps *lt_rps_ptr = &m_sh_->lt_rps;
HevcLongTermRps *lt_rps_ptr = &p_slice_header->lt_rps;
for (i = 0, j = 0, k = 0; i < lt_rps_ptr->num_of_pics; i++) {
uint32_t poc_lt = lt_rps_ptr->pocs[i]; // oocLt
if (m_sh_->delta_poc_msb_present_flag[i]) {
poc_lt += curr_pic_info_.pic_order_cnt - m_sh_->delta_poc_msb_cycle_lt[i] * max_poc_lsb - (curr_pic_info_.pic_order_cnt & (max_poc_lsb - 1));
if (p_slice_header->delta_poc_msb_present_flag[i]) {
poc_lt += curr_pic_info_.pic_order_cnt - p_slice_header->delta_poc_msb_cycle_lt[i] * max_poc_lsb - (curr_pic_info_.pic_order_cnt & (max_poc_lsb - 1));
}
if (lt_rps_ptr->used_by_curr_pic[i]) {
poc_lt_curr_[j] = poc_lt;
curr_delta_poc_msb_present_flag[j++] = m_sh_->delta_poc_msb_present_flag[i];
curr_delta_poc_msb_present_flag[j++] = p_slice_header->delta_poc_msb_present_flag[i];
} else {
poc_lt_foll_[k] = poc_lt;
foll_delta_poc_msb_present_flag[k++] = m_sh_->delta_poc_msb_present_flag[i];
foll_delta_poc_msb_present_flag[k++] = p_slice_header->delta_poc_msb_present_flag[i];
}
}
num_poc_lt_curr_ = j;
@@ -2100,8 +2116,8 @@ void HevcVideoParser::DecodeRps() {
}
}
void HevcVideoParser::ConstructRefPicLists() {
void HevcVideoParser::ConstructRefPicLists(HevcSliceInfo *p_slice_info) {
HevcSliceSegHeader *p_slice_header = &p_slice_info->slice_header;
uint32_t num_rps_curr_temp_list; // NumRpsCurrTempList0 or NumRpsCurrTempList1;
int i, j;
int rIdx;
@@ -2109,7 +2125,7 @@ void HevcVideoParser::ConstructRefPicLists() {
/// List 0
rIdx = 0;
num_rps_curr_temp_list = std::max(m_sh_->num_ref_idx_l0_active_minus1 + 1, num_pic_total_curr_);
num_rps_curr_temp_list = std::max(p_slice_header->num_ref_idx_l0_active_minus1 + 1, num_pic_total_curr_);
while (rIdx < num_rps_curr_temp_list) {
for (i = 0; i < num_poc_st_curr_before_ && rIdx < num_rps_curr_temp_list; rIdx++, i++) {
@@ -2125,14 +2141,14 @@ void HevcVideoParser::ConstructRefPicLists() {
}
}
for( rIdx = 0; rIdx <= m_sh_->num_ref_idx_l0_active_minus1; rIdx++) {
ref_pic_list_0_[rIdx] = m_sh_->ref_pic_list_modification_flag_l0 ? ref_pic_list_temp[m_sh_->list_entry_l0[rIdx]] : ref_pic_list_temp[rIdx];
for( rIdx = 0; rIdx <= p_slice_header->num_ref_idx_l0_active_minus1; rIdx++) {
p_slice_info->ref_pic_list_0_[rIdx] = p_slice_header->ref_pic_list_modification_flag_l0 ? ref_pic_list_temp[p_slice_header->list_entry_l0[rIdx]] : ref_pic_list_temp[rIdx];
}
/// List 1
if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) {
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
rIdx = 0;
num_rps_curr_temp_list = std::max(m_sh_->num_ref_idx_l1_active_minus1 + 1, num_pic_total_curr_);
num_rps_curr_temp_list = std::max(p_slice_header->num_ref_idx_l1_active_minus1 + 1, num_pic_total_curr_);
while (rIdx < num_rps_curr_temp_list) {
for (i = 0; i < num_poc_st_curr_after_ && rIdx < num_rps_curr_temp_list; rIdx++, i++) {
@@ -2148,8 +2164,8 @@ void HevcVideoParser::ConstructRefPicLists() {
}
}
for( rIdx = 0; rIdx <= m_sh_->num_ref_idx_l1_active_minus1; rIdx++) {
ref_pic_list_1_[rIdx] = m_sh_->ref_pic_list_modification_flag_l1 ? ref_pic_list_temp[m_sh_->list_entry_l1[rIdx]] : ref_pic_list_temp[rIdx];
for( rIdx = 0; rIdx <= p_slice_header->num_ref_idx_l1_active_minus1; rIdx++) {
p_slice_info->ref_pic_list_1_[rIdx] = p_slice_header->ref_pic_list_modification_flag_l1 ? ref_pic_list_temp[p_slice_header->list_entry_l1[rIdx]] : ref_pic_list_temp[rIdx];
}
}
}
@@ -2205,7 +2221,7 @@ int HevcVideoParser::MarkOutputPictures() {
if (IsCraPic(&slice_nal_unit_header_)) {
no_output_of_prior_pics_flag = 1;
} else {
no_output_of_prior_pics_flag = m_sh_->no_output_of_prior_pics_flag;
no_output_of_prior_pics_flag = slice_info_list_[0].slice_header.no_output_of_prior_pics_flag;
}
if (!no_output_of_prior_pics_flag) {
+19 -10
ファイルの表示
@@ -84,6 +84,16 @@ protected:
return nalu_header;
}
/*! \brief Slice info of a picture
*/
typedef struct {
HevcSliceSegHeader slice_header;
uint32_t slice_data_offset; // offset in the slice data buffer of this slice
uint32_t slice_data_size; // slice data size in bytes
uint8_t ref_pic_list_0_[HEVC_MAX_NUM_REF_PICS]; // RefPicList0
uint8_t ref_pic_list_1_[HEVC_MAX_NUM_REF_PICS]; // RefPicList1
} HevcSliceInfo;
/*! \brief Picture info for decoding process
*/
typedef struct {
@@ -121,8 +131,9 @@ protected:
HevcVideoParamSet* m_vps_ = nullptr;
HevcSeqParamSet* m_sps_ = nullptr;
HevcPicParamSet* m_pps_ = nullptr;
HevcSliceSegHeader* m_sh_ = nullptr;
HevcSliceSegHeader* m_sh_copy_ = nullptr;
std::vector<HevcSliceInfo> slice_info_list_;
std::vector<RocdecHevcSliceParams> slice_param_list_;
HevcNalUnitHeader slice_nal_unit_header_;
HevcPicInfo curr_pic_info_;
@@ -158,9 +169,6 @@ protected:
uint8_t ref_pic_set_lt_curr_[HEVC_MAX_NUM_REF_PICS]; // RefPicSetLtCurr
uint8_t ref_pic_set_lt_foll_[HEVC_MAX_NUM_REF_PICS]; // RefPicSetLtFoll
uint8_t ref_pic_list_0_[HEVC_MAX_NUM_REF_PICS]; // RefPicList0
uint8_t ref_pic_list_1_[HEVC_MAX_NUM_REF_PICS]; // RefPicList1
/*! \brief Function to parse Video Parameter Set
* \param [in] nalu A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] size Size of the input stream
@@ -262,12 +270,12 @@ protected:
void ParsePredWeightTable(HevcSliceSegHeader *slice_header_ptr, int chroma_array_type, uint8_t *stream_ptr, size_t &offset);
/*! \brief Function to parse Slice Header
* \param [in] nal_unit_type Input of <tt>uint32_t</tt> containing the enumerator value to the NAL Unit Type
* \param [in] nalu A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] size Size of the input stream
* \param [out] p_slice_header Pointer to the slice header struct
* \return True is successful, else false
*/
bool ParseSliceHeader(uint8_t *nalu, size_t size);
bool ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header);
/*! \brief Function to parse Sei Message Info
* \param [in] nalu A pointer of <tt>uint8_t</tt> for the input stream to be parsed
@@ -276,17 +284,18 @@ protected:
*/
void ParseSeiMessage(uint8_t *nalu, size_t size);
/*! \brief Function to calculate the picture order count of the current picture (8.3.1)
/*! \brief Function to calculate the picture order count of the current picture. Once per picutre. (8.3.1)
*/
void CalculateCurrPoc();
/*! \brief Function to perform decoding process for reference picture set (8.3.2)
/*! \brief Function to perform decoding process for reference picture set. Once per picture. (8.3.2)
*/
void DecodeRps();
/*! \brief Function to perform decoding process for reference picture lists construction (8.3.4)
/*! \brief Function to perform decoding process for reference picture lists construction per slice. (8.3.4)
* \param [in] p_slice_info Pointer to the slice info struct
*/
void ConstructRefPicLists();
void ConstructRefPicLists(HevcSliceInfo *p_slice_info);
/*! \brief Function to initialize DPB buffer.
*/
+2 -1
ファイルの表示
@@ -75,6 +75,7 @@ typedef struct {
#define ZEROBYTES_SHORTSTARTCODE 2 //indicates the number of zero bytes in the short start-code prefix
#define RBSP_BUF_SIZE 1024 // enough to parse any parameter sets or slice headers
#define INIT_SLICE_LIST_NUM 16 // initial slice information/parameter struct list size
/**
* @brief Base class for video parsing
@@ -126,7 +127,7 @@ protected:
int rbsp_size_;
uint8_t rbsp_buf_[RBSP_BUF_SIZE]; // to store parameter set or slice header RBSP
int slice_num_;
int num_slices_;
uint8_t* pic_stream_data_ptr_;
int pic_stream_data_size_;
+21 -8
ファイルの表示
@@ -24,7 +24,8 @@ THE SOFTWARE.
VaapiVideoDecoder::VaapiVideoDecoder(RocDecoderCreateInfo &decoder_create_info) : decoder_create_info_{decoder_create_info},
drm_fd_{-1}, va_display_{0}, va_config_attrib_{{}}, va_config_id_{0}, va_profile_ {VAProfileNone}, va_context_id_{0}, va_surface_ids_{{}},
pic_params_buf_id_{0}, iq_matrix_buf_id_{0}, slice_params_buf_id_{0}, slice_data_buf_id_{0} {};
pic_params_buf_id_{0}, iq_matrix_buf_id_{0}, num_slices_{0}, slice_data_buf_id_{0} {
};
VaapiVideoDecoder::~VaapiVideoDecoder() {
if (drm_fd_ != -1) {
@@ -185,9 +186,11 @@ rocDecStatus VaapiVideoDecoder::DestroyDataBuffers() {
CHECK_VAAPI(vaDestroyBuffer(va_display_, iq_matrix_buf_id_));
iq_matrix_buf_id_ = 0;
}
if (slice_params_buf_id_) {
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_params_buf_id_));
slice_params_buf_id_ = 0;
for (int i = 0; i < num_slices_; i++) {
if (slice_params_buf_id_[i]) {
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_params_buf_id_[i]));
slice_params_buf_id_[i] = 0;
}
}
if (slice_data_buf_id_) {
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_data_buf_id_));
@@ -231,7 +234,7 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
iq_matrix_size = sizeof(RocdecHevcIQMatrix);
}
slice_params_ptr = (void*)&pPicParams->slice_params.hevc;
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))) ||
@@ -260,7 +263,7 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
iq_matrix_ptr = (void*)&pPicParams->iq_matrix.avc;
iq_matrix_size = sizeof(RocdecAvcIQMatrix);
slice_params_ptr = (void*)&pPicParams->slice_params.avc;
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))) {
@@ -276,16 +279,26 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
}
}
// Destroy the data buffers of the previous frame
rocDecStatus rocdec_status = DestroyDataBuffers();
if (rocdec_status != ROCDEC_SUCCESS) {
ERR("Failed to destroy VAAPI buffer.");
return rocdec_status;
}
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VAPictureParameterBufferType, pic_params_size, 1, pic_params_ptr, &pic_params_buf_id_));
if (scaling_list_enabled) {
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VAIQMatrixBufferType, iq_matrix_size, 1, iq_matrix_ptr, &iq_matrix_buf_id_));
}
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VASliceParameterBufferType, slice_params_size, 1, slice_params_ptr, &slice_params_buf_id_));
// Resize if needed
num_slices_ = pPicParams->num_slices;
if (num_slices_ > slice_params_buf_id_.size()) {
slice_params_buf_id_.resize(num_slices_, {0});
}
for (int i = 0; i < num_slices_; i++) {
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VASliceParameterBufferType, slice_params_size, 1, slice_params_ptr, &slice_params_buf_id_[i]));
slice_params_ptr = (void*)((uint8_t*)slice_params_ptr + slice_params_size);
}
CHECK_VAAPI(vaCreateBuffer(va_display_, va_context_id_, VASliceDataBufferType, pPicParams->bitstream_data_len, 1, (void*)pPicParams->bitstream_data, &slice_data_buf_id_));
// Sumbmit buffers to VAAPI driver
@@ -294,7 +307,7 @@ rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
if (scaling_list_enabled) {
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &iq_matrix_buf_id_, 1));
}
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &slice_params_buf_id_, 1));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, slice_params_buf_id_.data(), num_slices_));
CHECK_VAAPI(vaRenderPicture(va_display_, va_context_id_, &slice_data_buf_id_, 1));
CHECK_VAAPI(vaEndPicture(va_display_, va_context_id_));
+4 -1
ファイルの表示
@@ -42,6 +42,8 @@ THE SOFTWARE.
}\
}
#define INIT_SLICE_PARAM_LIST_NUM 16 // initial slice parameter buffer list size
class VaapiVideoDecoder {
public:
VaapiVideoDecoder(RocDecoderCreateInfo &decoder_create_info);
@@ -64,7 +66,8 @@ private:
VABufferID pic_params_buf_id_;
VABufferID iq_matrix_buf_id_;
VABufferID slice_params_buf_id_;
std::vector<VABufferID> slice_params_buf_id_ = std::vector<VABufferID>(INIT_SLICE_PARAM_LIST_NUM, 0);
uint32_t num_slices_;
VABufferID slice_data_buf_id_;
uint32_t slice_data_buf_size_;