Added the bit stream reader feature. (#433)
* * rocDecode/ES parser: Added elementary stream file parser for HEVC and AVC.
* * rocDecode/ES parser: Added elementary stream file parser for AV1. Also cleaned up the bitstream ring buffer code.
* * rocDecode/ES parser: Added the IVF container file parser for AV1. Also fixed a bug in fill ring buffer function.
* * rocDecode/ES file parder: Added supported stream type detection.
- The stream type detection checks the unique syntax patterns of the stream type and calculate the likeliheed score. Based on the score, the most likely type is determined.
- The current supported stream types are: AVC/HEVC/AV1 elementary streams, IVF AV1 streams.
* * rocDecode/ES file parser: Fixed an AVC decode regression due to a copy and paste error.
* * rocDecode/ES file parser: Added bit depth parsing for codec support check; Added stronger AV1 detection for IVF AV1 stream type.
* * rocDecode/ES file parser: Removed debugging logs.
* * rocDecode/ES file parser: Added exmaple code to use the built-in file parser.
* * rocDecode/Bitstream reader: Renamed the elementary parser feature to bitstream reader and re-organized the code.
- Moved the bitstream reader code to rocDecode core lib from utility.
- Added bitstream reader interface in parallel with rocDecode parser and decoder interfaces.
* * rocDecode/Bitstream reader: Added sample to use bitstream reader, instead of FFMPEG demuxer, to get picture data. Also reverted the original sample app back to using FFMPEG demuxer only.
* * rocDecode/Bitstream reader: Renamed the new sample app.
* * rocDecode/Bitstream reader: FFMPEG dependency reduction.
- Moved MD5 functions out of RocVideoDecoder utility class. This removed RocVideoDecoder's dependency on FFMPEG.
- Added the new MD5 utility, which depends on FFMPEG lib. MD5 message digest generation is now performed in the MD5 utility.
- Modified decode sampples that uses MD5 generation function.
- Removed FFMPEG dependency from video decoder basic sample.
* * rocDecode/Bitstream reader: Added option to use bitstream reader to video decode sample and conformance test script. Added the missing destroy bitstream reader call in video decode basic sample.
* * rocDecode/Bitstream reader: Minor format change. No functional changes.
* * rocDecode/Bitstream reader: Added handling of unsupported stream file type by the bitstream reader to decode sample apps.
* * rocDecode/Bitstream reader: Fixed build errors of several samples.
* * rocDecode/Bitstream reader: Added changes based on review comments.
* * rocDecode/Bitstream reader: File name changes based on review comments.
* * rocDecode/Bitstream reader: Moved MD5 code into single header file. Added changes based on review comments.
* * rocDecode/Bitstream reader: Removed redundant path.
* * rocDecode/Bitstream reader: Changed rocDecode version to 0.10.0. Added minor changes based on review comments.
---------
Co-authored-by: Kiriti Gowda <kiritigowda@gmail.com>
[ROCm/rocdecode commit: e62aa3e09b]
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
fb82691ef2
Коммит
c8a16141e4
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "rocdecode.h"
|
||||
|
||||
#define BS_RING_SIZE (16 * 1024 * 1024)
|
||||
#define INIT_PIC_DATA_SIZE (2 * 1024 * 1024)
|
||||
|
||||
enum {
|
||||
kStreamTypeUnsupported = -1,
|
||||
kStreamTypeAvcElementary = 0,
|
||||
kStreamTypeHevcElementary,
|
||||
kStreamTypeAv1Elementary,
|
||||
kStreamTypeAv1Ivf,
|
||||
kStreamTypeNumSupported
|
||||
} StreamFileType;
|
||||
|
||||
#define STREAM_PROBE_SIZE 2 * 1024
|
||||
#define STREAM_TYPE_SCORE_THRESHOLD 50
|
||||
|
||||
class RocVideoESParser {
|
||||
public:
|
||||
RocVideoESParser(const char *input_file_path);
|
||||
RocVideoESParser();
|
||||
~RocVideoESParser();
|
||||
|
||||
/*! \brief Function to probe the bitstream file and try to get the codec id
|
||||
* \retrun Codec id
|
||||
*/
|
||||
rocDecVideoCodec GetCodecId();
|
||||
|
||||
/*! \brief Function to retrieve the bitstream of a picture
|
||||
* \param [out] p_pic_data Pointer to the picture data
|
||||
* \param [out] pic_size Size of the picture in bytes
|
||||
* \param [out] pts Presentation time stamp
|
||||
*/
|
||||
int GetPicData(uint8_t **p_pic_data, int *pic_size, int64_t *pts);
|
||||
|
||||
/*! \brief Function to return the bit depth of the stream
|
||||
*/
|
||||
int GetBitDepth() {return bit_depth_;};
|
||||
|
||||
private:
|
||||
std::ifstream p_stream_file_;
|
||||
int stream_type_;
|
||||
int bit_depth_;
|
||||
|
||||
// Bitstream ring buffer
|
||||
uint8_t bs_ring_[BS_RING_SIZE];
|
||||
uint32_t read_ptr_; /// start position of unprocessed stream in the ring
|
||||
uint32_t write_ptr_; /// end position of unprocessed stream in the ring
|
||||
bool end_of_file_;
|
||||
bool end_of_stream_;
|
||||
int curr_byte_offset_;
|
||||
// AVC/HEVC
|
||||
int num_start_code_;
|
||||
int curr_start_code_offset_;
|
||||
int next_start_code_offset_;
|
||||
//int nal_unit_size_;
|
||||
// AV1
|
||||
int obu_byte_offset_; // header offset
|
||||
int obu_size_; // including header
|
||||
int num_td_obus_; // number of temporal delimiter OBUs
|
||||
|
||||
// Picture data (linear buffer)
|
||||
std::vector<uint8_t> pic_data_;
|
||||
int pic_data_size_;
|
||||
// AVC/HEVC
|
||||
int curr_pic_end_;
|
||||
int next_pic_start_;
|
||||
int num_pictures_;
|
||||
// AV1
|
||||
int num_temp_units_; // number of temporal units
|
||||
|
||||
bool ivf_file_header_read_; // indicator if IVF file header has been checked
|
||||
|
||||
/*! \brief Function to retrieve the bitstream of a picture for AVC/HEVC
|
||||
* \param [out] p_pic_data Pointer to the picture data
|
||||
* \param [out] pic_size Size of the picture in bytes
|
||||
*/
|
||||
int GetPicDataAvcHevc(uint8_t **p_pic_data, int *pic_size);
|
||||
|
||||
/*! \brief Function to retrieve the bitstream of a temporal unit for AV1
|
||||
* \param [out] p_pic_data Pointer to the picture data
|
||||
* \param [out] pic_size Size of the picture in bytes
|
||||
*/
|
||||
int GetPicDataAv1(uint8_t **p_pic_data, int *pic_size);
|
||||
|
||||
/*! \brief Function to retrieve the bitstream of a temporal unit for AV1 from IVF container
|
||||
* \param [out] p_pic_data Pointer to the picture data
|
||||
* \param [out] pic_size Size of the picture in bytes
|
||||
*/
|
||||
int GetPicDataIvfAv1(uint8_t **p_pic_data, int *pic_size);
|
||||
|
||||
/*! \brief Function to read bitstream from file and fill into the ring buffer.
|
||||
* \return Number of bytes read from file.
|
||||
*/
|
||||
int FetchBitStream();
|
||||
|
||||
/*! \brief Function to check the remaining data size in the ring buffer
|
||||
* \return Number of bytes still available in the ring
|
||||
*/
|
||||
int GetDataSizeInRB();
|
||||
|
||||
/*! \brief Function to read one byte from the ring buffer without advancing the read pointer
|
||||
* \param [in] offset The byte offset to read
|
||||
* \param [out] data The byte read
|
||||
* \return True: success; False: no more byte available.
|
||||
*/
|
||||
bool GetByte(int offset, uint8_t *data);
|
||||
|
||||
/*! \brief Function to read the specified bytes from the ring buffer without advancing the read pointer
|
||||
* \param [in] offset The starting byte offset to read
|
||||
* \param [in] size The numbers of bytes to read
|
||||
* \param [out] data The bytes read
|
||||
* \return True: success; False: can not read the set bytes
|
||||
*/
|
||||
bool ReadBytes(int offset, int size, uint8_t *data);
|
||||
|
||||
/*! \brief Function to update the read pointer by the set bytes
|
||||
* \param [in] value The new read pointer value
|
||||
*/
|
||||
void SetReadPointer(int value);
|
||||
|
||||
/*! \brief Function to find the start codes from the ring buffer to locate the NAL units
|
||||
* \return Returns: true: a new start code is found or end of stream reached; false: no start code found.
|
||||
*/
|
||||
bool FindStartCode();
|
||||
|
||||
/*! \brief Function to check if an HEVC NAL is the (first) slice of a picture
|
||||
* \param [in] start_code_offset Start code location of the NAL unit
|
||||
* \param [out] slice_flag Slice NAL unit indicator
|
||||
* \param [out] first_slice_flag First slice indicator
|
||||
*/
|
||||
void CheckHevcNalForSlice(int start_code_offset, int *slice_flag, int *first_slice_flag);
|
||||
|
||||
/*! \brief Function to check if an AVC NAL is the (first) slice of a picture
|
||||
* \param [in] start_code_offset Start code location of the NAL unit
|
||||
* \param [out] slice_flag Slice NAL unit indicator
|
||||
* \param [out] first_slice_flag First slice indicator
|
||||
*/
|
||||
void CheckAvcNalForSlice(int start_code_offset, int *slice_flag, int *first_slice_flag);
|
||||
|
||||
/*! \brief Function to copy a NAL unit from the bitstream ring buffer to the linear picture data buffer
|
||||
*/
|
||||
void CopyNalUnitFromRing();
|
||||
|
||||
/*! \brief Function to parse an OBU header and size
|
||||
* \param [out] obu_type Pointer to the returned OBU type
|
||||
* \return true if success
|
||||
*/
|
||||
bool ReadObuHeaderAndSize(int *obu_type);
|
||||
|
||||
/*! \brief Function to copy an OBU from the bitstream ring buffer to the linear picture data buffer
|
||||
* \return true if success
|
||||
*/
|
||||
bool CopyObuFromRing();
|
||||
|
||||
/*! \brief Function to check the 32 byte stream for IVF file header identity
|
||||
* \return true if IVF file header is identified; false: otherwise
|
||||
*/
|
||||
bool CheckIvfFileHeader(uint8_t *stream);
|
||||
|
||||
/*! \brief Function to probe the bitstream file and try to find if it is one of types supported.
|
||||
* \return Elementary stream file type
|
||||
*/
|
||||
int ProbeStreamType();
|
||||
|
||||
/*! \brief Function to check the likelihood of a stream to be an AVC elementary stream.
|
||||
* \param [in] p_stream Pointer to the stream
|
||||
* \param [in] stream_size Size of the stream in bytes
|
||||
* \return The likelihood score
|
||||
*/
|
||||
int CheckAvcEStream(uint8_t *p_stream, int stream_size);
|
||||
|
||||
/*! \brief Function to check the likelihood of a stream to be an HEVC elementary stream.
|
||||
* \param [in] p_stream Pointer to the stream
|
||||
* \param [in] stream_size Size of the stream in bytes
|
||||
* \return The likelihood score
|
||||
*/
|
||||
int CheckHevcEStream(uint8_t *p_stream, int stream_size);
|
||||
|
||||
/*! \brief Function to convert from Encapsulated Byte Sequence Packets to Raw Byte Sequence Payload
|
||||
* \param [inout] stream_buffer A pointer of <tt>uint8_t</tt> for the converted RBSP buffer.
|
||||
* \param [in] begin_bytepos Start position in the EBSP buffer to convert
|
||||
* \param [in] end_bytepos End position in the EBSP buffer to convert, generally it's size.
|
||||
* \return Returns the size of the converted buffer
|
||||
*/
|
||||
int EbspToRbsp(uint8_t *stream_buffer, int begin_bytepos, int end_bytepos);
|
||||
|
||||
/*! \brief Function to check the likelihood of a stream to be an AV1 elementary stream.
|
||||
* \param [in] p_stream Pointer to the stream
|
||||
* \param [in] stream_size Size of the stream in bytes
|
||||
* \return The likelihood score
|
||||
*/
|
||||
int CheckAv1EStream(uint8_t *p_stream, int stream_size);
|
||||
|
||||
/*! \brief Function to check the likelihood of a stream to be an IVF container of AV1 elementary stream.
|
||||
* \param [in] p_stream Pointer to the stream
|
||||
* \param [in] stream_size Size of the stream in bytes
|
||||
* \return The likelihood score
|
||||
*/
|
||||
int CheckIvfAv1Stream(uint8_t *p_stream, int stream_size);
|
||||
|
||||
/*! \brief Function to read variable length unsigned n-bit number appearing directly in the bitstream. 4.10.3. uvlc().
|
||||
* \param [in] p_stream Bit stream pointer
|
||||
* \param [in] bit_offset Starting bit offset
|
||||
* \param [out] bit_offset Updated bit offset
|
||||
* \return The unsigned value
|
||||
*/
|
||||
uint32_t ReadUVLC(const uint8_t *p_stream, size_t &bit_offset);
|
||||
};
|
||||
Ссылка в новой задаче
Block a user