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>
这个提交包含在:
+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) {
|
||||
|
||||
在新工单中引用
屏蔽一个用户