hc
2023-05-26 a23f51ed7a39e452c1037343a84d7db1ca2c5bd7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
 * Copyright 2017 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_H264E_VEPU_V2_H__
#define __HAL_H264E_VEPU_V2_H__
 
#include "mpp_enc_cfg.h"
#include "mpp_rc.h"
#include "vepu_common.h"
 
#define H264E_HAL_SET_REG(reg, addr, val)                                    \
    do {                                                                     \
        reg[(addr)>>2] = (RK_U32)(val);                                      \
        if (hal_h264e_debug & 0/*H264E_HAL_LOG_INFO*/)                              \
            mpp_log("line(%d) set reg[%03d/%03x]: %08x", __LINE__, (addr)>>2, addr, val); \
    } while (0)
 
typedef enum H264eVpuFrameType_t {
    H264E_VPU_FRAME_P = 0,
    H264E_VPU_FRAME_I = 1
} H264eVpuFrameType;
 
#define VEPU_CTRL_LEVELS            7
#define VEPU_CHECK_POINTS_MAX       10
 
typedef struct HalH264eVepuInput_t {
    /* Hardware config format */
    RK_S32          src_fmt;
    RK_S32          src_w;
    RK_S32          src_h;
 
    VepuStrideCfg   stride_cfg;
    RK_S32          pixel_stride;
 
    size_t          size_y;
    size_t          size_c;
 
    RK_U32          offset_cb;
    RK_U32          offset_cr;
 
    RK_U8           r_mask_msb;
    RK_U8           g_mask_msb;
    RK_U8           b_mask_msb;
    RK_U8           swap_8_in;
    RK_U8           swap_16_in;
    RK_U8           swap_32_in;
 
    RK_U32          color_conversion_coeff_a;
    RK_U32          color_conversion_coeff_b;
    RK_U32          color_conversion_coeff_c;
    RK_U32          color_conversion_coeff_e;
    RK_U32          color_conversion_coeff_f;
} HalH264eVepuPrep;
 
typedef struct HalH264eVepuFrmAddr_t {
    // original frame Y/Cb/Cr/RGB address
    RK_U32          orig[3];
    // reconstruction frame
    RK_U32          recn[2];
    RK_U32          refr[2];
} HalH264eVepuAddr;
 
/*
 * Vepu buffer allocater
 * There are three internal buffer for Vepu encoder:
 * 1. cabac table input buffer
 * 2. nal size table output buffer
 * 3. recon / refer frame buffer
 */
typedef struct HalH264eVepuBufs_t {
    MppBufferGroup  group;
 
    /* cabac table buffer */
    RK_S32          cabac_init_idc;
    MppBuffer       cabac_table;
 
    /*
     * nal size table buffer
     * table size must be 64-bit multiple, space for zero at the end of table
     * Atleast 1 macroblock row in every slice
     */
    RK_S32          mb_h;
    RK_S32          nal_tab_size;
    MppBuffer       nal_size_table;
 
    /*
     * recon / refer frame buffer
     * sync with encoder using slot index
     */
    size_t          frm_size;
    size_t          yuv_size;
    RK_S32          frm_cnt;
    MppBuffer       frm_buf[H264E_MAX_REFS_CNT + 1];
} HalH264eVepuBufs;
 
typedef struct HalH264eVepuMbRc_t {
    /* VEPU MB rate control parameter for config to hardware */
    RK_S32          qp_init;
    RK_S32          qp_min;
    RK_S32          qp_max;
 
    /*
     * VEPU MB can have max 10 check points (cp).
     *
     * On each check point hardware will check the target bit and
     * error bits and change qp according to delta qp step
     *
     * cp_distance_mbs  check point distance in mbs (0 = disabled)
     * cp_target        bitrate target at each check point
     * cp_error         error bit level step for each delta qp
     * cp_delta_qp      delta qp applied on when on bit rate error amount
     */
    RK_S32          cp_distance_mbs;
    RK_S32          cp_target[VEPU_CHECK_POINTS_MAX];
    RK_S32          cp_error[VEPU_CTRL_LEVELS];
    RK_S32          cp_delta_qp[VEPU_CTRL_LEVELS];
 
    /*
     * MAD based QP adjustment
     * mad_qp_change    [-8..7]
     * mad_threshold    MAD threshold div256
     */
    RK_S32          mad_qp_change;
    RK_S32          mad_threshold;
 
    /* slice split by mb row (0 = one slice) */
    RK_S32          slice_size_mb_rows;
 
    /* favor and penalty for mode decision */
 
    /*
     * VEPU MB rate control parameter which is read from hardware
     * out_strm_size    output stream size (bits)
     * qp_sum           QP Sum div2 output
     * rlc_count        RLC codeword count div4 output max 255*255*384/4
     */
    RK_U32          hdr_strm_size;
    RK_U32          hdr_free_size;
    RK_U32          out_strm_size;
    RK_S32          qp_sum;
    RK_S32          rlc_count;
 
    RK_S32          cp_usage[VEPU_CHECK_POINTS_MAX];
    /* Macroblock count with MAD value under threshold output */
    RK_S32          less_mad_count;
    /* MB count output */
    RK_S32          mb_count;
 
    /* hardware encoding status 0 - corret 1 - error */
    RK_U32          hw_status;
} HalH264eVepuMbRc;
 
