mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16:50 +08:00
[h265]:add h265 paser and hal part code
git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@293 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
@@ -39,6 +39,10 @@ typedef enum {
|
|||||||
MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3,
|
MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3,
|
||||||
MPP_ERR_STREAM = MPP_ERR_BASE - 4,
|
MPP_ERR_STREAM = MPP_ERR_BASE - 4,
|
||||||
MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5,
|
MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5,
|
||||||
|
MPP_ERR_NOMEM = MPP_ERR_BASE - 6,
|
||||||
|
MPP_ERR_PROTOL = MPP_ERR_BASE - 7,
|
||||||
|
MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8,
|
||||||
|
MPP_ERR_VPUHW = MPP_ERR_BASE - 9,
|
||||||
MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11,
|
MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11,
|
||||||
|
|
||||||
} MPP_RET;
|
} MPP_RET;
|
||||||
|
@@ -56,5 +56,16 @@ typedef signed long long int RK_S64;
|
|||||||
#ifndef MODULE_TAG
|
#ifndef MODULE_TAG
|
||||||
#define MODULE_TAG NULL
|
#define MODULE_TAG NULL
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NULL
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define NULL 0
|
||||||
|
#else
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INT64_C
|
||||||
|
#define INT64_C(c) (c ## LL)
|
||||||
|
#define UINT64_C(c) (c ## ULL)
|
||||||
|
#endif
|
||||||
#endif /*__RK_TYPE_H__*/
|
#endif /*__RK_TYPE_H__*/
|
||||||
|
@@ -1 +1,23 @@
|
|||||||
# vim: syntax=cmake
|
# vim: syntax=cmake
|
||||||
|
set(H265D_PARSER_HDR
|
||||||
|
h265d_defs.h
|
||||||
|
h265d_parser.h
|
||||||
|
h265d_codec.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(H265D_PARSER_SRC
|
||||||
|
../../../mpp_bitread.c
|
||||||
|
h265d_parser.c
|
||||||
|
h265d_ps.c
|
||||||
|
h265d_refs.c
|
||||||
|
h265d_sei.c
|
||||||
|
h265d_parser2_syntax.c
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(h265d_parser STATIC
|
||||||
|
${H265D_PARSER_SRC} ${H265D_PARSER_HDR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(h265d_parser osal)
|
||||||
|
|
||||||
|
add_subdirectory(test)
|
||||||
|
154
mpp/codec/dec/h265/h265d_codec.h
Normal file
154
mpp/codec/dec/h265/h265d_codec.h
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_codec.h
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __MPP_CODEC_H__
|
||||||
|
#define __MPP_CODEC_H__
|
||||||
|
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include "mpp_common.h"
|
||||||
|
#include "vpu_api.h"
|
||||||
|
#include "mpp_frame.h"
|
||||||
|
#include "mpp_dec.h"
|
||||||
|
|
||||||
|
enum MppColorSpace {
|
||||||
|
MPPCOL_SPC_RGB = 0,
|
||||||
|
MPPCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
|
||||||
|
MPPCOL_SPC_UNSPECIFIED = 2,
|
||||||
|
MPPCOL_SPC_FCC = 4,
|
||||||
|
MPPCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
|
||||||
|
MPPCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
|
||||||
|
MPPCOL_SPC_SMPTE240M = 7,
|
||||||
|
MPPCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
|
||||||
|
MPPCOL_SPC_NB , ///< Not part of ABI
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MppColorRange {
|
||||||
|
MPPCOL_RANGE_UNSPECIFIED = 0,
|
||||||
|
MPPCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
|
||||||
|
MPPCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges
|
||||||
|
MPPCOL_RANGE_NB , ///< Not part of ABI
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct MppRational {
|
||||||
|
RK_S32 num; ///< numerator
|
||||||
|
RK_S32 den; ///< denominator
|
||||||
|
} MppRational_t;
|
||||||
|
|
||||||
|
enum MppPictureStructure {
|
||||||
|
MPP_PICTURE_STRUCTURE_UNKNOWN, //< unknown
|
||||||
|
MPP_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field
|
||||||
|
MPP_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
|
||||||
|
MPP_PICTURE_STRUCTURE_FRAME, //< coded as frame
|
||||||
|
};
|
||||||
|
|
||||||
|
#define END_NOT_FOUND (-100)
|
||||||
|
|
||||||
|
typedef struct SplitContext {
|
||||||
|
RK_U8 *buffer;
|
||||||
|
RK_U32 buffer_size;
|
||||||
|
RK_S32 index;
|
||||||
|
RK_S32 last_index;
|
||||||
|
RK_U32 state; ///< contains the last few bytes in MSB order
|
||||||
|
RK_S32 frame_start_found;
|
||||||
|
RK_S32 overread; ///< the number of bytes which where irreversibly read from the next frame
|
||||||
|
RK_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes
|
||||||
|
RK_U64 state64; ///< contains the last 8 bytes in MSB order
|
||||||
|
RK_S32 eos;
|
||||||
|
} SplitContext_t;
|
||||||
|
|
||||||
|
typedef struct H265dContext {
|
||||||
|
|
||||||
|
void *priv_data;
|
||||||
|
|
||||||
|
void *split_cxt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for rk log printf
|
||||||
|
**/
|
||||||
|
// RK_LOG_CONTEX_t *log_ctx;
|
||||||
|
/**
|
||||||
|
* display width & height
|
||||||
|
**/
|
||||||
|
RK_S32 width, height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*codec decoder width & height
|
||||||
|
**/
|
||||||
|
RK_S32 coded_width, coded_height;
|
||||||
|
|
||||||
|
RK_U8 *extradata;
|
||||||
|
|
||||||
|
RK_U32 extradata_size;
|
||||||
|
|
||||||
|
VideoPacket_t *pkt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pixel format
|
||||||
|
**/
|
||||||
|
RK_U32 pix_fmt;
|
||||||
|
|
||||||
|
RK_U32 err_recognition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sample aspect ratio (0 if unknown)
|
||||||
|
* That is the width of a pixel divided by the height of the pixel.
|
||||||
|
* Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
|
||||||
|
* - decoding: Set by rkcodec.
|
||||||
|
*/
|
||||||
|
MppRational_t sample_aspect_ratio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* YUV colorspace type.
|
||||||
|
* - decoding: Set by rkcodec
|
||||||
|
*/
|
||||||
|
enum MppColorSpace colorspace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MPEG vs JPEG YUV range.
|
||||||
|
* - decoding: Set by rkcodec
|
||||||
|
*/
|
||||||
|
enum MppColorRange color_range;
|
||||||
|
|
||||||
|
void *compare_info;
|
||||||
|
|
||||||
|
RK_U32 need_split;
|
||||||
|
|
||||||
|
} H265dContext_t;
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RK_S32 h265d_parser2_syntax(void *ctx);
|
||||||
|
|
||||||
|
RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __MPP_CODEC_H__ */
|
45
mpp/codec/dec/h265/h265d_defs.h
Normal file
45
mpp/codec/dec/h265/h265d_defs.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_defs.h
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __H265D_DEF_H__
|
||||||
|
#define __H265D_DEF_H__
|
||||||
|
|
||||||
|
#ifdef VPS_EXTENSION
|
||||||
|
#define MAX_VPS_NUM_SCALABILITY_TYPES 16
|
||||||
|
#define MAX_VPS_LAYER_ID_PLUS1 MAX_LAYERS
|
||||||
|
#define MAX_VPS_LAYER_SETS_PLUS1 1024
|
||||||
|
#define VPS_EXTN_MASK_AND_DIM_INFO 1
|
||||||
|
#define VPS_MOVE_DIR_DEPENDENCY_FLAG 1
|
||||||
|
#define VPS_EXTN_DIRECT_REF_LAYERS 1
|
||||||
|
#define VPS_EXTN_PROFILE_INFO 1
|
||||||
|
#define VPS_PROFILE_OUTPUT_LAYERS 1
|
||||||
|
#define VPS_EXTN_OP_LAYER_SETS 1
|
||||||
|
#endif
|
||||||
|
#define DERIVE_LAYER_ID_LIST_VARIABLES 1
|
||||||
|
|
||||||
|
#endif /* H265D_DEF_H */
|
1746
mpp/codec/dec/h265/h265d_parser.c
Normal file
1746
mpp/codec/dec/h265/h265d_parser.c
Normal file
File diff suppressed because it is too large
Load Diff
755
mpp/codec/dec/h265/h265d_parser.h
Normal file
755
mpp/codec/dec/h265/h265d_parser.h
Normal file
@@ -0,0 +1,755 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_parser.h
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __H265D_PARSER_H__
|
||||||
|
#define __H265D_PARSER_H__
|
||||||
|
|
||||||
|
#include "mpp_bitread.h"
|
||||||
|
#include "mpp_common.h"
|
||||||
|
#include "h265d_codec.h"
|
||||||
|
#include "mpp_frame.h"
|
||||||
|
#include "limits.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <mpp_mem.h>
|
||||||
|
#include "mpp_dec.h"
|
||||||
|
|
||||||
|
extern RK_U32 h265d_debug;
|
||||||
|
#define H265D_DBG_FUNCTION (0x00000001)
|
||||||
|
#define H265D_DBG_VPS (0x00000002)
|
||||||
|
#define H265D_DBG_SPS (0x00000004)
|
||||||
|
#define H265D_DBG_PPS (0x00000008)
|
||||||
|
#define H265D_DBG_SLICE_HDR (0x00000010)
|
||||||
|
#define H265D_DBG_SEI (0x00000020)
|
||||||
|
#define H265D_DBG_GLOBAL (0x00000040)
|
||||||
|
#define H265D_DBG_REF (0x00000080)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define h265d_dbg(flag, fmt, ...) _mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_DPB_SIZE 16 // A.4.1
|
||||||
|
#define MAX_REFS 16
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 7.4.2.1
|
||||||
|
*/
|
||||||
|
#define MAX_SUB_LAYERS 7
|
||||||
|
#define MAX_VPS_COUNT 16
|
||||||
|
#define MAX_SPS_COUNT 16
|
||||||
|
#define MAX_PPS_COUNT 64
|
||||||
|
#define MAX_SHORT_TERM_RPS_COUNT 64
|
||||||
|
#define MAX_CU_SIZE 128
|
||||||
|
|
||||||
|
//TODO: check if this is really the maximum
|
||||||
|
#define MAX_TRANSFORM_DEPTH 5
|
||||||
|
|
||||||
|
#define MAX_TB_SIZE 32
|
||||||
|
#define MAX_PB_SIZE 64
|
||||||
|
#define MAX_LOG2_CTB_SIZE 6
|
||||||
|
#define MAX_QP 51
|
||||||
|
#define DEFAULT_INTRA_TC_OFFSET 2
|
||||||
|
|
||||||
|
#define HEVC_CONTEXTS 183
|
||||||
|
|
||||||
|
#define MRG_MAX_NUM_CANDS 5
|
||||||
|
|
||||||
|
#define L0 0
|
||||||
|
#define L1 1
|
||||||
|
|
||||||
|
#define EPEL_EXTRA_BEFORE 1
|
||||||
|
#define EPEL_EXTRA_AFTER 2
|
||||||
|
#define EPEL_EXTRA 3
|
||||||
|
#define QPEL_EXTRA_BEFORE 3
|
||||||
|
#define QPEL_EXTRA_AFTER 4
|
||||||
|
#define QPEL_EXTRA 7
|
||||||
|
|
||||||
|
#define EDGE_EMU_BUFFER_STRIDE 80
|
||||||
|
|
||||||
|
#define MAX_FRAME_SIZE 2048000
|
||||||
|
#define MPP_INPUT_BUFFER_PADDING_SIZE 8
|
||||||
|
|
||||||
|
#define MPP_PROFILE_HEVC_MAIN 1
|
||||||
|
#define MPP_PROFILE_HEVC_MAIN_10 2
|
||||||
|
#define MPP_PROFILE_HEVC_MAIN_STILL_PICTURE 3
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value of the luma sample at position (x, y) in the 2D array tab.
|
||||||
|
*/
|
||||||
|
#define IS_IDR(s) (s->nal_unit_type == NAL_IDR_W_RADL || s->nal_unit_type == NAL_IDR_N_LP)
|
||||||
|
#define IS_BLA(s) (s->nal_unit_type == NAL_BLA_W_RADL || s->nal_unit_type == NAL_BLA_W_LP || \
|
||||||
|
s->nal_unit_type == NAL_BLA_N_LP)
|
||||||
|
#define IS_IRAP(s) (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table 7-3: NAL unit type codes
|
||||||
|
*/
|
||||||
|
enum NALUnitType {
|
||||||
|
NAL_TRAIL_N = 0,
|
||||||
|
NAL_TRAIL_R = 1,
|
||||||
|
NAL_TSA_N = 2,
|
||||||
|
NAL_TSA_R = 3,
|
||||||
|
NAL_STSA_N = 4,
|
||||||
|
NAL_STSA_R = 5,
|
||||||
|
NAL_RADL_N = 6,
|
||||||
|
NAL_RADL_R = 7,
|
||||||
|
NAL_RASL_N = 8,
|
||||||
|
NAL_RASL_R = 9,
|
||||||
|
NAL_BLA_W_LP = 16,
|
||||||
|
NAL_BLA_W_RADL = 17,
|
||||||
|
NAL_BLA_N_LP = 18,
|
||||||
|
NAL_IDR_W_RADL = 19,
|
||||||
|
NAL_IDR_N_LP = 20,
|
||||||
|
NAL_CRA_NUT = 21,
|
||||||
|
NAL_VPS = 32,
|
||||||
|
NAL_SPS = 33,
|
||||||
|
NAL_PPS = 34,
|
||||||
|
NAL_AUD = 35,
|
||||||
|
NAL_EOS_NUT = 36,
|
||||||
|
NAL_EOB_NUT = 37,
|
||||||
|
NAL_FD_NUT = 38,
|
||||||
|
NAL_SEI_PREFIX = 39,
|
||||||
|
NAL_SEI_SUFFIX = 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum RPSType {
|
||||||
|
ST_CURR_BEF = 0,
|
||||||
|
ST_CURR_AFT,
|
||||||
|
ST_FOLL,
|
||||||
|
LT_CURR,
|
||||||
|
LT_FOLL,
|
||||||
|
NB_RPS_TYPE,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SliceType {
|
||||||
|
B_SLICE = 0,
|
||||||
|
P_SLICE = 1,
|
||||||
|
I_SLICE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ShortTermRPS {
|
||||||
|
RK_U32 num_negative_pics;
|
||||||
|
RK_S32 num_delta_pocs;
|
||||||
|
RK_S32 rps_idx_num_delta_pocs;
|
||||||
|
RK_S32 delta_poc[32];
|
||||||
|
RK_U8 used[32];
|
||||||
|
} ShortTermRPS;
|
||||||
|
|
||||||
|
typedef struct LongTermRPS {
|
||||||
|
RK_S32 poc[32];
|
||||||
|
RK_U8 used[32];
|
||||||
|
RK_U8 nb_refs;
|
||||||
|
} LongTermRPS;
|
||||||
|
|
||||||
|
typedef struct RefPicList {
|
||||||
|
struct HEVCFrame *ref[MAX_REFS];
|
||||||
|
RK_S32 list[MAX_REFS];
|
||||||
|
RK_S32 isLongTerm[MAX_REFS];
|
||||||
|
RK_S32 nb_refs;
|
||||||
|
} RefPicList;
|
||||||
|
|
||||||
|
typedef struct RefPicListTab {
|
||||||
|
RefPicList refPicList[2];
|
||||||
|
} RefPicListTab;
|
||||||
|
|
||||||
|
typedef struct HEVCWindow {
|
||||||
|
RK_S32 left_offset;
|
||||||
|
RK_S32 right_offset;
|
||||||
|
RK_S32 top_offset;
|
||||||
|
RK_S32 bottom_offset;
|
||||||
|
} HEVCWindow;
|
||||||
|
|
||||||
|
typedef struct VUI {
|
||||||
|
MppRational_t sar;
|
||||||
|
|
||||||
|
RK_S32 overscan_info_present_flag;
|
||||||
|
RK_S32 overscan_appropriate_flag;
|
||||||
|
|
||||||
|
RK_S32 video_signal_type_present_flag;
|
||||||
|
RK_S32 video_format;
|
||||||
|
RK_S32 video_full_range_flag;
|
||||||
|
RK_S32 colour_description_present_flag;
|
||||||
|
RK_U8 colour_primaries;
|
||||||
|
RK_U8 transfer_characteristic;
|
||||||
|
RK_U8 matrix_coeffs;
|
||||||
|
|
||||||
|
RK_S32 chroma_loc_info_present_flag;
|
||||||
|
RK_S32 chroma_sample_loc_type_top_field;
|
||||||
|
RK_S32 chroma_sample_loc_type_bottom_field;
|
||||||
|
RK_S32 neutra_chroma_indication_flag;
|
||||||
|
|
||||||
|
RK_S32 field_seq_flag;
|
||||||
|
RK_S32 frame_field_info_present_flag;
|
||||||
|
|
||||||
|
RK_S32 default_display_window_flag;
|
||||||
|
HEVCWindow def_disp_win;
|
||||||
|
|
||||||
|
RK_S32 vui_timing_info_present_flag;
|
||||||
|
RK_U32 vui_num_units_in_tick;
|
||||||
|
RK_U32 vui_time_scale;
|
||||||
|
RK_S32 vui_poc_proportional_to_timing_flag;
|
||||||
|
RK_S32 vui_num_ticks_poc_diff_one_minus1;
|
||||||
|
RK_S32 vui_hrd_parameters_present_flag;
|
||||||
|
|
||||||
|
RK_S32 bitstream_restriction_flag;
|
||||||
|
RK_S32 tiles_fixed_structure_flag;
|
||||||
|
RK_S32 motion_vectors_over_pic_boundaries_flag;
|
||||||
|
RK_S32 restricted_ref_pic_lists_flag;
|
||||||
|
RK_S32 min_spatial_segmentation_idc;
|
||||||
|
RK_S32 max_bytes_per_pic_denom;
|
||||||
|
RK_S32 max_bits_per_min_cu_denom;
|
||||||
|
RK_S32 log2_max_mv_length_horizontal;
|
||||||
|
RK_S32 log2_max_mv_length_vertical;
|
||||||
|
} VUI;
|
||||||
|
|
||||||
|
typedef struct PTLCommon {
|
||||||
|
RK_U8 profile_space;
|
||||||
|
RK_U8 tier_flag;
|
||||||
|
RK_U8 profile_idc;
|
||||||
|
RK_U8 profile_compatibility_flag[32];
|
||||||
|
RK_U8 level_idc;
|
||||||
|
RK_U8 progressive_source_flag;
|
||||||
|
RK_U8 interlaced_source_flag;
|
||||||
|
RK_U8 non_packed_constraint_flag;
|
||||||
|
RK_U8 frame_only_constraint_flag;
|
||||||
|
} PTLCommon;
|
||||||
|
|
||||||
|
typedef struct PTL {
|
||||||
|
PTLCommon general_ptl;
|
||||||
|
PTLCommon sub_layer_ptl[MAX_SUB_LAYERS];
|
||||||
|
|
||||||
|
RK_U8 sub_layer_profile_present_flag[MAX_SUB_LAYERS];
|
||||||
|
RK_U8 sub_layer_level_present_flag[MAX_SUB_LAYERS];
|
||||||
|
|
||||||
|
RK_S32 sub_layer_profile_space[MAX_SUB_LAYERS];
|
||||||
|
RK_U8 sub_layer_tier_flag[MAX_SUB_LAYERS];
|
||||||
|
RK_S32 sub_layer_profile_idc[MAX_SUB_LAYERS];
|
||||||
|
RK_U8 sub_layer_profile_compatibility_flags[MAX_SUB_LAYERS][32];
|
||||||
|
RK_S32 sub_layer_level_idc[MAX_SUB_LAYERS];
|
||||||
|
} PTL;
|
||||||
|
|
||||||
|
typedef struct HEVCVPS {
|
||||||
|
RK_U8 vps_temporal_id_nesting_flag;
|
||||||
|
RK_S32 vps_max_layers;
|
||||||
|
RK_S32 vps_max_sub_layers; ///< vps_max_temporal_layers_minus1 + 1
|
||||||
|
|
||||||
|
PTL ptl;
|
||||||
|
RK_S32 vps_sub_layer_ordering_info_present_flag;
|
||||||
|
RK_U32 vps_max_dec_pic_buffering[MAX_SUB_LAYERS];
|
||||||
|
RK_U32 vps_num_reorder_pics[MAX_SUB_LAYERS];
|
||||||
|
RK_U32 vps_max_latency_increase[MAX_SUB_LAYERS];
|
||||||
|
RK_S32 vps_max_layer_id;
|
||||||
|
RK_S32 vps_num_layer_sets; ///< vps_num_layer_sets_minus1 + 1
|
||||||
|
RK_U8 vps_timing_info_present_flag;
|
||||||
|
RK_U32 vps_num_units_in_tick;
|
||||||
|
RK_U32 vps_time_scale;
|
||||||
|
RK_U8 vps_poc_proportional_to_timing_flag;
|
||||||
|
RK_S32 vps_num_ticks_poc_diff_one; ///< vps_num_ticks_poc_diff_one_minus1 + 1
|
||||||
|
RK_S32 vps_num_hrd_parameters;
|
||||||
|
|
||||||
|
RK_S32 vps_extension_flag;
|
||||||
|
|
||||||
|
} HEVCVPS;
|
||||||
|
|
||||||
|
typedef struct ScalingList {
|
||||||
|
/* This is a little wasteful, since sizeID 0 only needs 8 coeffs,
|
||||||
|
* and size ID 3 only has 2 arrays, not 6. */
|
||||||
|
RK_U8 sl[4][6][64];
|
||||||
|
RK_U8 sl_dc[2][6];
|
||||||
|
} ScalingList;
|
||||||
|
|
||||||
|
typedef struct HEVCSPS {
|
||||||
|
RK_U32 vps_id;
|
||||||
|
RK_S32 sps_id;
|
||||||
|
RK_S32 chroma_format_idc;
|
||||||
|
RK_U8 separate_colour_plane_flag;
|
||||||
|
|
||||||
|
///< output (i.e. cropped) values
|
||||||
|
RK_S32 output_width, output_height;
|
||||||
|
HEVCWindow output_window;
|
||||||
|
|
||||||
|
HEVCWindow pic_conf_win;
|
||||||
|
|
||||||
|
RK_S32 bit_depth;
|
||||||
|
RK_S32 bit_depth_chroma;///<- zrh add
|
||||||
|
RK_S32 pixel_shift;
|
||||||
|
RK_S32 pix_fmt;
|
||||||
|
|
||||||
|
RK_U32 log2_max_poc_lsb;
|
||||||
|
RK_S32 pcm_enabled_flag;
|
||||||
|
|
||||||
|
RK_S32 max_sub_layers;
|
||||||
|
struct {
|
||||||
|
int max_dec_pic_buffering;
|
||||||
|
int num_reorder_pics;
|
||||||
|
int max_latency_increase;
|
||||||
|
} temporal_layer[MAX_SUB_LAYERS];
|
||||||
|
|
||||||
|
VUI vui;
|
||||||
|
PTL ptl;
|
||||||
|
|
||||||
|
RK_U8 scaling_list_enable_flag;
|
||||||
|
ScalingList scaling_list;
|
||||||
|
|
||||||
|
RK_U32 nb_st_rps;
|
||||||
|
ShortTermRPS st_rps[MAX_SHORT_TERM_RPS_COUNT];
|
||||||
|
|
||||||
|
RK_U8 amp_enabled_flag;
|
||||||
|
RK_U8 sao_enabled;
|
||||||
|
|
||||||
|
RK_U8 long_term_ref_pics_present_flag;
|
||||||
|
RK_U16 lt_ref_pic_poc_lsb_sps[32];
|
||||||
|
RK_U8 used_by_curr_pic_lt_sps_flag[32];
|
||||||
|
RK_U8 num_long_term_ref_pics_sps;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
RK_U8 bit_depth;
|
||||||
|
RK_U8 bit_depth_chroma;
|
||||||
|
RK_U32 log2_min_pcm_cb_size;
|
||||||
|
RK_U32 log2_max_pcm_cb_size;
|
||||||
|
RK_U8 loop_filter_disable_flag;
|
||||||
|
} pcm;
|
||||||
|
RK_U8 sps_temporal_mvp_enabled_flag;
|
||||||
|
RK_U8 sps_strong_intra_smoothing_enable_flag;
|
||||||
|
|
||||||
|
RK_U32 log2_min_cb_size;
|
||||||
|
RK_U32 log2_diff_max_min_coding_block_size;
|
||||||
|
RK_U32 log2_min_tb_size;
|
||||||
|
RK_U32 log2_max_trafo_size;
|
||||||
|
RK_S32 log2_ctb_size;
|
||||||
|
RK_U32 log2_min_pu_size;
|
||||||
|
|
||||||
|
RK_S32 max_transform_hierarchy_depth_inter;
|
||||||
|
RK_S32 max_transform_hierarchy_depth_intra;
|
||||||
|
|
||||||
|
///< coded frame dimension in various units
|
||||||
|
RK_S32 width;
|
||||||
|
RK_S32 height;
|
||||||
|
RK_S32 ctb_width;
|
||||||
|
RK_S32 ctb_height;
|
||||||
|
RK_S32 ctb_size;
|
||||||
|
RK_S32 min_cb_width;
|
||||||
|
RK_S32 min_cb_height;
|
||||||
|
RK_S32 min_tb_width;
|
||||||
|
RK_S32 min_tb_height;
|
||||||
|
RK_S32 min_pu_width;
|
||||||
|
RK_S32 min_pu_height;
|
||||||
|
|
||||||
|
RK_S32 hshift[3];
|
||||||
|
RK_S32 vshift[3];
|
||||||
|
|
||||||
|
RK_S32 qp_bd_offset;
|
||||||
|
#ifdef SCALED_REF_LAYER_OFFSETS
|
||||||
|
HEVCWindow scaled_ref_layer_window;
|
||||||
|
#endif
|
||||||
|
#ifdef REF_IDX_MFM
|
||||||
|
RK_S32 set_mfm_enabled_flag;
|
||||||
|
#endif
|
||||||
|
} HEVCSPS;
|
||||||
|
|
||||||
|
typedef struct HEVCPPS {
|
||||||
|
RK_S32 sps_id;
|
||||||
|
RK_S32 pps_id;
|
||||||
|
|
||||||
|
RK_U8 sign_data_hiding_flag;
|
||||||
|
|
||||||
|
RK_U8 cabac_init_present_flag;
|
||||||
|
|
||||||
|
RK_S32 num_ref_idx_l0_default_active; ///< num_ref_idx_l0_default_active_minus1 + 1
|
||||||
|
RK_S32 num_ref_idx_l1_default_active; ///< num_ref_idx_l1_default_active_minus1 + 1
|
||||||
|
RK_S32 pic_init_qp_minus26;
|
||||||
|
|
||||||
|
RK_U8 constrained_intra_pred_flag;
|
||||||
|
RK_U8 transform_skip_enabled_flag;
|
||||||
|
|
||||||
|
RK_U8 cu_qp_delta_enabled_flag;
|
||||||
|
RK_S32 diff_cu_qp_delta_depth;
|
||||||
|
|
||||||
|
RK_S32 cb_qp_offset;
|
||||||
|
RK_S32 cr_qp_offset;
|
||||||
|
RK_U8 pic_slice_level_chroma_qp_offsets_present_flag;
|
||||||
|
RK_U8 weighted_pred_flag;
|
||||||
|
RK_U8 weighted_bipred_flag;
|
||||||
|
RK_U8 output_flag_present_flag;
|
||||||
|
RK_U8 transquant_bypass_enable_flag;
|
||||||
|
|
||||||
|
RK_U8 dependent_slice_segments_enabled_flag;
|
||||||
|
RK_U8 tiles_enabled_flag;
|
||||||
|
RK_U8 entropy_coding_sync_enabled_flag;
|
||||||
|
|
||||||
|
RK_S32 num_tile_columns; ///< num_tile_columns_minus1 + 1
|
||||||
|
RK_S32 num_tile_rows; ///< num_tile_rows_minus1 + 1
|
||||||
|
RK_U8 uniform_spacing_flag;
|
||||||
|
RK_U8 loop_filter_across_tiles_enabled_flag;
|
||||||
|
|
||||||
|
RK_U8 seq_loop_filter_across_slices_enabled_flag;
|
||||||
|
|
||||||
|
RK_U8 deblocking_filter_control_present_flag;
|
||||||
|
RK_U8 deblocking_filter_override_enabled_flag;
|
||||||
|
RK_U8 disable_dbf;
|
||||||
|
RK_S32 beta_offset; ///< beta_offset_div2 * 2
|
||||||
|
RK_S32 tc_offset; ///< tc_offset_div2 * 2
|
||||||
|
|
||||||
|
RK_U8 scaling_list_data_present_flag;
|
||||||
|
ScalingList scaling_list;
|
||||||
|
|
||||||
|
RK_U8 lists_modification_present_flag;
|
||||||
|
RK_S32 log2_parallel_merge_level; ///< log2_parallel_merge_level_minus2 + 2
|
||||||
|
RK_S32 num_extra_slice_header_bits;
|
||||||
|
RK_U8 slice_header_extension_present_flag;
|
||||||
|
|
||||||
|
RK_U8 pps_extension_flag;
|
||||||
|
RK_U8 pps_extension_data_flag;
|
||||||
|
// Inferred parameters
|
||||||
|
RK_U32 *column_width; ///< ColumnWidth
|
||||||
|
RK_U32 *row_height; ///< RowHeight
|
||||||
|
RK_U32 *col_bd; ///< ColBd
|
||||||
|
RK_U32 *row_bd; ///< RowBd
|
||||||
|
RK_S32 *col_idxX;
|
||||||
|
|
||||||
|
RK_S32 *ctb_addr_rs_to_ts; ///< CtbAddrRSToTS
|
||||||
|
RK_S32 *ctb_addr_ts_to_rs; ///< CtbAddrTSToRS
|
||||||
|
RK_S32 *tile_id; ///< TileId
|
||||||
|
RK_S32 *tile_pos_rs; ///< TilePosRS
|
||||||
|
RK_S32 *min_cb_addr_zs; ///< MinCbAddrZS
|
||||||
|
RK_S32 *min_tb_addr_zs; ///< MinTbAddrZS
|
||||||
|
} HEVCPPS;
|
||||||
|
|
||||||
|
typedef struct SliceHeader {
|
||||||
|
RK_U32 pps_id;
|
||||||
|
|
||||||
|
///< address (in raster order) of the first block in the current slice segment
|
||||||
|
RK_U32 slice_segment_addr;
|
||||||
|
///< address (in raster order) of the first block in the current slice
|
||||||
|
RK_U32 slice_addr;
|
||||||
|
|
||||||
|
enum SliceType slice_type;
|
||||||
|
|
||||||
|
RK_S32 pic_order_cnt_lsb;
|
||||||
|
|
||||||
|
RK_U8 first_slice_in_pic_flag;
|
||||||
|
RK_U8 dependent_slice_segment_flag;
|
||||||
|
RK_U8 pic_output_flag;
|
||||||
|
RK_U8 colour_plane_id;
|
||||||
|
|
||||||
|
///< RPS coded in the slice header itself is stored here
|
||||||
|
int short_term_ref_pic_set_sps_flag;
|
||||||
|
int short_term_ref_pic_set_size;
|
||||||
|
ShortTermRPS slice_rps;
|
||||||
|
const ShortTermRPS *short_term_rps;
|
||||||
|
LongTermRPS long_term_rps;
|
||||||
|
RK_U32 list_entry_lx[2][32];
|
||||||
|
|
||||||
|
RK_U8 rpl_modification_flag[2];
|
||||||
|
RK_U8 no_output_of_prior_pics_flag;
|
||||||
|
RK_U8 slice_temporal_mvp_enabled_flag;
|
||||||
|
|
||||||
|
RK_U32 nb_refs[2];
|
||||||
|
|
||||||
|
RK_U8 slice_sample_adaptive_offset_flag[3];
|
||||||
|
RK_U8 mvd_l1_zero_flag;
|
||||||
|
|
||||||
|
RK_U8 cabac_init_flag;
|
||||||
|
RK_U8 disable_deblocking_filter_flag; ///< slice_header_disable_deblocking_filter_flag
|
||||||
|
RK_U8 slice_loop_filter_across_slices_enabled_flag;
|
||||||
|
RK_U8 collocated_list;
|
||||||
|
|
||||||
|
RK_U32 collocated_ref_idx;
|
||||||
|
|
||||||
|
RK_S32 slice_qp_delta;
|
||||||
|
RK_S32 slice_cb_qp_offset;
|
||||||
|
RK_S32 slice_cr_qp_offset;
|
||||||
|
|
||||||
|
RK_S32 beta_offset; ///< beta_offset_div2 * 2
|
||||||
|
RK_S32 tc_offset; ///< tc_offset_div2 * 2
|
||||||
|
|
||||||
|
RK_U32 max_num_merge_cand; ///< 5 - 5_minus_max_num_merge_cand
|
||||||
|
|
||||||
|
RK_S32 *entry_point_offset;
|
||||||
|
RK_S32 * offset;
|
||||||
|
RK_S32 * size;
|
||||||
|
RK_S32 num_entry_point_offsets;
|
||||||
|
|
||||||
|
RK_S8 slice_qp;
|
||||||
|
|
||||||
|
RK_U8 luma_log2_weight_denom;
|
||||||
|
RK_S16 chroma_log2_weight_denom;
|
||||||
|
|
||||||
|
RK_S16 luma_weight_l0[16];
|
||||||
|
RK_S16 chroma_weight_l0[16][2];
|
||||||
|
RK_S16 chroma_weight_l1[16][2];
|
||||||
|
RK_S16 luma_weight_l1[16];
|
||||||
|
|
||||||
|
RK_S16 luma_offset_l0[16];
|
||||||
|
RK_S16 chroma_offset_l0[16][2];
|
||||||
|
|
||||||
|
RK_S16 luma_offset_l1[16];
|
||||||
|
RK_S16 chroma_offset_l1[16][2];
|
||||||
|
|
||||||
|
#ifdef REF_IDX_FRAMEWORK
|
||||||
|
RK_S32 inter_layer_pred_enabled_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef JCTVC_M0458_INTERLAYER_RPS_SIG
|
||||||
|
RK_S32 active_num_ILR_ref_idx; //< Active inter-layer reference pictures
|
||||||
|
RK_S32 inter_layer_pred_layer_idc[MAX_VPS_LAYER_ID_PLUS1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RK_S32 slice_ctb_addr_rs;
|
||||||
|
} SliceHeader;
|
||||||
|
|
||||||
|
typedef struct CurrentFameInf {
|
||||||
|
HEVCVPS vps[MAX_VPS_COUNT];
|
||||||
|
HEVCSPS sps[MAX_SPS_COUNT];
|
||||||
|
HEVCPPS pps[MAX_PPS_COUNT];
|
||||||
|
SliceHeader sh;
|
||||||
|
} CurrentFameInf_t;
|
||||||
|
|
||||||
|
typedef struct DBParams {
|
||||||
|
RK_S32 beta_offset;
|
||||||
|
RK_S32 tc_offset;
|
||||||
|
} DBParams;
|
||||||
|
|
||||||
|
#define HEVC_FRAME_FLAG_OUTPUT (1 << 0)
|
||||||
|
#define HEVC_FRAME_FLAG_SHORT_REF (1 << 1)
|
||||||
|
#define HEVC_FRAME_FLAG_LONG_REF (1 << 2)
|
||||||
|
|
||||||
|
typedef struct HEVCFrame {
|
||||||
|
MppFrame frame;
|
||||||
|
RefPicList *refPicList;
|
||||||
|
RefPicListTab **rpl_tab;
|
||||||
|
RK_S32 ctb_count;
|
||||||
|
RK_S32 poc;
|
||||||
|
struct HEVCFrame *collocated_ref;
|
||||||
|
|
||||||
|
HEVCWindow window;
|
||||||
|
|
||||||
|
RK_U8 *rpl_tab_buf;
|
||||||
|
|
||||||
|
RK_U8 *rpl_buf;
|
||||||
|
/**
|
||||||
|
* A sequence counter, so that old frames are output first
|
||||||
|
* after a POC reset
|
||||||
|
*/
|
||||||
|
RK_U16 sequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A combination of HEVC_FRAME_FLAG_*
|
||||||
|
*/
|
||||||
|
RK_U8 flags;
|
||||||
|
RK_U32 slot_index;
|
||||||
|
} HEVCFrame;
|
||||||
|
|
||||||
|
typedef struct HEVCNAL {
|
||||||
|
RK_U8 *rbsp_buffer;
|
||||||
|
RK_S32 rbsp_buffer_size;
|
||||||
|
RK_S32 size;
|
||||||
|
const RK_U8 *data;
|
||||||
|
} HEVCNAL;
|
||||||
|
|
||||||
|
typedef struct HEVCLocalContext {
|
||||||
|
GetBitCxt_t gb;
|
||||||
|
} HEVCLocalContext;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct REF_PIC_DEC_INFO {
|
||||||
|
RK_U8 dbp_index;
|
||||||
|
RK_U8 is_long_term;
|
||||||
|
} REF_PIC_DEC_INFO;
|
||||||
|
|
||||||
|
typedef struct HEVCContext {
|
||||||
|
H265dContext_t *h265dctx;
|
||||||
|
|
||||||
|
HEVCLocalContext *HEVClc;
|
||||||
|
|
||||||
|
MppFrame frame;
|
||||||
|
|
||||||
|
const HEVCVPS *vps;
|
||||||
|
const HEVCSPS *sps;
|
||||||
|
const HEVCPPS *pps;
|
||||||
|
RK_U8 *vps_list[MAX_VPS_COUNT];
|
||||||
|
RK_U8 *sps_list[MAX_SPS_COUNT];
|
||||||
|
RK_U8 *pps_list[MAX_PPS_COUNT];
|
||||||
|
|
||||||
|
SliceHeader sh;
|
||||||
|
|
||||||
|
///< candidate references for the current frame
|
||||||
|
RefPicList rps[5];
|
||||||
|
|
||||||
|
enum NALUnitType nal_unit_type;
|
||||||
|
RK_S32 temporal_id; ///< temporal_id_plus1 - 1
|
||||||
|
HEVCFrame *ref;
|
||||||
|
HEVCFrame DPB[32];
|
||||||
|
RK_S32 poc;
|
||||||
|
RK_S32 pocTid0;
|
||||||
|
RK_S32 slice_idx; ///< number of the slice being currently decoded
|
||||||
|
RK_S32 eos; ///< current packet contains an EOS/EOB NAL
|
||||||
|
RK_S32 max_ra;
|
||||||
|
|
||||||
|
RK_S32 is_decoded;
|
||||||
|
|
||||||
|
|
||||||
|
/** used on BE to byteswap the lines for checksumming */
|
||||||
|
RK_U8 *checksum_buf;
|
||||||
|
RK_S32 checksum_buf_size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sequence counters for decoded and output frames, so that old
|
||||||
|
* frames are output first after a POC reset
|
||||||
|
*/
|
||||||
|
RK_U16 seq_decode;
|
||||||
|
RK_U16 seq_output;
|
||||||
|
|
||||||
|
RK_S32 wpp_err;
|
||||||
|
RK_S32 skipped_bytes;
|
||||||
|
|
||||||
|
RK_U8 *data;
|
||||||
|
|
||||||
|
HEVCNAL *nals;
|
||||||
|
RK_S32 nb_nals;
|
||||||
|
RK_S32 nals_allocated;
|
||||||
|
// type of the first VCL NAL of the current frame
|
||||||
|
enum NALUnitType first_nal_type;
|
||||||
|
|
||||||
|
RK_U8 context_initialized;
|
||||||
|
RK_U8 is_nalff; ///< this flag is != 0 if bitstream is encapsulated
|
||||||
|
///< as a format defined in 14496-15
|
||||||
|
RK_S32 temporal_layer_id;
|
||||||
|
RK_S32 decoder_id;
|
||||||
|
RK_S32 apply_defdispwin;
|
||||||
|
|
||||||
|
RK_S32 active_seq_parameter_set_id;
|
||||||
|
|
||||||
|
RK_S32 nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
|
||||||
|
RK_S32 nuh_layer_id;
|
||||||
|
|
||||||
|
/** frame packing arrangement variables */
|
||||||
|
RK_S32 sei_frame_packing_present;
|
||||||
|
RK_S32 frame_packing_arrangement_type;
|
||||||
|
RK_S32 content_interpretation_type;
|
||||||
|
RK_S32 quincunx_subsampling;
|
||||||
|
|
||||||
|
RK_S32 picture_struct;
|
||||||
|
|
||||||
|
/** 1 if the independent slice segment header was successfully parsed */
|
||||||
|
RK_U8 slice_initialized;
|
||||||
|
|
||||||
|
RK_S32 decode_checksum_sei;
|
||||||
|
|
||||||
|
|
||||||
|
RK_U8 scaling_list[81][1360];
|
||||||
|
RK_U8 scaling_list_listen[81];
|
||||||
|
RK_U8 sps_list_of_updated[MAX_SPS_COUNT];///< zrh add
|
||||||
|
RK_U8 pps_list_of_updated[MAX_PPS_COUNT];///< zrh add
|
||||||
|
|
||||||
|
RK_S32 rps_used[16];
|
||||||
|
RK_S32 nb_rps_used;
|
||||||
|
REF_PIC_DEC_INFO rps_pic_info[600][2][15]; // zrh add
|
||||||
|
RK_U8 lowdelay_flag[600];
|
||||||
|
RK_U8 rps_bit_offset[600];
|
||||||
|
RK_U8 rps_bit_offset_st[600];
|
||||||
|
RK_U8 slice_nb_rps_poc[600];
|
||||||
|
|
||||||
|
RK_S32 frame_size;
|
||||||
|
|
||||||
|
RK_S32 framestrid;
|
||||||
|
|
||||||
|
RK_U32 nb_frame;
|
||||||
|
|
||||||
|
RK_U8 output_frame_idx;
|
||||||
|
|
||||||
|
RK_U32 got_frame;
|
||||||
|
|
||||||
|
MppBufSlots slots;
|
||||||
|
|
||||||
|
HalDecTask *task;
|
||||||
|
|
||||||
|
void *hal_pic_private;
|
||||||
|
|
||||||
|
RK_S64 pts;
|
||||||
|
|
||||||
|
|
||||||
|
} HEVCContext;
|
||||||
|
|
||||||
|
RK_S32 mpp_hevc_decode_short_term_rps(HEVCContext *s, ShortTermRPS *rps,
|
||||||
|
const HEVCSPS *sps, RK_S32 is_slice_header);
|
||||||
|
RK_S32 mpp_hevc_decode_nal_vps(HEVCContext *s);
|
||||||
|
RK_S32 mpp_hevc_decode_nal_sps(HEVCContext *s);
|
||||||
|
RK_S32 mpp_hevc_decode_nal_pps(HEVCContext *s);
|
||||||
|
RK_S32 mpp_hevc_decode_nal_sei(HEVCContext *s);
|
||||||
|
|
||||||
|
RK_S32 mpp_hevc_extract_rbsp(HEVCContext *s, const RK_U8 *src, RK_S32 length,
|
||||||
|
HEVCNAL *nal);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark all frames in DPB as unused for reference.
|
||||||
|
*/
|
||||||
|
void mpp_hevc_clear_refs(HEVCContext *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop all frames currently in DPB.
|
||||||
|
*/
|
||||||
|
void mpp_hevc_flush_dpb(HEVCContext *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute POC of the current frame and return it.
|
||||||
|
*/
|
||||||
|
int mpp_hevc_compute_poc(HEVCContext *s, RK_S32 poc_lsb);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the reference picture sets for the current frame.
|
||||||
|
*/
|
||||||
|
RK_S32 mpp_hevc_frame_rps(HEVCContext *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the reference picture list(s) for the current slice.
|
||||||
|
*/
|
||||||
|
RK_S32 mpp_hevc_slice_rpl(HEVCContext *s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of candidate references for the current frame.
|
||||||
|
*/
|
||||||
|
RK_S32 mpp_hevc_frame_nb_refs(HEVCContext *s);
|
||||||
|
RK_S32 mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *frame, RK_S32 poc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find next frame in output order and put a reference to it in frame.
|
||||||
|
* @return 1 if a frame was output, 0 otherwise
|
||||||
|
*/
|
||||||
|
void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, RK_S32 flags);
|
||||||
|
|
||||||
|
void mpp_hevc_pps_free(RK_U8 *data);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __H265D_PAESER_H__ */
|
311
mpp/codec/dec/h265/h265d_parser2_syntax.c
Normal file
311
mpp/codec/dec/h265/h265d_parser2_syntax.c
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_parser2_syntax.c
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MODULE_TAG "H265SYNATX"
|
||||||
|
#include "h265d_parser.h"
|
||||||
|
#include "h265d_syntax.h"
|
||||||
|
|
||||||
|
static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
|
||||||
|
unsigned index, unsigned flag)
|
||||||
|
{
|
||||||
|
mpp_assert((index & 0x7f) == index && (flag & 0x01) == flag);
|
||||||
|
pic->bPicEntry = index | (flag << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
|
||||||
|
{
|
||||||
|
RK_U32 i;
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicList); i++) {
|
||||||
|
if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index) {
|
||||||
|
//mpp_err("retun %d slot_index = %d",i,surface_index);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_picture_parameters(const HEVCContext *h,
|
||||||
|
DXVA_PicParams_HEVC *pp)
|
||||||
|
{
|
||||||
|
const HEVCFrame *current_picture = h->ref;
|
||||||
|
const HEVCPPS *pps = (HEVCPPS *)h->pps_list[h->sh.pps_id];
|
||||||
|
const HEVCSPS *sps = (HEVCSPS *)h->sps_list[pps->sps_id];
|
||||||
|
|
||||||
|
RK_U32 i, j;
|
||||||
|
|
||||||
|
memset(pp, 0, sizeof(*pp));
|
||||||
|
|
||||||
|
pp->PicWidthInMinCbsY = sps->min_cb_width;
|
||||||
|
pp->PicHeightInMinCbsY = sps->min_cb_height;
|
||||||
|
pp->pps_id = h->sh.pps_id;
|
||||||
|
pp->sps_id = pps->sps_id;
|
||||||
|
pp->vps_id = sps->vps_id;
|
||||||
|
|
||||||
|
pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc << 0) |
|
||||||
|
(sps->separate_colour_plane_flag << 2) |
|
||||||
|
((sps->bit_depth - 8) << 3) |
|
||||||
|
((sps->bit_depth - 8) << 6) |
|
||||||
|
((sps->log2_max_poc_lsb - 4) << 9) |
|
||||||
|
(0 << 13) |
|
||||||
|
(0 << 14) |
|
||||||
|
(0 << 15);
|
||||||
|
|
||||||
|
fill_picture_entry(&pp->CurrPic, current_picture->slot_index, 0);
|
||||||
|
|
||||||
|
pp->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
|
||||||
|
pp->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
|
||||||
|
pp->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
|
||||||
|
pp->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
|
||||||
|
pp->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
|
||||||
|
pp->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
|
||||||
|
pp->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
|
||||||
|
pp->num_short_term_ref_pic_sets = sps->nb_st_rps;
|
||||||
|
pp->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
|
||||||
|
|
||||||
|
pp->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
|
||||||
|
pp->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
|
||||||
|
pp->init_qp_minus26 = pps->pic_init_qp_minus26;
|
||||||
|
|
||||||
|
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
|
||||||
|
pp->ucNumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps->rps_idx_num_delta_pocs;
|
||||||
|
pp->wNumBitsForShortTermRPSInSlice = h->sh.short_term_ref_pic_set_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp->dwCodingParamToolFlags = (sps->scaling_list_enable_flag << 0) |
|
||||||
|
(sps->amp_enabled_flag << 1) |
|
||||||
|
(sps->sao_enabled << 2) |
|
||||||
|
(sps->pcm_enabled_flag << 3) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth - 1) : 0) << 4) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth_chroma - 1) : 0) << 8) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size) : 0) << 14) |
|
||||||
|
(sps->pcm.loop_filter_disable_flag << 16) |
|
||||||
|
(sps->long_term_ref_pics_present_flag << 17) |
|
||||||
|
(sps->sps_temporal_mvp_enabled_flag << 18) |
|
||||||
|
(sps->sps_strong_intra_smoothing_enable_flag << 19) |
|
||||||
|
(pps->dependent_slice_segments_enabled_flag << 20) |
|
||||||
|
(pps->output_flag_present_flag << 21) |
|
||||||
|
(pps->num_extra_slice_header_bits << 22) |
|
||||||
|
(pps->sign_data_hiding_flag << 25) |
|
||||||
|
(pps->cabac_init_present_flag << 26) |
|
||||||
|
(0 << 27);
|
||||||
|
|
||||||
|
pp->dwCodingSettingPicturePropertyFlags = (pps->constrained_intra_pred_flag << 0) |
|
||||||
|
(pps->transform_skip_enabled_flag << 1) |
|
||||||
|
(pps->cu_qp_delta_enabled_flag << 2) |
|
||||||
|
(pps->pic_slice_level_chroma_qp_offsets_present_flag << 3) |
|
||||||
|
(pps->weighted_pred_flag << 4) |
|
||||||
|
(pps->weighted_bipred_flag << 5) |
|
||||||
|
(pps->transquant_bypass_enable_flag << 6) |
|
||||||
|
(pps->tiles_enabled_flag << 7) |
|
||||||
|
(pps->entropy_coding_sync_enabled_flag << 8) |
|
||||||
|
(pps->uniform_spacing_flag << 9) |
|
||||||
|
((pps->tiles_enabled_flag ? pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
|
||||||
|
(pps->seq_loop_filter_across_slices_enabled_flag << 11) |
|
||||||
|
(pps->deblocking_filter_override_enabled_flag << 12) |
|
||||||
|
(pps->disable_dbf << 13) |
|
||||||
|
(pps->lists_modification_present_flag << 14) |
|
||||||
|
(pps->slice_header_extension_present_flag << 15) |
|
||||||
|
(IS_IRAP(h) << 16) |
|
||||||
|
(IS_IDR(h) << 17) |
|
||||||
|
/* IntraPicFlag */
|
||||||
|
(IS_IRAP(h) << 18) |
|
||||||
|
(0 << 19);
|
||||||
|
pp->pps_cb_qp_offset = pps->cb_qp_offset;
|
||||||
|
pp->pps_cr_qp_offset = pps->cr_qp_offset;
|
||||||
|
if (pps->tiles_enabled_flag) {
|
||||||
|
pp->num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||||
|
pp->num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||||
|
|
||||||
|
if (!pps->uniform_spacing_flag) {
|
||||||
|
for (i = 0; i < (RK_U32)pps->num_tile_columns; i++)
|
||||||
|
pp->column_width_minus1[i] = pps->column_width[i] - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < (RK_U32)pps->num_tile_rows; i++)
|
||||||
|
pp->row_height_minus1[i] = pps->row_height[i] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pp->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
|
||||||
|
pp->pps_beta_offset_div2 = pps->beta_offset / 2;
|
||||||
|
pp->pps_tc_offset_div2 = pps->tc_offset / 2;
|
||||||
|
pp->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
|
||||||
|
pp->CurrPicOrderCntVal = h->poc;
|
||||||
|
|
||||||
|
mpp_err("fill RefPicList from the DPB");
|
||||||
|
// fill RefPicList from the DPB
|
||||||
|
for (i = 0, j = 0; i < MPP_ARRAY_ELEMS(pp->RefPicList); i++) {
|
||||||
|
const HEVCFrame *frame = NULL;
|
||||||
|
while (!frame && j < MPP_ARRAY_ELEMS(h->DPB)) {
|
||||||
|
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
|
||||||
|
frame = &h->DPB[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame) {
|
||||||
|
fill_picture_entry(&pp->RefPicList[i], frame->slot_index, !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
|
||||||
|
pp->PicOrderCntValList[i] = frame->poc;
|
||||||
|
mpp_buf_slot_inc_hw_ref(h->slots, frame->slot_index);
|
||||||
|
h->task->refer[i] = frame->slot_index;
|
||||||
|
//mpp_err("ref[%d] = %d",i,frame->slot_index);
|
||||||
|
} else {
|
||||||
|
pp->RefPicList[i].bPicEntry = 0xff;
|
||||||
|
pp->PicOrderCntValList[i] = 0;
|
||||||
|
h->task->refer[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DO_REF_LIST(ref_idx, ref_list) { \
|
||||||
|
const RefPicList *rpl = &h->rps[ref_idx]; \
|
||||||
|
for (i = 0, j = 0; i < MPP_ARRAY_ELEMS(pp->ref_list); i++) { \
|
||||||
|
const HEVCFrame *frame = NULL; \
|
||||||
|
while (!frame && j < (RK_U32)rpl->nb_refs) \
|
||||||
|
frame = rpl->ref[j++]; \
|
||||||
|
if (frame) \
|
||||||
|
pp->ref_list[i] = get_refpic_index(pp, frame->slot_index); \
|
||||||
|
else \
|
||||||
|
pp->ref_list[i] = 0xff; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill short term and long term lists
|
||||||
|
DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
|
||||||
|
DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
|
||||||
|
DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
|
||||||
|
|
||||||
|
}
|
||||||
|
extern RK_U8 mpp_hevc_diag_scan4x4_x[16];
|
||||||
|
extern RK_U8 mpp_hevc_diag_scan4x4_y[16];
|
||||||
|
extern RK_U8 mpp_hevc_diag_scan8x8_x[64];
|
||||||
|
extern RK_U8 mpp_hevc_diag_scan8x8_y[64];
|
||||||
|
|
||||||
|
static void fill_scaling_lists(const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
|
||||||
|
{
|
||||||
|
RK_U32 i, j, pos;
|
||||||
|
const HEVCPPS *pps = (HEVCPPS *)h->pps_list[h->sh.pps_id];
|
||||||
|
const HEVCSPS *sps = (HEVCSPS *)h->sps_list[pps->sps_id];
|
||||||
|
const ScalingList *sl = pps->scaling_list_data_present_flag ?
|
||||||
|
&pps->scaling_list : &sps->scaling_list;
|
||||||
|
|
||||||
|
memset(qm, 0, sizeof(*qm));
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
pos = 4 * mpp_hevc_diag_scan4x4_y[j] + mpp_hevc_diag_scan4x4_x[j];
|
||||||
|
qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 64; j++) {
|
||||||
|
pos = 8 * mpp_hevc_diag_scan8x8_y[j] + mpp_hevc_diag_scan8x8_x[j];
|
||||||
|
qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
|
||||||
|
qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
|
||||||
|
|
||||||
|
if (i < 2)
|
||||||
|
qm->ucScalingLists3[i][j] = sl->sl[3][i * 3][pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
|
||||||
|
|
||||||
|
if (i < 2)
|
||||||
|
qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i * 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
|
||||||
|
unsigned position, unsigned size)
|
||||||
|
{
|
||||||
|
memset(slice, 0, sizeof(*slice));
|
||||||
|
slice->BSNALunitDataLocation = position;
|
||||||
|
slice->SliceBytesInBuffer = size;
|
||||||
|
slice->wBadSliceChopping = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 h265d_parser2_syntax(void *ctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
H265dContext_t *h265dctx = (H265dContext_t *)ctx;
|
||||||
|
const HEVCContext *h = h265dctx->priv_data;
|
||||||
|
|
||||||
|
h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private;
|
||||||
|
|
||||||
|
/* Fill up DXVA_PicParams_HEVC */
|
||||||
|
fill_picture_parameters(h, &ctx_pic->pp);
|
||||||
|
|
||||||
|
/* Fill up DXVA_Qmatrix_HEVC */
|
||||||
|
fill_scaling_lists(h, &ctx_pic->qm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 h265d_syntax_fill_slice(void *ctx, MppBuffer *streambuf)
|
||||||
|
{
|
||||||
|
H265dContext_t *h265dctx = (H265dContext_t *)ctx;
|
||||||
|
const HEVCContext *h = h265dctx->priv_data;
|
||||||
|
h265d_dxva2_picture_context_t *ctx_pic = h->hal_pic_private;
|
||||||
|
RK_S32 i, count = 0;
|
||||||
|
RK_U32 position = 0;
|
||||||
|
RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(streambuf);
|
||||||
|
RK_U8 *current = ptr;
|
||||||
|
if (current == NULL) {
|
||||||
|
return MPP_ERR_NULL_PTR;
|
||||||
|
}
|
||||||
|
for (i = 0; i < h->nb_nals; i++) {
|
||||||
|
static const RK_U8 start_code[] = {0, 0, 1 };
|
||||||
|
static const RK_U32 start_code_size = sizeof(start_code);
|
||||||
|
GetBitCxt_t gb_cxt, *gb;
|
||||||
|
RK_S32 value;
|
||||||
|
RK_U32 nal_type;
|
||||||
|
|
||||||
|
mpp_Init_Bits(&gb_cxt, (RK_U8 *)h->nals[i].data,
|
||||||
|
h->nals[i].size);
|
||||||
|
|
||||||
|
gb = &gb_cxt;
|
||||||
|
|
||||||
|
READ_BIT1(gb, &value);
|
||||||
|
|
||||||
|
if ( value != 0)
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
|
||||||
|
READ_BITS(gb, 6, &nal_type);
|
||||||
|
|
||||||
|
if (nal_type >= 32) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(current, start_code, start_code_size);
|
||||||
|
current += start_code_size;
|
||||||
|
position += start_code_size;
|
||||||
|
memcpy(current, h->nals[i].data, h->nals[i].size);
|
||||||
|
mpp_err("h->nals[%d].size = %d", i, h->nals[i].size);
|
||||||
|
fill_slice_short(&ctx_pic->slice_short[i], position, h->nals[i].size);
|
||||||
|
current += h->nals[i].size;
|
||||||
|
position += h->nals[i].size;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
ctx_pic->slice_count = count;
|
||||||
|
ctx_pic->bitstream_size = position;
|
||||||
|
ctx_pic->bitstream = (RK_U8*)ptr;
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
2146
mpp/codec/dec/h265/h265d_ps.c
Normal file
2146
mpp/codec/dec/h265/h265d_ps.c
Normal file
File diff suppressed because it is too large
Load Diff
450
mpp/codec/dec/h265/h265d_refs.c
Normal file
450
mpp/codec/dec/h265/h265d_refs.c
Normal file
@@ -0,0 +1,450 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265_refs.c
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
#define LOG_TAG "H265_PARSER_REF"
|
||||||
|
#include "h265d_parser.h"
|
||||||
|
#define HEVC_ALIGN(value, x) ((value + (x-1)) & (~(x-1)))
|
||||||
|
|
||||||
|
void mpp_hevc_unref_frame(HEVCContext *s, HEVCFrame *frame, int flags)
|
||||||
|
{
|
||||||
|
/* frame->frame can be NULL if context init failed */
|
||||||
|
if (!frame->frame || (frame->slot_index == 0xff))
|
||||||
|
return;
|
||||||
|
|
||||||
|
frame->flags &= ~flags;
|
||||||
|
if (!frame->flags) {
|
||||||
|
mpp_free(frame->rpl_buf);
|
||||||
|
mpp_free(frame->rpl_tab_buf);
|
||||||
|
frame->rpl_tab = NULL;
|
||||||
|
frame->refPicList = NULL;
|
||||||
|
frame->collocated_ref = NULL;
|
||||||
|
if (frame->slot_index <= 0x7f) {
|
||||||
|
h265d_dbg(H265D_DBG_REF, "poc %d clr ref index %d", frame->poc, frame->slot_index);
|
||||||
|
mpp_buf_slot_clr_dpb_ref(s->slots, frame->slot_index);
|
||||||
|
}
|
||||||
|
h265d_dbg(H265D_DBG_REF, "unref_frame poc %d frame->slot_index %d \n", frame->poc, frame->slot_index);
|
||||||
|
frame->poc = INT_MAX;
|
||||||
|
frame->slot_index = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mpp_hevc_clear_refs(HEVCContext *s)
|
||||||
|
{
|
||||||
|
RK_U32 i;
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
mpp_hevc_unref_frame(s, &s->DPB[i],
|
||||||
|
HEVC_FRAME_FLAG_SHORT_REF |
|
||||||
|
HEVC_FRAME_FLAG_LONG_REF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpp_hevc_flush_dpb(HEVCContext *s)
|
||||||
|
{
|
||||||
|
RK_U32 i;
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
mpp_hevc_unref_frame(s, &s->DPB[i], ~0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HEVCFrame *alloc_frame(HEVCContext *s)
|
||||||
|
{
|
||||||
|
|
||||||
|
RK_S32 j;
|
||||||
|
RK_U32 i;
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
HEVCFrame *frame = &s->DPB[i];
|
||||||
|
if (frame->slot_index != 0xff) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != MPP_OK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
mpp_err("width = %d height = %d", s->h265dctx->width, s->h265dctx->height);
|
||||||
|
mpp_frame_set_width(frame->frame, s->h265dctx->width);
|
||||||
|
mpp_frame_set_height(frame->frame, s->h265dctx->height);
|
||||||
|
|
||||||
|
mpp_frame_set_hor_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_width, 256) | 256);
|
||||||
|
mpp_frame_set_ver_stride(frame->frame, HEVC_ALIGN(s->h265dctx->coded_height, 8));
|
||||||
|
|
||||||
|
// frame->frame->color_type = s->h265dctx->pix_fmt;
|
||||||
|
// if (!frame->frame->sample_aspect_ratio.num)
|
||||||
|
// frame->frame->sample_aspect_ratio = s->h265dctx->sample_aspect_ratio;
|
||||||
|
mpp_frame_set_pts(frame->frame, s->pts);
|
||||||
|
|
||||||
|
frame->rpl_buf = mpp_calloc(RK_U8, s->nb_nals * sizeof(RefPicListTab));
|
||||||
|
if (!frame->rpl_buf)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
frame->ctb_count = s->sps->ctb_width * s->sps->ctb_height;
|
||||||
|
frame->rpl_tab_buf = mpp_calloc(RK_U8, frame->ctb_count * sizeof(RefPicListTab));
|
||||||
|
|
||||||
|
if (!frame->rpl_tab_buf)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
frame->rpl_tab = (RefPicListTab **)frame->rpl_tab_buf;
|
||||||
|
|
||||||
|
for (j = 0; j < frame->ctb_count; j++)
|
||||||
|
frame->rpl_tab[j] = (RefPicListTab *)frame->rpl_buf;
|
||||||
|
|
||||||
|
// frame->frame->top_field_first = s->picture_struct;
|
||||||
|
ret = mpp_buf_slot_get_unused(s->slots, &frame->slot_index);
|
||||||
|
return frame;
|
||||||
|
fail:
|
||||||
|
mpp_hevc_unref_frame(s, frame, ~0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
mpp_err( "Error allocating frame, DPB full.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpp_hevc_set_new_ref(HEVCContext *s, MppFrame *mframe, int poc)
|
||||||
|
{
|
||||||
|
|
||||||
|
HEVCFrame *ref = NULL;
|
||||||
|
RK_U32 i;
|
||||||
|
|
||||||
|
/* check that this POC doesn't already exist */
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
HEVCFrame *frame = &s->DPB[i];
|
||||||
|
|
||||||
|
if ((frame->slot_index != 0xff) && frame->sequence == s->seq_decode &&
|
||||||
|
frame->poc == poc && !s->nuh_layer_id) {
|
||||||
|
mpp_err( "Duplicate POC in a sequence: %d.\n",
|
||||||
|
poc);
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = alloc_frame(s);
|
||||||
|
if (!ref)
|
||||||
|
return MPP_ERR_NOMEM;
|
||||||
|
|
||||||
|
*mframe = ref->frame;
|
||||||
|
s->ref = ref;
|
||||||
|
|
||||||
|
ref->poc = poc;
|
||||||
|
h265d_dbg(H265D_DBG_REF, "alloc frame poc %d slot_index %d", poc, ref->slot_index);
|
||||||
|
ref->flags = HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_SHORT_REF;
|
||||||
|
|
||||||
|
mpp_buf_slot_set_dpb_ref(s->slots, ref->slot_index);
|
||||||
|
mpp_buf_slot_set_hw_dst(s->slots, ref->slot_index, ref->frame);
|
||||||
|
s->task->output = ref->slot_index;
|
||||||
|
|
||||||
|
ref->sequence = s->seq_decode;
|
||||||
|
ref->window = s->sps->output_window;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int init_slice_rpl(HEVCContext *s)
|
||||||
|
{
|
||||||
|
HEVCFrame *frame = s->ref;
|
||||||
|
RK_S32 ctb_count = frame->ctb_count;
|
||||||
|
RK_S32 ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_segment_addr];
|
||||||
|
RK_S32 i;
|
||||||
|
|
||||||
|
if (s->slice_idx >= s->nb_nals)
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
|
||||||
|
for (i = ctb_addr_ts; i < ctb_count; i++)
|
||||||
|
frame->rpl_tab[i] = (RefPicListTab *)frame->rpl_buf + s->slice_idx;
|
||||||
|
|
||||||
|
frame->refPicList = (RefPicList *)frame->rpl_tab[ctb_addr_ts];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HEVCFrame *find_ref_idx(HEVCContext *s, int poc)
|
||||||
|
{
|
||||||
|
RK_U32 i;
|
||||||
|
RK_S32 LtMask = (1 << s->sps->log2_max_poc_lsb) - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
HEVCFrame *ref = &s->DPB[i];
|
||||||
|
if ((ref->slot_index != 0xff) && (ref->sequence == s->seq_decode)) {
|
||||||
|
if ((ref->poc & LtMask) == poc)
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
HEVCFrame *ref = &s->DPB[i];
|
||||||
|
if ((ref->slot_index != 0xff) && ref->sequence == s->seq_decode) {
|
||||||
|
if (ref->poc == poc || (ref->poc & LtMask) == poc)
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_err(
|
||||||
|
"Could not find ref with POC %d\n", poc);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpp_hevc_slice_rpl(HEVCContext *s)
|
||||||
|
{
|
||||||
|
|
||||||
|
SliceHeader *sh = &s->sh;
|
||||||
|
|
||||||
|
RK_U8 nb_list = sh->slice_type == B_SLICE ? 2 : 1;
|
||||||
|
RK_U8 list_idx;
|
||||||
|
RK_U32 i;
|
||||||
|
RK_S32 j, ret;
|
||||||
|
|
||||||
|
ret = init_slice_rpl(s);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!(s->rps[ST_CURR_BEF].nb_refs + s->rps[ST_CURR_AFT].nb_refs +
|
||||||
|
s->rps[LT_CURR].nb_refs)) {
|
||||||
|
mpp_err( "Zero refs in the frame RPS.\n");
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (list_idx = 0; list_idx < nb_list; list_idx++) {
|
||||||
|
RefPicList rpl_tmp;
|
||||||
|
memset(&rpl_tmp, 0, sizeof(rpl_tmp));
|
||||||
|
RefPicList *rpl = &s->ref->refPicList[list_idx];
|
||||||
|
|
||||||
|
/* The order of the elements is
|
||||||
|
* ST_CURR_BEF - ST_CURR_AFT - LT_CURR for the L0 and
|
||||||
|
* ST_CURR_AFT - ST_CURR_BEF - LT_CURR for the L1 */
|
||||||
|
RK_S32 cand_lists[3] = { list_idx ? ST_CURR_AFT : ST_CURR_BEF,
|
||||||
|
list_idx ? ST_CURR_BEF : ST_CURR_AFT,
|
||||||
|
LT_CURR
|
||||||
|
};
|
||||||
|
|
||||||
|
/* concatenate the candidate lists for the current frame */
|
||||||
|
while ((RK_U32)rpl_tmp.nb_refs < sh->nb_refs[list_idx]) {
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(cand_lists); i++) {
|
||||||
|
RefPicList *rps = &s->rps[cand_lists[i]];
|
||||||
|
for (j = 0; j < rps->nb_refs && rpl_tmp.nb_refs < MAX_REFS; j++) {
|
||||||
|
rpl_tmp.list[rpl_tmp.nb_refs] = rps->list[j];
|
||||||
|
rpl_tmp.ref[rpl_tmp.nb_refs] = rps->ref[j];
|
||||||
|
rpl_tmp.isLongTerm[rpl_tmp.nb_refs] = i == 2;
|
||||||
|
rpl_tmp.nb_refs++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reorder the references if necessary */
|
||||||
|
if (sh->rpl_modification_flag[list_idx]) {
|
||||||
|
for (i = 0; i < sh->nb_refs[list_idx]; i++) {
|
||||||
|
int idx = sh->list_entry_lx[list_idx][i];
|
||||||
|
|
||||||
|
if (!s->decoder_id && idx >= rpl_tmp.nb_refs) {
|
||||||
|
mpp_err( "Invalid reference index.\n");
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl->list[i] = rpl_tmp.list[idx];
|
||||||
|
rpl->ref[i] = rpl_tmp.ref[idx];
|
||||||
|
rpl->isLongTerm[i] = rpl_tmp.isLongTerm[idx];
|
||||||
|
rpl->nb_refs++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(rpl, &rpl_tmp, sizeof(*rpl));
|
||||||
|
rpl->nb_refs = MPP_MIN((RK_U32)rpl->nb_refs, sh->nb_refs[list_idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sh->collocated_list == list_idx &&
|
||||||
|
sh->collocated_ref_idx < (RK_U32)rpl->nb_refs)
|
||||||
|
s->ref->collocated_ref = rpl->ref[sh->collocated_ref_idx];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mark_ref(HEVCFrame *frame, int flag)
|
||||||
|
{
|
||||||
|
frame->flags &= ~(HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF);
|
||||||
|
frame->flags |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HEVCFrame *generate_missing_ref(HEVCContext *s, int poc)
|
||||||
|
{
|
||||||
|
HEVCFrame *frame;
|
||||||
|
mpp_log("generate_missing_ref in \n");
|
||||||
|
frame = alloc_frame(s);
|
||||||
|
if (!frame)
|
||||||
|
return NULL;
|
||||||
|
#if 0
|
||||||
|
if (!s->sps->pixel_shift) {
|
||||||
|
for (i = 0; frame->frame->buf[i]; i++)
|
||||||
|
memset(frame->frame->buf[i]->data, 1 << (s->sps->bit_depth - 1),
|
||||||
|
frame->frame->buf[i]->size);
|
||||||
|
} else {
|
||||||
|
for (i = 0; frame->frame->data[i]; i++)
|
||||||
|
for (y = 0; y < (s->sps->height >> s->sps->vshift[i]); y++)
|
||||||
|
for (x = 0; x < (s->sps->width >> s->sps->hshift[i]); x++) {
|
||||||
|
AV_WN16(frame->frame->data[i] + y * frame->frame->linesize[i] + 2 * x,
|
||||||
|
1 << (s->sps->bit_depth - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
frame->poc = poc;
|
||||||
|
|
||||||
|
mpp_err("generate_missing_ref frame poc %d slot_index %d", poc, frame->slot_index);
|
||||||
|
frame->sequence = s->seq_decode;
|
||||||
|
frame->flags = 0;
|
||||||
|
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add a reference with the given poc to the list and mark it as used in DPB */
|
||||||
|
static int add_candidate_ref(HEVCContext *s, RefPicList *list,
|
||||||
|
int poc, int ref_flag)
|
||||||
|
{
|
||||||
|
HEVCFrame *ref = find_ref_idx(s, poc);
|
||||||
|
|
||||||
|
if (ref == s->ref)
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
|
||||||
|
if (!ref) {
|
||||||
|
ref = generate_missing_ref(s, poc);
|
||||||
|
if (!ref)
|
||||||
|
return MPP_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
list->list[list->nb_refs] = ref->poc;
|
||||||
|
list->ref[list->nb_refs] = ref;
|
||||||
|
list->nb_refs++;
|
||||||
|
if (ref_flag) {
|
||||||
|
h265d_dbg(H265D_DBG_REF, "set ref poc = %d ref->slot_index %d", ref->poc, ref->slot_index);
|
||||||
|
mpp_buf_slot_set_dpb_ref(s->slots, ref->slot_index);
|
||||||
|
}
|
||||||
|
mark_ref(ref, ref_flag);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_hevc_frame_rps(HEVCContext *s)
|
||||||
|
{
|
||||||
|
|
||||||
|
const ShortTermRPS *short_rps = s->sh.short_term_rps;
|
||||||
|
const LongTermRPS *long_rps = &s->sh.long_term_rps;
|
||||||
|
RefPicList *rps = s->rps;
|
||||||
|
RK_S32 ret;
|
||||||
|
RK_U32 i;
|
||||||
|
|
||||||
|
if (!short_rps) {
|
||||||
|
rps[0].nb_refs = rps[1].nb_refs = 0;
|
||||||
|
if (!long_rps)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear the reference flags on all frames except the current one */
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
HEVCFrame *frame = &s->DPB[i];
|
||||||
|
if (frame == s->ref)
|
||||||
|
continue;
|
||||||
|
mark_ref(frame, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NB_RPS_TYPE; i++)
|
||||||
|
rps[i].nb_refs = 0;
|
||||||
|
|
||||||
|
/* add the short refs */
|
||||||
|
for (i = 0; short_rps && (RK_S32)i < short_rps->num_delta_pocs; i++) {
|
||||||
|
int poc = s->poc + short_rps->delta_poc[i];
|
||||||
|
int list;
|
||||||
|
|
||||||
|
if (!short_rps->used[i])
|
||||||
|
list = ST_FOLL;
|
||||||
|
else if (i < short_rps->num_negative_pics)
|
||||||
|
list = ST_CURR_BEF;
|
||||||
|
else
|
||||||
|
list = ST_CURR_AFT;
|
||||||
|
|
||||||
|
ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_SHORT_REF);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the long refs */
|
||||||
|
for (i = 0; long_rps && i < long_rps->nb_refs; i++) {
|
||||||
|
int poc = long_rps->poc[i];
|
||||||
|
int list = long_rps->used[i] ? LT_CURR : LT_FOLL;
|
||||||
|
|
||||||
|
ret = add_candidate_ref(s, &rps[list], poc, HEVC_FRAME_FLAG_LONG_REF);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/* release any frames that are now unused */
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) {
|
||||||
|
mpp_hevc_unref_frame(s, &s->DPB[i], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpp_hevc_compute_poc(HEVCContext *s, int poc_lsb)
|
||||||
|
{
|
||||||
|
RK_S32 max_poc_lsb = 1 << s->sps->log2_max_poc_lsb;
|
||||||
|
RK_S32 prev_poc_lsb = s->pocTid0 % max_poc_lsb;
|
||||||
|
RK_S32 prev_poc_msb = s->pocTid0 - prev_poc_lsb;
|
||||||
|
RK_S32 poc_msb;
|
||||||
|
|
||||||
|
if (poc_lsb < prev_poc_lsb && prev_poc_lsb - poc_lsb >= max_poc_lsb / 2)
|
||||||
|
poc_msb = prev_poc_msb + max_poc_lsb;
|
||||||
|
else if (poc_lsb > prev_poc_lsb && poc_lsb - prev_poc_lsb > max_poc_lsb / 2)
|
||||||
|
poc_msb = prev_poc_msb - max_poc_lsb;
|
||||||
|
else
|
||||||
|
poc_msb = prev_poc_msb;
|
||||||
|
|
||||||
|
// For BLA picture types, POCmsb is set to 0.
|
||||||
|
if (s->nal_unit_type == NAL_BLA_W_LP ||
|
||||||
|
s->nal_unit_type == NAL_BLA_W_RADL ||
|
||||||
|
s->nal_unit_type == NAL_BLA_N_LP)
|
||||||
|
poc_msb = 0;
|
||||||
|
|
||||||
|
return poc_msb + poc_lsb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpp_hevc_frame_nb_refs(HEVCContext *s)
|
||||||
|
{
|
||||||
|
RK_S32 ret = 0;
|
||||||
|
RK_S32 i;
|
||||||
|
const ShortTermRPS *rps = s->sh.short_term_rps;
|
||||||
|
LongTermRPS *long_rps = &s->sh.long_term_rps;
|
||||||
|
|
||||||
|
if (s->sh.slice_type == I_SLICE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (rps) {
|
||||||
|
for (i = 0; (RK_U32)i < rps->num_negative_pics; i++)
|
||||||
|
ret += !!rps->used[i];
|
||||||
|
for (; i < rps->num_delta_pocs; i++)
|
||||||
|
ret += !!rps->used[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (long_rps) {
|
||||||
|
for (i = 0; i < long_rps->nb_refs; i++)
|
||||||
|
ret += !!long_rps->used[i];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
203
mpp/codec/dec/h265/h265d_sei.c
Normal file
203
mpp/codec/dec/h265/h265d_sei.c
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_sei.c
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "h265d_parser.h"
|
||||||
|
|
||||||
|
static RK_S32 decode_nal_sei_decoded_picture_hash(HEVCContext *s)
|
||||||
|
{
|
||||||
|
RK_S32 cIdx, i;
|
||||||
|
RK_U8 hash_type;
|
||||||
|
//uint16_t picture_crc;
|
||||||
|
//RK_U32 picture_checksum;
|
||||||
|
GetBitCxt_t*gb = &s->HEVClc->gb;
|
||||||
|
READ_BITS(gb, 8, &hash_type);
|
||||||
|
|
||||||
|
for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
|
||||||
|
if (hash_type == 0) {
|
||||||
|
//s->is_md5 = 1;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
READ_SKIPBITS(gb, 8);
|
||||||
|
} else if (hash_type == 1) {
|
||||||
|
READ_SKIPBITS(gb, 16);
|
||||||
|
} else if (hash_type == 2) {
|
||||||
|
READ_SKIPBITS(gb, 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
|
||||||
|
{
|
||||||
|
GetBitCxt_t *gb = &s->HEVClc->gb;
|
||||||
|
RK_S32 value = 0;
|
||||||
|
|
||||||
|
READ_UE(gb, &value); // frame_packing_arrangement_id
|
||||||
|
READ_BIT1(gb, &value);
|
||||||
|
s->sei_frame_packing_present = !value;
|
||||||
|
|
||||||
|
if (s->sei_frame_packing_present) {
|
||||||
|
READ_BITS(gb, 7, &s->frame_packing_arrangement_type);
|
||||||
|
READ_BIT1(gb, &s->quincunx_subsampling);
|
||||||
|
READ_BITS(gb, 6, &s->content_interpretation_type);
|
||||||
|
|
||||||
|
// the following skips spatial_flipping_flag frame0_flipped_flag
|
||||||
|
// field_views_flag current_frame_is_frame0_flag
|
||||||
|
// frame0_self_contained_flag frame1_self_contained_flag
|
||||||
|
READ_SKIPBITS(gb, 6);
|
||||||
|
|
||||||
|
if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
|
||||||
|
READ_SKIPBITS(gb, 16); // frame[01]_grid_position_[xy]
|
||||||
|
READ_SKIPBITS(gb, 8); // frame_packing_arrangement_reserved_byte
|
||||||
|
READ_SKIPBITS(gb, 1); // frame_packing_arrangement_persistance_flag
|
||||||
|
}
|
||||||
|
READ_SKIPBITS(gb, 1); // upsampled_aspect_ratio_flag
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 decode_pic_timing(HEVCContext *s)
|
||||||
|
{
|
||||||
|
GetBitCxt_t *gb = &s->HEVClc->gb;
|
||||||
|
HEVCSPS *sps;
|
||||||
|
|
||||||
|
if (!s->sps_list[s->active_seq_parameter_set_id])
|
||||||
|
return MPP_ERR_NOMEM;
|
||||||
|
sps = (HEVCSPS*)s->sps_list[s->active_seq_parameter_set_id];
|
||||||
|
s->picture_struct = MPP_PICTURE_STRUCTURE_UNKNOWN;
|
||||||
|
if (sps->vui.frame_field_info_present_flag) {
|
||||||
|
READ_BITS(gb, 4, &s->picture_struct);
|
||||||
|
switch (s->picture_struct) {
|
||||||
|
case 0 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "(progressive) frame \n"); break;
|
||||||
|
case 1 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field\n"); break;
|
||||||
|
case 2 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field\n"); break;
|
||||||
|
case 3 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, in that order\n"); break;
|
||||||
|
case 4 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, in that order\n"); break;
|
||||||
|
case 5 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "top field, bottom field, top field repeated, in that order\n"); break;
|
||||||
|
case 6 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "bottom field, top field, bottom field repeated, in that order\n"); break;
|
||||||
|
case 7 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame doubling\n"); break;
|
||||||
|
case 8 : s->picture_struct = MPP_PICTURE_STRUCTURE_FRAME; h265d_dbg(H265D_DBG_SEI, "frame tripling\n"); break;
|
||||||
|
case 9 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with previous bottom field in output order\n"); break;
|
||||||
|
case 10 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with previous top field in output order\n"); break;
|
||||||
|
case 11 : s->picture_struct = MPP_PICTURE_STRUCTURE_TOP_FIELD; h265d_dbg(H265D_DBG_SEI, "top field paired with next bottom field in output order\n"); break;
|
||||||
|
case 12 : s->picture_struct = MPP_PICTURE_STRUCTURE_BOTTOM_FIELD; h265d_dbg(H265D_DBG_SEI, "bottom field paired with next top field in output order\n"); break;
|
||||||
|
}
|
||||||
|
READ_SKIPBITS(gb, 2); // source_scan_type
|
||||||
|
READ_SKIPBITS(gb, 1); // duplicate_flag
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 active_parameter_sets(HEVCContext *s)
|
||||||
|
{
|
||||||
|
GetBitCxt_t *gb = &s->HEVClc->gb;
|
||||||
|
RK_S32 num_sps_ids_minus1;
|
||||||
|
RK_S32 i, value;
|
||||||
|
RK_U32 active_seq_parameter_set_id;
|
||||||
|
|
||||||
|
READ_SKIPBITS(gb, 4); // active_video_parameter_set_id
|
||||||
|
READ_SKIPBITS(gb, 1); // self_contained_cvs_flag
|
||||||
|
READ_SKIPBITS(gb, 1); // num_sps_ids_minus1
|
||||||
|
READ_UE(gb, &num_sps_ids_minus1); // num_sps_ids_minus1
|
||||||
|
|
||||||
|
READ_UE(gb, &active_seq_parameter_set_id);
|
||||||
|
if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
|
||||||
|
mpp_err( "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
s->active_seq_parameter_set_id = active_seq_parameter_set_id;
|
||||||
|
|
||||||
|
for (i = 1; i <= num_sps_ids_minus1; i++)
|
||||||
|
READ_UE(gb, &value); // active_seq_parameter_set_id[i]
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 decode_nal_sei_message(HEVCContext *s)
|
||||||
|
{
|
||||||
|
GetBitCxt_t *gb = &s->HEVClc->gb;
|
||||||
|
|
||||||
|
int payload_type = 0;
|
||||||
|
int payload_size = 0;
|
||||||
|
int byte = 0xFF;
|
||||||
|
h265d_dbg(H265D_DBG_SEI, "Decoding SEI\n");
|
||||||
|
|
||||||
|
while (byte == 0xFF) {
|
||||||
|
READ_BITS(gb, 8, &byte);
|
||||||
|
payload_type += byte;
|
||||||
|
}
|
||||||
|
byte = 0xFF;
|
||||||
|
while (byte == 0xFF) {
|
||||||
|
READ_BITS(gb, 8, &byte);
|
||||||
|
payload_size += byte;
|
||||||
|
}
|
||||||
|
if (s->nal_unit_type == NAL_SEI_PREFIX) {
|
||||||
|
if (payload_type == 256 /*&& s->decode_checksum_sei*/) {
|
||||||
|
decode_nal_sei_decoded_picture_hash(s);
|
||||||
|
return 1;
|
||||||
|
} else if (payload_type == 45) {
|
||||||
|
decode_nal_sei_frame_packing_arrangement(s);
|
||||||
|
return 1;
|
||||||
|
} else if (payload_type == 1) {
|
||||||
|
int ret = decode_pic_timing(s);
|
||||||
|
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
|
||||||
|
READ_SKIPBITS(gb, 8 * payload_size);
|
||||||
|
return ret;
|
||||||
|
} else if (payload_type == 129) {
|
||||||
|
active_parameter_sets(s);
|
||||||
|
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
h265d_dbg(H265D_DBG_SEI, "Skipped PREFIX SEI %d\n", payload_type);
|
||||||
|
READ_SKIPBITS(gb, 8 * payload_size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else { /* nal_unit_type == NAL_SEI_SUFFIX */
|
||||||
|
if (payload_type == 132 /* && s->decode_checksum_sei */)
|
||||||
|
decode_nal_sei_decoded_picture_hash(s);
|
||||||
|
else {
|
||||||
|
h265d_dbg(H265D_DBG_SEI, "Skipped SUFFIX SEI %d\n", payload_type);
|
||||||
|
READ_SKIPBITS(gb, 8 * payload_size);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 more_rbsp_data(GetBitCxt_t *gb)
|
||||||
|
{
|
||||||
|
return gb->bytes_left_ > 1 && gb->data_[0] != 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_hevc_decode_nal_sei(HEVCContext *s)
|
||||||
|
{
|
||||||
|
RK_S32 ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = decode_nal_sei_message(s);
|
||||||
|
if (ret < 0)
|
||||||
|
return MPP_ERR_NOMEM;
|
||||||
|
} while (more_rbsp_data(&s->HEVClc->gb));
|
||||||
|
return 1;
|
||||||
|
}
|
24
mpp/codec/dec/h265/test/CMakeLists.txt
Normal file
24
mpp/codec/dec/h265/test/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# vim: syntax=cmake
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# codec h265 built-in unit test case
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# log system unit test
|
||||||
|
option(H265D_TEST "Build codec h265d_parser unit test" ON)
|
||||||
|
if(H265D_TEST)
|
||||||
|
add_executable(h265d_parser_test h265d_parser_test.c)
|
||||||
|
include_directories(.)
|
||||||
|
link_directories(.)
|
||||||
|
if(ANDROID)
|
||||||
|
target_link_libraries(h265d_parser_test m h265d_parser osal h265d_hal mpp_codec mpp vpu)
|
||||||
|
else()
|
||||||
|
set(OPENHEVCSO "${CMAKE_SOURCE_DIR}/mpp/codec/dec/h265/test")
|
||||||
|
add_library(openhevcwrapper SHARED IMPORTED)
|
||||||
|
set_target_properties(openhevcwrapper PROPERTIES
|
||||||
|
IMPORTED_LOCATION
|
||||||
|
"${OPENHEVCSO}/libLibOpenHevcWrapper.so")
|
||||||
|
target_link_libraries(h265d_parser_test openhevcwrapper m h265d_parser osal h265d_hal mpp_codec mpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
520
mpp/codec/dec/h265/test/h265d_parser_test.c
Normal file
520
mpp/codec/dec/h265/test/h265d_parser_test.c
Normal file
@@ -0,0 +1,520 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Rockchip Electronics S.LSI Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* @file h265d_parser_test.c
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MODULE_TAG "H265TEST"
|
||||||
|
#include "h265d_api.h"
|
||||||
|
#include "hal_h265d_api.h"
|
||||||
|
|
||||||
|
#include "mpp_log.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "mpp_err.h"
|
||||||
|
#include "mpp_mem.h"
|
||||||
|
#include "mpp_frame.h"
|
||||||
|
#include "openHevcWrapper.h"
|
||||||
|
#include "mpp_buf_slot.h"
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include "mpp_common.h"
|
||||||
|
#include "mpp_dec.h"
|
||||||
|
#include "h265d_api.h"
|
||||||
|
#include "hal_h265d_api.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum VPU_API_DEMO_RET {
|
||||||
|
PARSER_DEMO_OK = 0,
|
||||||
|
PARSER_DEMO_PARSE_HELP_OK = 1,
|
||||||
|
|
||||||
|
PARSER_DEMO_ERROR_BASE = -100,
|
||||||
|
ERROR_INVALID_PARAM = PARSER_DEMO_ERROR_BASE - 1,
|
||||||
|
ERROR_INVALID_STREAM = PARSER_DEMO_ERROR_BASE - 2,
|
||||||
|
ERROR_IO = PARSER_DEMO_ERROR_BASE - 3,
|
||||||
|
ERROR_MEMORY = PARSER_DEMO_ERROR_BASE - 4,
|
||||||
|
ERROR_INIT_VPU = PARSER_DEMO_ERROR_BASE - 5,
|
||||||
|
|
||||||
|
ERROR_VPU_DECODE = PARSER_DEMO_ERROR_BASE - 90,
|
||||||
|
} PARSER_API_DEMO_RET;
|
||||||
|
|
||||||
|
typedef struct ParserCmd {
|
||||||
|
RK_U8* name;
|
||||||
|
RK_U8* argname;
|
||||||
|
RK_U8* help;
|
||||||
|
} ParserCmd_t;
|
||||||
|
|
||||||
|
typedef struct parserDemoCmdContext {
|
||||||
|
RK_U32 width;
|
||||||
|
RK_U32 height;
|
||||||
|
RK_U8 input_file[200];
|
||||||
|
RK_U8 output_file[200];
|
||||||
|
RK_U8 have_input;
|
||||||
|
RK_U8 have_output;
|
||||||
|
RK_U8 disable_debug;
|
||||||
|
RK_U32 record_frames;
|
||||||
|
RK_S64 record_start_ms;
|
||||||
|
} ParserDemoCmdContext_t;
|
||||||
|
|
||||||
|
|
||||||
|
static ParserCmd_t parserCmd[] = {
|
||||||
|
{(RK_U8*)"i", (RK_U8*)"input_file", (RK_U8*)"input bitstream file"},
|
||||||
|
{(RK_U8*)"o", (RK_U8*)"output_file", (RK_U8*)"output bitstream file, "},
|
||||||
|
{(RK_U8*)"w", (RK_U8*)"width", (RK_U8*)"the width of input bitstream"},
|
||||||
|
{(RK_U8*)"h", (RK_U8*)"height", (RK_U8*)"the height of input bitstream"},
|
||||||
|
{(RK_U8*)"vframes", (RK_U8*)"number", (RK_U8*)"set the number of video frames to record"},
|
||||||
|
{(RK_U8*)"ss", (RK_U8*)"time_off", (RK_U8*)"set the start time offset, use Ms as the unit."},
|
||||||
|
{(RK_U8*)"d", (RK_U8*)"disable", (RK_U8*)"disable the debug output info."},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void show_usage()
|
||||||
|
{
|
||||||
|
mpp_log("usage: parserDemo [options] input_file, \n\n");
|
||||||
|
|
||||||
|
mpp_log("Getting help:\n");
|
||||||
|
mpp_log("-help --print options of vpu api demo\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 show_help()
|
||||||
|
{
|
||||||
|
mpp_log("usage: parserDemo [options] input_file, \n\n");
|
||||||
|
|
||||||
|
RK_U32 i = 0;
|
||||||
|
RK_U32 n = sizeof(parserCmd) / sizeof(ParserCmd_t);
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
mpp_log("-%s %s\t\t%s\n",
|
||||||
|
parserCmd[i].name, parserCmd[i].argname, parserCmd[i].help);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RK_S32 parse_options(int argc, char **argv, ParserDemoCmdContext_t* cmdCxt)
|
||||||
|
{
|
||||||
|
const char *opt;
|
||||||
|
RK_S32 optindex, handleoptions = 1, ret = 0;
|
||||||
|
|
||||||
|
if ((argc < 2) || (cmdCxt == NULL)) {
|
||||||
|
mpp_log("parser demo, input parameter invalid\n");
|
||||||
|
show_usage();
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse options */
|
||||||
|
optindex = 1;
|
||||||
|
while (optindex < argc) {
|
||||||
|
opt = (const char*)argv[optindex++];
|
||||||
|
|
||||||
|
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
|
||||||
|
if (opt[1] == '-') {
|
||||||
|
if (opt[2] != '\0') {
|
||||||
|
opt++;
|
||||||
|
} else {
|
||||||
|
handleoptions = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opt++;
|
||||||
|
|
||||||
|
switch (*opt) {
|
||||||
|
case 'i':
|
||||||
|
if (argv[optindex]) {
|
||||||
|
memcpy(cmdCxt->input_file, argv[optindex], strlen(argv[optindex]));
|
||||||
|
cmdCxt->input_file[strlen(argv[optindex])] = '\0';
|
||||||
|
cmdCxt->have_input = 1;
|
||||||
|
} else {
|
||||||
|
mpp_log("input file is invalid\n");
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
if (argv[optindex]) {
|
||||||
|
memcpy(cmdCxt->output_file, argv[optindex], strlen(argv[optindex]));
|
||||||
|
cmdCxt->output_file[strlen(argv[optindex])] = '\0';
|
||||||
|
cmdCxt->have_output = 1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
mpp_log("out file is invalid\n");
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
case 'd':
|
||||||
|
cmdCxt->disable_debug = 1;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
if (argv[optindex]) {
|
||||||
|
cmdCxt->width = atoi(argv[optindex]);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
mpp_log("input width is invalid\n");
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
case 'h':
|
||||||
|
if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) {
|
||||||
|
show_help();
|
||||||
|
ret = PARSER_DEMO_PARSE_HELP_OK;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
} else if (argv[optindex]) {
|
||||||
|
cmdCxt->height = atoi(argv[optindex]);
|
||||||
|
} else {
|
||||||
|
mpp_log("input height is invalid\n");
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((*(opt + 1) != '\0') && argv[optindex]) {
|
||||||
|
if (!strncmp(opt, "vframes", 7)) {
|
||||||
|
cmdCxt->record_frames = atoi(argv[optindex]);
|
||||||
|
} else if (!strncmp(opt, "ss", 2)) {
|
||||||
|
cmdCxt->record_start_ms = atoi(argv[optindex]);
|
||||||
|
} else {
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = -1;
|
||||||
|
goto PARSE_OPINIONS_OUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
optindex += ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PARSE_OPINIONS_OUT:
|
||||||
|
if (ret < 0) {
|
||||||
|
mpp_log("vpu api demo, input parameter invalid\n");
|
||||||
|
show_usage();
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RK_S32 find_start_code (RK_U8 *Buf, RK_S32 zeros_in_startcode)
|
||||||
|
{
|
||||||
|
RK_S32 i;
|
||||||
|
for (i = 0; i < zeros_in_startcode; i++)
|
||||||
|
if (Buf[i] != 0)
|
||||||
|
return 0;
|
||||||
|
return Buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 get_next_nal(FILE* inpf, unsigned char* Buf)
|
||||||
|
{
|
||||||
|
RK_S32 pos = 0;
|
||||||
|
RK_S32 StartCodeFound = 0;
|
||||||
|
RK_S32 info2 = 0;
|
||||||
|
RK_S32 info3 = 0;
|
||||||
|
|
||||||
|
while (!feof(inpf) && (Buf[pos++] = fgetc(inpf)) == 0);
|
||||||
|
|
||||||
|
while (pos < 3) Buf[pos++] = fgetc(inpf);
|
||||||
|
while (!StartCodeFound) {
|
||||||
|
if (feof (inpf)) {
|
||||||
|
return pos - 1;
|
||||||
|
}
|
||||||
|
Buf[pos++] = fgetc(inpf);
|
||||||
|
info3 = find_start_code(&Buf[pos - 4], 3);
|
||||||
|
if (info3 != 1)
|
||||||
|
info2 = find_start_code(&Buf[pos - 3], 2);
|
||||||
|
StartCodeFound = (info2 == 1 || info3 == 1);
|
||||||
|
}
|
||||||
|
fseek(inpf, - 4 + info2, SEEK_CUR);
|
||||||
|
return pos - 4 + info2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static RK_S32 poll_task(void *hal, MppBufSlots slots, HalDecTask *dec)
|
||||||
|
{
|
||||||
|
HalTask syn;
|
||||||
|
RK_U32 i;
|
||||||
|
syn.dec = *dec;
|
||||||
|
hal_h265d_wait(hal, &syn);
|
||||||
|
mpp_err("dec->output = %d", dec->output);
|
||||||
|
mpp_buf_slot_clr_hw_dst(slots, dec->output);
|
||||||
|
for (i = 0; i < MPP_ARRAY_ELEMS(dec->refer); i++) {
|
||||||
|
RK_S32 id;
|
||||||
|
id = dec->refer[i];
|
||||||
|
if (id >= 0)
|
||||||
|
mpp_buf_slot_dec_hw_ref(slots, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RK_S32 hevc_parser_test(ParserDemoCmdContext_t *cmd)
|
||||||
|
{
|
||||||
|
FILE* pInFile = NULL;
|
||||||
|
RK_U8 * buf = NULL;
|
||||||
|
RK_S32 nal_len = 0;
|
||||||
|
void *mpp_codex_ctx = NULL;
|
||||||
|
void *hal = NULL;
|
||||||
|
// void *openHevcHandle = NULL;
|
||||||
|
MppBufSlots slots;
|
||||||
|
ParserCfg parser_cfg;
|
||||||
|
MppHalCfg hal_cfg;
|
||||||
|
MppBufferGroup mFrameGroup = NULL;
|
||||||
|
MppBufferGroup mStreamGroup = NULL;
|
||||||
|
MppPacket rkpkt = NULL;
|
||||||
|
MppFrame frame = NULL;
|
||||||
|
|
||||||
|
MppBuffer prestrem = NULL;
|
||||||
|
MppBuffer currentstrem = NULL;
|
||||||
|
|
||||||
|
HalDecTask *cutask = NULL;
|
||||||
|
HalDecTask *pretask = NULL;
|
||||||
|
|
||||||
|
FILE * fp = NULL;
|
||||||
|
RK_U32 wait_task = 0;
|
||||||
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
|
if (fp == NULL) {
|
||||||
|
fp = fopen("data/dump.yuv", "wb");
|
||||||
|
}
|
||||||
|
if (cmd->width == 0 || cmd->height == 0) {
|
||||||
|
cmd->width = 4096;
|
||||||
|
cmd->height = 2160;
|
||||||
|
}
|
||||||
|
|
||||||
|
cutask = mpp_calloc(HalDecTask, 1);
|
||||||
|
pretask = mpp_calloc(HalDecTask, 1);
|
||||||
|
|
||||||
|
mpp_codex_ctx = mpp_calloc(void, api_h265d_parser.ctx_size);
|
||||||
|
mpp_err("api_h265d_parser.ctx_size = %d", api_h265d_parser.ctx_size);
|
||||||
|
hal = mpp_calloc(void, hal_api_h265d.ctx_size);
|
||||||
|
if (cmd->have_input) {
|
||||||
|
mpp_log("input bitstream w: %d, h: %d, path: %s\n",
|
||||||
|
cmd->width, cmd->height,
|
||||||
|
cmd->input_file);
|
||||||
|
|
||||||
|
mpp_log("fopen in \n");
|
||||||
|
pInFile = fopen((const char*)cmd->input_file, "rb");
|
||||||
|
if (pInFile == NULL) {
|
||||||
|
mpp_log("input file not exsist\n");
|
||||||
|
return ERROR_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_log("fopen out \n");
|
||||||
|
} else {
|
||||||
|
mpp_log("please set input bitstream file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
mpp_log("mallc in void * value %d \n", sizeof(void *));
|
||||||
|
buf = mpp_malloc(RK_U8, 2048000);
|
||||||
|
mpp_buf_slot_init(&slots);
|
||||||
|
mpp_buf_slot_setup(slots, 20, cmd->width * cmd->height * 2, 0);
|
||||||
|
if (NULL == slots) {
|
||||||
|
mpp_err("could not init buffer slot\n");
|
||||||
|
return MPP_ERR_UNKNOW;
|
||||||
|
}
|
||||||
|
if (mFrameGroup == NULL) {
|
||||||
|
ret = mpp_buffer_group_normal_get(&mFrameGroup, MPP_BUFFER_TYPE_ION);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("h265d mpp_buffer_group_get failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
//mpp_buffer_group_limit_config(mFrameGroup,cmd->width*cmd->height*2,20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStreamGroup == NULL) {
|
||||||
|
ret = mpp_buffer_group_normal_get(&mStreamGroup, MPP_BUFFER_TYPE_ION);
|
||||||
|
if (MPP_OK != ret) {
|
||||||
|
mpp_err("h265d mpp_buffer_group_get failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_buffer_get(mStreamGroup, ¤tstrem, 1024 * 1024);
|
||||||
|
mpp_buffer_get(mStreamGroup, &prestrem, 2 * 1024 * 1024);
|
||||||
|
|
||||||
|
parser_cfg.slots = slots;
|
||||||
|
hal_cfg.slots = slots;
|
||||||
|
h265d_init(mpp_codex_ctx, &parser_cfg);
|
||||||
|
hal_h265d_init(hal, &hal_cfg);
|
||||||
|
mpp_log("mallc out \n");
|
||||||
|
if (buf == NULL) {
|
||||||
|
mpp_log("malloc fail for input buf");
|
||||||
|
}
|
||||||
|
//buf[0] = 0;
|
||||||
|
while (!feof(pInFile)) {
|
||||||
|
nal_len = get_next_nal(pInFile, buf);
|
||||||
|
RK_U32 index;
|
||||||
|
RK_U8 *tmpbuf = buf;
|
||||||
|
void *pos = NULL;
|
||||||
|
mpp_err("get nal len from file %d", nal_len);
|
||||||
|
do {
|
||||||
|
mpp_packet_init(&rkpkt, tmpbuf, nal_len);
|
||||||
|
memset(cutask, 0, sizeof(HalDecTask));
|
||||||
|
memset(&cutask->refer, -1, sizeof(cutask->refer));
|
||||||
|
cutask->stmbuf = currentstrem;
|
||||||
|
h265d_prepare(mpp_codex_ctx, rkpkt, cutask);
|
||||||
|
pos = mpp_packet_get_pos(rkpkt);
|
||||||
|
if (pos < (void*)(tmpbuf + nal_len)) {
|
||||||
|
tmpbuf = pos;
|
||||||
|
nal_len = (void*)(tmpbuf + nal_len) - pos;
|
||||||
|
mpp_err("nal_len = %d", nal_len);
|
||||||
|
} else {
|
||||||
|
nal_len = 0;
|
||||||
|
}
|
||||||
|
if (cutask->valid) {
|
||||||
|
if (wait_task) {
|
||||||
|
poll_task(hal, slots, pretask);
|
||||||
|
wait_task = 0;
|
||||||
|
}
|
||||||
|
cutask->valid = 0;
|
||||||
|
h265d_parser(mpp_codex_ctx, cutask);
|
||||||
|
}
|
||||||
|
if (cutask->valid) {
|
||||||
|
HalTask syn;
|
||||||
|
syn.dec = *cutask;
|
||||||
|
mpp_buf_slot_get_hw_dst(slots, &index);
|
||||||
|
|
||||||
|
if (NULL == mpp_buf_slot_get_buffer(slots, index)) {
|
||||||
|
MppBuffer buffer = NULL;
|
||||||
|
RK_U32 size = mpp_buf_slot_get_size(slots);
|
||||||
|
mpp_err("size = %d", size);
|
||||||
|
mpp_buffer_get(mFrameGroup, &buffer, size);
|
||||||
|
if (buffer)
|
||||||
|
mpp_buf_slot_set_buffer(slots, index, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
hal_h265d_gen_regs(hal, &syn);
|
||||||
|
|
||||||
|
hal_h265d_start(hal, &syn);
|
||||||
|
{
|
||||||
|
MppBuffer tmp = NULL;
|
||||||
|
HalDecTask *task = NULL;
|
||||||
|
|
||||||
|
tmp = currentstrem;
|
||||||
|
currentstrem = prestrem;
|
||||||
|
prestrem = tmp;
|
||||||
|
|
||||||
|
task = cutask;
|
||||||
|
cutask = pretask;
|
||||||
|
pretask = task;
|
||||||
|
}
|
||||||
|
wait_task = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = mpp_buf_slot_get_display(slots, &frame);
|
||||||
|
if (ret == MPP_OK) {
|
||||||
|
mpp_log("get_display for ");
|
||||||
|
}
|
||||||
|
if (frame) {
|
||||||
|
#if 1//def DUMP
|
||||||
|
RK_U32 stride_w, stride_h;
|
||||||
|
void *ptr = NULL;
|
||||||
|
stride_w = mpp_frame_get_hor_stride(frame);
|
||||||
|
stride_h = mpp_frame_get_ver_stride(frame);
|
||||||
|
MppBuffer framebuf = mpp_frame_get_buffer(frame);
|
||||||
|
ptr = mpp_buffer_get_ptr(framebuf);
|
||||||
|
fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp);
|
||||||
|
fflush(fp);
|
||||||
|
#endif
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
frame = NULL;
|
||||||
|
}
|
||||||
|
} while (ret == MPP_OK);
|
||||||
|
mpp_packet_deinit(&rkpkt);
|
||||||
|
} while ( nal_len );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wait_task) {
|
||||||
|
poll_task(hal, slots, pretask);
|
||||||
|
wait_task = 0;
|
||||||
|
}
|
||||||
|
h265d_flush((void*)mpp_codex_ctx);
|
||||||
|
do {
|
||||||
|
ret = mpp_buf_slot_get_display(slots, &frame);
|
||||||
|
if (ret == MPP_OK) {
|
||||||
|
mpp_log("get_display for ");
|
||||||
|
}
|
||||||
|
if (frame) {
|
||||||
|
mpp_frame_deinit(&frame);
|
||||||
|
}
|
||||||
|
} while (ret == MPP_OK);
|
||||||
|
|
||||||
|
if (mpp_codex_ctx != NULL) {
|
||||||
|
h265d_deinit(mpp_codex_ctx);
|
||||||
|
mpp_codex_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hal != NULL) {
|
||||||
|
mpp_err("hal_h265d_deinit in");
|
||||||
|
hal_h265d_deinit(hal);
|
||||||
|
}
|
||||||
|
if (slots != NULL)
|
||||||
|
mpp_buf_slot_deinit(slots);
|
||||||
|
|
||||||
|
if (mFrameGroup != NULL) {
|
||||||
|
mpp_buffer_group_put(mFrameGroup);
|
||||||
|
}
|
||||||
|
if (currentstrem)
|
||||||
|
mpp_buffer_put(currentstrem);
|
||||||
|
if (prestrem)
|
||||||
|
mpp_buffer_put(prestrem);
|
||||||
|
|
||||||
|
if (mStreamGroup != NULL) {
|
||||||
|
mpp_buffer_group_put(mStreamGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_free(buf);
|
||||||
|
mpp_free(mpp_codex_ctx);
|
||||||
|
mpp_free(hal);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
ParserDemoCmdContext_t demoCmdCtx;
|
||||||
|
RK_S32 ret = 0;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
show_usage();
|
||||||
|
mpp_log("vpu api demo complete directly\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mpp_env_set_u32("buf_slot_debug", 0x10000010, 0);
|
||||||
|
|
||||||
|
ParserDemoCmdContext_t* cmd = &demoCmdCtx;
|
||||||
|
memset((void*)cmd, 0, sizeof(ParserDemoCmdContext_t));
|
||||||
|
if ((ret = parse_options(argc, argv, cmd)) != 0) {
|
||||||
|
if (ret == PARSER_DEMO_PARSE_HELP_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpp_log("parse_options fail\n\n");
|
||||||
|
show_usage();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
hevc_parser_test(cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
100
mpp/codec/dec/h265/test/openHevcWrapper.h
Normal file
100
mpp/codec/dec/h265/test/openHevcWrapper.h
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* openhevc.h wrapper to openhevc or ffmpeg
|
||||||
|
* Copyright (c) 2012-2013 Raulet, Wassim Hamidouche, Gildas Cocherel, Pierre Edouard Lepere
|
||||||
|
*
|
||||||
|
* This file is part of openhevc.
|
||||||
|
*
|
||||||
|
* openHevc is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* openhevc is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with openhevc; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPEN_HEVC_WRAPPER_H
|
||||||
|
#define OPEN_HEVC_WRAPPER_H
|
||||||
|
|
||||||
|
#define NV_VERSION "1.2" ///< Current software version
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef void* OpenHevc_Handle;
|
||||||
|
|
||||||
|
typedef struct OpenHevc_Rational {
|
||||||
|
int num; ///< numerator
|
||||||
|
int den; ///< denominator
|
||||||
|
} OpenHevc_Rational;
|
||||||
|
|
||||||
|
typedef struct OpenHevc_FrameInfo {
|
||||||
|
int nYPitch;
|
||||||
|
int nUPitch;
|
||||||
|
int nVPitch;
|
||||||
|
int nBitDepth;
|
||||||
|
int nWidth;
|
||||||
|
int nHeight;
|
||||||
|
int nDisplayWidth;
|
||||||
|
int nDisplayHeight;
|
||||||
|
OpenHevc_Rational sample_aspect_ratio;
|
||||||
|
OpenHevc_Rational frameRate;
|
||||||
|
int display_picture_number;
|
||||||
|
int flag; //progressive, interlaced, interlaced top field first, interlaced bottom field first.
|
||||||
|
int64_t nTimeStamp;
|
||||||
|
} OpenHevc_FrameInfo;
|
||||||
|
|
||||||
|
typedef struct OpenHevc_Frame {
|
||||||
|
void** pvY;
|
||||||
|
void** pvU;
|
||||||
|
void** pvV;
|
||||||
|
OpenHevc_FrameInfo frameInfo;
|
||||||
|
} OpenHevc_Frame;
|
||||||
|
|
||||||
|
typedef struct OpenHevc_Frame_cpy {
|
||||||
|
void* pvY;
|
||||||
|
void* pvU;
|
||||||
|
void* pvV;
|
||||||
|
OpenHevc_FrameInfo frameInfo;
|
||||||
|
} OpenHevc_Frame_cpy;
|
||||||
|
|
||||||
|
OpenHevc_Handle libOpenHevcInit(int nb_pthreads, int thread_type);
|
||||||
|
int libOpenHevcStartDecoder(OpenHevc_Handle openHevcHandle);
|
||||||
|
int libOpenHevcDecode(OpenHevc_Handle openHevcHandle, const unsigned char *buff, int nal_len, int64_t pts);
|
||||||
|
void libOpenHevcGetPictureInfo(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo);
|
||||||
|
void libOpenHevcCopyExtraData(OpenHevc_Handle openHevcHandle, unsigned char *extra_data, int extra_size_alloc);
|
||||||
|
|
||||||
|
void libOpenHevcGetPictureSize2(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo);
|
||||||
|
int libOpenHevcGetOutput(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame *openHevcFrame);
|
||||||
|
int libOpenHevcGetOutputCpy(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame_cpy *openHevcFrame);
|
||||||
|
void libOpenHevcSetCheckMD5(OpenHevc_Handle openHevcHandle, int val);
|
||||||
|
void libOpenHevcSetDebugMode(OpenHevc_Handle openHevcHandle, int val);
|
||||||
|
void libOpenHevcSetTemporalLayer_id(OpenHevc_Handle openHevcHandle, int val);
|
||||||
|
void libOpenHevcSetNoCropping(OpenHevc_Handle openHevcHandle, int val);
|
||||||
|
void libOpenHevcSetActiveDecoders(OpenHevc_Handle openHevcHandle, int val);
|
||||||
|
|
||||||
|
void libOpenHevcClose(OpenHevc_Handle openHevcHandle);
|
||||||
|
void libOpenHevcFlush(OpenHevc_Handle openHevcHandle);
|
||||||
|
const char *libOpenHevcVersion(OpenHevc_Handle openHevcHandle);
|
||||||
|
int libOpenHevcControl(OpenHevc_Handle openHevcHandle, int cmd, void* parm);
|
||||||
|
OpenHevc_Handle libHevcParserInit();
|
||||||
|
int libHevcParser(OpenHevc_Handle openHevcHandle, void* vpacket, void *vparsepacket);
|
||||||
|
void libHevcParserClose(OpenHevc_Handle openHevcHandle);
|
||||||
|
void libHevcParserflush(OpenHevc_Handle openHevcHandle);
|
||||||
|
void* libOpenHevcGetSliceInfo(OpenHevc_Handle openHevcHandle);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // OPEN_HEVC_WRAPPER_H
|
@@ -16,7 +16,19 @@
|
|||||||
|
|
||||||
#ifndef __H265D_API_H__
|
#ifndef __H265D_API_H__
|
||||||
#define __H265D_API_H__
|
#define __H265D_API_H__
|
||||||
|
#include "parser_api.h"
|
||||||
|
|
||||||
|
extern const ParserApi api_h265d_parser;
|
||||||
|
|
||||||
|
MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task);
|
||||||
|
MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg);
|
||||||
|
MPP_RET h265d_parser(void *ctx, HalDecTask *task);
|
||||||
|
MPP_RET h265d_deinit(void *ctx);
|
||||||
|
MPP_RET h265d_flush(void *ctx);
|
||||||
|
MPP_RET h265d_reset(void *ctx);
|
||||||
|
MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param);
|
||||||
|
RK_S32 mpp_hevc_split_frame(void *sc,
|
||||||
|
const RK_U8 **poutbuf, RK_S32 *poutbuf_size,
|
||||||
|
const RK_U8 *buf, RK_S32 buf_size);
|
||||||
|
|
||||||
#endif /*__H265D_API_H__*/
|
#endif /*__H265D_API_H__*/
|
193
mpp/common/h265d_syntax.h
Normal file
193
mpp/common/h265d_syntax.h
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file h265d_syntax.h
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
#ifndef __H265D_SYNTAX__
|
||||||
|
#define __H265D_SYNTAX__
|
||||||
|
typedef unsigned long DWORD;
|
||||||
|
typedef unsigned char BYTE;
|
||||||
|
typedef unsigned short WORD;
|
||||||
|
typedef unsigned long ULONG;
|
||||||
|
typedef unsigned short USHORT;
|
||||||
|
typedef unsigned char UCHAR;
|
||||||
|
typedef unsigned int UINT;
|
||||||
|
typedef unsigned int UINT32;
|
||||||
|
|
||||||
|
typedef signed int BOOL;
|
||||||
|
typedef signed int INT;
|
||||||
|
typedef signed char CHAR;
|
||||||
|
typedef signed short SHORT;
|
||||||
|
typedef signed long LONG;
|
||||||
|
typedef void *PVOID;
|
||||||
|
|
||||||
|
/* HEVC Picture Entry structure */
|
||||||
|
#define MAX_SLICES 600
|
||||||
|
typedef struct _DXVA_PicEntry_HEVC {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UCHAR Index7Bits : 7;
|
||||||
|
UCHAR AssociatedFlag : 1;
|
||||||
|
};
|
||||||
|
UCHAR bPicEntry;
|
||||||
|
};
|
||||||
|
} DXVA_PicEntry_HEVC, *LPDXVA_PicEntry_HEVC;
|
||||||
|
|
||||||
|
/* HEVC Picture Parameter structure */
|
||||||
|
typedef struct _DXVA_PicParams_HEVC {
|
||||||
|
USHORT PicWidthInMinCbsY;
|
||||||
|
USHORT PicHeightInMinCbsY;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
USHORT chroma_format_idc : 2;
|
||||||
|
USHORT separate_colour_plane_flag : 1;
|
||||||
|
USHORT bit_depth_luma_minus8 : 3;
|
||||||
|
USHORT bit_depth_chroma_minus8 : 3;
|
||||||
|
USHORT log2_max_pic_order_cnt_lsb_minus4 : 4;
|
||||||
|
USHORT NoPicReorderingFlag : 1;
|
||||||
|
USHORT NoBiPredFlag : 1;
|
||||||
|
USHORT ReservedBits1 : 1;
|
||||||
|
};
|
||||||
|
USHORT wFormatAndSequenceInfoFlags;
|
||||||
|
};
|
||||||
|
DXVA_PicEntry_HEVC CurrPic;
|
||||||
|
UCHAR sps_max_dec_pic_buffering_minus1;
|
||||||
|
UCHAR log2_min_luma_coding_block_size_minus3;
|
||||||
|
UCHAR log2_diff_max_min_luma_coding_block_size;
|
||||||
|
UCHAR log2_min_transform_block_size_minus2;
|
||||||
|
UCHAR log2_diff_max_min_transform_block_size;
|
||||||
|
UCHAR max_transform_hierarchy_depth_inter;
|
||||||
|
UCHAR max_transform_hierarchy_depth_intra;
|
||||||
|
UCHAR num_short_term_ref_pic_sets;
|
||||||
|
UCHAR num_long_term_ref_pics_sps;
|
||||||
|
UCHAR num_ref_idx_l0_default_active_minus1;
|
||||||
|
UCHAR num_ref_idx_l1_default_active_minus1;
|
||||||
|
CHAR init_qp_minus26;
|
||||||
|
UCHAR ucNumDeltaPocsOfRefRpsIdx;
|
||||||
|
USHORT wNumBitsForShortTermRPSInSlice;
|
||||||
|
USHORT ReservedBits2;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UINT32 scaling_list_enabled_flag : 1;
|
||||||
|
UINT32 amp_enabled_flag : 1;
|
||||||
|
UINT32 sample_adaptive_offset_enabled_flag : 1;
|
||||||
|
UINT32 pcm_enabled_flag : 1;
|
||||||
|
UINT32 pcm_sample_bit_depth_luma_minus1 : 4;
|
||||||
|
UINT32 pcm_sample_bit_depth_chroma_minus1 : 4;
|
||||||
|
UINT32 log2_min_pcm_luma_coding_block_size_minus3 : 2;
|
||||||
|
UINT32 log2_diff_max_min_pcm_luma_coding_block_size : 2;
|
||||||
|
UINT32 pcm_loop_filter_disabled_flag : 1;
|
||||||
|
UINT32 long_term_ref_pics_present_flag : 1;
|
||||||
|
UINT32 sps_temporal_mvp_enabled_flag : 1;
|
||||||
|
UINT32 strong_intra_smoothing_enabled_flag : 1;
|
||||||
|
UINT32 dependent_slice_segments_enabled_flag : 1;
|
||||||
|
UINT32 output_flag_present_flag : 1;
|
||||||
|
UINT32 num_extra_slice_header_bits : 3;
|
||||||
|
UINT32 sign_data_hiding_enabled_flag : 1;
|
||||||
|
UINT32 cabac_init_present_flag : 1;
|
||||||
|
UINT32 ReservedBits3 : 5;
|
||||||
|
};
|
||||||
|
UINT32 dwCodingParamToolFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
UINT32 constrained_intra_pred_flag : 1;
|
||||||
|
UINT32 transform_skip_enabled_flag : 1;
|
||||||
|
UINT32 cu_qp_delta_enabled_flag : 1;
|
||||||
|
UINT32 pps_slice_chroma_qp_offsets_present_flag : 1;
|
||||||
|
UINT32 weighted_pred_flag : 1;
|
||||||
|
UINT32 weighted_bipred_flag : 1;
|
||||||
|
UINT32 transquant_bypass_enabled_flag : 1;
|
||||||
|
UINT32 tiles_enabled_flag : 1;
|
||||||
|
UINT32 entropy_coding_sync_enabled_flag : 1;
|
||||||
|
UINT32 uniform_spacing_flag : 1;
|
||||||
|
UINT32 loop_filter_across_tiles_enabled_flag : 1;
|
||||||
|
UINT32 pps_loop_filter_across_slices_enabled_flag : 1;
|
||||||
|
UINT32 deblocking_filter_override_enabled_flag : 1;
|
||||||
|
UINT32 pps_deblocking_filter_disabled_flag : 1;
|
||||||
|
UINT32 lists_modification_present_flag : 1;
|
||||||
|
UINT32 slice_segment_header_extension_present_flag : 1;
|
||||||
|
UINT32 IrapPicFlag : 1;
|
||||||
|
UINT32 IdrPicFlag : 1;
|
||||||
|
UINT32 IntraPicFlag : 1;
|
||||||
|
UINT32 ReservedBits4 : 13;
|
||||||
|
};
|
||||||
|
UINT32 dwCodingSettingPicturePropertyFlags;
|
||||||
|
};
|
||||||
|
CHAR pps_cb_qp_offset;
|
||||||
|
CHAR pps_cr_qp_offset;
|
||||||
|
UCHAR num_tile_columns_minus1;
|
||||||
|
UCHAR num_tile_rows_minus1;
|
||||||
|
USHORT column_width_minus1[19];
|
||||||
|
USHORT row_height_minus1[21];
|
||||||
|
UCHAR diff_cu_qp_delta_depth;
|
||||||
|
CHAR pps_beta_offset_div2;
|
||||||
|
CHAR pps_tc_offset_div2;
|
||||||
|
UCHAR log2_parallel_merge_level_minus2;
|
||||||
|
INT CurrPicOrderCntVal;
|
||||||
|
DXVA_PicEntry_HEVC RefPicList[15];
|
||||||
|
UCHAR ReservedBits5;
|
||||||
|
INT PicOrderCntValList[15];
|
||||||
|
UCHAR RefPicSetStCurrBefore[8];
|
||||||
|
UCHAR RefPicSetStCurrAfter[8];
|
||||||
|
UCHAR RefPicSetLtCurr[8];
|
||||||
|
USHORT ReservedBits6;
|
||||||
|
USHORT ReservedBits7;
|
||||||
|
UINT StatusReportFeedbackNumber;
|
||||||
|
UINT32 vps_id;
|
||||||
|
UINT32 pps_id;
|
||||||
|
UINT32 sps_id;
|
||||||
|
UCHAR scaling_list_data_present_flag;
|
||||||
|
} DXVA_PicParams_HEVC, *LPDXVA_PicParams_HEVC;
|
||||||
|
|
||||||
|
/* HEVC Quantizatiuon Matrix structure */
|
||||||
|
typedef struct _DXVA_Qmatrix_HEVC {
|
||||||
|
UCHAR ucScalingLists0[6][16];
|
||||||
|
UCHAR ucScalingLists1[6][64];
|
||||||
|
UCHAR ucScalingLists2[6][64];
|
||||||
|
UCHAR ucScalingLists3[2][64];
|
||||||
|
UCHAR ucScalingListDCCoefSizeID2[6];
|
||||||
|
UCHAR ucScalingListDCCoefSizeID3[2];
|
||||||
|
} DXVA_Qmatrix_HEVC, *LPDXVA_Qmatrix_HEVC;
|
||||||
|
|
||||||
|
|
||||||
|
/* HEVC Slice Control Structure */
|
||||||
|
typedef struct _DXVA_Slice_HEVC_Short {
|
||||||
|
UINT BSNALunitDataLocation;
|
||||||
|
UINT SliceBytesInBuffer;
|
||||||
|
USHORT wBadSliceChopping;
|
||||||
|
} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short;
|
||||||
|
|
||||||
|
typedef struct h265d_dxva2_picture_context {
|
||||||
|
DXVA_PicParams_HEVC pp;
|
||||||
|
DXVA_Qmatrix_HEVC qm;
|
||||||
|
UINT32 slice_count;
|
||||||
|
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
|
||||||
|
const UCHAR *bitstream;
|
||||||
|
UINT32 bitstream_size;
|
||||||
|
} h265d_dxva2_picture_context_t;
|
||||||
|
|
||||||
|
#endif /*__H265D_SYNTAX__*/
|
47
mpp/hal/inc/hal_h265d_api.h
Normal file
47
mpp/hal/inc/hal_h265d_api.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __HAL_H265D_API_H__
|
||||||
|
#define __HAL_H265D_API_H__
|
||||||
|
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include "mpp_err.h"
|
||||||
|
#include "mpp_hal.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const MppHalApi hal_api_h265d;
|
||||||
|
|
||||||
|
RK_S32 hal_h265d_init(void *hal, MppHalCfg *cfg);
|
||||||
|
RK_S32 hal_h265d_gen_regs(void *hal, HalTask *syn);
|
||||||
|
RK_S32 hal_h265d_deinit(void *hal);
|
||||||
|
MPP_RET hal_h265d_start(void *hal, HalTask *task);
|
||||||
|
MPP_RET hal_h265d_wait(void *hal, HalTask *task);
|
||||||
|
MPP_RET hal_h265d_reset(void *hal);
|
||||||
|
MPP_RET hal_h265d_flush(void *hal);
|
||||||
|
MPP_RET hal_h265d_control(void *hal, RK_S32 cmd_type, void *param);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__HAL_H265D_API_H__*/
|
@@ -71,6 +71,8 @@ typedef struct HalDecTask_t {
|
|||||||
// current tesk protocol syntax information
|
// current tesk protocol syntax information
|
||||||
MppSyntax syntax;
|
MppSyntax syntax;
|
||||||
|
|
||||||
|
MppBuffer stmbuf;
|
||||||
|
|
||||||
// for test purpose
|
// for test purpose
|
||||||
// current tesk output slot index
|
// current tesk output slot index
|
||||||
RK_S32 output;
|
RK_S32 output;
|
||||||
|
129
mpp/hal/inc/vpu.h
Normal file
129
mpp/hal/inc/vpu.h
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics S.LSI Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __VPU_H__
|
||||||
|
#define __VPU_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rk_type.h"
|
||||||
|
|
||||||
|
#define VPU_SUCCESS (0)
|
||||||
|
#define VPU_FAILURE (-1)
|
||||||
|
|
||||||
|
#define VPU_HW_WAIT_OK VPU_SUCCESS
|
||||||
|
#define VPU_HW_WAIT_ERROR VPU_FAILURE
|
||||||
|
#define VPU_HW_WAIT_TIMEOUT 1
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>60 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 240B
|
||||||
|
#define VPU_REG_NUM_DEC (60)
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>41 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 164B
|
||||||
|
#define VPU_REG_NUM_PP (41)
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>101 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 404B
|
||||||
|
#define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP)
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>96 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С 384B
|
||||||
|
#define VPU_REG_NUM_ENC (96)
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
|
||||||
|
VPU_ENC = 0x0,
|
||||||
|
VPU_DEC = 0x1,
|
||||||
|
VPU_PP = 0x2,
|
||||||
|
VPU_DEC_PP = 0x3,
|
||||||
|
VPU_DEC_HEVC = 0x4,
|
||||||
|
VPU_TYPE_BUTT ,
|
||||||
|
|
||||||
|
} VPU_CLIENT_TYPE;
|
||||||
|
|
||||||
|
/* Hardware decoder configuration description */
|
||||||
|
|
||||||
|
typedef struct VPUHwDecConfig {
|
||||||
|
RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */
|
||||||
|
RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */
|
||||||
|
RK_U32 h264Support; /* HW supports h.264 */
|
||||||
|
RK_U32 jpegSupport; /* HW supports JPEG */
|
||||||
|
RK_U32 mpeg4Support; /* HW supports MPEG-4 */
|
||||||
|
RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */
|
||||||
|
RK_U32 vc1Support; /* HW supports VC-1 Simple */
|
||||||
|
RK_U32 mpeg2Support; /* HW supports MPEG-2 */
|
||||||
|
RK_U32 ppSupport; /* HW supports post-processor */
|
||||||
|
RK_U32 ppConfig; /* HW post-processor functions bitmask */
|
||||||
|
RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */
|
||||||
|
RK_U32 refBufSupport; /* HW supports reference picture buffering */
|
||||||
|
RK_U32 vp6Support; /* HW supports VP6 */
|
||||||
|
RK_U32 vp7Support; /* HW supports VP7 */
|
||||||
|
RK_U32 vp8Support; /* HW supports VP8 */
|
||||||
|
RK_U32 avsSupport; /* HW supports AVS */
|
||||||
|
RK_U32 jpegESupport; /* HW supports JPEG extensions */
|
||||||
|
RK_U32 rvSupport; /* HW supports REAL */
|
||||||
|
RK_U32 mvcSupport; /* HW supports H264 MVC extension */
|
||||||
|
} VPUHwDecConfig_t;
|
||||||
|
|
||||||
|
/* Hardware encoder configuration description */
|
||||||
|
|
||||||
|
typedef struct VPUHwEndConfig {
|
||||||
|
RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */
|
||||||
|
RK_U32 h264Enabled; /* HW supports H.264 */
|
||||||
|
RK_U32 jpegEnabled; /* HW supports JPEG */
|
||||||
|
RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */
|
||||||
|
RK_U32 vsEnabled; /* HW supports video stabilization */
|
||||||
|
RK_U32 rgbEnabled; /* HW supports RGB input */
|
||||||
|
RK_U32 reg_size; /* HW bus type in use */
|
||||||
|
RK_U32 reserv[2];
|
||||||
|
} VPUHwEncConfig_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
|
||||||
|
// common command
|
||||||
|
VPU_CMD_REGISTER ,
|
||||||
|
VPU_CMD_REGISTER_ACK_OK ,
|
||||||
|
VPU_CMD_REGISTER_ACK_FAIL ,
|
||||||
|
VPU_CMD_UNREGISTER ,
|
||||||
|
|
||||||
|
VPU_SEND_CONFIG ,
|
||||||
|
VPU_SEND_CONFIG_ACK_OK , // <20><><EFBFBD><EFBFBD><EFBFBD>óɹ<C3B3><C9B9><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>λ
|
||||||
|
VPU_SEND_CONFIG_ACK_FAIL , // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD><D8B4><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>λ
|
||||||
|
|
||||||
|
VPU_GET_HW_INFO ,
|
||||||
|
VPU_GET_HW_INFO_ACK_OK ,
|
||||||
|
VPU_GET_HW_INFO_ACK_FAIL ,
|
||||||
|
|
||||||
|
VPU_CMD_BUTT ,
|
||||||
|
} VPU_CMD_TYPE;
|
||||||
|
|
||||||
|
int VPUClientInit(VPU_CLIENT_TYPE type);
|
||||||
|
RK_S32 VPUClientRelease(int socket);
|
||||||
|
RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs);
|
||||||
|
RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len);
|
||||||
|
RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size);
|
||||||
|
RK_S32 VPUClientGetIOMMUStatus();
|
||||||
|
RK_U32 VPUCheckSupportWidth();
|
||||||
|
|
||||||
|
void *vpu_service(void *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __VPU_H__ */
|
||||||
|
|
||||||
|
|
@@ -1 +1,23 @@
|
|||||||
# vim: syntax=cmake
|
# vim: syntax=cmake
|
||||||
|
# hal h265 reg
|
||||||
|
|
||||||
|
set(HAL_H265D_HDR
|
||||||
|
hal_h265d_reg.h
|
||||||
|
cabac.h
|
||||||
|
../../../common/h265d_syntax.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HAL_H265D_SRC
|
||||||
|
hal_h265d_reg.c
|
||||||
|
../../../mpp_bitread.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(mpp_hal PROPERTIES FOLDER "mpp/hal")
|
||||||
|
|
||||||
|
add_library(h265d_hal STATIC
|
||||||
|
${HAL_H265D_SRC} ${HAL_H265D_HDR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(h265d_hal osal)
|
||||||
|
|
||||||
|
#add_subdirectory(test)
|
||||||
|
1751
mpp/hal/rkdec/h265d/cabac.h
Normal file
1751
mpp/hal/rkdec/h265d/cabac.h
Normal file
File diff suppressed because it is too large
Load Diff
1469
mpp/hal/rkdec/h265d/hal_h265d_reg.c
Normal file
1469
mpp/hal/rkdec/h265d/hal_h265d_reg.c
Normal file
File diff suppressed because it is too large
Load Diff
131
mpp/hal/rkdec/h265d/hal_h265d_reg.h
Normal file
131
mpp/hal/rkdec/h265d/hal_h265d_reg.h
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @file hal_h265d_reg.h
|
||||||
|
* @brief
|
||||||
|
* @author csy(csy@rock-chips.com)
|
||||||
|
|
||||||
|
* @version 1.0.0
|
||||||
|
* @history
|
||||||
|
* 2015.7.15 : Create
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HAL_H265D_REG_H__
|
||||||
|
#define __HAL_H265D_REG_H__
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include "mpp_log.h"
|
||||||
|
|
||||||
|
extern RK_U32 h265h_debug;
|
||||||
|
#define H265H_DBG_FUNCTION (0x00000001)
|
||||||
|
#define H265H_DBG_RPS (0x00000002)
|
||||||
|
#define H265H_DBG_PPS (0x00000004)
|
||||||
|
#define H265H_DBG_REG (0x00000008)
|
||||||
|
|
||||||
|
|
||||||
|
#define h265h_dbg(flag, fmt, ...) _mpp_dbg(h265h_debug, flag, fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct swreg_id {
|
||||||
|
RK_U32 minor_ver : 8 ;
|
||||||
|
RK_U32 major_ver : 8 ;
|
||||||
|
RK_U32 prod_num : 16 ;
|
||||||
|
} sw_id;
|
||||||
|
|
||||||
|
struct swreg_int {
|
||||||
|
RK_U32 sw_dec_e : 1 ;
|
||||||
|
RK_U32 sw_dec_clkgate_e : 1 ;
|
||||||
|
RK_U32 reserve0 : 2 ;
|
||||||
|
RK_U32 sw_dec_irq_dis : 1 ;
|
||||||
|
RK_U32 sw_dec_timeout_e : 1 ;
|
||||||
|
RK_U32 sw_buf_empty_en : 1 ;
|
||||||
|
RK_U32 reserve1 : 1 ;
|
||||||
|
RK_U32 sw_dec_irq : 1 ;
|
||||||
|
RK_U32 sw_dec_irq_raw : 1 ;
|
||||||
|
RK_U32 reserve2 : 2 ;
|
||||||
|
RK_U32 sw_dec_rdy_sta : 1 ;
|
||||||
|
RK_U32 sw_dec_bus_sta : 1 ;
|
||||||
|
RK_U32 sw_dec_error_sta : 1 ;
|
||||||
|
RK_U32 sw_dec_empty_sta : 1 ;
|
||||||
|
RK_U32 reserve3 : 3 ;
|
||||||
|
RK_U32 sw_softrst_en_p : 1 ;
|
||||||
|
RK_U32 sw_force_softreset_valid: 1 ;
|
||||||
|
RK_U32 sw_softreset_rdy : 1 ;
|
||||||
|
} sw_interrupt; ///<- zrh: do nothing in C Model
|
||||||
|
|
||||||
|
struct swreg_sysctrl {
|
||||||
|
RK_U32 sw_in_endian : 1 ;
|
||||||
|
RK_U32 sw_in_swap32_e : 1 ;
|
||||||
|
RK_U32 sw_in_swap64_e : 1 ;
|
||||||
|
RK_U32 sw_str_endian : 1 ;
|
||||||
|
RK_U32 sw_str_swap32_e : 1 ;
|
||||||
|
RK_U32 sw_str_swap64_e : 1 ;
|
||||||
|
RK_U32 sw_out_endian : 1 ;
|
||||||
|
RK_U32 sw_out_swap32_e : 1 ;
|
||||||
|
RK_U32 sw_out_cbcr_swap : 1 ;
|
||||||
|
RK_U32 reserve : 1 ;
|
||||||
|
RK_U32 sw_rlc_mode_direct_write : 1;
|
||||||
|
RK_U32 sw_rlc_mode : 1 ;
|
||||||
|
RK_U32 sw_strm_start_bit : 7 ;
|
||||||
|
} sw_sysctrl; ///<- zrh: do nothing in C Model
|
||||||
|
|
||||||
|
struct swreg_pic {
|
||||||
|
RK_U32 sw_y_hor_virstride : 9 ;
|
||||||
|
RK_U32 reserve : 3 ;
|
||||||
|
RK_U32 sw_uv_hor_virstride : 9 ;
|
||||||
|
RK_U32 sw_slice_num : 8 ;
|
||||||
|
} sw_picparameter;
|
||||||
|
|
||||||
|
RK_U32 sw_strm_rlc_base ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 sw_stream_len ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 sw_cabactbl_base ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 sw_decout_base ;
|
||||||
|
RK_U32 sw_y_virstride ;
|
||||||
|
RK_U32 sw_yuv_virstride ;
|
||||||
|
RK_U32 sw_refer_base[15] ;
|
||||||
|
RK_S32 sw_refer_poc[15] ;
|
||||||
|
RK_S32 sw_cur_poc ;
|
||||||
|
RK_U32 sw_rlcwrite_base ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 sw_pps_base ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 sw_rps_base ;///<- zrh: do nothing in C Model
|
||||||
|
RK_U32 cabac_error_en ;///<- zrh add
|
||||||
|
RK_U32 cabac_error_status ;///<- zrh add
|
||||||
|
|
||||||
|
struct cabac_error_ctu {
|
||||||
|
RK_U32 sw_cabac_error_ctu_xoffset : 8;
|
||||||
|
RK_U32 sw_cabac_error_ctu_yoffset : 8;
|
||||||
|
RK_U32 sw_streamfifo_space2full : 7;
|
||||||
|
RK_U32 reversed0 : 9;
|
||||||
|
} cabac_error_ctu;
|
||||||
|
|
||||||
|
struct sao_ctu_position {
|
||||||
|
RK_U32 sw_saowr_xoffset : 9;
|
||||||
|
RK_U32 reversed0 : 7;
|
||||||
|
RK_U32 sw_saowr_yoffset : 10;
|
||||||
|
RK_U32 reversed1 : 6;
|
||||||
|
} sao_ctu_position;
|
||||||
|
|
||||||
|
RK_U32 sw_ref_valid ; //this is not same with hardware
|
||||||
|
RK_U32 sw_refframe_index[15];
|
||||||
|
|
||||||
|
RK_U32 performance_cycle;
|
||||||
|
RK_U32 axi_ddr_rdata;
|
||||||
|
RK_U32 axi_ddr_wdata;
|
||||||
|
RK_U32 fpgadebug_reset;
|
||||||
|
} REGS_t;
|
||||||
|
|
||||||
|
#endif
|
437
mpp/hal/vpu/h265d/dxva2_hevc.c
Normal file
437
mpp/hal/vpu/h265d/dxva2_hevc.c
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
/*
|
||||||
|
* DXVA2 HEVC HW acceleration.
|
||||||
|
* Copyright 2010 Rockchip Electronics Co. LTD
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "h265d_parser.h"
|
||||||
|
#define MAX_SLICES 256
|
||||||
|
|
||||||
|
struct hevc_dxva2_picture_context {
|
||||||
|
DXVA_PicParams_HEVC pp;
|
||||||
|
DXVA_Qmatrix_HEVC qm;
|
||||||
|
unsigned slice_count;
|
||||||
|
DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
|
||||||
|
const uint8_t *bitstream;
|
||||||
|
unsigned bitstream_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void fill_picture_entry(DXVA_PicEntry_HEVC *pic,
|
||||||
|
unsigned index, unsigned flag)
|
||||||
|
{
|
||||||
|
av_assert0((index & 0x7f) == index && (flag & 0x01) == flag);
|
||||||
|
pic->bPicEntry = index | (flag << 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
|
||||||
|
if ((pp->RefPicList[i].bPicEntry & 0x7f) == surface_index)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h,
|
||||||
|
DXVA_PicParams_HEVC *pp)
|
||||||
|
{
|
||||||
|
const HEVCFrame *current_picture = h->ref;
|
||||||
|
const HEVCSPS *sps = h->ps.sps;
|
||||||
|
const HEVCPPS *pps = h->ps.pps;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
memset(pp, 0, sizeof(*pp));
|
||||||
|
|
||||||
|
pp->PicWidthInMinCbsY = sps->min_cb_width;
|
||||||
|
pp->PicHeightInMinCbsY = sps->min_cb_height;
|
||||||
|
|
||||||
|
pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc << 0) |
|
||||||
|
(sps->separate_colour_plane_flag << 2) |
|
||||||
|
((sps->bit_depth - 8) << 3) |
|
||||||
|
((sps->bit_depth - 8) << 6) |
|
||||||
|
((sps->log2_max_poc_lsb - 4) << 9) |
|
||||||
|
(0 << 13) |
|
||||||
|
(0 << 14) |
|
||||||
|
(0 << 15);
|
||||||
|
|
||||||
|
fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, current_picture->frame), 0);
|
||||||
|
|
||||||
|
pp->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
|
||||||
|
pp->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
|
||||||
|
pp->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
|
||||||
|
pp->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
|
||||||
|
pp->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
|
||||||
|
pp->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
|
||||||
|
pp->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
|
||||||
|
pp->num_short_term_ref_pic_sets = sps->nb_st_rps;
|
||||||
|
pp->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
|
||||||
|
|
||||||
|
pp->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
|
||||||
|
pp->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
|
||||||
|
pp->init_qp_minus26 = pps->pic_init_qp_minus26;
|
||||||
|
|
||||||
|
if (h->sh.short_term_ref_pic_set_sps_flag == 0 && h->sh.short_term_rps) {
|
||||||
|
pp->ucNumDeltaPocsOfRefRpsIdx = h->sh.short_term_rps->rps_idx_num_delta_pocs;
|
||||||
|
pp->wNumBitsForShortTermRPSInSlice = h->sh.short_term_ref_pic_set_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp->dwCodingParamToolFlags = (sps->scaling_list_enable_flag << 0) |
|
||||||
|
(sps->amp_enabled_flag << 1) |
|
||||||
|
(sps->sao_enabled << 2) |
|
||||||
|
(sps->pcm_enabled_flag << 3) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth - 1) : 0) << 4) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.bit_depth_chroma - 1) : 0) << 8) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.log2_min_pcm_cb_size - 3) : 0) << 12) |
|
||||||
|
((sps->pcm_enabled_flag ? (sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size) : 0) << 14) |
|
||||||
|
(sps->pcm.loop_filter_disable_flag << 16) |
|
||||||
|
(sps->long_term_ref_pics_present_flag << 17) |
|
||||||
|
(sps->sps_temporal_mvp_enabled_flag << 18) |
|
||||||
|
(sps->sps_strong_intra_smoothing_enable_flag << 19) |
|
||||||
|
(pps->dependent_slice_segments_enabled_flag << 20) |
|
||||||
|
(pps->output_flag_present_flag << 21) |
|
||||||
|
(pps->num_extra_slice_header_bits << 22) |
|
||||||
|
(pps->sign_data_hiding_flag << 25) |
|
||||||
|
(pps->cabac_init_present_flag << 26) |
|
||||||
|
(0 << 27);
|
||||||
|
|
||||||
|
pp->dwCodingSettingPicturePropertyFlags = (pps->constrained_intra_pred_flag << 0) |
|
||||||
|
(pps->transform_skip_enabled_flag << 1) |
|
||||||
|
(pps->cu_qp_delta_enabled_flag << 2) |
|
||||||
|
(pps->pic_slice_level_chroma_qp_offsets_present_flag << 3) |
|
||||||
|
(pps->weighted_pred_flag << 4) |
|
||||||
|
(pps->weighted_bipred_flag << 5) |
|
||||||
|
(pps->transquant_bypass_enable_flag << 6) |
|
||||||
|
(pps->tiles_enabled_flag << 7) |
|
||||||
|
(pps->entropy_coding_sync_enabled_flag << 8) |
|
||||||
|
(pps->uniform_spacing_flag << 9) |
|
||||||
|
((pps->tiles_enabled_flag ? pps->loop_filter_across_tiles_enabled_flag : 0) << 10) |
|
||||||
|
(pps->seq_loop_filter_across_slices_enabled_flag << 11) |
|
||||||
|
(pps->deblocking_filter_override_enabled_flag << 12) |
|
||||||
|
(pps->disable_dbf << 13) |
|
||||||
|
(pps->lists_modification_present_flag << 14) |
|
||||||
|
(pps->slice_header_extension_present_flag << 15) |
|
||||||
|
(IS_IRAP(h) << 16) |
|
||||||
|
(IS_IDR(h) << 17) |
|
||||||
|
/* IntraPicFlag */
|
||||||
|
(IS_IRAP(h) << 18) |
|
||||||
|
(0 << 19);
|
||||||
|
pp->pps_cb_qp_offset = pps->cb_qp_offset;
|
||||||
|
pp->pps_cr_qp_offset = pps->cr_qp_offset;
|
||||||
|
if (pps->tiles_enabled_flag) {
|
||||||
|
pp->num_tile_columns_minus1 = pps->num_tile_columns - 1;
|
||||||
|
pp->num_tile_rows_minus1 = pps->num_tile_rows - 1;
|
||||||
|
|
||||||
|
if (!pps->uniform_spacing_flag) {
|
||||||
|
for (i = 0; i < pps->num_tile_columns; i++)
|
||||||
|
pp->column_width_minus1[i] = pps->column_width[i] - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < pps->num_tile_rows; i++)
|
||||||
|
pp->row_height_minus1[i] = pps->row_height[i] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pp->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
|
||||||
|
pp->pps_beta_offset_div2 = pps->beta_offset / 2;
|
||||||
|
pp->pps_tc_offset_div2 = pps->tc_offset / 2;
|
||||||
|
pp->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
|
||||||
|
pp->CurrPicOrderCntVal = h->poc;
|
||||||
|
|
||||||
|
// fill RefPicList from the DPB
|
||||||
|
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefPicList); i++) {
|
||||||
|
const HEVCFrame *frame = NULL;
|
||||||
|
while (!frame && j < FF_ARRAY_ELEMS(h->DPB)) {
|
||||||
|
if (&h->DPB[j] != current_picture && (h->DPB[j].flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF)))
|
||||||
|
frame = &h->DPB[j];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame) {
|
||||||
|
fill_picture_entry(&pp->RefPicList[i], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
|
||||||
|
pp->PicOrderCntValList[i] = frame->poc;
|
||||||
|
} else {
|
||||||
|
pp->RefPicList[i].bPicEntry = 0xff;
|
||||||
|
pp->PicOrderCntValList[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DO_REF_LIST(ref_idx, ref_list) { \
|
||||||
|
const RefPicList *rpl = &h->rps[ref_idx]; \
|
||||||
|
for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->ref_list); i++) { \
|
||||||
|
const HEVCFrame *frame = NULL; \
|
||||||
|
while (!frame && j < rpl->nb_refs) \
|
||||||
|
frame = rpl->ref[j++]; \
|
||||||
|
if (frame) \
|
||||||
|
pp->ref_list[i] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, frame->frame)); \
|
||||||
|
else \
|
||||||
|
pp->ref_list[i] = 0xff; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill short term and long term lists
|
||||||
|
DO_REF_LIST(ST_CURR_BEF, RefPicSetStCurrBefore);
|
||||||
|
DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
|
||||||
|
DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
|
||||||
|
|
||||||
|
pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_scaling_lists(AVDXVAContext *ctx, const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
|
||||||
|
{
|
||||||
|
unsigned i, j, pos;
|
||||||
|
const ScalingList *sl = h->ps.pps->scaling_list_data_present_flag ?
|
||||||
|
&h->ps.pps->scaling_list : &h->ps.sps->scaling_list;
|
||||||
|
|
||||||
|
memset(qm, 0, sizeof(*qm));
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
pos = 4 * mpp_hevc_diag_scan4x4_y[j] + mpp_hevc_diag_scan4x4_x[j];
|
||||||
|
qm->ucScalingLists0[i][j] = sl->sl[0][i][pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < 64; j++) {
|
||||||
|
pos = 8 * mpp_hevc_diag_scan8x8_y[j] + mpp_hevc_diag_scan8x8_x[j];
|
||||||
|
qm->ucScalingLists1[i][j] = sl->sl[1][i][pos];
|
||||||
|
qm->ucScalingLists2[i][j] = sl->sl[2][i][pos];
|
||||||
|
|
||||||
|
if (i < 2)
|
||||||
|
qm->ucScalingLists3[i][j] = sl->sl[3][i * 3][pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
qm->ucScalingListDCCoefSizeID2[i] = sl->sl_dc[0][i];
|
||||||
|
if (i < 2)
|
||||||
|
qm->ucScalingListDCCoefSizeID3[i] = sl->sl_dc[1][i * 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
|
||||||
|
unsigned position, unsigned size)
|
||||||
|
{
|
||||||
|
memset(slice, 0, sizeof(*slice));
|
||||||
|
slice->BSNALunitDataLocation = position;
|
||||||
|
slice->SliceBytesInBuffer = size;
|
||||||
|
slice->wBadSliceChopping = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
|
||||||
|
DECODER_BUFFER_DESC *bs,
|
||||||
|
DECODER_BUFFER_DESC *sc)
|
||||||
|
{
|
||||||
|
const HEVCContext *h = avctx->priv_data;
|
||||||
|
AVDXVAContext *ctx = avctx->hwaccel_context;
|
||||||
|
const HEVCFrame *current_picture = h->ref;
|
||||||
|
struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
|
||||||
|
DXVA_Slice_HEVC_Short *slice = NULL;
|
||||||
|
void *dxva_data_ptr;
|
||||||
|
uint8_t *dxva_data, *current, *end;
|
||||||
|
unsigned dxva_size;
|
||||||
|
void *slice_data;
|
||||||
|
unsigned slice_size;
|
||||||
|
unsigned padding;
|
||||||
|
unsigned i;
|
||||||
|
unsigned type;
|
||||||
|
|
||||||
|
/* Create an annex B bitstream buffer with only slice NAL and finalize slice */
|
||||||
|
#if CONFIG_D3D11VA
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
|
||||||
|
type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
|
||||||
|
if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
|
||||||
|
D3D11VA_CONTEXT(ctx)->decoder,
|
||||||
|
type,
|
||||||
|
&dxva_size, &dxva_data_ptr)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CONFIG_DXVA2
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
|
||||||
|
type = DXVA2_BitStreamDateBufferType;
|
||||||
|
if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
|
||||||
|
type,
|
||||||
|
&dxva_data_ptr, &dxva_size)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dxva_data = dxva_data_ptr;
|
||||||
|
current = dxva_data;
|
||||||
|
end = dxva_data + dxva_size;
|
||||||
|
|
||||||
|
for (i = 0; i < ctx_pic->slice_count; i++) {
|
||||||
|
static const uint8_t start_code[] = { 0, 0, 1 };
|
||||||
|
static const unsigned start_code_size = sizeof(start_code);
|
||||||
|
unsigned position, size;
|
||||||
|
|
||||||
|
slice = &ctx_pic->slice_short[i];
|
||||||
|
|
||||||
|
position = slice->BSNALunitDataLocation;
|
||||||
|
size = slice->SliceBytesInBuffer;
|
||||||
|
if (start_code_size + size > end - current) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
slice->BSNALunitDataLocation = current - dxva_data;
|
||||||
|
slice->SliceBytesInBuffer = start_code_size + size;
|
||||||
|
|
||||||
|
memcpy(current, start_code, start_code_size);
|
||||||
|
current += start_code_size;
|
||||||
|
|
||||||
|
memcpy(current, &ctx_pic->bitstream[position], size);
|
||||||
|
current += size;
|
||||||
|
}
|
||||||
|
padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);
|
||||||
|
if (slice && padding > 0) {
|
||||||
|
memset(current, 0, padding);
|
||||||
|
current += padding;
|
||||||
|
|
||||||
|
slice->SliceBytesInBuffer += padding;
|
||||||
|
}
|
||||||
|
#if CONFIG_D3D11VA
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
|
||||||
|
if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
#if CONFIG_DXVA2
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
|
||||||
|
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
if (i < ctx_pic->slice_count)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#if CONFIG_D3D11VA
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
|
||||||
|
D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
|
||||||
|
memset(dsc11, 0, sizeof(*dsc11));
|
||||||
|
dsc11->BufferType = type;
|
||||||
|
dsc11->DataSize = current - dxva_data;
|
||||||
|
dsc11->NumMBsInBuffer = 0;
|
||||||
|
|
||||||
|
type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if CONFIG_DXVA2
|
||||||
|
if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
|
||||||
|
DXVA2_DecodeBufferDesc *dsc2 = bs;
|
||||||
|
memset(dsc2, 0, sizeof(*dsc2));
|
||||||
|
dsc2->CompressedBufferType = type;
|
||||||
|
dsc2->DataSize = current - dxva_data;
|
||||||
|
dsc2->NumMBsInBuffer = 0;
|
||||||
|
|
||||||
|
type = DXVA2_SliceControlBufferType;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
slice_data = ctx_pic->slice_short;
|
||||||
|
slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
|
||||||
|
|
||||||
|
av_assert0(((current - dxva_data) & 127) == 0);
|
||||||
|
return ff_dxva2_commit_buffer(avctx, ctx, sc,
|
||||||
|
type,
|
||||||
|
slice_data, slice_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int dxva2_hevc_start_frame(AVCodecContext *avctx,
|
||||||
|
av_unused const uint8_t *buffer,
|
||||||
|
av_unused RK_U32 size)
|
||||||
|
{
|
||||||
|
const HEVCContext *h = avctx->priv_data;
|
||||||
|
AVDXVAContext *ctx = avctx->hwaccel_context;
|
||||||
|
struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
|
||||||
|
|
||||||
|
if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
|
||||||
|
DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
|
||||||
|
DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
|
||||||
|
return -1;
|
||||||
|
av_assert0(ctx_pic);
|
||||||
|
|
||||||
|
/* Fill up DXVA_PicParams_HEVC */
|
||||||
|
fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
|
||||||
|
|
||||||
|
/* Fill up DXVA_Qmatrix_HEVC */
|
||||||
|
fill_scaling_lists(ctx, h, &ctx_pic->qm);
|
||||||
|
|
||||||
|
ctx_pic->slice_count = 0;
|
||||||
|
ctx_pic->bitstream_size = 0;
|
||||||
|
ctx_pic->bitstream = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
|
||||||
|
const uint8_t *buffer,
|
||||||
|
uint32_t size)
|
||||||
|
{
|
||||||
|
const HEVCContext *h = avctx->priv_data;
|
||||||
|
const HEVCFrame *current_picture = h->ref;
|
||||||
|
struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
|
||||||
|
unsigned position;
|
||||||
|
|
||||||
|
if (ctx_pic->slice_count >= MAX_SLICES)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!ctx_pic->bitstream)
|
||||||
|
ctx_pic->bitstream = buffer;
|
||||||
|
ctx_pic->bitstream_size += size;
|
||||||
|
|
||||||
|
position = buffer - ctx_pic->bitstream;
|
||||||
|
fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], position, size);
|
||||||
|
ctx_pic->slice_count++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dxva2_hevc_end_frame(AVCodecContext *avctx)
|
||||||
|
{
|
||||||
|
HEVCContext *h = avctx->priv_data;
|
||||||
|
struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
|
||||||
|
int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
|
||||||
|
&ctx_pic->pp, sizeof(ctx_pic->pp),
|
||||||
|
scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
|
||||||
|
commit_bitstream_and_slice_buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_HEVC_DXVA2_HWACCEL
|
||||||
|
AVHWAccel ff_hevc_dxva2_hwaccel = {
|
||||||
|
.name = "hevc_dxva2",
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.id = AV_CODEC_ID_HEVC,
|
||||||
|
.pix_fmt = AV_PIX_FMT_DXVA2_VLD,
|
||||||
|
.start_frame = dxva2_hevc_start_frame,
|
||||||
|
.decode_slice = dxva2_hevc_decode_slice,
|
||||||
|
.end_frame = dxva2_hevc_end_frame,
|
||||||
|
.frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_HEVC_D3D11VA_HWACCEL
|
||||||
|
AVHWAccel ff_hevc_d3d11va_hwaccel = {
|
||||||
|
.name = "hevc_d3d11va",
|
||||||
|
.type = AVMEDIA_TYPE_VIDEO,
|
||||||
|
.id = AV_CODEC_ID_HEVC,
|
||||||
|
.pix_fmt = AV_PIX_FMT_D3D11VA_VLD,
|
||||||
|
.start_frame = dxva2_hevc_start_frame,
|
||||||
|
.decode_slice = dxva2_hevc_decode_slice,
|
||||||
|
.end_frame = dxva2_hevc_end_frame,
|
||||||
|
.frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
|
||||||
|
};
|
||||||
|
#endif
|
193
mpp/mpp_bitread.c
Normal file
193
mpp/mpp_bitread.c
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include "mpp_mem.h"
|
||||||
|
#include "mpp_bitread.h"
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static RK_S32 rk_UpdateCurrByte(GetBitCxt_t *pBitCtx)
|
||||||
|
{
|
||||||
|
if (pBitCtx->bytes_left_ < 1)
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
|
||||||
|
// Emulation prevention three-byte detection.
|
||||||
|
// If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03).
|
||||||
|
if (*pBitCtx->data_ == 0x03 && (pBitCtx->prev_two_bytes_ & 0xffff) == 0) {
|
||||||
|
// Detected 0x000003, skip last byte.
|
||||||
|
++pBitCtx->data_;
|
||||||
|
--pBitCtx->bytes_left_;
|
||||||
|
++pBitCtx->emulation_prevention_bytes_;
|
||||||
|
// Need another full three bytes before we can detect the sequence again.
|
||||||
|
pBitCtx->prev_two_bytes_ = 0xffff;
|
||||||
|
|
||||||
|
if (pBitCtx->bytes_left_ < 1)
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load a new byte and advance pointers.
|
||||||
|
pBitCtx->curr_byte_ = *pBitCtx->data_++ & 0xff;
|
||||||
|
--pBitCtx->bytes_left_;
|
||||||
|
pBitCtx->num_remaining_bits_in_curr_byte_ = 8;
|
||||||
|
|
||||||
|
pBitCtx->prev_two_bytes_ = (pBitCtx->prev_two_bytes_ << 8) | pBitCtx->curr_byte_;
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read |num_bits| (1 to 31 inclusive) from the stream and return them
|
||||||
|
// in |out|, with first bit in the stream as MSB in |out| at position
|
||||||
|
// (|num_bits| - 1).
|
||||||
|
RK_S32 mpp_ReadBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_S32 *out)
|
||||||
|
{
|
||||||
|
RK_S32 bits_left = num_bits;
|
||||||
|
*out = 0;
|
||||||
|
if (num_bits > 31) {
|
||||||
|
// rk_err("%s num bit exceed 32",__function__);
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pBitCtx->num_remaining_bits_in_curr_byte_ < bits_left) {
|
||||||
|
// Take all that's left in current byte, shift to make space for the rest.
|
||||||
|
*out |= (pBitCtx->curr_byte_ << (bits_left - pBitCtx->num_remaining_bits_in_curr_byte_));
|
||||||
|
bits_left -= pBitCtx->num_remaining_bits_in_curr_byte_;
|
||||||
|
|
||||||
|
if (rk_UpdateCurrByte(pBitCtx)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*out |= (pBitCtx->curr_byte_ >> (pBitCtx->num_remaining_bits_in_curr_byte_ - bits_left));
|
||||||
|
*out &= ((1 << num_bits) - 1);
|
||||||
|
pBitCtx->num_remaining_bits_in_curr_byte_ -= bits_left;
|
||||||
|
pBitCtx->UsedBits += num_bits;
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_ReadLongBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_U32 *out)
|
||||||
|
{
|
||||||
|
RK_S32 val = 0, val1 = 0;
|
||||||
|
if (mpp_ReadBits(pBitCtx, 16, &val)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
if (mpp_ReadBits(pBitCtx, (num_bits - 16), &val1)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
val = val << 16;
|
||||||
|
*out = (RK_U32)(val | val1);
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_SkipBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits)
|
||||||
|
{
|
||||||
|
RK_S32 bits_left = num_bits;
|
||||||
|
|
||||||
|
while (pBitCtx->num_remaining_bits_in_curr_byte_ < bits_left) {
|
||||||
|
// Take all that's left in current byte, shift to make space for the rest.
|
||||||
|
bits_left -= pBitCtx->num_remaining_bits_in_curr_byte_;
|
||||||
|
|
||||||
|
if (rk_UpdateCurrByte(pBitCtx)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pBitCtx->num_remaining_bits_in_curr_byte_ -= bits_left;
|
||||||
|
pBitCtx->UsedBits += num_bits;
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RK_S32 mpp_ReadUE(GetBitCxt_t *pBitCtx, RK_U32 *val)
|
||||||
|
{
|
||||||
|
RK_S32 num_bits = -1;
|
||||||
|
RK_S32 bit;
|
||||||
|
RK_S32 rest;
|
||||||
|
// Count the number of contiguous zero bits.
|
||||||
|
do {
|
||||||
|
if (mpp_ReadBits(pBitCtx, 1, &bit)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
num_bits++;
|
||||||
|
} while (bit == 0);
|
||||||
|
|
||||||
|
if (num_bits > 31) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
// Calculate exp-Golomb code value of size num_bits.
|
||||||
|
*val = (1 << num_bits) - 1;
|
||||||
|
|
||||||
|
if (num_bits > 0) {
|
||||||
|
if (mpp_ReadBits(pBitCtx, num_bits, &rest)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
*val += rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_S32 mpp_ReadSE(GetBitCxt_t *pBitCtx, RK_S32 *val)
|
||||||
|
{
|
||||||
|
RK_U32 ue;
|
||||||
|
if (mpp_ReadUE(pBitCtx, &ue)) {
|
||||||
|
return MPP_ERR_STREAM;
|
||||||
|
}
|
||||||
|
if (ue % 2 == 0) { // odd
|
||||||
|
*val = -(RK_S32)(ue >> 1);
|
||||||
|
} else {
|
||||||
|
*val = (RK_S32)((ue >> 1) + 1);
|
||||||
|
}
|
||||||
|
return MPP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RK_S32 mpp_has_more_rbsp_data(GetBitCxt_t *pBitCtx)
|
||||||
|
{
|
||||||
|
// Make sure we have more bits, if we are at 0 bits in current byte
|
||||||
|
// and updating current byte fails, we don't have more data anyway.
|
||||||
|
if (pBitCtx->num_remaining_bits_in_curr_byte_ == 0 && !rk_UpdateCurrByte(pBitCtx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// On last byte?
|
||||||
|
if (pBitCtx->bytes_left_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Last byte, look for stop bit;
|
||||||
|
// We have more RBSP data if the last non-zero bit we find is not the
|
||||||
|
// first available bit.
|
||||||
|
return (pBitCtx->curr_byte_ &
|
||||||
|
((1 << (pBitCtx->num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpp_Init_Bits(GetBitCxt_t *pBitCtx, RK_U8 *data, RK_S32 size)
|
||||||
|
{
|
||||||
|
memset(pBitCtx, 0, sizeof(GetBitCxt_t));
|
||||||
|
pBitCtx->data_ = data;
|
||||||
|
pBitCtx->bytes_left_ = size;
|
||||||
|
pBitCtx->num_remaining_bits_in_curr_byte_ = 0;
|
||||||
|
// Initially set to 0xffff to accept all initial two-byte sequences.
|
||||||
|
pBitCtx->prev_two_bytes_ = 0xffff;
|
||||||
|
pBitCtx->emulation_prevention_bytes_ = 0;
|
||||||
|
// add
|
||||||
|
pBitCtx->buf = data;
|
||||||
|
pBitCtx->buf_len = size;
|
||||||
|
pBitCtx->UsedBits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void mpp_Set_Bits_LogContex(GetBitCxt_t *pBitCtx, RK_LOG_CONTEX_t *p_ctx)
|
||||||
|
{
|
||||||
|
//pBitCtx->ctx = p_ctx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mpp_Reset_UseBits(GetBitCxt_t *pBitCtx)
|
||||||
|
{
|
||||||
|
pBitCtx->UsedBits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RK_U8 mpp_get_curdata_value(GetBitCxt_t *pBitCtx)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (*pBitCtx->data_);
|
||||||
|
}
|
120
mpp/mpp_bitread.h
Normal file
120
mpp/mpp_bitread.h
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#ifndef __RK_BIT_READ_H__
|
||||||
|
#define __RK_BIT_READ_H__
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "rk_type.h"
|
||||||
|
#include "mpp_log.h"
|
||||||
|
#include "mpp_common.h"
|
||||||
|
#include "mpp_err.h"
|
||||||
|
|
||||||
|
#define READ_BITS(pBitCtx, num_bits, out) \
|
||||||
|
do { \
|
||||||
|
RK_S32 _out; \
|
||||||
|
RK_S32 _ret = 0; \
|
||||||
|
_ret = mpp_ReadBits(pBitCtx, num_bits, &_out); \
|
||||||
|
if (!_ret) { *out = _out; } \
|
||||||
|
else { return MPP_ERR_STREAM; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define READ_SKIPBITS(pBitCtx, num_bits) \
|
||||||
|
do { \
|
||||||
|
RK_S32 _ret = 0; \
|
||||||
|
_ret = mpp_SkipBits(pBitCtx, num_bits); \
|
||||||
|
if (_ret) {return MPP_ERR_STREAM; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define READ_BIT1(pBitCtx, out) \
|
||||||
|
do { \
|
||||||
|
RK_S32 _out; \
|
||||||
|
RK_S32 _ret = 0; \
|
||||||
|
_ret = mpp_ReadBits(pBitCtx, 1, &_out); \
|
||||||
|
if (!_ret) { *out = _out; } \
|
||||||
|
else { return MPP_ERR_STREAM;} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define READ_UE(pBitCtx, out) \
|
||||||
|
do { \
|
||||||
|
RK_U32 _out; \
|
||||||
|
RK_S32 _ret = 0; \
|
||||||
|
_ret = mpp_ReadUE(pBitCtx, &_out); \
|
||||||
|
if (!_ret) { *out = _out; } \
|
||||||
|
else { return MPP_ERR_STREAM; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define READ_SE(pBitCtx, out) \
|
||||||
|
do { \
|
||||||
|
RK_S32 _out; \
|
||||||
|
RK_S32 _ret = 0; \
|
||||||
|
_ret = mpp_ReadSE(pBitCtx, &_out); \
|
||||||
|
if (!_ret) { *out = _out; } \
|
||||||
|
else { return MPP_ERR_STREAM; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define CHECK_RANGE(pBitCtx,val, _min, _max) \
|
||||||
|
do { \
|
||||||
|
if ((val) < (_min) || (val) > (_max)) { \
|
||||||
|
mpp_log("%d[%d,%d]", val, _min, _max); \
|
||||||
|
return MPP_ERR_STREAM; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
#define CHECK_ERROR(pBitCtx,val) \
|
||||||
|
do { \
|
||||||
|
if (!(val)) { \
|
||||||
|
mpp_log("value false"); \
|
||||||
|
mpp_assert(0); \
|
||||||
|
return MPP_ERR_STREAM; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================================
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// Pointer to the next unread (not in curr_byte_) byte in the stream.
|
||||||
|
RK_U8 *data_;
|
||||||
|
// Bytes left in the stream (without the curr_byte_).
|
||||||
|
RK_U32 bytes_left_;
|
||||||
|
// Contents of the current byte; first unread bit starting at position
|
||||||
|
// 8 - num_remaining_bits_in_curr_byte_ from MSB.
|
||||||
|
RK_S64 curr_byte_;
|
||||||
|
// Number of bits remaining in curr_byte_
|
||||||
|
RK_S32 num_remaining_bits_in_curr_byte_;
|
||||||
|
// Used in emulation prevention three byte detection (see spec).
|
||||||
|
// Initially set to 0xffff to accept all initial two-byte sequences.
|
||||||
|
RK_S64 prev_two_bytes_;
|
||||||
|
// Number of emulation preventation bytes (0x000003) we met.
|
||||||
|
RK_S64 emulation_prevention_bytes_;
|
||||||
|
// file to debug
|
||||||
|
// count PPS SPS SEI read bits
|
||||||
|
RK_S32 UsedBits;
|
||||||
|
RK_U8 *buf;
|
||||||
|
RK_S32 buf_len;
|
||||||
|
} GetBitCxt_t;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RK_S32 mpp_ReadBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_S32 *out);
|
||||||
|
RK_S32 mpp_ReadLongBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits, RK_U32 *out);
|
||||||
|
RK_S32 mpp_SkipBits(GetBitCxt_t *pBitCtx, RK_S32 num_bits);
|
||||||
|
RK_S32 mpp_ReadUE(GetBitCxt_t *pBitCtx, RK_U32* val);
|
||||||
|
RK_S32 mpp_ReadSE(GetBitCxt_t *pBitCtx, RK_S32* val);
|
||||||
|
void mpp_Init_Bits(GetBitCxt_t *pBitCtx, RK_U8 *data, RK_S32 size);
|
||||||
|
RK_S32 mpp_has_more_rbsp_data(GetBitCxt_t * pBitCtx);
|
||||||
|
//void mpp_Set_Bits_LogContex(GetBitCxt_t *pBitCtx, RK_LOG_CONTEX_t *p_ctx);
|
||||||
|
void mpp_Reset_UseBits(GetBitCxt_t *pBitCtx);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __RK_BIT_READ_H__ */
|
Reference in New Issue
Block a user