* * rocDecode/AVC: Added initial AVC parser.
 - Added AVC SPS, PPS and slice header parsing functions.
 - Merged common parsing code from AVC and HEVC parsers to their super class.

* * rocDecode/AVC: Formating changes. No functional changes.
Этот коммит содержится в:
jeffqjiangNew
2024-01-16 20:57:40 -05:00
коммит произвёл GitHub
родитель 2e2f1e3f21
Коммит 395a1249c1
12 изменённых файлов: 1966 добавлений и 345 удалений
+334
Просмотреть файл
@@ -0,0 +1,334 @@
/*
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 <stdint.h>
#define AVC_MAX_SPS_NUM 32
#define AVC_MAX_PPS_NUM 256
#define AVC_MAX_SLICE_NUM 256
#define AVC_MAX_CPB_COUNT 32
#define AVC_MAX_NUM_SLICE_GROUPS_MINUS 8
#define AVC_MAX_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE 256
#define AVC_MAX_REF_FRAME_NUM 16
#define AVC_MAX_REF_PICTURE_NUM 32
#define AVC_MAX_DPB_FRAMES 16
#define AVC_MACRO_BLOCK_SIZE 16
// AVC spec. Table 7-1 – NAL unit type codes, syntax element categories, and NAL unit type classes.
enum AvcNalUnitType {
kAvcNalTypeUnspecified = 0,
kAvcNalTypeSlice_Non_IDR = 1,
kAvcNalTypeSlice_Data_Partition_A = 2,
kAvcNalTypeSlice_Data_Partition_B = 3,
kAvcNalTypeSlice_Data_Partition_C = 4,
kAvcNalTypeSlice_IDR = 5,
kAvcNalTypeSEI_Info = 6,
kAvcNalTypeSeq_Parameter_Set = 7,
kAvcNalTypePic_Parameter_Set = 8,
kAvcNalTypeAccess_Unit_Delimiter = 9,
kAvcNalTypeEnd_Of_Seq = 10,
kAvcNalTypeEnd_Of_Stream = 11,
kAvcNalTypeFiller_Data = 12,
kAvcNalTypeSeq_Parameter_Set_Ext = 13,
kAvcNalTypePrefix_NAL_Unit = 14,
kAvcNalTypeSubset_Seq_Parameter_Set = 15,
kAvcNalTypeDepth_Parameter_Set = 16,
};
// AVC spec. Table 7-6 – Name association to slice_type.
enum AvcSliceType {
kAvcSliceTypeP = 0,
kAvcSliceTypeB = 1,
kAvcSliceTypeI = 2,
kAvcSliceTypeSP = 3,
kAvcSliceTypeSI = 4,
kAvcSliceTypeP_5 = 5,
kAvcSliceTypeB_6 = 6,
kAvcSliceTypeI_7 = 7,
kAvcSliceTypeSP_8 = 8,
kAvcSliceTypeSI_9 = 9
};
// AVC spec. Annex A.2.
enum AvcProfile {
kAvcBaselineProfile = 66,
kAvcMainProfile = 77,
kAvcExtendedProfile = 88,
kAvcHighProfile = 100,
kAvcHigh10Profile = 110,
kAvcHigh422Profile = 122,
kAvcHigh444Profile = 144
};
// AVC spec. Annex A.3.
enum AvcLevel {
kAvcLevel1 = 10,
kAvcLevel1_1 = 11,
kAvcLevel1_2 = 12,
kAvcLevel1_3 = 13,
kAvcLevel2 = 20,
kAvcLevel2_1 = 21,
kAvcLevel2_2 = 22,
kAvcLevel3 = 30,
kAvcLevel3_1 = 31,
kAvcLevel3_2 = 32,
kAvcLevel4 = 40,
kAvcLevel4_1 = 41,
kAvcLevel4_2 = 42,
kAvcLevel5 = 50,
kAvcLevel5_1 = 51,
kAvcLevel5_2 = 52,
kAvcLevel6 = 60,
kAvcLevel6_1 = 61,
kAvcLevel6_2 = 62
};
// NAL unit header syntax. AVC spec. Section 7.3.1.
typedef struct {
uint32_t forbidden_zero_bit; // f(1)
uint32_t nal_ref_idc; // u(2)
uint32_t nal_unit_type; // u(5)
} AvcNalUnitHeader;
// HRD parameters syntax. AVC spec. Section E.1.2.
typedef struct {
uint32_t cpb_cnt_minus1; // ue(v)
uint32_t bit_rate_scale; // u(4)
uint32_t cpb_size_scale; // u(4)
uint32_t bit_rate_value_minus1[AVC_MAX_CPB_COUNT]; // ue(v)
uint32_t cpb_size_value_minus1[AVC_MAX_CPB_COUNT]; // ue(v)
uint32_t cbr_flag[AVC_MAX_CPB_COUNT]; // u(1)
uint32_t initial_cpb_removal_delay_length_minus1; // u(5)
uint32_t cpb_removal_delay_length_minus1; // u(5
uint32_t dpb_output_delay_length_minus1; // u(5)
uint32_t time_offset_length; // u(5)
} AvcHrdParameters;
// VUI parameters syntax. AVC spec. Section E.1.1.
typedef struct {
uint32_t aspect_ratio_info_present_flag; // u(1)
uint32_t aspect_ratio_idc; // u(8)
uint32_t sar_width; // u(16)
uint32_t sar_height; // u(16)
uint32_t overscan_info_present_flag; // u(1)
uint32_t overscan_appropriate_flag; // u(1)
uint32_t video_signal_type_present_flag; // u(1)
uint32_t video_format; // u(3)
uint32_t video_full_range_flag; // u(1)
uint32_t colour_description_present_flag; // u(1)
uint32_t colour_primaries; // u(8)
uint32_t transfer_characteristics; // u(8)
uint32_t matrix_coefficients; // u(8)
uint32_t chroma_loc_info_present_flag; // u(1)
uint32_t chroma_sample_loc_type_top_field; // ue(v)
uint32_t chroma_sample_loc_type_bottom_field; // ue(v)
uint32_t timing_info_present_flag; // u(1)
uint32_t num_units_in_tick; // u(32)
uint32_t time_scale; // u(32)
uint32_t fixed_frame_rate_flag; // u(1)
uint32_t nal_hrd_parameters_present_flag; // u(1)
AvcHrdParameters nal_hrd_parameters; // hrd_paramters()
uint32_t vcl_hrd_parameters_present_flag; // u(1)
AvcHrdParameters vcl_hrd_parameters; // hrd_paramters()
uint32_t low_delay_hrd_flag; // u(1)
uint32_t pic_struct_present_flag; // u(1)
uint32_t bitstream_restriction_flag; // u(1)
uint32_t motion_vectors_over_pic_boundaries_flag; // u(1)
uint32_t max_bytes_per_pic_denom; // ue(v)
uint32_t max_bits_per_mb_denom; // ue(v)
uint32_t log2_max_mv_length_vertical; // ue(v)
uint32_t log2_max_mv_length_horizontal; // ue(v)
uint32_t num_reorder_frames; // ue(v)
uint32_t max_dec_frame_buffering; // ue(v)
} AvcVuiSeqParameters;
// Sequence parameter set data syntax. AVC spec. 7.3.2.1.1.
typedef struct {
uint32_t is_received; // received with seq_parameter_set_id
uint32_t profile_idc; // u(8)
uint32_t constraint_set0_flag; // u(1)
uint32_t constraint_set1_flag; // u(1)
uint32_t constraint_set2_flag; // u(1)
uint32_t constraint_set3_flag; // u(1)
uint32_t constraint_set4_flag; // u(1)
uint32_t constraint_set5_flag; // u(1)
uint32_t reserved_zero_2bits; // u(2)
uint32_t level_idc; // u(8)
uint32_t seq_parameter_set_id; // ue(v)
uint32_t chroma_format_idc; // ue(v)
uint32_t separate_colour_plane_flag; // u(1)
uint32_t bit_depth_luma_minus8; // ue(v)
uint32_t bit_depth_chroma_minus8; // ue(v)
uint32_t qpprime_y_zero_transform_bypass_flag; // u(1)
uint32_t seq_scaling_matrix_present_flag; // u(1)
uint32_t seq_scaling_list_present_flag[12]; // u(1)
uint32_t scaling_list_4x4[6][16]; // ScalingList4x4
uint32_t scaling_list_8x8[6][64]; // ScalingList8x8
uint32_t use_default_scaling_matrix_4x4_flag[6]; // UseDefaultScalingMatrix4x4Flag
uint32_t use_default_scaling_matrix_8x8_flag[6]; // UseDefaultScalingMatrix8x8Flag
uint32_t log2_max_frame_num_minus4; // ue(v)
uint32_t pic_order_cnt_type; // ue(v)
uint32_t log2_max_pic_order_cnt_lsb_minus4; // ue(v)
uint32_t delta_pic_order_always_zero_flag; // u(1)
int32_t offset_for_non_ref_pic; // se(v)
int32_t offset_for_top_to_bottom_field; // se(v)
uint32_t num_ref_frames_in_pic_order_cnt_cycle; // ue(v)
int32_t offset_for_ref_frame[AVC_MAX_NUM_REF_FRAMES_IN_PIC_ORDER_CNT_CYCLE]; // se(v)
uint32_t max_num_ref_frames; // ue(v)
uint32_t gaps_in_frame_num_value_allowed_flag; // u(1)
uint32_t pic_width_in_mbs_minus1; // ue(v)
uint32_t pic_height_in_map_units_minus1; // ue(v)
uint32_t frame_mbs_only_flag; // u(1)
uint32_t mb_adaptive_frame_field_flag; // u(1)
uint32_t direct_8x8_inference_flag; // u(1)
uint32_t frame_cropping_flag; // u(1)
uint32_t frame_crop_left_offset; // ue(v)
uint32_t frame_crop_right_offset; // ue(v)
uint32_t frame_crop_top_offset; // ue(v)
uint32_t frame_crop_bottom_offset; // ue(v)
uint32_t vui_parameters_present_flag; // u(1)
AvcVuiSeqParameters vui_seq_parameters; // vui_parameters()
} AvcSeqParameterSet;
// Picture parameter set RBSP syntax. AVC Spec. 7.3.2.2.
typedef struct {
uint32_t is_received; // is received with pic_parameter_set_id
uint32_t pic_parameter_set_id; // ue(v)
uint32_t seq_parameter_set_id; // ue(v)
uint32_t entropy_coding_mode_flag; // u(1)
uint32_t bottom_field_pic_order_in_frame_present_flag; // u(1)
uint32_t num_slice_groups_minus1; // ue(v)
uint32_t slice_group_map_type; // ue(v)
uint32_t run_length_minus1[AVC_MAX_NUM_SLICE_GROUPS_MINUS]; // ue(v)
uint32_t top_left[AVC_MAX_NUM_SLICE_GROUPS_MINUS]; // ue(v)
uint32_t bottom_right[AVC_MAX_NUM_SLICE_GROUPS_MINUS]; // ue(v)
uint32_t slice_group_change_direction_flag; // u(1)
uint32_t slice_group_change_rate_minus1; // ue(v)
uint32_t pic_size_in_map_units_minus1; // ue(v)
uint32_t *slice_group_id; // complete MBAmap u(v)
uint32_t num_ref_idx_l0_default_active_minus1; // ue(v)
uint32_t num_ref_idx_l1_default_active_minus1; // ue(v)
uint32_t weighted_pred_flag; // u(1)
uint32_t weighted_bipred_idc; // u(2)
int32_t pic_init_qp_minus26; // se(v)
int32_t pic_init_qs_minus26; // se(v)
int32_t chroma_qp_index_offset; // se(v)
uint32_t deblocking_filter_control_present_flag; // u(1)
uint32_t constrained_intra_pred_flag; // u(1)
uint32_t redundant_pic_cnt_present_flag; // u(1)
uint32_t transform_8x8_mode_flag; // u(1)
uint32_t pic_scaling_matrix_present_flag; // u(1)
uint32_t pic_scaling_list_present_flag[12]; // u(1)
uint32_t scaling_list_4x4[6][16]; // ScalingList4x4
uint32_t scaling_list_8x8[6][64]; // ScalingList8x8
uint32_t use_default_scaling_matrix_4x4_flag[6]; // UseDefaultScalingMatrix4x4Flag
uint32_t use_default_scaling_matrix_8x8_flag[6]; // UseDefaultScalingMatrix8x8Flag
int32_t second_chroma_qp_index_offset; // se(v)
} AvcPicParameterSet;
// Reference picture list modification syntax. AVC spec. 7.3.3.1.
typedef struct {
uint32_t modification_of_pic_nums_idc; // ue(v)
uint32_t abs_diff_pic_num_minus1; // ue(v)
uint32_t long_term_pic_num; // ue(v)
} AvcListMod;
typedef struct {
uint32_t ref_pic_list_modification_flag_l0; // u(1)
AvcListMod modification_l0[AVC_MAX_REF_PICTURE_NUM];
uint32_t ref_pic_list_modification_flag_l1; // u(1)
AvcListMod modification_l1[AVC_MAX_REF_PICTURE_NUM];
} AvcRefPicListMod;
// Prediction weight table syntax. AVC spec. 7.3.3.2.
typedef struct {
uint32_t luma_weight_l0_flag; // u(1)
int32_t luma_weight_l0; // se(v)
int32_t luma_offset_l0; // se(v)
uint32_t chroma_weight_l0_flag; // u(1)
int32_t chroma_weight_l0[2]; // se(v)
int32_t chroma_offset_l0[2]; // se(v)
uint32_t luma_weight_l1_flag; // u(1)
int32_t luma_weight_l1; // se(v)
int32_t luma_offset_l1; // se(v)
uint32_t chroma_weight_l1_flag; // u(1)
int32_t chroma_weight_l1[2]; // se(v)
int32_t chroma_offset_l1[2]; // se(v)
} AvcWeightFactor;
typedef struct {
uint32_t luma_log2_weight_denom; // ue(v)
uint32_t chroma_log2_weight_denom; // ue(v)
AvcWeightFactor weight_factor[AVC_MAX_REF_PICTURE_NUM];
} AvcPredWeightTable;
// Decoded reference picture marking syntax. AVC spec. 7.3.3.3.
typedef struct {
uint32_t memory_management_control_operation; // ue(v)
uint32_t difference_of_pic_nums_minus1; // ue(v)
uint32_t long_term_pic_num; // ue(v)
uint32_t long_term_frame_idx; // ue(v)
uint32_t max_long_term_frame_idx_plus1; // ue(v)
} AvcMmco;
typedef struct {
uint32_t no_output_of_prior_pics_flag; // u(1)
uint32_t long_term_reference_flag; // u(1)
uint32_t adaptive_ref_pic_marking_mode_flag; // u(1)
AvcMmco mmco[AVC_MAX_REF_PICTURE_NUM];
uint32_t mmco_count;
} AvcDecRefPicMarking;
// Slice header syntax. AVC Spec. 7.3.3.
typedef struct {
uint32_t first_mb_in_slice; // ue(v)
uint32_t slice_type; // ue(v)
uint32_t pic_parameter_set_id; // ue(v)
uint32_t colour_plane_id; // u(2)
uint32_t frame_num; // u(v)
uint32_t field_pic_flag; // u(1)
uint32_t bottom_field_flag; // u(1)
uint32_t idr_pic_id; // ue(v)
uint32_t pic_order_cnt_lsb; // u(v)
int32_t delta_pic_order_cnt_bottom; // se(v)
int32_t delta_pic_order_cnt[2]; // se(v)
uint32_t redundant_pic_cnt; // ue(v)
uint32_t direct_spatial_mv_pred_flag; // u(1)
uint32_t num_ref_idx_active_override_flag; // u(1)
uint32_t num_ref_idx_l0_active_minus1; // ue(v)
uint32_t num_ref_idx_l1_active_minus1; // ue(v)
AvcRefPicListMod ref_pic_list;
AvcPredWeightTable pred_weight_table;
AvcDecRefPicMarking dec_ref_pic_marking;
uint32_t cabac_init_idc; // ue(v)
int32_t slice_qp_delta; // se(v)
uint32_t sp_for_switch_flag; // u(1)
int32_t slice_qs_delta; // se(v)
uint32_t disable_deblocking_filter_idc; // ue(v)
int32_t slice_alpha_c0_offset_div2; // se(v)
int32_t slice_beta_offset_div2; // se(v)
uint32_t slice_group_change_cycle; // u(v)
} AvcSliceHeader;
Разница между файлами не показана из-за своего большого размера Загрузить разницу
+153
Просмотреть файл
@@ -0,0 +1,153 @@
/*
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 "avc_defines.h"
#include "roc_video_parser.h"
class AvcVideoParser : public RocVideoParser {
public:
/*! \brief AvcVideoParser constructor
*/
AvcVideoParser();
/*! \brief AvcVideoParser destructor
*/
virtual ~AvcVideoParser();
/*! \brief Function to Initialize the parser
* \param [in] p_params Input of <tt>RocdecParserParams</tt> with codec type to initialize parser.
* \return <tt>rocDecStatus</tt> Returns success on completion, else error code for failure
*/
virtual rocDecStatus Initialize(RocdecParserParams *p_params);
/*! \brief Function to Parse video data: Typically called from application when a demuxed picture is ready to be parsed
* \param [in] p_data Pointer to picture data of type <tt>RocdecSourceDataPacket</tt>
* @return <tt>rocDecStatus</tt> Returns success on completion, else error_code for failure
*/
virtual rocDecStatus ParseVideoData(RocdecSourceDataPacket *p_data);
/*! \brief function to uninitialize AVC parser
* @return rocDecStatus
*/
virtual rocDecStatus UnInitialize(); // derived method
protected:
/*! \brief Decoded picture buffer
*/
typedef struct{
uint32_t dpb_size; // DPB buffer size in number of frames
} DecodedPictureBuffer;
AvcNalUnitHeader nal_unit_header_;
AvcSeqParameterSet sps_list_[AVC_MAX_SPS_NUM];
int32_t active_sps_id_;
AvcPicParameterSet pps_list_[AVC_MAX_PPS_NUM];
int32_t active_pps_id_;
AvcNalUnitHeader slice_nal_unit_header_;
AvcSliceHeader slice_header_0_;
int prev_has_mmco_5_;
int curr_has_mmco_5_;
int prev_ref_pic_bottom_field_;
int curr_ref_pic_bottom_field_;
// DPB
DecodedPictureBuffer dpb_buffer_;
/*! \brief Function to parse one picture bit stream received from the demuxer.
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] pic_data_size Size of the input stream
* \return <tt>ParserResult</tt>
*/
ParserResult ParsePictureData(const uint8_t *p_stream, uint32_t pic_data_size);
/*! \brief Function to parse the NAL unit header
* \param [in] header_byte The AVC NAL unit header byte
* \return <tt>AvcNalUnitHeader</tt> Parsed nal header
*/
AvcNalUnitHeader ParseNalUnitHeader(uint8_t header_byte);
/*! \brief Function to parse Sequence Parameter Set
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] size Size of the input stream
* \return No return value
*/
void ParseSps(uint8_t *p_stream, size_t size);
/*! \brief Function to parse Picture Parameter Set
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] size Size of the input stream
* \return No return value
*/
void ParsePps(uint8_t *p_stream, size_t stream_size_in_byte);
/*! \brief Function to parse slice header
* \param p_stream The pointer to the input bit stream
* \param [in] stream_size_in_byte The byte size of the stream
* \param [out] p_slice_header The pointer to the slice header strucutre
* \return <tt>ParserResult</tt>
*/
ParserResult ParseSliceHeader(uint8_t *p_stream, size_t stream_size_in_byte, AvcSliceHeader *p_slice_header);
/*! \brief Function to parse a scaling list
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in/out] offset Current bit offset
* \param [out] scaling_list Pointer to the output scaling list
* \param [in] list_size Scaling list size
* \param [out] use_default_scaling_matrix_flag Array of flags that indicate whether to use default values
*/
void GetScalingList(uint8_t *p_stream, size_t &offset, uint32_t *scaling_list, uint32_t list_size, uint32_t *use_default_scaling_matrix_flag);
/*! \brief Function to parse vidio usability information (VUI) parameters
* \param [in] p_stream The pointer to the input bit stream
* \param [in/out] offset Current bit offset
* \param [out] p_vui_params The pointer to VUI structure
* \return No return value
*/
void GetVuiParameters(uint8_t *p_stream, size_t &offset, AvcVuiSeqParameters *p_vui_params);
/*! \brief Function to check if there is more data in RBSP
* \param [in] p_stream The pointer to the input bit stream
* \param [in] stream_size_in_byte The byte size of the stream
* \param [in] bit_offset The current bit offset
* \return true/false
*/
bool MoreRbspData(uint8_t *p_stream, size_t stream_size_in_byte, size_t bit_offset);
#if DBGINFO
/*! \brief Function to log out parsed SPS content for debug.
*/
void PrintSps(AvcSeqParameterSet *p_sps);
/*! \brief Function to log out parsed PPS content for debug.
*/
void PrintPps(AvcPicParameterSet *p_pps);
/*! \brief Function to log out parsed slice header content for debug.
*/
void PrintSliceHeader(AvcSliceHeader *p_slice_header);
#endif // DBGINFO
};
-62
Просмотреть файл
@@ -1,62 +0,0 @@
/*
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 "h264_parser.h"
/**
* @brief Construct a new HEVCParser object
*
*/
H264VideoParser::H264VideoParser() {
}
/**
* @brief Function to initialize any h264 parser related members
*
* @return rocDecStatus
*/
rocDecStatus H264VideoParser::Initialize(RocdecParserParams *pParams) {
RocVideoParser::Initialize(pParams);
//todo::
return ROCDEC_NOT_IMPLEMENTED;
}
/**
* @brief Function to Parse video data: Typically called from application when a demuxed picture is ready to be parsed
*
* @param pData: IN: pointer to demuxed data packet
* @return rocDecStatus
*/
rocDecStatus H264VideoParser::ParseVideoData(RocdecSourceDataPacket *pData) {
return ROCDEC_NOT_IMPLEMENTED;
}
/**
* @brief function to uninitialize h264 parser
*
* @return rocDecStatus
*/
rocDecStatus H264VideoParser::UnInitialize() {
//todo::
return ROCDEC_NOT_IMPLEMENTED;
}
-58
Просмотреть файл
@@ -1,58 +0,0 @@
/*
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 "roc_video_parser.h"
class H264VideoParser : public RocVideoParser {
public:
/**
* @brief Construct a new HEVCParser object
*
*/
H264VideoParser();
/**
* @brief Derived Function to Initialize the parser
*
* @return rocDecStatus
*/
virtual rocDecStatus Initialize(RocdecParserParams *pParams);
/**
* @brief Function to Parse video data: Typically called from application when a demuxed picture is ready to be parsed
* @brief Derived from base class
*
* @param pData: Pointer to picture data
* @return rocDecStatus: returns success on completion, else error_code for failure
*/
virtual rocDecStatus ParseVideoData(RocdecSourceDataPacket *pData);
/**
* @brief function to uninitialize h264 parser
*
* @return rocDecStatus
*/
virtual rocDecStatus UnInitialize(); // derived method
private:
};
-1
Просмотреть файл
@@ -30,7 +30,6 @@ THE SOFTWARE.
#define HEVC_SCALING_LIST_NUM 6 ///< list number for quantization matrix
#define HEVC_SCALING_LIST_MAX_INDEX 64
#define RBSP_BUF_SIZE 1024 // enough to parse any parameter sets or slice headers
#define HEVC_MAX_DPB_FRAMES 16 // (A-2)
#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.
+28 -121
Просмотреть файл
@@ -36,12 +36,10 @@ inline T *AllocStruct(const int max_cnt) {
}
HevcVideoParser::HevcVideoParser() {
pic_count_ = 0;
first_pic_after_eos_nal_unit_ = 0;
m_active_vps_id_ = -1;
m_active_sps_id_ = -1;
m_active_pps_id_ = -1;
b_new_picture_ = false;
// allocate all fixed size structors here
m_vps_ = AllocStruct<HevcVideoParamSet>(MAX_VPS_COUNT);
m_sps_ = AllocStruct<HevcSeqParamSet>(MAX_SPS_COUNT);
@@ -60,11 +58,7 @@ HevcVideoParser::HevcVideoParser() {
}
rocDecStatus HevcVideoParser::Initialize(RocdecParserParams *p_params) {
ParserResult status = Init();
if (status)
return ROCDEC_RUNTIME_ERROR;
RocVideoParser::Initialize(p_params);
return ROCDEC_SUCCESS;
return RocVideoParser::Initialize(p_params);
}
/**
@@ -83,7 +77,7 @@ rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
// Clear DPB output/display buffer number
dpb_buffer_.num_output_pics = 0;
bool status = ParseFrameData(p_data->payload, p_data->payload_size);
bool status = ParsePictureData(p_data->payload, p_data->payload_size);
if (!status) {
ERR(STR("Parser failed!"));
return ROCDEC_RUNTIME_ERROR;
@@ -154,11 +148,6 @@ HevcVideoParser::~HevcVideoParser() {
}
}
ParserResult HevcVideoParser::Init() {
b_new_picture_ = false;
return PARSER_OK;
}
int HevcVideoParser::FillSeqCallbackFn(HevcSeqParamSet* sps_data) {
video_format_params_.codec = rocDecVideoCodec_HEVC;
video_format_params_.frame_rate.numerator = frame_rate_.numerator;
@@ -555,11 +544,11 @@ int HevcVideoParser::OutputDecodedPictures() {
return PARSER_OK;
}
bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_data_size) {
bool HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size) {
int ret = PARSER_OK;
frame_data_buffer_ptr_ = (uint8_t*)p_stream;
frame_data_size_ = frame_data_size;
pic_data_buffer_ptr_ = (uint8_t*)p_stream;
pic_data_size_ = pic_data_size;
curr_byte_offset_ = 0;
start_code_num_ = 0;
curr_start_code_offset_ = 0;
@@ -571,7 +560,6 @@ bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
do {
ret = GetNalUnit();
if (ret == PARSER_NOT_FOUND) {
ERR(STR("Error: no start code found in the frame data."));
return false;
@@ -582,26 +570,26 @@ bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
// start code + NAL unit header = 5 bytes
int ebsp_size = nal_unit_size_ - 5 > RBSP_BUF_SIZE ? RBSP_BUF_SIZE : nal_unit_size_ - 5; // only copy enough bytes for header parsing
nal_unit_header_ = ParseNalUnitHeader(&frame_data_buffer_ptr_[curr_start_code_offset_ + 3]);
nal_unit_header_ = ParseNalUnitHeader(&pic_data_buffer_ptr_[curr_start_code_offset_ + 3]);
switch (nal_unit_header_.nal_unit_type) {
case NAL_UNIT_VPS: {
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);
ParseVps(m_rbsp_buf_, m_rbsp_size_);
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
ParseVps(rbsp_buf_, rbsp_size_);
break;
}
case NAL_UNIT_SPS: {
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);
ParseSps(m_rbsp_buf_, m_rbsp_size_);
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
ParseSps(rbsp_buf_, rbsp_size_);
break;
}
case NAL_UNIT_PPS: {
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);
ParsePps(m_rbsp_buf_, m_rbsp_size_);
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
ParsePps(rbsp_buf_, rbsp_size_);
break;
}
@@ -621,20 +609,20 @@ bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
case NAL_UNIT_CODED_SLICE_RADL_R:
case NAL_UNIT_CODED_SLICE_RASL_N:
case NAL_UNIT_CODED_SLICE_RASL_R: {
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);
memcpy(rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), ebsp_size);
rbsp_size_ = EbspToRbsp(rbsp_buf_, 0, ebsp_size);
// For each picture, only parse the first slice header
if (slice_num_ == 0) {
// Save slice NAL unit header
slice_nal_unit_header_ = nal_unit_header_;
// Use the data directly from demuxer without copying
pic_stream_data_ptr_ = frame_data_buffer_ptr_ + curr_start_code_offset_;
pic_stream_data_ptr_ = pic_data_buffer_ptr_ + curr_start_code_offset_;
// Picture stream data size is calculated as the diff between the frame end and the first slice offset.
// This is to consider the possibility of non-slice NAL units between slices.
pic_stream_data_size_ = frame_data_size - curr_start_code_offset_;
pic_stream_data_size_ = pic_data_size - curr_start_code_offset_;
ParseSliceHeader(m_rbsp_buf_, m_rbsp_size_);
ParseSliceHeader(rbsp_buf_, rbsp_size_);
// Start decode process
if (IsIrapPic(&slice_nal_unit_header_)) {
@@ -694,9 +682,9 @@ bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
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_, (frame_data_buffer_ptr_ + curr_start_code_offset_ + 5), sei_ebsp_size);
m_rbsp_size_ = EBSPtoRBSP(sei_rbsp_buf_, 0, sei_ebsp_size);
ParseSeiMessage(sei_rbsp_buf_, m_rbsp_size_);
memcpy(sei_rbsp_buf_, (pic_data_buffer_ptr_ + curr_start_code_offset_ + 5), sei_ebsp_size);
rbsp_size_ = EbspToRbsp(sei_rbsp_buf_, 0, sei_ebsp_size);
ParseSeiMessage(sei_rbsp_buf_, rbsp_size_);
}
break;
}
@@ -725,47 +713,6 @@ bool HevcVideoParser::ParseFrameData(const uint8_t* p_stream, uint32_t frame_dat
return true;
}
int HevcVideoParser::GetNalUnit() {
bool start_code_found = false;
nal_unit_size_ = 0;
curr_start_code_offset_ = next_start_code_offset_; // save the current start code offset
// Search for the next start code
while (curr_byte_offset_ < frame_data_size_ - 2) {
if (frame_data_buffer_ptr_[curr_byte_offset_] == 0 && frame_data_buffer_ptr_[curr_byte_offset_ + 1] == 0 && frame_data_buffer_ptr_[curr_byte_offset_ + 2] == 0x01) {
curr_start_code_offset_ = next_start_code_offset_; // save the current start code offset
start_code_found = true;
start_code_num_++;
next_start_code_offset_ = curr_byte_offset_;
// Move the pointer 3 bytes forward
curr_byte_offset_ += 3;
// For the very first NAL unit, search for the next start code (or reach the end of frame)
if (start_code_num_ == 1) {
start_code_found = false;
curr_start_code_offset_ = next_start_code_offset_;
continue;
} else {
break;
}
}
curr_byte_offset_++;
}
if (start_code_num_ == 0) {
// No NAL unit in the frame data
return PARSER_NOT_FOUND;
}
if (start_code_found) {
nal_unit_size_ = next_start_code_offset_ - curr_start_code_offset_;
return PARSER_OK;
} else {
nal_unit_size_ = frame_data_size_ - curr_start_code_offset_;
return PARSER_EOF;
}
}
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) {
if (profile_present_flag) {
ptl->general_profile_space = Parser::ReadBits(nalu, offset, 2);
@@ -2393,48 +2340,8 @@ int HevcVideoParser::BumpPicFromDpb() {
return PARSER_OK;
}
size_t HevcVideoParser::EBSPtoRBSP(uint8_t *streamBuffer,size_t begin_bytepos, size_t end_bytepos) {
int count = 0;
if (end_bytepos < begin_bytepos) {
return end_bytepos;
}
uint8_t *streamBuffer_i = streamBuffer + begin_bytepos;
uint8_t *streamBuffer_end = streamBuffer + end_bytepos;
int reduce_count = 0;
for (; streamBuffer_i != streamBuffer_end; ) {
//starting from begin_bytepos to avoid header information
//in NAL unit, 0x000000, 0x000001 or 0x000002 shall not occur at any uint8_t-aligned position
uint8_t tmp =* streamBuffer_i;
if (count == ZEROBYTES_SHORTSTARTCODE) {
if (tmp == 0x03) {
//check the 4th uint8_t after 0x000003, except when cabac_zero_word is used, in which case the last three bytes of this NAL unit must be 0x000003
if ((streamBuffer_i + 1 != streamBuffer_end) && (streamBuffer_i[1] > 0x03)) {
return static_cast<size_t>(-1);
}
//if cabac_zero_word is used, the final uint8_t of this NAL unit(0x03) is discarded, and the last two bytes of RBSP must be 0x0000
if (streamBuffer_i + 1 == streamBuffer_end) {
break;
}
memmove(streamBuffer_i, streamBuffer_i + 1, streamBuffer_end-streamBuffer_i - 1);
streamBuffer_end--;
reduce_count++;
count = 0;
tmp = *streamBuffer_i;
} else if (tmp < 0x03) {
}
}
if (tmp == 0x00) {
count++;
} else {
count = 0;
}
streamBuffer_i++;
}
return end_bytepos - begin_bytepos + reduce_count;
}
#if DBGINFO
void HevcVideoParser::PrintVps(HevcVideoParser::HevcVideoParamSet *vps_ptr) {
void HevcVideoParser::PrintVps(HevcVideoParamSet *vps_ptr) {
MSG("=== hevc_video_parameter_set_t ===");
MSG("vps_video_parameter_set_id = " << vps_ptr->vps_video_parameter_set_id);
MSG("vps_base_layer_internal_flag = " << vps_ptr->vps_base_layer_internal_flag);
@@ -2485,7 +2392,7 @@ void HevcVideoParser::PrintVps(HevcVideoParser::HevcVideoParamSet *vps_ptr) {
MSG("");
}
void HevcVideoParser::PrintSps(HevcVideoParser::HevcSeqParamSet *sps_ptr) {
void HevcVideoParser::PrintSps(HevcSeqParamSet *sps_ptr) {
MSG("=== hevc_sequence_parameter_set_t ===");
MSG("sps_video_parameter_set_id = " << sps_ptr->sps_video_parameter_set_id);
MSG("sps_max_sub_layers_minus1 = " << sps_ptr->sps_max_sub_layers_minus1);
@@ -2597,7 +2504,7 @@ void HevcVideoParser::PrintSps(HevcVideoParser::HevcSeqParamSet *sps_ptr) {
MSG("");
}
void HevcVideoParser::PrintPps(HevcVideoParser::HevcPicParamSet *pps_ptr) {
void HevcVideoParser::PrintPps(HevcPicParamSet *pps_ptr) {
MSG("=== hevc_picture_parameter_set_t ===");
MSG("pps_pic_parameter_set_id = " << pps_ptr->pps_pic_parameter_set_id);
MSG("pps_seq_parameter_set_id = " << pps_ptr->pps_seq_parameter_set_id);
@@ -2747,7 +2654,7 @@ void HevcVideoParser::PrintSliceSegHeader(HevcSliceSegHeader *slice_header_ptr)
MSG("");
}
void HevcVideoParser::PrintStRps(HevcVideoParser::HevcShortTermRps *rps_ptr) {
void HevcVideoParser::PrintStRps(HevcShortTermRps *rps_ptr) {
MSG("==== Short-term reference picture set =====")
MSG("inter_ref_pic_set_prediction_flag = " << rps_ptr->inter_ref_pic_set_prediction_flag);
MSG("delta_idx_minus1 = " << rps_ptr->delta_idx_minus1);
@@ -2810,7 +2717,7 @@ void HevcVideoParser::PrintStRps(HevcVideoParser::HevcShortTermRps *rps_ptr) {
MSG("");
}
void HevcVideoParser::PrintLtRefInfo(HevcVideoParser::HevcLongTermRps *lt_info_ptr) {
void HevcVideoParser::PrintLtRefInfo(HevcLongTermRps *lt_info_ptr) {
MSG("==== Long-term reference picture info =====");
MSG("num_of_pics = " << lt_info_ptr->num_of_pics);
MSG_NO_NEWLINE("pocs[]:");
+3 -54
Просмотреть файл
@@ -26,11 +26,8 @@ THE SOFTWARE.
#include "hevc_defines.h"
#include <map>
#include <vector>
#include <algorithm>
#define ZEROBYTES_SHORTSTARTCODE 2 //indicates the number of zero bytes in the short start-code prefix
//size_id = 0
extern int scaling_list_default_0[1][6][16];
//size_id = 1, 2
@@ -116,18 +113,7 @@ protected:
uint32_t output_pic_list[HEVC_MAX_DPB_FRAMES]; // sorted output picuture index to frame_buffer_list[]
} DecodedPictureBuffer;
/*! \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 in <tt>size_t</tt>
*/
size_t EBSPtoRBSP(uint8_t *stream_buffer, size_t begin_bytepos, size_t end_bytepos);
// Data members of HEVC class
uint32_t pic_count_; // decoded picture count for the current bitstream
HevcNalUnitHeader nal_unit_header_;
int32_t m_active_vps_id_;
int32_t m_active_sps_id_;
@@ -140,22 +126,6 @@ protected:
HevcNalUnitHeader slice_nal_unit_header_;
HevcPicInfo curr_pic_info_;
bool b_new_picture_;
int m_packet_count_;
int m_rbsp_size_;
uint8_t m_rbsp_buf_[RBSP_BUF_SIZE]; // to store parameter set or slice header RBSP
uint8_t *sei_rbsp_buf_; // buffer to store SEI RBSP. Allocated at run time.
uint32_t sei_rbsp_buf_size_;
std::vector<RocdecSeiMessage> sei_message_list_;
int sei_message_count_; // total SEI playload message count of the current frame.
uint8_t *sei_payload_buf_; // buffer to store SEI playload. Allocated at run time.
uint32_t sei_payload_buf_size_;
uint32_t sei_payload_size_; // total SEI payload size of the current frame
int slice_num_;
uint8_t* pic_stream_data_ptr_;
int pic_stream_data_size_;
int first_pic_after_eos_nal_unit_; // to flag the first picture after EOS
int no_rasl_output_flag_; // NoRaslOutputFlag
@@ -191,17 +161,6 @@ protected:
uint8_t ref_pic_list_0_[HEVC_MAX_NUM_REF_PICS]; // RefPicList0
uint8_t ref_pic_list_1_[HEVC_MAX_NUM_REF_PICS]; // RefPicList1
// Frame bit stream info
uint8_t *frame_data_buffer_ptr_; // bit stream buffer pointer of the current frame from the demuxer
int frame_data_size_; // bit stream size of the current frame
int curr_byte_offset_; // current parsing byte offset
// NAL unit info
int start_code_num_; // number of start codes found so far
int curr_start_code_offset_;
int next_start_code_offset_;
int nal_unit_size_;
/*! \brief Function to parse Video Parameter Set
* \param [in] nalu A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] size Size of the input stream
@@ -358,17 +317,12 @@ protected:
*/
int BumpPicFromDpb();
/*! \brief Function to parse the data received from the demuxer.
/*! \brief Function to parse one picture bit stream received from the demuxer.
* \param [in] p_stream A pointer of <tt>uint8_t</tt> for the input stream to be parsed
* \param [in] frame_data_size Size of the input stream
* \param [in] pic_data_size Size of the input stream
* \return True is successful, else false
*/
bool ParseFrameData(const uint8_t* p_stream, uint32_t frame_data_size);
/*! \brief Function to get the NAL Unit data
* \return Returns OK if successful, else error code
*/
int GetNalUnit();
bool ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size);
#if DBGINFO
void PrintVps(HevcVideoParamSet *vps_ptr);
@@ -380,11 +334,6 @@ protected:
#endif // DBGINFO
private:
/*! \brief Function to initialize the HEVC parser members
* \return Returns OK in <tt>ParserResult</tt> if successful, else error code
*/
ParserResult Init();
// functions to fill structures for callback functions
int FillSeqCallbackFn(HevcSeqParamSet* sps_data);
void FillSeiMessageCallbackFn();
+2 -2
Просмотреть файл
@@ -25,7 +25,7 @@ THE SOFTWARE.
#include <string>
#include "rocparser.h"
#include "roc_video_parser.h"
#include "h264_parser.h"
#include "avc_parser.h"
#include "hevc_parser.h"
class RocParserHandle {
@@ -44,7 +44,7 @@ private:
void CreateParser(RocdecParserParams *params) {
switch(params->CodecType) {
case rocDecVideoCodec_H264:
roc_parser_ = std::make_shared<H264VideoParser>();
roc_parser_ = std::make_shared<AvcVideoParser>();
break;
case rocDecVideoCodec_HEVC:
roc_parser_ = std::make_shared<HevcVideoParser>();
+82
Просмотреть файл
@@ -23,6 +23,7 @@ THE SOFTWARE.
#include "roc_video_parser.h"
RocVideoParser::RocVideoParser() {
pic_count_ = 0;
pic_width_ = 0;
pic_height_ = 0;
new_sps_activated_ = false;
@@ -50,3 +51,84 @@ rocDecStatus RocVideoParser::Initialize(RocdecParserParams *pParams) {
return ROCDEC_SUCCESS;
}
ParserResult RocVideoParser::GetNalUnit() {
bool start_code_found = false;
nal_unit_size_ = 0;
curr_start_code_offset_ = next_start_code_offset_; // save the current start code offset
// Search for the next start code
while (curr_byte_offset_ < pic_data_size_ - 2) {
if (pic_data_buffer_ptr_[curr_byte_offset_] == 0 && pic_data_buffer_ptr_[curr_byte_offset_ + 1] == 0 && pic_data_buffer_ptr_[curr_byte_offset_ + 2] == 0x01) {
curr_start_code_offset_ = next_start_code_offset_; // save the current start code offset
start_code_found = true;
start_code_num_++;
next_start_code_offset_ = curr_byte_offset_;
// Move the pointer 3 bytes forward
curr_byte_offset_ += 3;
// For the very first NAL unit, search for the next start code (or reach the end of frame)
if (start_code_num_ == 1) {
start_code_found = false;
curr_start_code_offset_ = next_start_code_offset_;
continue;
} else {
break;
}
}
curr_byte_offset_++;
}
if (start_code_num_ == 0) {
// No NAL unit in the frame data
return PARSER_NOT_FOUND;
}
if (start_code_found) {
nal_unit_size_ = next_start_code_offset_ - curr_start_code_offset_;
return PARSER_OK;
} else {
nal_unit_size_ = pic_data_size_ - curr_start_code_offset_;
return PARSER_EOF;
}
}
size_t RocVideoParser::EbspToRbsp(uint8_t *streamBuffer,size_t begin_bytepos, size_t end_bytepos) {
int count = 0;
if (end_bytepos < begin_bytepos) {
return end_bytepos;
}
uint8_t *streamBuffer_i = streamBuffer + begin_bytepos;
uint8_t *streamBuffer_end = streamBuffer + end_bytepos;
int reduce_count = 0;
for (; streamBuffer_i != streamBuffer_end; ) {
//starting from begin_bytepos to avoid header information
//in NAL unit, 0x000000, 0x000001 or 0x000002 shall not occur at any uint8_t-aligned position
uint8_t tmp =* streamBuffer_i;
if (count == ZEROBYTES_SHORTSTARTCODE) {
if (tmp == 0x03) {
//check the 4th uint8_t after 0x000003, except when cabac_zero_word is used, in which case the last three bytes of this NAL unit must be 0x000003
if ((streamBuffer_i + 1 != streamBuffer_end) && (streamBuffer_i[1] > 0x03)) {
return static_cast<size_t>(-1);
}
//if cabac_zero_word is used, the final uint8_t of this NAL unit(0x03) is discarded, and the last two bytes of RBSP must be 0x0000
if (streamBuffer_i + 1 == streamBuffer_end) {
break;
}
memmove(streamBuffer_i, streamBuffer_i + 1, streamBuffer_end-streamBuffer_i - 1);
streamBuffer_end--;
reduce_count++;
count = 0;
tmp = *streamBuffer_i;
} else if (tmp < 0x03) {
}
}
if (tmp == 0x00) {
count++;
} else {
count = 0;
}
streamBuffer_i++;
}
return end_bytepos - begin_bytepos + reduce_count;
}
+84 -46
Просмотреть файл
@@ -23,55 +23,10 @@ THE SOFTWARE.
#include <memory>
#include <string>
#include <vector>
#include "rocparser.h"
#include "../commons.h"
/**
* @brief Base class for video parsing
*
*/
class RocVideoParser {
public:
RocVideoParser(); // default constructor
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);
virtual rocDecStatus ParseVideoData(RocdecSourceDataPacket *pData) = 0; // pure virtual: implemented by derived class
virtual rocDecStatus UnInitialize() = 0; // pure virtual: implemented by derived class
protected:
RocdecParserParams parser_params_ = {};
/**
* @brief callback function pointers for the parser
*
*/
PFNVIDSEQUENCECALLBACK pfn_sequece_cb_; /**< Called before decoding frames and/or whenever there is a fmt change */
PFNVIDDECODECALLBACK pfn_decode_picture_cb_; /**< Called when a picture is ready to be decoded (decode order) */
PFNVIDDISPLAYCALLBACK pfn_display_picture_cb_; /**< Called whenever a picture is ready to be displayed (display order) */
PFNVIDSEIMSGCALLBACK pfn_get_sei_message_cb_; /**< Called when all SEI messages are parsed for particular frame */
uint32_t pic_width_;
uint32_t pic_height_;
bool new_sps_activated_;
struct {
uint32_t numerator;
uint32_t denominator;
} frame_rate_;
RocdecVideoFormat video_format_params_;
RocdecSeiMessageInfo sei_message_info_params_;
RocdecPicParams dec_pic_params_;
};
enum ParserSeekOrigin {
PARSER_SEEK_BEGIN = 0,
PARSER_SEEK_CURRENT = 1,
PARSER_SEEK_END = 2,
};
typedef enum ParserResult {
PARSER_OK = 0,
PARSER_FAIL ,
@@ -113,6 +68,89 @@ typedef enum ParserResult {
PARSER_CODEC_NOT_SUPPORTED ,//codec not supported
} ParserResult;
#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
/**
* @brief Base class for video parsing
*
*/
class RocVideoParser {
public:
RocVideoParser(); // default constructor
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);
virtual rocDecStatus ParseVideoData(RocdecSourceDataPacket *pData) = 0; // pure virtual: implemented by derived class
virtual rocDecStatus UnInitialize() = 0; // pure virtual: implemented by derived class
protected:
RocdecParserParams parser_params_ = {};
/*! \brief callback function pointers for the parser
*/
PFNVIDSEQUENCECALLBACK pfn_sequece_cb_; /**< Called before decoding frames and/or whenever there is a fmt change */
PFNVIDDECODECALLBACK pfn_decode_picture_cb_; /**< Called when a picture is ready to be decoded (decode order) */
PFNVIDDISPLAYCALLBACK pfn_display_picture_cb_; /**< Called whenever a picture is ready to be displayed (display order) */
PFNVIDSEIMSGCALLBACK pfn_get_sei_message_cb_; /**< Called when all SEI messages are parsed for particular frame */
uint32_t pic_count_; // decoded picture count for the current bitstream
uint32_t pic_width_;
uint32_t pic_height_;
bool new_sps_activated_;
struct {
uint32_t numerator;
uint32_t denominator;
} frame_rate_;
RocdecVideoFormat video_format_params_;
RocdecSeiMessageInfo sei_message_info_params_;
RocdecPicParams dec_pic_params_;
// Picture bit stream info
uint8_t *pic_data_buffer_ptr_; // bit stream buffer pointer of the current frame from the demuxer
int pic_data_size_; // bit stream size of the current frame
int curr_byte_offset_; // current parsing byte offset
// NAL unit info
int start_code_num_; // number of start codes found so far
int curr_start_code_offset_;
int next_start_code_offset_;
int nal_unit_size_;
int rbsp_size_;
uint8_t rbsp_buf_[RBSP_BUF_SIZE]; // to store parameter set or slice header RBSP
int slice_num_;
uint8_t* pic_stream_data_ptr_;
int pic_stream_data_size_;
uint8_t *sei_rbsp_buf_; // buffer to store SEI RBSP. Allocated at run time.
uint32_t sei_rbsp_buf_size_;
std::vector<RocdecSeiMessage> sei_message_list_;
int sei_message_count_; // total SEI playload message count of the current frame.
uint8_t *sei_payload_buf_; // buffer to store SEI playload. Allocated at run time.
uint32_t sei_payload_buf_size_;
uint32_t sei_payload_size_; // total SEI payload size of the current frame
/*! \brief Function to get the NAL Unit data
* \return Returns OK if successful, else error code
*/
ParserResult GetNalUnit();
/*! \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 in <tt>size_t</tt>
*/
size_t EbspToRbsp(uint8_t *stream_buffer, size_t begin_bytepos, size_t end_bytepos);
};
// helpers
namespace Parser {
inline char GetLowByte(uint16_t data) {
+1 -1
Просмотреть файл
@@ -1060,7 +1060,7 @@ void RocVideoDecoder::GetDeviceinfo(std::string &device_name, std::string &gcn_a
bool RocVideoDecoder::GetOutputSurfaceInfo(OutputSurfaceInfo **surface_info) {
if (!disp_width_ || !disp_height_) {
std::cerr << "ERROR: RocVideoDecoderr is not intialized" << std::endl;
std::cerr << "ERROR: RocVideoDecoder is not intialized" << std::endl;
return false;
}
*surface_info = &output_surface_info_;