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>
Este cometimento está contido em:
cometido por
GitHub
ascendente
e2b9e7197a
cometimento
ba36534f1f
@@ -1180,9 +1180,17 @@ ParserResult AvcVideoParser::ParseSliceHeader(uint8_t *p_stream, size_t stream_s
|
||||
// Set active SPS and PPS for the current slice
|
||||
active_pps_id_ = p_slice_header->pic_parameter_set_id;
|
||||
p_pps = &pps_list_[active_pps_id_];
|
||||
if (p_pps->is_received == 0) {
|
||||
ERR("Empty PPS is referred.");
|
||||
return PARSER_WRONG_STATE;
|
||||
}
|
||||
if (active_sps_id_ != p_pps->seq_parameter_set_id) {
|
||||
active_sps_id_ = p_pps->seq_parameter_set_id;
|
||||
p_sps = &sps_list_[active_sps_id_];
|
||||
if ( p_sps->is_received == 0) {
|
||||
ERR("Empty SPS is referred.");
|
||||
return PARSER_WRONG_STATE;
|
||||
}
|
||||
// Re-set DPB size.
|
||||
dpb_buffer_.dpb_size = p_sps->max_num_ref_frames + 3;
|
||||
dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > AVC_MAX_DPB_FRAMES ? AVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size;
|
||||
|
||||
@@ -337,7 +337,8 @@ typedef struct {
|
||||
|
||||
/*! \brief Structure for Video Parameter Set
|
||||
*/
|
||||
typedef struct{
|
||||
typedef struct {
|
||||
uint32_t is_received; // received with vps_video_parameter_set_id
|
||||
uint32_t vps_video_parameter_set_id; //u(4)
|
||||
uint32_t vps_base_layer_internal_flag; //u(1)
|
||||
uint32_t vps_base_layer_available_flag; //u(1)
|
||||
@@ -377,6 +378,7 @@ typedef struct{
|
||||
/*! \brief Structure for Sequence Parameter Set
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t is_received; // received with sps_seq_parameter_set_id
|
||||
uint32_t sps_video_parameter_set_id; //u(4)
|
||||
uint32_t sps_max_sub_layers_minus1; //u(3)
|
||||
bool sps_temporal_id_nesting_flag; //u(1)
|
||||
@@ -443,6 +445,7 @@ typedef struct {
|
||||
/*! \brief Structure for Picture Parameter Set
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t is_received; // received with pps_pic_parameter_set_id
|
||||
uint32_t pps_pic_parameter_set_id; //ue(v)
|
||||
uint32_t pps_seq_parameter_set_id; //ue(v)
|
||||
bool dependent_slice_segments_enabled_flag; //u(1)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -273,9 +273,9 @@ protected:
|
||||
* \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
|
||||
* \return <tt>ParserResult</tt>
|
||||
*/
|
||||
bool ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header);
|
||||
ParserResult ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header);
|
||||
|
||||
/*! \brief Function to calculate the picture order count of the current picture. Once per picutre. (8.3.1)
|
||||
*/
|
||||
@@ -322,9 +322,9 @@ protected:
|
||||
/*! \brief Function to parse one picture bit stream received from the demuxer.
|
||||
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
|
||||
* \param [in] pic_data_size Size of the input stream
|
||||
* \return True is successful, else false
|
||||
* \return <tt>ParserResult</tt>
|
||||
*/
|
||||
bool ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size);
|
||||
ParserResult ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size);
|
||||
|
||||
#if DBGINFO
|
||||
void PrintVps(HevcVideoParamSet *vps_ptr);
|
||||
|
||||
Criar uma nova questão referindo esta
Bloquear um utilizador