typedef void *HalH264eVepuMbRcCtx;
 
typedef struct HalH264eVepuStreamAmend_t {
    RK_S32          enable;
    H264eSlice      *slice;
    H264ePrefixNal  *prefix;
    RK_S32          slice_enabled;
 
    RK_U8           *src_buf;
    RK_U8           *dst_buf;
    RK_S32          buf_size;
 
    MppPacket       packet;
    RK_S32          buf_base;
    RK_S32          old_length;
    RK_S32          new_length;
} HalH264eVepuStreamAmend;
 
#ifdef __cplusplus
extern "C" {
#endif
 
RK_S32 exp_golomb_signed(RK_S32 val);
 
/* buffer management function */
MPP_RET h264e_vepu_buf_init(HalH264eVepuBufs *bufs);
MPP_RET h264e_vepu_buf_deinit(HalH264eVepuBufs *bufs);
 
MPP_RET h264e_vepu_buf_set_cabac_idc(HalH264eVepuBufs *bufs, RK_S32 idc);
MPP_RET h264e_vepu_buf_set_frame_size(HalH264eVepuBufs *bufs, RK_S32 w, RK_S32 h);
 
MppBuffer h264e_vepu_buf_get_nal_size_table(HalH264eVepuBufs *bufs);
MppBuffer h264e_vepu_buf_get_frame_buffer(HalH264eVepuBufs *bufs, RK_S32 index);
 
/* preprocess setup function */
MPP_RET h264e_vepu_prep_setup(HalH264eVepuPrep *prep, MppEncPrepCfg *cfg);
MPP_RET h264e_vepu_prep_get_addr(HalH264eVepuPrep *prep, MppBuffer buffer,
                                 RK_U32 (*addr)[3]);
 
/* macroblock bitrate control function */
MPP_RET h264e_vepu_mbrc_init(HalH264eVepuMbRcCtx *ctx, HalH264eVepuMbRc *mbrc);
MPP_RET h264e_vepu_mbrc_deinit(HalH264eVepuMbRcCtx ctx);
 
MPP_RET h264e_vepu_mbrc_setup(HalH264eVepuMbRcCtx ctx, MppEncCfgSet *cfg);
MPP_RET h264e_vepu_slice_split_cfg(H264eSlice *slice, HalH264eVepuMbRc *mbrc,
                                   EncRcTask *rc_task, MppEncCfgSet *set_cfg);
 
/*
 * generate hardware MB rc config by:
 * 1 - HalH264eVepuMbRcCtx ctx
 *     The previous frame encoding status
 * 2 - RcSyntax
 *     Provide current frame target bitrate related info
 * 3 - EncFrmStatus
 *     Provide dpb related info like I / P frame, temporal id, refer distance
 *
 * Then output the HalH264eVepuMbRc for register generation
 */
MPP_RET h264e_vepu_mbrc_prepare(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc,
                                EncRcTask *rc_task);
MPP_RET h264e_vepu_mbrc_update(HalH264eVepuMbRcCtx ctx, HalH264eVepuMbRc *mbrc);
 
MPP_RET h264e_vepu_stream_amend_init(HalH264eVepuStreamAmend *ctx);
MPP_RET h264e_vepu_stream_amend_deinit(HalH264eVepuStreamAmend *ctx);
MPP_RET h264e_vepu_stream_amend_config(HalH264eVepuStreamAmend *ctx,
                                       MppPacket packet, MppEncCfgSet *cfg,
                                       H264eSlice *slice, H264ePrefixNal *prefix);
MPP_RET h264e_vepu_stream_amend_proc(HalH264eVepuStreamAmend *ctx);
MPP_RET h264e_vepu_stream_amend_sync_ref_idc(HalH264eVepuStreamAmend *ctx);
 
#ifdef __cplusplus
}
#endif
 
#endif