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);