diff --git a/src/parser/avc_parser.cpp b/src/parser/avc_parser.cpp
index dabed8ea00..25b2fb9b0e 100644
--- a/src/parser/avc_parser.cpp
+++ b/src/parser/avc_parser.cpp
@@ -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;
diff --git a/src/parser/hevc_defines.h b/src/parser/hevc_defines.h
index 91edf90f29..d841b43278 100644
--- a/src/parser/hevc_defines.h
+++ b/src/parser/hevc_defines.h
@@ -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)
diff --git a/src/parser/hevc_parser.cpp b/src/parser/hevc_parser.cpp
index 5376525099..0ded8882be 100644
--- a/src/parser/hevc_parser.cpp
+++ b/src/parser/hevc_parser.cpp
@@ -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) {
diff --git a/src/parser/hevc_parser.h b/src/parser/hevc_parser.h
index 679854eb7c..982dfe4dc0 100644
--- a/src/parser/hevc_parser.h
+++ b/src/parser/hevc_parser.h
@@ -273,9 +273,9 @@ protected:
* \param [in] nalu A pointer of uint8_t 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 ParserResult
*/
- 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 uint8_t for the input stream to be parsed
* \param [in] pic_data_size Size of the input stream
- * \return True is successful, else false
+ * \return ParserResult
*/
- 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);