rocDecode: Added error handling of missing headers in cases where they are not parsed but referred in the frame decode process. One example is when frame seek is performed and the target picture is not a random access point. (#335)

* * rocDecode: Added error handling of missing headers in cases where they are not parsed but referred in the frame decode process. One example is when frame seek is performed and the target picture is not a random access point.

* * rocDecode/HEVC: Added some missing error handlings.

---------

Co-authored-by: Aryan Salmanpour <aryan.salmanpour@amd.com>
这个提交包含在:
jeffqjiangNew
2024-05-03 15:18:08 -04:00
提交者 GitHub
父节点 e2b9e7197a
当前提交 ba36534f1f
修改 4 个文件,包含 43 行新增14 行删除
+27 -9
查看文件
@@ -81,8 +81,7 @@ rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
// Clear DPB output/display buffer number
dpb_buffer_.num_output_pics = 0;
bool status = ParsePictureData(p_data->payload, p_data->payload_size);
if (!status) {
if (ParsePictureData(p_data->payload, p_data->payload_size) != PARSER_OK) {
ERR(STR("Parser failed!"));
return ROCDEC_RUNTIME_ERROR;
}
@@ -550,8 +549,9 @@ int HevcVideoParser::OutputDecodedPictures() {
return PARSER_OK;
}
bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size) {
int ret = PARSER_OK;
ParserResult HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size) {
ParserResult ret = PARSER_OK;
ParserResult ret2;
pic_data_buffer_ptr_ = (uint8_t*)p_stream;
pic_data_size_ = pic_data_size;
@@ -568,7 +568,7 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
ret = GetNalUnit();
if (ret == PARSER_NOT_FOUND) {
ERR(STR("Error: no start code found in the frame data."));
return false;
return ret;
}
// Parse the NAL unit
@@ -629,7 +629,9 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
HevcSliceSegHeader *p_slice_header = &slice_info_list_[num_slices_].slice_header;
ParseSliceHeader(rbsp_buf_, rbsp_size_, p_slice_header);
if ((ret2 = ParseSliceHeader(rbsp_buf_, rbsp_size_, p_slice_header)) != PARSER_OK) {
return ret2;
}
// Start decode process
if (num_slices_ == 0) {
@@ -726,7 +728,7 @@ bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_dat
}
} while (1);
return true;
return PARSER_OK;
}
void HevcVideoParser::ParsePtl(HevcProfileTierLevel *ptl, bool profile_present_flag, uint32_t max_num_sub_layers_minus1, uint8_t *nalu, size_t size, size_t& offset) {
@@ -1267,6 +1269,7 @@ void HevcVideoParser::ParseVps(uint8_t *nalu, size_t size) {
}
}
p_vps->vps_extension_flag = Parser::GetBit(nalu, offset);
p_vps->is_received = 1;
#if DBGINFO
PrintVps(p_vps);
@@ -1394,6 +1397,7 @@ void HevcVideoParser::ParseSps(uint8_t *nalu, size_t size) {
ParseVui(&sps_ptr->vui_parameters, sps_ptr->sps_max_sub_layers_minus1, nalu, size, offset);
}
sps_ptr->sps_extension_flag = Parser::GetBit(nalu, offset);
sps_ptr->is_received = 1;
#if DBGINFO
PrintSps(sps_ptr);
@@ -1512,12 +1516,14 @@ void HevcVideoParser::ParsePps(uint8_t *nalu, size_t size) {
pps_ptr->log2_sao_offset_scale_chroma = Parser::ExpGolomb::ReadUe(nalu, offset);
}
pps_ptr->is_received = 1;
#if DBGINFO
PrintPps(pps_ptr);
#endif // DBGINFO
}
bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header) {
ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header) {
HevcPicParamSet *pps_ptr = nullptr;
HevcSeqParamSet *sps_ptr = nullptr;
size_t offset = 0;
@@ -1534,6 +1540,10 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegH
m_active_pps_id_ = Parser::ExpGolomb::ReadUe(nalu, offset);
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 ( pps_ptr->is_received == 0) {
ERR("Empty PPS is referred.");
return PARSER_WRONG_STATE;
}
if (m_active_sps_id_ != pps_ptr->pps_seq_parameter_set_id) {
m_active_sps_id_ = pps_ptr->pps_seq_parameter_set_id;
sps_ptr = &m_sps_[m_active_sps_id_];
@@ -1543,7 +1553,15 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegH
new_sps_activated_ = true; // Note: clear this flag after the actions are taken.
}
sps_ptr = &m_sps_[m_active_sps_id_];
if (sps_ptr->is_received == 0) {
ERR("Empty SPS is referred.");
return PARSER_WRONG_STATE;
}
m_active_vps_id_ = sps_ptr->sps_video_parameter_set_id;
if (m_vps_[m_active_vps_id_].is_received == 0) {
ERR("Empty VPS is referred.");
return PARSER_WRONG_STATE;
}
// Check video dimension change
if ( pic_width_ != sps_ptr->pic_width_in_luma_samples || pic_height_ != sps_ptr->pic_height_in_luma_samples) {
@@ -1825,7 +1843,7 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegH
PrintSliceSegHeader(p_slice_header);
#endif // DBGINFO
return false;
return PARSER_OK;
}
bool HevcVideoParser::IsIdrPic(HevcNalUnitHeader *nal_header_ptr) {