* rocDecode/AVC: Added support for multiple slice parameter buffer submission for AVC multi-slice streams. (#234)

This commit is contained in:
jeffqjiangNew
2024-02-12 10:22:42 -05:00
committed by GitHub
parent de5841d249
commit c496dfd3f2
2 changed files with 185 additions and 149 deletions
+170 -144
View File
@@ -34,6 +34,8 @@ AvcVideoParser::AvcVideoParser() {
prev_ref_pic_bottom_field_ = 0;
curr_ref_pic_bottom_field_ = 0;
slice_info_list_.assign(INIT_SLICE_LIST_NUM, {0});
slice_param_list_.assign(INIT_SLICE_LIST_NUM, {0});
memset(&curr_pic_, 0, sizeof(AvcPicture));
InitDpb();
}
@@ -129,28 +131,37 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
case kAvcNalTypeSlice_Data_Partition_A:
case kAvcNalTypeSlice_Data_Partition_B:
case kAvcNalTypeSlice_Data_Partition_C: {
// 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_ + 4), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
// For each picture, only parse the first slice header
if (num_slices_ == 0) {
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_;
AvcSliceHeader *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_, &slice_header_0_);
// Start decode process
// Set current picture properties
CalculateCurrPoc(); // 8.2.1
prev_has_mmco_5_ = curr_has_mmco_5_;
prev_ref_pic_bottom_field_ = curr_ref_pic_bottom_field_;
if (slice_header_0_.field_pic_flag) {
if (slice_header_0_.bottom_field_flag) {
if (p_slice_header->field_pic_flag) {
if (p_slice_header->bottom_field_flag) {
curr_pic_.pic_structure = kBottomField;
} else {
curr_pic_.pic_structure = kTopField;
@@ -158,14 +169,18 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
} else {
curr_pic_.pic_structure = kFrame;
}
curr_pic_.frame_num = slice_header_0_.frame_num;
curr_pic_.frame_num = p_slice_header->frame_num;
}
// Set up reference picture list
if (slice_header_0_.slice_type != kAvcSliceTypeI && slice_header_0_.slice_type != kAvcSliceTypeSI && slice_header_0_.slice_type != kAvcSliceTypeI_7 && slice_header_0_.slice_type != kAvcSliceTypeSI_9) {
SetupReflist();
}
// Set up reference picture list
if (p_slice_header->slice_type != kAvcSliceTypeI && p_slice_header->slice_type != kAvcSliceTypeSI && p_slice_header->slice_type != kAvcSliceTypeI_7 && p_slice_header->slice_type != kAvcSliceTypeSI_9) {
SetupReflist(&slice_info_list_[num_slices_]);
}
// Find a free buffer in DPB for the current picture
if (num_slices_ == 0) {
// Find a free buffer in DPB for the current picture. Due to the current 1-1 mapping of DPB and
// decoded buffer pool at VAAP level, we need to get a surface from DPB for the current picture to be
// decoded into.
FindFreeBufInDpb();
}
num_slices_++;
@@ -318,7 +333,7 @@ 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_;
AvcSliceHeader *p_slice_header = &slice_info_list_[0].slice_header;
dec_pic_params_ = {0};
dec_pic_params_.pic_width = pic_width_;
@@ -422,92 +437,101 @@ 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; // Todo
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].pic_idx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_0[i].frame_idx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_0[i].frame_idx = 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 ? RocdecAvcPicture_FLAGS_BOTTOM_FIELD : RocdecAvcPicture_FLAGS_TOP_FIELD;
}
p_slice_param->ref_pic_list_0[i].flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecAvcPicture_FLAGS_SHORT_TERM_REFERENCE : RocdecAvcPicture_FLAGS_LONG_TERM_REFERENCE;
}
// 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++) {
RocdecAvcSliceParams *p_slice_param = &slice_param_list_[slice_index];
AvcSliceInfo *p_slice_info = &slice_info_list_[slice_index];
AvcSliceHeader *p_slice_header = &p_slice_info->slice_header;
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].pic_idx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_1[i].frame_idx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_1[i].frame_idx = p_ref_pic->frame_num;
p_slice_param->slice_data_size = p_slice_info->slice_data_size;
p_slice_param->slice_data_offset = p_slice_info->slice_data_offset;
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 = &p_slice_info->ref_list_0_[i];
if (p_ref_pic->is_reference != kUnusedForReference) {
p_slice_param->ref_pic_list_0[i].pic_idx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_0[i].frame_idx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_0[i].frame_idx = 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 ? RocdecAvcPicture_FLAGS_BOTTOM_FIELD : RocdecAvcPicture_FLAGS_TOP_FIELD;
}
p_slice_param->ref_pic_list_0[i].flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecAvcPicture_FLAGS_SHORT_TERM_REFERENCE : RocdecAvcPicture_FLAGS_LONG_TERM_REFERENCE;
}
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 ? RocdecAvcPicture_FLAGS_BOTTOM_FIELD : RocdecAvcPicture_FLAGS_TOP_FIELD;
}
if (p_slice_header->slice_type == kAvcSliceTypeB || p_slice_header->slice_type == kAvcSliceTypeB_6 ) {
AvcPicture *p_ref_pic = &p_slice_info->ref_list_1_[i];
if (p_ref_pic->is_reference != kUnusedForReference) {
p_slice_param->ref_pic_list_1[i].pic_idx = p_ref_pic->pic_idx;
if ( p_ref_pic->is_reference == kUsedForLongTerm) {
p_slice_param->ref_pic_list_1[i].frame_idx = p_ref_pic->long_term_pic_num;
} else {
p_slice_param->ref_pic_list_1[i].frame_idx = 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 ? RocdecAvcPicture_FLAGS_BOTTOM_FIELD : RocdecAvcPicture_FLAGS_TOP_FIELD;
}
p_slice_param->ref_pic_list_1[i].flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecAvcPicture_FLAGS_SHORT_TERM_REFERENCE : RocdecAvcPicture_FLAGS_LONG_TERM_REFERENCE;
}
p_slice_param->ref_pic_list_1[i].flags |= p_ref_pic->is_reference == kUsedForShortTerm ? RocdecAvcPicture_FLAGS_SHORT_TERM_REFERENCE : RocdecAvcPicture_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;
}
// 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++) {
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_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];
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];
}
}
}
}
dec_pic_params_.slice_params.avc = slice_param_list_.data();
// Set up scaling lists
RocdecAvcIQMatrix *p_iq_matrix = &dec_pic_params_.iq_matrix.avc;
@@ -1425,7 +1449,7 @@ void AvcVideoParser::InitDpb() {
// 8.2.1
void AvcVideoParser::CalculateCurrPoc() {
AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_];
AvcSliceHeader *p_slice_header = &slice_header_0_;
AvcSliceHeader *p_slice_header = &slice_info_list_[0].slice_header;
int frame_num_offset; // FrameNumOffset
int max_pic_order_cnt_lsb = 1 << (p_sps->log2_max_pic_order_cnt_lsb_minus4 + 4); // MaxPicOrderCntLsb
@@ -1625,42 +1649,44 @@ static inline int CompareLongTermPicNumAsc(const void *p_pic_info_1, const void
}
}
void AvcVideoParser::SetupReflist() {
void AvcVideoParser::SetupReflist(AvcSliceInfo *p_slice_info) {
AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_];
int max_frame_num = 1 << (p_sps->log2_max_frame_num_minus4 + 4);
AvcSliceHeader *p_slice_header = &slice_header_0_;
int i;
AvcSliceHeader *p_slice_header = &p_slice_info->slice_header;
memset(ref_list_0_, 0, sizeof(ref_list_0_));
memset(ref_list_1_, 0, sizeof(ref_list_1_));
memset(p_slice_info->ref_list_0_, 0, sizeof(p_slice_info->ref_list_0_));
memset(p_slice_info->ref_list_1_, 0, sizeof(p_slice_info->ref_list_1_));
// 8.2.4.1. Calculate picture numbers
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
// 8.2.4.1. Calculate picture numbers. Only do it once.
if (num_slices_ == 0) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm) {
// Eq. 8-27
if (p_ref_pic->frame_num > curr_pic_.frame_num) {
p_ref_pic->frame_num_wrap = p_ref_pic->frame_num - max_frame_num;
} else {
p_ref_pic->frame_num_wrap = p_ref_pic->frame_num;
}
if (p_ref_pic->is_reference == kUsedForShortTerm) {
// Eq. 8-27
if (p_ref_pic->frame_num > curr_pic_.frame_num) {
p_ref_pic->frame_num_wrap = p_ref_pic->frame_num - max_frame_num;
} else {
p_ref_pic->frame_num_wrap = p_ref_pic->frame_num;
}
if (curr_pic_.pic_structure == kFrame) {
p_ref_pic->pic_num = p_ref_pic->frame_num_wrap; // Eq. 8-28
} else if (((curr_pic_.pic_structure == kTopField) && (p_ref_pic->pic_structure == kTopField)) || ((curr_pic_.pic_structure == kBottomField) && (p_ref_pic->pic_structure == kBottomField))) {
p_ref_pic->pic_num = 2 * p_ref_pic->frame_num_wrap + 1; // Eq. 8-30
} else {
p_ref_pic->pic_num = 2 * p_ref_pic->frame_num_wrap; // Eq. 8-31
}
} else if (p_ref_pic->is_reference == kUsedForLongTerm) {
// Note: Todo: assign long_term_frame_idx in MarkDecodedRefPics()
if (curr_pic_.pic_structure == kFrame) {
p_ref_pic->long_term_pic_num = p_ref_pic->long_term_frame_idx; // Eq. 8-29
} else if (((curr_pic_.pic_structure == kTopField) && (p_ref_pic->pic_structure == kTopField)) || ((curr_pic_.pic_structure == kBottomField) && (p_ref_pic->pic_structure == kBottomField))) {
p_ref_pic->long_term_pic_num = 2 * p_ref_pic->long_term_frame_idx + 1; // Eq. 8-32
} else {
p_ref_pic->long_term_pic_num = 2 * p_ref_pic->long_term_frame_idx; // Eq. 8-33
if (curr_pic_.pic_structure == kFrame) {
p_ref_pic->pic_num = p_ref_pic->frame_num_wrap; // Eq. 8-28
} else if (((curr_pic_.pic_structure == kTopField) && (p_ref_pic->pic_structure == kTopField)) || ((curr_pic_.pic_structure == kBottomField) && (p_ref_pic->pic_structure == kBottomField))) {
p_ref_pic->pic_num = 2 * p_ref_pic->frame_num_wrap + 1; // Eq. 8-30
} else {
p_ref_pic->pic_num = 2 * p_ref_pic->frame_num_wrap; // Eq. 8-31
}
} else if (p_ref_pic->is_reference == kUsedForLongTerm) {
// Note: Todo: assign long_term_frame_idx in MarkDecodedRefPics()
if (curr_pic_.pic_structure == kFrame) {
p_ref_pic->long_term_pic_num = p_ref_pic->long_term_frame_idx; // Eq. 8-29
} else if (((curr_pic_.pic_structure == kTopField) && (p_ref_pic->pic_structure == kTopField)) || ((curr_pic_.pic_structure == kBottomField) && (p_ref_pic->pic_structure == kBottomField))) {
p_ref_pic->long_term_pic_num = 2 * p_ref_pic->long_term_frame_idx + 1; // Eq. 8-32
} else {
p_ref_pic->long_term_pic_num = 2 * p_ref_pic->long_term_frame_idx; // Eq. 8-33
}
}
}
}
@@ -1670,28 +1696,28 @@ void AvcVideoParser::SetupReflist() {
if (curr_pic_.pic_structure == kFrame) { // 8.2.4.2.1
// Group short term ref pictures
int ref_index = 0;
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm) {
ref_list_0_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_0_[ref_index] = *p_ref_pic;
ref_index++;
}
}
// Group long term ref pictures
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForLongTerm) {
ref_list_0_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_0_[ref_index] = *p_ref_pic;
ref_index++;
}
}
// Sort short term refs with descending order of pic_num
if (dpb_buffer_.num_short_term > 1) {
qsort((void*)ref_list_0_, dpb_buffer_.num_short_term, sizeof(AvcPicture), ComparePicNumDesc);
qsort((void*)p_slice_info->ref_list_0_, dpb_buffer_.num_short_term, sizeof(AvcPicture), ComparePicNumDesc);
}
// Sort long term refs with ascending order of long_term_pic_num
if (dpb_buffer_.num_long_term > 1) {
qsort((void*)&ref_list_0_[dpb_buffer_.num_short_term], dpb_buffer_.num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
qsort((void*)&p_slice_info->ref_list_0_[dpb_buffer_.num_short_term], dpb_buffer_.num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
} else { // 8.2.4.2.2
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Add P ref field list init." << std::endl;
@@ -1704,45 +1730,45 @@ void AvcVideoParser::SetupReflist() {
int num_long_term = 0;
int ref_index = 0;
// Group short term ref pictures that have smaller POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt < curr_pic_.pic_order_cnt) {
ref_list_0_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_0_[ref_index] = *p_ref_pic;
num_short_term_smaller++;
ref_index++;
}
}
// Sort in descending order of POC
if (num_short_term_smaller > 1) {
qsort((void*)ref_list_0_, num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
qsort((void*)p_slice_info->ref_list_0_, num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
}
// Group short term ref pictures that have greater POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt > curr_pic_.pic_order_cnt) {
ref_list_0_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_0_[ref_index] = *p_ref_pic;
num_short_term_greater++;
ref_index++;
}
}
// Sort in ascending order of POC
if (num_short_term_greater > 1) {
qsort((void*)&ref_list_0_[num_short_term_smaller], num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
qsort((void*)&p_slice_info->ref_list_0_[num_short_term_smaller], num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
}
// Group long term ref pictures
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForLongTerm) {
ref_list_0_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_0_[ref_index] = *p_ref_pic;
num_long_term++;
ref_index++;
}
}
// Sort long term refs with ascending order of long_term_pic_num
if (num_long_term > 1) {
qsort((void*)&ref_list_0_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
qsort((void*)&p_slice_info->ref_list_0_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
// RefPicList1
@@ -1752,45 +1778,45 @@ void AvcVideoParser::SetupReflist() {
ref_index = 0;
// Group short term ref pictures that have greater POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt > curr_pic_.pic_order_cnt) {
ref_list_1_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_1_[ref_index] = *p_ref_pic;
num_short_term_greater++;
ref_index++;
}
}
// Sort in ascending order of POC
if (num_short_term_greater > 1) {
qsort((void*)ref_list_1_, num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
qsort((void*)p_slice_info->ref_list_1_, num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
}
// Group short term ref pictures that have smaller POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt < curr_pic_.pic_order_cnt) {
ref_list_1_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_1_[ref_index] = *p_ref_pic;
num_short_term_smaller++;
ref_index++;
}
}
// Sort in descending order of POC
if (num_short_term_smaller > 1) {
qsort((void*)&ref_list_1_[num_short_term_greater], num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
qsort((void*)&p_slice_info->ref_list_1_[num_short_term_greater], num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
}
// Group long term ref pictures
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForLongTerm) {
ref_list_1_[ref_index] = *p_ref_pic;
p_slice_info->ref_list_1_[ref_index] = *p_ref_pic;
num_long_term++;
ref_index++;
}
}
// Sort long term refs with ascending order of long_term_pic_num
if (num_long_term > 1) {
qsort((void*)&ref_list_1_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
qsort((void*)&p_slice_info->ref_list_1_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
} else { // 8.2.4.2.4
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Add B ref field list init." << std::endl;
@@ -1834,7 +1860,7 @@ ParserResult AvcVideoParser::FindFreeBufInDpb() {
ParserResult AvcVideoParser::MarkDecodedRefPics() {
AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_];
AvcSliceHeader *p_slice_header = &slice_header_0_;
AvcSliceHeader *p_slice_header = &slice_info_list_[0].slice_header;
int i;
if (slice_nal_unit_header_.nal_ref_idc == 0) {
+15 -5
View File
@@ -80,6 +80,16 @@ protected:
kUsedForLongTerm = 2
};
/*! \brief Slice info of a picture
*/
typedef struct {
AvcSliceHeader 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
AvcPicture ref_list_0_[AVC_MAX_REF_FRAME_NUM];
AvcPicture ref_list_1_[AVC_MAX_REF_FRAME_NUM];
} AvcSliceInfo;
/*! \brief Decoded picture buffer
*/
typedef struct{
@@ -96,7 +106,8 @@ protected:
int32_t active_pps_id_;
AvcNalUnitHeader slice_nal_unit_header_;
AvcSliceHeader slice_header_0_;
std::vector<AvcSliceInfo> slice_info_list_;
std::vector<RocdecAvcSliceParams> slice_param_list_;
int prev_pic_order_cnt_msb_; // prevPicOrderCntMsb
int prev_pic_order_cnt_lsb_; // prevPicOrderCntLsb
@@ -111,8 +122,6 @@ protected:
// 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
@@ -193,9 +202,10 @@ protected:
*/
void CalculateCurrPoc();
/*! \brief Function to set up the reference picutre lists. 8.2.4.
/*! \brief Function to set up the reference picutre lists for each slice. 8.2.4.
* \param [in] p_slice_info Poiner to slice info struct
*/
void SetupReflist();
void SetupReflist(AvcSliceInfo *p_slice_info);
/*! \brief Function to find a free buffer in DPB for the current picture
*/