diff --git a/src/parser/avc_parser.cpp b/src/parser/avc_parser.cpp
index 502f5d1b98..fd7213fdbf 100644
--- a/src/parser/avc_parser.cpp
+++ b/src/parser/avc_parser.cpp
@@ -69,6 +69,11 @@ rocDecStatus AvcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
new_sps_activated_ = false;
}
+ // Whenever new sei message found
+ if (pfn_get_sei_message_cb_ && sei_message_count_ > 0) {
+ SendSeiMsgPayload();
+ }
+
// Decode the picture
if (SendPicForDecode() != PARSER_OK) {
ERR(STR("Failed to decode!"));
@@ -209,7 +214,20 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
case kAvcNalTypeSEI_Info: {
if (pfn_get_sei_message_cb_) {
- // Todo
+ int sei_ebsp_size = nal_unit_size_ - 4; // copy the entire NAL unit
+ if (sei_rbsp_buf_) {
+ if (sei_ebsp_size > sei_rbsp_buf_size_) {
+ delete [] sei_rbsp_buf_;
+ sei_rbsp_buf_ = new uint8_t [sei_ebsp_size];
+ sei_rbsp_buf_size_ = sei_ebsp_size;
+ }
+ } else {
+ sei_rbsp_buf_size_ = sei_ebsp_size > INIT_SEI_PAYLOAD_BUF_SIZE ? sei_ebsp_size : INIT_SEI_PAYLOAD_BUF_SIZE;
+ sei_rbsp_buf_ = new uint8_t [sei_rbsp_buf_size_];
+ }
+ memcpy(sei_rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 4), sei_ebsp_size);
+ rbsp_size_ = EbspToRbsp(sei_rbsp_buf_, 0, sei_ebsp_size);
+ ParseSeiMessage(sei_rbsp_buf_, rbsp_size_);
}
break;
}
@@ -349,6 +367,16 @@ ParserResult AvcVideoParser::NotifyNewSps(AvcSeqParameterSet *p_sps) {
}
}
+void AvcVideoParser::SendSeiMsgPayload() {
+ sei_message_info_params_.sei_message_count = sei_message_count_;
+ sei_message_info_params_.sei_message = sei_message_list_.data();
+ sei_message_info_params_.sei_data = (void*)sei_payload_buf_;
+ sei_message_info_params_.picIdx = curr_pic_.pic_idx;
+
+ // callback function with RocdecSeiMessageInfo params filled out
+ if (pfn_get_sei_message_cb_) pfn_get_sei_message_cb_(parser_params_.user_data, &sei_message_info_params_);
+}
+
ParserResult AvcVideoParser::SendPicForDecode() {
int i, j;
AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_];
diff --git a/src/parser/avc_parser.h b/src/parser/avc_parser.h
index a0b82ad225..45ae8208b1 100644
--- a/src/parser/avc_parser.h
+++ b/src/parser/avc_parser.h
@@ -144,6 +144,10 @@ protected:
*/
ParserResult OutputDecodedPictures();
+ /*! \brief Callback function to send parsed SEI playload to decoder.
+ */
+ void SendSeiMsgPayload();
+
/*! \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
diff --git a/src/parser/hevc_defines.h b/src/parser/hevc_defines.h
index 01b07c11d9..91edf90f29 100644
--- a/src/parser/hevc_defines.h
+++ b/src/parser/hevc_defines.h
@@ -34,8 +34,6 @@ THE SOFTWARE.
#define HEVC_MAX_NUM_REF_PICS 16
// 7.4.7.1. (num_tile_columns_minus1 + 1) * PicHeightInCtbsY − 1. Max tile columns = 20 (A.4.2). Pic height in 16x16 CTB of 8K = 270.
#define MAX_ENTRY_POINT_OFFSETS 20 * 270
-#define INIT_SEI_MESSAGE_COUNT 16 // initial SEI message count
-#define INIT_SEI_PAYLOAD_BUF_SIZE 1024 * 1024 // initial SEI payload buffer size, 1 MB
/*! \brief Enumerator for the NAL Unit types - ISO-IEC 14496-15-2004.pdf, page 14, table 1 " NAL unit types in elementary streams
*/
diff --git a/src/parser/hevc_parser.cpp b/src/parser/hevc_parser.cpp
index 2cebc5d61a..5376525099 100644
--- a/src/parser/hevc_parser.cpp
+++ b/src/parser/hevc_parser.cpp
@@ -48,31 +48,34 @@ HevcVideoParser::HevcVideoParser() {
slice_info_list_.assign(INIT_SLICE_LIST_NUM, {0});
slice_param_list_.assign(INIT_SLICE_LIST_NUM, {0});
- sei_rbsp_buf_ = nullptr;
- sei_rbsp_buf_size_ = 0;
- sei_payload_buf_ = nullptr;
- sei_payload_buf_size_ = 0;
- sei_message_list_.assign(INIT_SEI_MESSAGE_COUNT, {0});
-
memset(&curr_pic_info_, 0, sizeof(HevcPicInfo));
InitDpb();
}
+HevcVideoParser::~HevcVideoParser() {
+ if (m_vps_) {
+ delete [] m_vps_;
+ }
+ if (m_sps_) {
+ delete [] m_sps_;
+ }
+ if (m_pps_) {
+ delete [] m_pps_;
+ }
+ if (m_sh_copy_) {
+ delete m_sh_copy_;
+ }
+}
+
rocDecStatus HevcVideoParser::Initialize(RocdecParserParams *p_params) {
return RocVideoParser::Initialize(p_params);
}
-/**
- * @brief function to uninitialize hevc parser
- *
- * @return rocDecStatus
- */
rocDecStatus HevcVideoParser::UnInitialize() {
//todo:: do any uninitialization here
return ROCDEC_SUCCESS;
}
-
rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
if (p_data->payload && p_data->payload_size) {
// Clear DPB output/display buffer number
@@ -94,7 +97,7 @@ rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
// Whenever new sei message found
if (pfn_get_sei_message_cb_ && sei_message_count_ > 0) {
- FillSeiMessageCallbackFn();
+ SendSeiMsgPayload();
}
// Decode the picture
@@ -125,27 +128,6 @@ rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
return ROCDEC_SUCCESS;
}
-HevcVideoParser::~HevcVideoParser() {
- if (m_vps_) {
- delete [] m_vps_;
- }
- if (m_sps_) {
- delete [] m_sps_;
- }
- if (m_pps_) {
- delete [] m_pps_;
- }
- if (m_sh_copy_) {
- delete m_sh_copy_;
- }
- if (sei_rbsp_buf_) {
- delete [] sei_rbsp_buf_;
- }
- if (sei_payload_buf_) {
- delete [] sei_payload_buf_;
- }
-}
-
int HevcVideoParser::FillSeqCallbackFn(HevcSeqParamSet* sps_data) {
video_format_params_.codec = rocDecVideoCodec_HEVC;
video_format_params_.frame_rate.numerator = frame_rate_.numerator;
@@ -247,7 +229,7 @@ int HevcVideoParser::FillSeqCallbackFn(HevcSeqParamSet* sps_data) {
}
}
-void HevcVideoParser::FillSeiMessageCallbackFn() {
+void HevcVideoParser::SendSeiMsgPayload() {
sei_message_info_params_.sei_message_count = sei_message_count_;
sei_message_info_params_.sei_message = sei_message_list_.data();
sei_message_info_params_.sei_data = (void*)sei_payload_buf_;
@@ -1846,57 +1828,6 @@ bool HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegH
return false;
}
-void HevcVideoParser::ParseSeiMessage(uint8_t *nalu, size_t size) {
- int offset = 0; // byte offset
- int payload_type;
- int payload_size;
-
- do {
- payload_type = 0;
- while (nalu[offset] == 0xFF) {
- payload_type += 255; // ff_byte
- offset++;
- }
- payload_type += nalu[offset]; // last_payload_type_byte
- offset++;
-
- payload_size = 0;
- while (nalu[offset] == 0xFF) {
- payload_size += 255; // ff_byte
- offset++;
- }
- payload_size += nalu[offset]; // last_payload_size_byte
- offset++;
-
- // We start with INIT_SEI_MESSAGE_COUNT. Should be enough for normal use cases. If not, resize.
- if((sei_message_count_ + 1) > sei_message_list_.size()) {
- sei_message_list_.resize((sei_message_count_ + 1));
- }
- sei_message_list_[sei_message_count_].sei_message_type = payload_type;
- sei_message_list_[sei_message_count_].sei_message_size = payload_size;
-
- if (sei_payload_buf_) {
- if ((payload_size + sei_payload_size_) > sei_payload_buf_size_) {
- uint8_t *tmp_ptr = new uint8_t [payload_size + sei_payload_size_];
- memcpy(tmp_ptr, sei_payload_buf_, sei_payload_size_); // save the existing payload
- delete [] sei_payload_buf_;
- sei_payload_buf_ = tmp_ptr;
- }
- } else {
- // First payload, sei_payload_size_ is 0.
- sei_payload_buf_size_ = payload_size > INIT_SEI_PAYLOAD_BUF_SIZE ? payload_size : INIT_SEI_PAYLOAD_BUF_SIZE;
- sei_payload_buf_ = new uint8_t [sei_payload_buf_size_];
- }
- // Append the current payload to sei_payload_buf_
- memcpy(sei_payload_buf_ + sei_payload_size_, nalu + offset, payload_size);
-
- sei_payload_size_ += payload_size;
- sei_message_count_++;
-
- offset += payload_size;
- } while (offset < size && nalu[offset] != 0x80);
-}
-
bool HevcVideoParser::IsIdrPic(HevcNalUnitHeader *nal_header_ptr) {
return (nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_W_RADL || nal_header_ptr->nal_unit_type == NAL_UNIT_CODED_SLICE_IDR_N_LP);
}
diff --git a/src/parser/hevc_parser.h b/src/parser/hevc_parser.h
index 51162f6757..679854eb7c 100644
--- a/src/parser/hevc_parser.h
+++ b/src/parser/hevc_parser.h
@@ -42,6 +42,11 @@ public:
*/
HevcVideoParser();
+ /**
+ * @brief HEVCParser object destructor
+ */
+ virtual ~HevcVideoParser();
+
/*! \brief Function to Initialize the parser
* \param [in] p_params Input of RocdecParserParams with codec type to initialize parser.
* \return rocDecStatus Returns success on completion, else error code for failure
@@ -61,11 +66,6 @@ public:
*/
virtual rocDecStatus UnInitialize(); // derived method :: nothing to do for this
- /**
- * @brief HEVCParser object destructor
- */
- virtual ~HevcVideoParser();
-
protected:
/*! \brief Inline function to Parse the NAL Unit Header
*
@@ -277,13 +277,6 @@ protected:
*/
bool ParseSliceHeader(uint8_t *nalu, size_t size, HevcSliceSegHeader *p_slice_header);
- /*! \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. Once per picutre. (8.3.1)
*/
void CalculateCurrPoc();
@@ -343,16 +336,20 @@ protected:
#endif // DBGINFO
private:
- // functions to fill structures for callback functions
+ /*! \brief Callback function to notify decoder about new SPS.
+ */
int FillSeqCallbackFn(HevcSeqParamSet* sps_data);
- void FillSeiMessageCallbackFn();
- /*! \brief Function to fill the decode parameters and call back decoder to decode a picture
+ /*! \brief Callback function to send parsed SEI playload to decoder.
+ */
+ void SendSeiMsgPayload();
+
+ /*! \brief Callback function to fill the decode parameters and call decoder to decode a picture
* \return Return code in ParserResult form
*/
int SendPicForDecode();
- /*! \brief Function to output decoded pictures from DPB for post-processing.
+ /*! \brief Callback function to output decoded pictures from DPB for post-processing.
* \return Return code in ParserResult form
*/
int OutputDecodedPictures();
diff --git a/src/parser/roc_video_parser.cpp b/src/parser/roc_video_parser.cpp
index ccaef3e23c..41c8ca4427 100644
--- a/src/parser/roc_video_parser.cpp
+++ b/src/parser/roc_video_parser.cpp
@@ -29,6 +29,21 @@ RocVideoParser::RocVideoParser() {
new_sps_activated_ = false;
frame_rate_.numerator = 0;
frame_rate_.denominator = 0;
+
+ sei_rbsp_buf_ = nullptr;
+ sei_rbsp_buf_size_ = 0;
+ sei_payload_buf_ = nullptr;
+ sei_payload_buf_size_ = 0;
+ sei_message_list_.assign(INIT_SEI_MESSAGE_COUNT, {0});
+}
+
+RocVideoParser::~RocVideoParser() {
+ if (sei_rbsp_buf_) {
+ delete [] sei_rbsp_buf_;
+ }
+ if (sei_payload_buf_) {
+ delete [] sei_payload_buf_;
+ }
}
/**
@@ -132,3 +147,54 @@ size_t RocVideoParser::EbspToRbsp(uint8_t *streamBuffer,size_t begin_bytepos, si
}
return end_bytepos - begin_bytepos + reduce_count;
}
+
+void RocVideoParser::ParseSeiMessage(uint8_t *nalu, size_t size) {
+ int offset = 0; // byte offset
+ int payload_type;
+ int payload_size;
+
+ do {
+ payload_type = 0;
+ while (nalu[offset] == 0xFF) {
+ payload_type += 255; // ff_byte
+ offset++;
+ }
+ payload_type += nalu[offset]; // last_payload_type_byte
+ offset++;
+
+ payload_size = 0;
+ while (nalu[offset] == 0xFF) {
+ payload_size += 255; // ff_byte
+ offset++;
+ }
+ payload_size += nalu[offset]; // last_payload_size_byte
+ offset++;
+
+ // We start with INIT_SEI_MESSAGE_COUNT. Should be enough for normal use cases. If not, resize.
+ if((sei_message_count_ + 1) > sei_message_list_.size()) {
+ sei_message_list_.resize((sei_message_count_ + 1));
+ }
+ sei_message_list_[sei_message_count_].sei_message_type = payload_type;
+ sei_message_list_[sei_message_count_].sei_message_size = payload_size;
+
+ if (sei_payload_buf_) {
+ if ((payload_size + sei_payload_size_) > sei_payload_buf_size_) {
+ uint8_t *tmp_ptr = new uint8_t [payload_size + sei_payload_size_];
+ memcpy(tmp_ptr, sei_payload_buf_, sei_payload_size_); // save the existing payload
+ delete [] sei_payload_buf_;
+ sei_payload_buf_ = tmp_ptr;
+ }
+ } else {
+ // First payload, sei_payload_size_ is 0.
+ sei_payload_buf_size_ = payload_size > INIT_SEI_PAYLOAD_BUF_SIZE ? payload_size : INIT_SEI_PAYLOAD_BUF_SIZE;
+ sei_payload_buf_ = new uint8_t [sei_payload_buf_size_];
+ }
+ // Append the current payload to sei_payload_buf_
+ memcpy(sei_payload_buf_ + sei_payload_size_, nalu + offset, payload_size);
+
+ sei_payload_size_ += payload_size;
+ sei_message_count_++;
+
+ offset += payload_size;
+ } while (offset < size && nalu[offset] != 0x80);
+}
\ No newline at end of file
diff --git a/src/parser/roc_video_parser.h b/src/parser/roc_video_parser.h
index f98acde6c4..62967d5bda 100644
--- a/src/parser/roc_video_parser.h
+++ b/src/parser/roc_video_parser.h
@@ -76,6 +76,8 @@ typedef struct {
#define ZEROBYTES_SHORTSTARTCODE 2 //indicates the number of zero bytes in the short start-code prefix
#define RBSP_BUF_SIZE 1024 // enough to parse any parameter sets or slice headers
#define INIT_SLICE_LIST_NUM 16 // initial slice information/parameter struct list size
+#define INIT_SEI_MESSAGE_COUNT 16 // initial SEI message count
+#define INIT_SEI_PAYLOAD_BUF_SIZE 1024 * 1024 // initial SEI payload buffer size, 1 MB
/**
* @brief Base class for video parsing
@@ -84,8 +86,8 @@ typedef struct {
class RocVideoParser {
public:
RocVideoParser(); // default constructor
+ virtual ~RocVideoParser();
RocVideoParser(RocdecParserParams *pParams) : parser_params_(*pParams) {};
- virtual ~RocVideoParser() = default ;
virtual void SetParserParams(RocdecParserParams *pParams) { parser_params_ = *pParams; };
RocdecParserParams *GetParserParams() {return &parser_params_;};
virtual rocDecStatus Initialize(RocdecParserParams *pParams);
@@ -152,6 +154,13 @@ protected:
* \return Returns the size of the converted buffer in size_t
*/
size_t EbspToRbsp(uint8_t *stream_buffer, size_t begin_bytepos, size_t end_bytepos);
+
+ /*! \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);
};
// helpers