diff --git a/src/parser/hevc_parser.cpp b/src/parser/hevc_parser.cpp
index 96de41122a..5d6b58c491 100644
--- a/src/parser/hevc_parser.cpp
+++ b/src/parser/hevc_parser.cpp
@@ -69,6 +69,10 @@ rocDecStatus HEVCVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
new_sps_activated_ = false;
}
+ // Whenever new sei message found
+ if (sei_message_count_ > 0) {
+ FillSeiMessageCallbackFn(m_sei_message_);
+ }
return ROCDEC_SUCCESS;
}
@@ -88,6 +92,9 @@ HEVCVideoParser::~HEVCVideoParser() {
if (m_sh_copy_) {
delete m_sh_copy_;
}
+ if (m_sei_message_) {
+ delete m_sei_message_;
+ }
}
HEVCVideoParser::VpsData* HEVCVideoParser::AllocVps() {
@@ -138,6 +145,18 @@ HEVCVideoParser::SliceHeaderData* HEVCVideoParser::AllocSliceHeader() {
return p;
}
+HEVCVideoParser::SeiMessageData* HEVCVideoParser::AllocSeiMessage() {
+ SeiMessageData *p = nullptr;
+ try {
+ p = new SeiMessageData;
+ }
+ catch(const std::exception& e) {
+ ERR(STR("Failed to alloc Sei Message Data, ") + STR(e.what()))
+ }
+ memset(p, 0, sizeof(SeiMessageData));
+ return p;
+}
+
ParserResult HEVCVideoParser::Init() {
b_new_picture_ = false;
m_vps_ = AllocVps();
@@ -145,12 +164,12 @@ ParserResult HEVCVideoParser::Init() {
m_pps_ = AllocPps();
m_sh_ = AllocSliceHeader();
m_sh_copy_ = AllocSliceHeader();
+ m_sei_message_ = AllocSeiMessage();
return PARSER_OK;
}
void HEVCVideoParser::FillSeqCallbackFn(SpsData* sps_data) {
video_format_params_.codec = rocDecVideoCodec_HEVC;
- // TODO: Check the two frame_rate - setting default
video_format_params_.frame_rate.numerator = 0;
video_format_params_.frame_rate.denominator = 0;
video_format_params_.bit_depth_luma_minus8 = sps_data->bit_depth_luma_minus8;
@@ -205,7 +224,6 @@ void HEVCVideoParser::FillSeqCallbackFn(SpsData* sps_data) {
video_format_params_.display_area.bottom = video_format_params_.coded_height;
}
- // TODO: Check bitrate - setting default
video_format_params_.bitrate = 0;
if (sps_data->vui_parameters_present_flag) {
if (sps_data->vui_parameters.aspect_ratio_info_present_flag) {
@@ -225,13 +243,30 @@ void HEVCVideoParser::FillSeqCallbackFn(SpsData* sps_data) {
video_format_params_.video_signal_description.matrix_coefficients = sps_data->vui_parameters.matrix_coeffs;
video_format_params_.video_signal_description.reserved_zero_bits = 0;
}
- // TODO: check seqhdr_data_length
video_format_params_.seqhdr_data_length = 0;
// callback function with RocdecVideoFormat params filled out
pfn_sequece_cb_(parser_params_.pUserData, &video_format_params_);
}
+void HEVCVideoParser::FillSeiMessageCallbackFn(SeiMessageData* sei_message_data) {
+ sei_message_info_params_.sei_message_count = sei_message_count_;
+ sei_message_info_params_.pSEIMessage = nullptr;
+ sei_message_info_params_.pSEIMessage->sei_message_type = sei_message_data->payload_type;
+ sei_message_info_params_.pSEIMessage->sei_message_size = sei_message_data->payload_size;
+ // TODO: check reserve[3] values
+ for (int i = 0; i < 3; i++) {
+ sei_message_info_params_.pSEIMessage->reserved[i] = 0;
+ }
+ sei_message_info_params_.pSEIData = &sei_message_data;
+
+ // TODO: check picIdx value
+ sei_message_info_params_.picIdx = 0;
+
+ // callback function with RocdecSeiMessageInfo params filled out
+ pfn_get_sei_message_cb_(parser_params_.pUserData, &sei_message_info_params_);
+}
+
bool HEVCVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_data_size) {
int ret = PARSER_OK;
@@ -243,6 +278,7 @@ bool HEVCVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
next_start_code_offset_ = 0;
slice_num_ = 0;
+ sei_message_count_ = 0;
do {
ret = GetNalUnit();
@@ -320,9 +356,17 @@ bool HEVCVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
break;
}
- default:
- // Do nothing for now.
+ case NAL_UNIT_PREFIX_SEI: {
+ memcpy(m_rbsp_buf_, (frame_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
+ m_rbsp_size_ = EBSPtoRBSP(m_rbsp_buf_, 0, ebsp_size);
+ ParseSeiMessage(m_rbsp_buf_, m_rbsp_size_);
+ sei_message_count_++;
break;
+ }
+
+ default:
+ ERR(STR("Error: Invalid NAL unit type"));
+ return false;
}
}
@@ -1414,6 +1458,33 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si
return false;
}
+void HEVCVideoParser::ParseSeiMessage(uint8_t *nalu, size_t size) {
+ size_t offset = 0;
+ uint32_t sei_message_id = Parser::ExpGolomb::ReadUe(nalu, offset);
+ SeiMessageData *sei_message_ptr = &m_sei_message_[sei_message_id];
+ memset(sei_message_ptr, 0, sizeof(SeiMessageData));
+
+ sei_message_ptr->payload_type = 0;
+ sei_message_ptr->payload_size = 0;
+ uint8_t temp_byte;
+ temp_byte = Parser::GetBit(nalu, offset);
+ while (temp_byte == 0XFF) {
+ sei_message_ptr->payload_type += 255;
+ temp_byte = Parser::GetBit(nalu, offset);
+ }
+ sei_message_ptr->payload_type += temp_byte;
+ sei_message_ptr->payload_size = 0;
+ temp_byte = Parser::GetBit(nalu, offset);
+ while (temp_byte == 0XFF) {
+ sei_message_ptr->payload_size += 255;
+ temp_byte = Parser::GetBit(nalu, offset);
+ }
+ sei_message_ptr->payload_size += temp_byte;
+
+ // copy the payload to buffer
+ memcpy(m_sei_data_, sei_message_ptr, sei_message_ptr->payload_size);
+}
+
void HEVCVideoParser::CalculateCurrPOC() {
if (nal_unit_header_.nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nal_unit_header_.nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP) {
curr_pic_info_.pic_order_cnt = 0;
@@ -2128,4 +2199,15 @@ void HEVCVideoParser::PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_p
}
MSG("");
}
+
+void HEVCVideoParser::PrintSeiMessage(HEVCVideoParser::SeiMessageDara *sei_message_ptr) {
+ MSG("=== hevc_sei_message_info ===");
+ MSG("payload_type = " << sei_message_ptr->payload_type);
+ MSG("payload_size = " << sei_message_ptr->payload_size);
+ MSG("pic_idx = " << sei_message_ptr->pic_idx);
+ MSG_NO_NEWLINE("reserved[3]: ");
+ for(int i = 0; i < 3; i++) {
+ MSG_NO_NEWLINE(" " << sei_message_ptr->reserved[i]);
+ }
+ MSG("");
#endif // DBGINFO
\ No newline at end of file
diff --git a/src/parser/hevc_parser.h b/src/parser/hevc_parser.h
index 3436b368ef..923a35d152 100644
--- a/src/parser/hevc_parser.h
+++ b/src/parser/hevc_parser.h
@@ -41,6 +41,7 @@ extern int scaling_list_default_3[1][2][64];
#define MAX_SPS_COUNT 16 // 7.3.2.2.1
#define MAX_PPS_COUNT 64 // 7.4.3.3.1
#define RBSP_BUF_SIZE 1024 // enough to parse any parameter sets or slice headers
+#define SEI_BUF_SIZE 1024
#define HVC_MAX_DPB_FRAMES 16 // (A-2)
#define HEVC_MAX_NUM_REF_PICS 16
@@ -597,6 +598,12 @@ protected:
uint8_t slice_segment_header_extension_data_byte[256]; //u(8)
} SliceHeaderData;
+ typedef struct {
+ uint8_t payload_type;
+ uint8_t reserved[3];
+ uint32_t payload_size;
+ } SeiMessageData;
+
/*! \brief Inline function to Parse the NAL Unit Header
*
* \param [in] nal_unit A pointer of uint8_t containing the Demuxed output stream
@@ -662,10 +669,13 @@ protected:
PpsData* m_pps_;
SliceHeaderData* m_sh_;
SliceHeaderData* m_sh_copy_;
+ SeiMessageData* m_sei_message_;
+ uint8_t m_sei_data_[SEI_BUF_SIZE]; // to store SEI payload
HevcPicInfo curr_pic_info_;
bool b_new_picture_;
int m_packet_count_;
int slice_num_;
+ int sei_message_count_;
int m_rbsp_size_;
uint8_t m_rbsp_buf_[RBSP_BUF_SIZE]; // to store parameter set or slice header RBSP
@@ -814,6 +824,12 @@ protected:
*/
bool ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, size_t size);
+ /*! \brief Function to parse Sei Message Info
+ * \param [in] nalu A pointer of uint8_t for the input stream to be parsed
+ * \param [in] size Size of the input stream
+ * \return No return value
+ */
+ void ParseSeiMessage(uint8_t *nalu, size_t size);
/*! \brief Function to calculate the picture order count of the current picture (8.3.1)
*/
void CalculateCurrPOC();
@@ -850,6 +866,7 @@ protected:
void PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slice_header_ptr);
void PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr);
void PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_ptr);
+ void PrintSeiMessage(HEVCVideoParser::SeiMessageData *sei_message_ptr);
#endif // DBGINFO
private:
@@ -878,6 +895,12 @@ private:
*/
SliceHeaderData* AllocSliceHeader();
+ /*! \brief Function to allocate memory for Sei Message Structure
+ * \return Returns pointer to the allocated memory for SeiMessageData
+ */
+ SeiMessageData* AllocSeiMessage();
+
// functions to fill structures for callback functions
void FillSeqCallbackFn(SpsData* sps_data);
+ void FillSeiMessageCallbackFn(SeiMessageData* sei_message_data);
};
\ No newline at end of file
diff --git a/src/parser/roc_video_parser.h b/src/parser/roc_video_parser.h
index 4d540bf792..f0ca294e59 100644
--- a/src/parser/roc_video_parser.h
+++ b/src/parser/roc_video_parser.h
@@ -57,6 +57,7 @@ protected:
bool new_sps_activated_;
RocdecVideoFormat video_format_params_;
+ RocdecSeiMessageInfo sei_message_info_params_;
};
enum ParserSeekOrigin {