IRAP POC calculation fix. (#66)
* * rocDecode/HEVC: Fixed a bug in IRAP picture order count calculation. Added a few picture type check utilities.
* * rocDecode/HEVC: Minor coding style changes. No functional changes.
[ROCm/rocdecode commit: 69c2243c9c]
This commit is contained in:
@@ -23,6 +23,9 @@ THE SOFTWARE.
|
||||
#include "hevc_parser.h"
|
||||
|
||||
HEVCVideoParser::HEVCVideoParser() {
|
||||
pic_count_ = 0;
|
||||
first_pic_after_eos_nal_unit_ = 0;
|
||||
|
||||
m_active_vps_id_ = -1;
|
||||
m_active_sps_id_ = -1;
|
||||
m_active_pps_id_ = -1;
|
||||
@@ -83,6 +86,8 @@ rocDecStatus HEVCVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
|
||||
pic_count_++;
|
||||
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -405,8 +410,8 @@ int HEVCVideoParser::SendPicForDecode() {
|
||||
pic_param_ptr->slice_parsing_fields.bits.deblocking_filter_override_enabled_flag = pps_ptr->deblocking_filter_override_enabled_flag;
|
||||
pic_param_ptr->slice_parsing_fields.bits.pps_disable_deblocking_filter_flag = pps_ptr->pps_deblocking_filter_disabled_flag;
|
||||
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.RapPicFlag = (slice_nal_unit_header_.nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && slice_nal_unit_header_.nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23) ? 1 : 0;
|
||||
pic_param_ptr->slice_parsing_fields.bits.IdrPicFlag = (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) ? 1 : 0;
|
||||
pic_param_ptr->slice_parsing_fields.bits.RapPicFlag = IsIrapPic(&slice_nal_unit_header_) ? 1 : 0;
|
||||
pic_param_ptr->slice_parsing_fields.bits.IdrPicFlag = IsIdrPic(&slice_nal_unit_header_) ? 1 : 0;
|
||||
pic_param_ptr->slice_parsing_fields.bits.IntraPicFlag = m_sh_->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;
|
||||
@@ -628,7 +633,21 @@ bool HEVCVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
|
||||
// This is to consider the possibility of non-slice NAL units between slices.
|
||||
pic_stream_data_size_ = frame_data_size - curr_start_code_offset_;
|
||||
|
||||
ParseSliceHeader(slice_nal_unit_header_.nal_unit_type, m_rbsp_buf_, m_rbsp_size_);
|
||||
ParseSliceHeader(m_rbsp_buf_, m_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;
|
||||
}
|
||||
else {
|
||||
no_rasl_output_flag_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (first_pic_after_eos_nal_unit_) {
|
||||
first_pic_after_eos_nal_unit_ = 0; // clear the flag
|
||||
}
|
||||
|
||||
// Get POC
|
||||
CalculateCurrPOC();
|
||||
@@ -656,6 +675,16 @@ bool HEVCVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
|
||||
break;
|
||||
}
|
||||
|
||||
case NAL_UNIT_EOS: {
|
||||
first_pic_after_eos_nal_unit_ = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
case NAL_UNIT_EOB: {
|
||||
pic_count_ = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1511,7 +1540,7 @@ void HEVCVideoParser::ParsePps(uint8_t *nalu, size_t size) {
|
||||
#endif // DBGINFO
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, size_t size) {
|
||||
bool HEVCVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) {
|
||||
PpsData *pps_ptr = NULL;
|
||||
SpsData *sps_ptr = NULL;
|
||||
size_t offset = 0;
|
||||
@@ -1520,7 +1549,7 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si
|
||||
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);
|
||||
if (nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1566,7 +1595,7 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si
|
||||
m_sh_->colour_plane_id = Parser::ReadBits(nalu, offset, 2);
|
||||
}
|
||||
|
||||
if (nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_W_RADL && nal_unit_type != NAL_UNIT_CODED_SLICE_IDR_N_LP) {
|
||||
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));
|
||||
|
||||
@@ -1815,8 +1844,28 @@ void HEVCVideoParser::ParseSeiMessage(uint8_t *nalu, size_t size) {
|
||||
memcpy(m_sei_data_, sei_message_ptr, sei_message_ptr->payload_size);
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::IsIdrPic(NalUnitHeader *nal_header_ptr) {
|
||||
return (nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP);
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::IsBlaPic(NalUnitHeader *nal_header_ptr) {
|
||||
return (nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_BLA_W_LP || nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_BLA_W_RADL || nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_BLA_N_LP);
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::IsCraPic(NalUnitHeader *nal_header_ptr) {
|
||||
return (nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_CRA_NUT);
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::IsRaslPic(NalUnitHeader *nal_header_ptr) {
|
||||
return (nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_RASL_N || nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_RASL_R);
|
||||
}
|
||||
|
||||
bool HEVCVideoParser::IsIrapPic(NalUnitHeader *nal_header_ptr) {
|
||||
return (nal_header_ptr->nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && nal_header_ptr->nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23);
|
||||
}
|
||||
|
||||
void HEVCVideoParser::CalculateCurrPOC() {
|
||||
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) {
|
||||
if (IsIdrPic(&slice_nal_unit_header_)) {
|
||||
curr_pic_info_.pic_order_cnt = 0;
|
||||
curr_pic_info_.prev_poc_lsb = 0;
|
||||
curr_pic_info_.prev_poc_msb = 0;
|
||||
@@ -1826,7 +1875,7 @@ void HEVCVideoParser::CalculateCurrPOC() {
|
||||
int max_poc_lsb = 1 << (m_sps_[m_active_sps_id_].log2_max_pic_order_cnt_lsb_minus4 + 4); // MaxPicOrderCntLsb
|
||||
int poc_msb; // PicOrderCntMsb
|
||||
// If the current picture is an IRAP picture with NoRaslOutputFlag equal to 1, PicOrderCntMsb is set equal to 0.
|
||||
if (slice_nal_unit_header_.nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && slice_nal_unit_header_.nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23) {
|
||||
if (IsIrapPic(&slice_nal_unit_header_) && no_rasl_output_flag_ == 1) {
|
||||
poc_msb = 0;
|
||||
}
|
||||
else {
|
||||
@@ -1856,13 +1905,13 @@ void HEVCVideoParser::DeocdeRps() {
|
||||
|
||||
// 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".
|
||||
if (slice_nal_unit_header_.nal_unit_type >= NAL_UNIT_CODED_SLICE_BLA_W_LP && slice_nal_unit_header_.nal_unit_type <= NAL_UNIT_RESERVED_IRAP_VCL23) {
|
||||
if (IsIrapPic(&slice_nal_unit_header_) && no_rasl_output_flag_ == 1) {
|
||||
for (i = 0; i < HVC_MAX_DPB_FRAMES; i++) {
|
||||
dpb_buffer_.frame_buffer_list[i].is_reference = kUnusedForReference;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
if (IsIdrPic(&slice_nal_unit_header_)) {
|
||||
num_poc_st_curr_before_ = 0;
|
||||
num_poc_st_curr_after_ = 0;
|
||||
num_poc_st_foll_ = 0;
|
||||
@@ -2535,14 +2584,14 @@ void HEVCVideoParser::PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_p
|
||||
MSG("");
|
||||
}
|
||||
|
||||
void HEVCVideoParser::PrintSeiMessage(HEVCVideoParser::SeiMessageDara *sei_message_ptr) {
|
||||
void HEVCVideoParser::PrintSeiMessage(HEVCVideoParser::SeiMessageData *sei_message_ptr) {
|
||||
MSG("=== hevc_sei_message_info ===");
|
||||
MSG("payload_type = " << sei_message_ptr->payload_type);
|
||||
MSG("payload_size = " << sei_message_ptr->payload_size);
|
||||
MSG("pic_idx = " << sei_message_ptr->pic_idx);
|
||||
MSG_NO_NEWLINE("reserved[3]: ");
|
||||
for(int i = 0; i < 3; i++) {
|
||||
MSG_NO_NEWLINE(" " << sei_message_ptr->reserved[i]);
|
||||
}
|
||||
MSG("");
|
||||
}
|
||||
#endif // DBGINFO
|
||||
Reference in New Issue
Block a user