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]
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <memory>
|
||||
#include <string>
|
||||
#include "roc_bitstream_reader.h"
|
||||
#include "es_reader.h"
|
||||
|
||||
class RocBitstreamReaderHandle {
|
||||
public:
|
||||
explicit RocBitstreamReaderHandle(const char *input_file_path) : bs_reader_(std::make_shared<RocVideoESParser>(input_file_path)) {};
|
||||
~RocBitstreamReaderHandle() { ClearErrors(); }
|
||||
bool NoError() { return error_.empty(); }
|
||||
const char* ErrorMsg() { return error_.c_str(); }
|
||||
void CaptureError(const std::string& err_msg) { error_ = err_msg; }
|
||||
rocDecStatus GetBitstreamCodecType(rocDecVideoCodec *codec_type) { *codec_type = bs_reader_->GetCodecId(); return ROCDEC_SUCCESS; }
|
||||
rocDecStatus GetBitstreamBitDepth(int *bit_depth) { *bit_depth = bs_reader_->GetBitDepth(); return ROCDEC_SUCCESS; }
|
||||
rocDecStatus GetBitstreamPicData(uint8_t **pic_data, int *pic_size, int64_t *pts) { return static_cast<rocDecStatus>(bs_reader_->GetPicData(pic_data, pic_size, pts)); }
|
||||
|
||||
private:
|
||||
std::shared_ptr<RocVideoESParser> bs_reader_ = nullptr;
|
||||
void ClearErrors() { error_ = ""; }
|
||||
|
||||
std::string error_;
|
||||
};
|
||||
تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
Diff را بارگزاری کن
@@ -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);
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "../commons.h"
|
||||
#include "bs_reader_handle.h"
|
||||
|
||||
rocDecStatus ROCDECAPI rocDecCreateBitstreamReader(RocdecBitstreamReader *bs_reader_handle, const char *input_file_path) {
|
||||
if (bs_reader_handle == nullptr || input_file_path == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
RocdecBitstreamReader handle = nullptr;
|
||||
try {
|
||||
handle = new RocBitstreamReaderHandle(input_file_path);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
ERR( STR("Failed to create RocBitstreamReader handle, ") + STR(e.what()))
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
*bs_reader_handle = handle;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus ROCDECAPI rocDecGetBitstreamCodecType(RocdecBitstreamReader bs_reader_handle, rocDecVideoCodec *codec_type) {
|
||||
if (bs_reader_handle == nullptr || codec_type == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
auto roc_bs_reader_handle = static_cast<RocBitstreamReaderHandle*>(bs_reader_handle);
|
||||
rocDecStatus ret;
|
||||
try {
|
||||
ret = roc_bs_reader_handle->GetBitstreamCodecType(codec_type);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
roc_bs_reader_handle->CaptureError(e.what());
|
||||
ERR(e.what())
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rocDecStatus ROCDECAPI rocDecGetBitstreamBitDepth(RocdecBitstreamReader bs_reader_handle, int *bit_depth) {
|
||||
if (bs_reader_handle == nullptr || bit_depth == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
auto roc_bs_reader_handle = static_cast<RocBitstreamReaderHandle*>(bs_reader_handle);
|
||||
rocDecStatus ret;
|
||||
try {
|
||||
ret = roc_bs_reader_handle->GetBitstreamBitDepth(bit_depth);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
roc_bs_reader_handle->CaptureError(e.what());
|
||||
ERR(e.what())
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rocDecStatus ROCDECAPI rocDecGetBitstreamPicData(RocdecBitstreamReader bs_reader_handle, uint8_t **pic_data, int *pic_size, int64_t *pts) {
|
||||
if (bs_reader_handle == nullptr || pic_data == nullptr || pic_size == nullptr || pts == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
auto roc_bs_reader_handle = static_cast<RocBitstreamReaderHandle*>(bs_reader_handle);
|
||||
rocDecStatus ret;
|
||||
try {
|
||||
ret = roc_bs_reader_handle->GetBitstreamPicData(pic_data, pic_size, pts);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
roc_bs_reader_handle->CaptureError(e.what());
|
||||
ERR(e.what())
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
rocDecStatus ROCDECAPI rocDecDestroyBitstreamReader(RocdecBitstreamReader bs_reader_handle) {
|
||||
if (bs_reader_handle == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
auto roc_bs_reader_handle = static_cast<RocBitstreamReaderHandle*>(bs_reader_handle);
|
||||
delete roc_bs_reader_handle;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
مرجع در شماره جدید
Block a user