xref: /OK3568_Linux_fs/external/mpp/mpp/base/mpp_enc_cfg.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "mpp_enc_cfg"
18 
19 #include <string.h>
20 
21 #include "rk_venc_cfg.h"
22 
23 #include "mpp_env.h"
24 #include "mpp_mem.h"
25 #include "mpp_time.h"
26 #include "mpp_debug.h"
27 #include "mpp_common.h"
28 #include "mpp_thread.h"
29 
30 #include "mpp_cfg.h"
31 #include "mpp_enc_cfg_impl.h"
32 
33 #define MPP_ENC_CFG_DBG_FUNC            (0x00000001)
34 #define MPP_ENC_CFG_DBG_INFO            (0x00000002)
35 #define MPP_ENC_CFG_DBG_SET             (0x00000004)
36 #define MPP_ENC_CFG_DBG_GET             (0x00000008)
37 
38 #define mpp_enc_cfg_dbg(flag, fmt, ...) _mpp_dbg_f(mpp_enc_cfg_debug, flag, fmt, ## __VA_ARGS__)
39 
40 #define mpp_enc_cfg_dbg_func(fmt, ...)  mpp_enc_cfg_dbg(MPP_ENC_CFG_DBG_FUNC, fmt, ## __VA_ARGS__)
41 #define mpp_enc_cfg_dbg_info(fmt, ...)  mpp_enc_cfg_dbg(MPP_ENC_CFG_DBG_INFO, fmt, ## __VA_ARGS__)
42 #define mpp_enc_cfg_dbg_set(fmt, ...)   mpp_enc_cfg_dbg(MPP_ENC_CFG_DBG_SET, fmt, ## __VA_ARGS__)
43 #define mpp_enc_cfg_dbg_get(fmt, ...)   mpp_enc_cfg_dbg(MPP_ENC_CFG_DBG_GET, fmt, ## __VA_ARGS__)
44 
45 RK_U32 mpp_enc_cfg_debug = 0;
46 
47 /*
48  * MppEncCfgInfo data struct
49  *
50  *   +----------+
51  *   |   head   |
52  *   +----------+
53  *   |   trie   |
54  *   |   node   |
55  *   |   ....   |
56  *   +----------+
57  *   |   info   |
58  *   |   node   |
59  *   |   ....   |
60  *   +----------+
61  */
62 typedef struct MppEncCfgInfo_t {
63     MppCfgInfoHead      head;
64     MppTrieNode         trie_node[];
65     /* MppCfgInfoNode is following trie_node */
66 } MppEncCfgInfo;
67 
mpp_enc_cfg_find(MppEncCfgInfo * info,const char * name)68 static MppCfgInfoNode *mpp_enc_cfg_find(MppEncCfgInfo *info, const char *name)
69 {
70     MppTrieNode *node;
71 
72     if (NULL == info || NULL == name)
73         return NULL;
74 
75     node = mpp_trie_get_node(info->trie_node, name);
76     if (NULL == node)
77         return NULL;
78 
79     return (MppCfgInfoNode *)(((char *)info->trie_node) + node->id);
80 }
81 
82 class MppEncCfgService
83 {
84 private:
85     MppEncCfgService();
86     ~MppEncCfgService();
87     MppEncCfgService(const MppEncCfgService &);
88     MppEncCfgService &operator=(const MppEncCfgService &);
89 
90     MppEncCfgInfo *mInfo;
91     RK_S32 mCfgSize;
92 
93 public:
get()94     static MppEncCfgService *get() {
95         static Mutex lock;
96         static MppEncCfgService instance;
97 
98         AutoMutex auto_lock(&lock);
99         return &instance;
100     }
101 
get_info(const char * name)102     MppCfgInfoNode *get_info(const char *name) { return mpp_enc_cfg_find(mInfo, name); };
103     MppCfgInfoNode *get_info_root();
104 
get_node_count()105     RK_S32 get_node_count() { return mInfo ? mInfo->head.node_count : 0; };
get_info_count()106     RK_S32 get_info_count() { return mInfo ? mInfo->head.info_count : 0; };
get_info_size()107     RK_S32 get_info_size() { return mInfo ? mInfo->head.info_size : 0; };
get_cfg_size()108     RK_S32 get_cfg_size() { return mCfgSize; };
109 };
110 
111 #define EXPAND_AS_API(base, name, cfg_type, in_type, flag, field_change, field_data) \
112     MppCfgApi api_##base##_##name = \
113     { \
114         #base":"#name, \
115         CFG_FUNC_TYPE_##cfg_type, \
116         (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \
117         flag, \
118         (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \
119         sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \
120     };
121 
122 #define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \
123     &api_##base##_##name,
124 
125 #define ENTRY_TABLE(ENTRY)  \
126     /* base config */ \
127     ENTRY(base, low_delay,      S32, RK_S32,            MPP_ENC_BASE_CFG_CHANGE_LOW_DELAY,      base, low_delay) \
128     /* rc config */ \
129     ENTRY(rc,   mode,           S32, MppEncRcMode,      MPP_ENC_RC_CFG_CHANGE_RC_MODE,          rc, rc_mode) \
130     ENTRY(rc,   bps_target,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_BPS,              rc, bps_target) \
131     ENTRY(rc,   bps_max,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_BPS,              rc, bps_max) \
132     ENTRY(rc,   bps_min,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_BPS,              rc, bps_min) \
133     ENTRY(rc,   fps_in_flex,    S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_IN,           rc, fps_in_flex) \
134     ENTRY(rc,   fps_in_num,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_IN,           rc, fps_in_num) \
135     ENTRY(rc,   fps_in_denorm,  S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_IN,           rc, fps_in_denorm) \
136     ENTRY(rc,   fps_out_flex,   S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_OUT,          rc, fps_out_flex) \
137     ENTRY(rc,   fps_out_num,    S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_OUT,          rc, fps_out_num) \
138     ENTRY(rc,   fps_out_denorm, S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_FPS_OUT,          rc, fps_out_denorm) \
139     ENTRY(rc,   gop,            S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_GOP,              rc, gop) \
140     ENTRY(rc,   ref_cfg,        Ptr, void *,            MPP_ENC_RC_CFG_CHANGE_GOP_REF_CFG,      rc, ref_cfg) \
141     ENTRY(rc,   max_reenc_times,U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_MAX_REENC,        rc, max_reenc_times) \
142     ENTRY(rc,   priority,       U32, MppEncRcPriority,  MPP_ENC_RC_CFG_CHANGE_PRIORITY,         rc, rc_priority) \
143     ENTRY(rc,   drop_mode,      U32, MppEncRcDropFrmMode, MPP_ENC_RC_CFG_CHANGE_DROP_FRM,       rc, drop_mode) \
144     ENTRY(rc,   drop_thd,       U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_DROP_FRM,         rc, drop_threshold) \
145     ENTRY(rc,   drop_gap,       U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_DROP_FRM,         rc, drop_gap) \
146     ENTRY(rc,   max_i_prop,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_MAX_I_PROP,       rc, max_i_prop) \
147     ENTRY(rc,   min_i_prop,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_MIN_I_PROP,       rc, min_i_prop) \
148     ENTRY(rc,   init_ip_ratio,  S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_INIT_IP_RATIO,    rc, init_ip_ratio) \
149     ENTRY(rc,   super_mode,     U32, MppEncRcSuperFrameMode, MPP_ENC_RC_CFG_CHANGE_SUPER_FRM,   rc, super_mode) \
150     ENTRY(rc,   super_i_thd,    U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_SUPER_FRM,        rc, super_i_thd) \
151     ENTRY(rc,   super_p_thd,    U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_SUPER_FRM,        rc, super_p_thd) \
152     ENTRY(rc,   debreath_en,    U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_DEBREATH,         rc, debreath_en) \
153     ENTRY(rc,   debreath_strength,  U32, RK_U32,        MPP_ENC_RC_CFG_CHANGE_DEBREATH,         rc, debre_strength) \
154     ENTRY(rc,   qp_init,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_INIT,          rc, qp_init) \
155     ENTRY(rc,   qp_min,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_min) \
156     ENTRY(rc,   qp_max,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_max) \
157     ENTRY(rc,   qp_min_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_min_i) \
158     ENTRY(rc,   qp_max_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_max_i) \
159     ENTRY(rc,   qp_step,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP,      rc, qp_max_step) \
160     ENTRY(rc,   qp_ip,          S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_IP,            rc, qp_delta_ip) \
161     ENTRY(rc,   qp_vi,          S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_VI,            rc, qp_delta_vi) \
162     ENTRY(rc,   hier_qp_en,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_HIER_QP,          rc, hier_qp_en) \
163     ENTRY(rc,   hier_qp_delta,  St,  RK_S32 *,          MPP_ENC_RC_CFG_CHANGE_HIER_QP,          rc, hier_qp_delta) \
164     ENTRY(rc,   hier_frame_num, St,  RK_S32 *,          MPP_ENC_RC_CFG_CHANGE_HIER_QP,          rc, hier_frame_num) \
165     ENTRY(rc,   stats_time,     S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_ST_TIME,          rc, stats_time) \
166     ENTRY(rc,   refresh_en,     U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_REFRESH,          rc, refresh_en) \
167     ENTRY(rc,   refresh_mode,   U32, MppEncRcRefreshMode, MPP_ENC_RC_CFG_CHANGE_REFRESH,        rc, refresh_mode) \
168     ENTRY(rc,   refresh_num,    U32, RK_U32,            MPP_ENC_RC_CFG_CHANGE_REFRESH,          rc, refresh_num) \
169     /* prep config */ \
170     ENTRY(prep, width,          S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_INPUT,          prep, width) \
171     ENTRY(prep, height,         S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_INPUT,          prep, height) \
172     ENTRY(prep, hor_stride,     S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_INPUT,          prep, hor_stride) \
173     ENTRY(prep, ver_stride,     S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_INPUT,          prep, ver_stride) \
174     ENTRY(prep, format,         S32, MppFrameFormat,    MPP_ENC_PREP_CFG_CHANGE_FORMAT,         prep, format) \
175     ENTRY(prep, colorspace,     S32, MppFrameColorSpace,MPP_ENC_PREP_CFG_CHANGE_COLOR_SPACE,    prep, color) \
176     ENTRY(prep, colorprim,      S32, MppFrameColorPrimaries, MPP_ENC_PREP_CFG_CHANGE_COLOR_PRIME, prep, colorprim) \
177     ENTRY(prep, colortrc,       S32, MppFrameColorTransferCharacteristic, MPP_ENC_PREP_CFG_CHANGE_COLOR_TRC, prep, colortrc) \
178     ENTRY(prep, colorrange,     S32, MppFrameColorRange,MPP_ENC_PREP_CFG_CHANGE_COLOR_RANGE,    prep, range) \
179     ENTRY(prep, range,          S32, MppFrameColorRange,MPP_ENC_PREP_CFG_CHANGE_COLOR_RANGE,    prep, range) \
180     ENTRY(prep, rotation,       S32, MppEncRotationCfg, MPP_ENC_PREP_CFG_CHANGE_ROTATION,       prep, rotation_ext) \
181     ENTRY(prep, mirroring,      S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_MIRRORING,      prep, mirroring_ext) \
182     ENTRY(prep, flip,           S32, RK_S32,            MPP_ENC_PREP_CFG_CHANGE_FLIP,           prep, flip) \
183     /* codec coding config */ \
184     ENTRY(codec, type,          S32, MppCodingType,     0,                                      codec, coding) \
185     /* h264 config */ \
186     ENTRY(h264, stream_type,    S32, RK_S32,            MPP_ENC_H264_CFG_STREAM_TYPE,           codec.h264, stream_type) \
187     ENTRY(h264, profile,        S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_PROFILE,        codec.h264, profile) \
188     ENTRY(h264, level,          S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_PROFILE,        codec.h264, level) \
189     ENTRY(h264, poc_type,       U32, RK_U32,            MPP_ENC_H264_CFG_CHANGE_POC_TYPE,       codec.h264, poc_type) \
190     ENTRY(h264, log2_max_poc_lsb,   U32, RK_U32,        MPP_ENC_H264_CFG_CHANGE_MAX_POC_LSB,    codec.h264, log2_max_poc_lsb) \
191     ENTRY(h264, log2_max_frm_num,   U32, RK_U32,        MPP_ENC_H264_CFG_CHANGE_MAX_FRM_NUM,    codec.h264, log2_max_frame_num) \
192     ENTRY(h264, gaps_not_allowed,   U32, RK_U32,        MPP_ENC_H264_CFG_CHANGE_GAPS_IN_FRM_NUM, codec.h264, gaps_not_allowed) \
193     ENTRY(h264, cabac_en,       S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_ENTROPY,        codec.h264, entropy_coding_mode_ex) \
194     ENTRY(h264, cabac_idc,      S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_ENTROPY,        codec.h264, cabac_init_idc_ex) \
195     ENTRY(h264, trans8x8,       S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_TRANS_8x8,      codec.h264, transform8x8_mode_ex) \
196     ENTRY(h264, const_intra,    S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_CONST_INTRA,    codec.h264, constrained_intra_pred_mode) \
197     ENTRY(h264, scaling_list,   S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_SCALING_LIST,   codec.h264, scaling_list_mode) \
198     ENTRY(h264, cb_qp_offset,   S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_CHROMA_QP,      codec.h264, chroma_cb_qp_offset) \
199     ENTRY(h264, cr_qp_offset,   S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_CHROMA_QP,      codec.h264, chroma_cr_qp_offset) \
200     ENTRY(h264, dblk_disable,   S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_DEBLOCKING,     codec.h264, deblock_disable) \
201     ENTRY(h264, dblk_alpha,     S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_DEBLOCKING,     codec.h264, deblock_offset_alpha) \
202     ENTRY(h264, dblk_beta,      S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_DEBLOCKING,     codec.h264, deblock_offset_beta) \
203     ENTRY(h264, qp_init,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_INIT,          rc, qp_init) \
204     ENTRY(h264, qp_min,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_min) \
205     ENTRY(h264, qp_max,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_max) \
206     ENTRY(h264, qp_min_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_min_i) \
207     ENTRY(h264, qp_max_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_max_i) \
208     ENTRY(h264, qp_step,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP,      rc, qp_max_step) \
209     ENTRY(h264, qp_delta_ip,    S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_IP,            rc, qp_delta_ip) \
210     ENTRY(h264, max_tid,        S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_MAX_TID,        codec.h264, max_tid) \
211     ENTRY(h264, max_ltr,        S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_MAX_LTR,        codec.h264, max_ltr_frames) \
212     ENTRY(h264, prefix_mode,    S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_ADD_PREFIX,     codec.h264, prefix_mode) \
213     ENTRY(h264, base_layer_pid, S32, RK_S32,            MPP_ENC_H264_CFG_CHANGE_BASE_LAYER_PID, codec.h264, base_layer_pid) \
214     ENTRY(h264, constraint_set, U32, RK_U32,            MPP_ENC_H264_CFG_CHANGE_CONSTRAINT_SET, codec.h264, constraint_set) \
215     /* h265 config*/ \
216     ENTRY(h265, profile,        S32, RK_S32,            MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE,    codec.h265, profile) \
217     ENTRY(h265, level,          S32, RK_S32,            MPP_ENC_H265_CFG_PROFILE_LEVEL_TILER_CHANGE,    codec.h265, level) \
218     ENTRY(h265, scaling_list,   U32, RK_U32,            MPP_ENC_H265_CFG_TRANS_CHANGE,                  codec.h265, trans_cfg.defalut_ScalingList_enable) \
219     ENTRY(h265, cb_qp_offset,   S32, RK_S32,            MPP_ENC_H265_CFG_TRANS_CHANGE,                  codec.h265, trans_cfg.cb_qp_offset) \
220     ENTRY(h265, cr_qp_offset,   S32, RK_S32,            MPP_ENC_H265_CFG_TRANS_CHANGE,                  codec.h265, trans_cfg.cr_qp_offset) \
221     ENTRY(h265, dblk_disable,   U32, RK_U32,            MPP_ENC_H265_CFG_DBLK_CHANGE,                   codec.h265, dblk_cfg.slice_deblocking_filter_disabled_flag) \
222     ENTRY(h265, dblk_alpha,     S32, RK_S32,            MPP_ENC_H265_CFG_DBLK_CHANGE,                   codec.h265, dblk_cfg.slice_beta_offset_div2) \
223     ENTRY(h265, dblk_beta,      S32, RK_S32,            MPP_ENC_H265_CFG_DBLK_CHANGE,                   codec.h265, dblk_cfg.slice_tc_offset_div2) \
224     ENTRY(h265, qp_init,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_INIT,          rc, qp_init) \
225     ENTRY(h265, qp_min,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_min) \
226     ENTRY(h265, qp_max,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_max) \
227     ENTRY(h265, qp_min_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_min_i) \
228     ENTRY(h265, qp_max_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_max_i) \
229     ENTRY(h265, qp_step,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP,      rc, qp_max_step) \
230     ENTRY(h265, qp_delta_ip,    S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_IP,            rc, qp_delta_ip) \
231     ENTRY(h265, sao_luma_disable,   S32, RK_S32,        MPP_ENC_H265_CFG_SAO_CHANGE,            codec.h265, sao_cfg.slice_sao_luma_disable) \
232     ENTRY(h265, sao_chroma_disable, S32, RK_S32,        MPP_ENC_H265_CFG_SAO_CHANGE,            codec.h265, sao_cfg.slice_sao_chroma_disable) \
233     ENTRY(h265, lpf_acs_sli_en, U32, RK_U32,            MPP_ENC_H265_CFG_SLICE_LPFACS_CHANGE,   codec.h265, lpf_acs_sli_en) \
234     ENTRY(h265, lpf_acs_tile_disable, U32, RK_U32,      MPP_ENC_H265_CFG_TILE_LPFACS_CHANGE,    codec.h265, lpf_acs_tile_disable) \
235     ENTRY(h265, auto_tile,      S32, RK_S32,            MPP_ENC_H265_CFG_TILE_CHANGE,           codec.h265, auto_tile) \
236     /* vp8 config */ \
237     ENTRY(vp8,  qp_init,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_INIT,          rc, qp_init) \
238     ENTRY(vp8,  qp_min,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_min) \
239     ENTRY(vp8,  qp_max,         S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE,         rc, qp_max) \
240     ENTRY(vp8,  qp_min_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_min_i) \
241     ENTRY(vp8,  qp_max_i,       S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_RANGE_I,       rc, qp_max_i) \
242     ENTRY(vp8,  qp_step,        S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_MAX_STEP,      rc, qp_max_step) \
243     ENTRY(vp8,  qp_delta_ip,    S32, RK_S32,            MPP_ENC_RC_CFG_CHANGE_QP_IP,            rc, qp_delta_ip) \
244     ENTRY(vp8,  disable_ivf,    S32, RK_S32,            MPP_ENC_VP8_CFG_CHANGE_DIS_IVF,         codec.vp8, disable_ivf) \
245     /* jpeg config */ \
246     ENTRY(jpeg, quant,          S32, RK_S32,            MPP_ENC_JPEG_CFG_CHANGE_QP,             codec.jpeg, quant) \
247     ENTRY(jpeg, qtable_y,       Ptr, RK_U8*,            MPP_ENC_JPEG_CFG_CHANGE_QTABLE,         codec.jpeg, qtable_y) \
248     ENTRY(jpeg, qtable_u,       Ptr, RK_U8*,            MPP_ENC_JPEG_CFG_CHANGE_QTABLE,         codec.jpeg, qtable_u) \
249     ENTRY(jpeg, qtable_v,       Ptr, RK_U8*,            MPP_ENC_JPEG_CFG_CHANGE_QTABLE,         codec.jpeg, qtable_v) \
250     ENTRY(jpeg, q_factor,       S32, RK_S32,            MPP_ENC_JPEG_CFG_CHANGE_QFACTOR,        codec.jpeg, q_factor) \
251     ENTRY(jpeg, qf_max,         S32, RK_S32,            MPP_ENC_JPEG_CFG_CHANGE_QFACTOR,        codec.jpeg, qf_max) \
252     ENTRY(jpeg, qf_min,         S32, RK_S32,            MPP_ENC_JPEG_CFG_CHANGE_QFACTOR,        codec.jpeg, qf_min) \
253     /* split config */ \
254     ENTRY(split, mode,          U32, RK_U32,            MPP_ENC_SPLIT_CFG_CHANGE_MODE,          split, split_mode) \
255     ENTRY(split, arg,           U32, RK_U32,            MPP_ENC_SPLIT_CFG_CHANGE_ARG,           split, split_arg) \
256     ENTRY(split, out,           U32, RK_U32,            MPP_ENC_SPLIT_CFG_CHANGE_OUTPUT,        split, split_out) \
257     /* hardware detail config */ \
258     ENTRY(hw,   qp_row,         S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_QP_ROW,           hw, qp_delta_row) \
259     ENTRY(hw,   qp_row_i,       S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_QP_ROW_I,         hw, qp_delta_row_i) \
260     ENTRY(hw,   aq_thrd_i,      St,  RK_S32 *,          MPP_ENC_HW_CFG_CHANGE_AQ_THRD_I,        hw, aq_thrd_i) \
261     ENTRY(hw,   aq_thrd_p,      St,  RK_S32 *,          MPP_ENC_HW_CFG_CHANGE_AQ_THRD_P,        hw, aq_thrd_p) \
262     ENTRY(hw,   aq_step_i,      St,  RK_S32 *,          MPP_ENC_HW_CFG_CHANGE_AQ_STEP_I,        hw, aq_step_i) \
263     ENTRY(hw,   aq_step_p,      St,  RK_S32 *,          MPP_ENC_HW_CFG_CHANGE_AQ_STEP_P,        hw, aq_step_p) \
264     ENTRY(hw,   mb_rc_disable,  S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_MB_RC,            hw, mb_rc_disable) \
265     ENTRY(hw,   mode_bias,      St,  RK_S32 *,          MPP_ENC_HW_CFG_CHANGE_CU_MODE_BIAS,     hw, mode_bias) \
266     ENTRY(hw,   skip_bias_en,   S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_CU_SKIP_BIAS,     hw, skip_bias_en) \
267     ENTRY(hw,   skip_sad,       S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_CU_SKIP_BIAS,     hw, skip_sad) \
268     ENTRY(hw,   skip_bias,      S32, RK_S32,            MPP_ENC_HW_CFG_CHANGE_CU_SKIP_BIAS,     hw, skip_bias) \
269     /* quality fine tuning config */ \
270     ENTRY(tune, scene_mode,     S32, MppEncSceneMode,   MPP_ENC_TUNE_CFG_CHANGE_SCENE_MODE,     tune, scene_mode)
271 
mpp_enc_cfg_flaten(MppTrie trie,MppCfgApi ** cfgs)272 static MppEncCfgInfo *mpp_enc_cfg_flaten(MppTrie trie, MppCfgApi **cfgs)
273 {
274     MppEncCfgInfo *info = NULL;
275     MppTrieNode *node_root = mpp_trie_node_root(trie);
276     RK_S32 node_count = mpp_trie_get_node_count(trie);
277     RK_S32 info_count = mpp_trie_get_info_count(trie);
278     MppTrieNode *node_trie;
279     char *buf = NULL;
280     RK_S32 pos = 0;
281     RK_S32 len = 0;
282     RK_S32 i;
283 
284     pos += node_count * sizeof(*node_root);
285 
286     mpp_enc_cfg_dbg_info("info node offset %d\n", pos);
287 
288     /* update info size and string name size */
289     for (i = 0; i < info_count; i++) {
290         const char *name = cfgs[i]->name;
291         const char **info_trie = mpp_trie_get_info(trie, name);
292 
293         mpp_assert(*info_trie == name);
294         len = strlen(name);
295         pos += sizeof(MppCfgInfoNode) + MPP_ALIGN(len + 1, sizeof(RK_U64));
296     }
297 
298     len = pos + sizeof(*info);
299     mpp_enc_cfg_dbg_info("tire + info size %d total %d\n", pos, len);
300 
301     info = mpp_malloc_size(MppEncCfgInfo, len);
302     if (NULL == info)
303         return NULL;
304 
305     memcpy(info->trie_node, node_root, sizeof(*node_root) * node_count);
306 
307     node_root = info->trie_node;
308     pos = node_count * sizeof(*node_root);
309     buf = (char *)node_root + pos;
310 
311     for (i = 0; i < info_count; i++) {
312         MppCfgInfoNode *node_info = (MppCfgInfoNode *)buf;
313         MppCfgApi *api = cfgs[i];
314         const char *name = api->name;
315         RK_S32 node_size;
316 
317         node_trie = mpp_trie_get_node(node_root, name);
318         node_trie->id = pos;
319 
320         node_info->name_len     = MPP_ALIGN(strlen(name) + 1, sizeof(RK_U64));
321         node_info->data_type    = api->data_type;
322         node_info->flag_offset  = api->flag_offset;
323         node_info->flag_value   = api->flag_value;
324         node_info->data_offset  = api->data_offset;
325         node_info->data_size    = api->data_size;
326         node_info->node_next    = 0;
327 
328         node_size = node_info->name_len + sizeof(*node_info);
329         node_info->node_size    = node_size;
330 
331         mpp_cfg_node_fixup_func(node_info);
332 
333         strcpy(node_info->name, name);
334 
335         mpp_enc_cfg_dbg_info("cfg %s offset %d size %d update %d flag %x\n",
336                              node_info->name,
337                              node_info->data_offset, node_info->data_size,
338                              node_info->flag_offset, node_info->flag_value);
339 
340         pos += node_size;
341         buf += node_size;
342     }
343 
344     mpp_enc_cfg_dbg_info("total size %d +H %d\n", pos, pos + sizeof(info->head));
345 
346     info->head.info_size  = pos;
347     info->head.info_count = info_count;
348     info->head.node_count = node_count;
349     info->head.cfg_size   = sizeof(MppEncCfgSet);
350 
351     return info;
352 }
353 
MppEncCfgService()354 MppEncCfgService::MppEncCfgService() :
355     mInfo(NULL),
356     mCfgSize(0)
357 {
358     ENTRY_TABLE(EXPAND_AS_API);
359 
360     MppCfgApi *cfgs[] = {
361         ENTRY_TABLE(EXPAND_AS_ARRAY)
362     };
363 
364     RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs);
365     MppTrie trie;
366     MPP_RET ret;
367     RK_S32 i;
368 
369     ret = mpp_trie_init(&trie, 1732, cfg_cnt);
370     if (ret) {
371         mpp_err_f("failed to init enc cfg set trie\n");
372         return ;
373     }
374 
375     for (i = 0; i < cfg_cnt; i++)
376         mpp_trie_add_info(trie, &cfgs[i]->name);
377 
378     mInfo = mpp_enc_cfg_flaten(trie, cfgs);
379     mCfgSize = mInfo->head.cfg_size;
380 
381     mpp_enc_cfg_dbg_func("node cnt: %d\n", get_node_count());
382 
383     mpp_trie_deinit(trie);
384 }
385 
~MppEncCfgService()386 MppEncCfgService::~MppEncCfgService()
387 {
388     MPP_FREE(mInfo);
389 }
390 
get_info_root()391 MppCfgInfoNode *MppEncCfgService::get_info_root()
392 {
393     if (NULL == mInfo)
394         return NULL;
395 
396     return (MppCfgInfoNode *)(mInfo->trie_node + mInfo->head.node_count);
397 }
398 
mpp_enc_cfg_set_default(MppEncCfgSet * cfg)399 static void mpp_enc_cfg_set_default(MppEncCfgSet *cfg)
400 {
401     RK_U32 i;
402 
403     cfg->rc.max_reenc_times = 1;
404 
405     cfg->prep.color = MPP_FRAME_SPC_UNSPECIFIED;
406     cfg->prep.colorprim = MPP_FRAME_PRI_UNSPECIFIED;
407     cfg->prep.colortrc = MPP_FRAME_TRC_UNSPECIFIED;
408 
409     for (i = 0; i < MPP_ARRAY_ELEMS(cfg->hw.mode_bias); i++)
410         cfg->hw.mode_bias[i] = 8;
411 
412     cfg->hw.skip_sad  = 8;
413     cfg->hw.skip_bias = 8;
414 }
415 
mpp_enc_cfg_init(MppEncCfg * cfg)416 MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg)
417 {
418     MppEncCfgImpl *p = NULL;
419     RK_S32 cfg_size;
420 
421     if (NULL == cfg) {
422         mpp_err_f("invalid NULL input config\n");
423         return MPP_ERR_NULL_PTR;
424     }
425 
426     mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0);
427 
428     cfg_size = MppEncCfgService::get()->get_cfg_size();
429     p = mpp_calloc(MppEncCfgImpl, 1);
430     if (NULL == p) {
431         mpp_err_f("create encoder config failed %p\n", p);
432         *cfg = NULL;
433         return MPP_ERR_NOMEM;
434     }
435 
436     mpp_assert(cfg_size == sizeof(p->cfg));
437     p->size = cfg_size;
438     mpp_enc_cfg_set_default(&p->cfg);
439 
440     *cfg = p;
441 
442     return MPP_OK;
443 }
444 
mpp_enc_cfg_deinit(MppEncCfg cfg)445 MPP_RET mpp_enc_cfg_deinit(MppEncCfg cfg)
446 {
447     if (NULL == cfg) {
448         mpp_err_f("invalid NULL input config\n");
449         return MPP_ERR_NULL_PTR;
450     }
451 
452     MPP_FREE(cfg);
453 
454     return MPP_OK;
455 }
456 
457 #define ENC_CFG_SET_ACCESS(func_name, in_type, cfg_type) \
458     MPP_RET func_name(MppEncCfg cfg, const char *name, in_type val) \
459     { \
460         if (NULL == cfg || NULL == name) { \
461             mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \
462             return MPP_ERR_NULL_PTR; \
463         } \
464         MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
465         MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \
466         if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
467             return MPP_NOK; \
468         } \
469         mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \
470         MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \
471         return ret; \
472     }
473 
474 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_s32, RK_S32, S32);
475 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_u32, RK_U32, U32);
476 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_s64, RK_S64, S64);
477 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_u64, RK_U64, U64);
478 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_ptr, void *, Ptr);
479 ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_st,  void *, St);
480 
481 #define ENC_CFG_GET_ACCESS(func_name, in_type, cfg_type) \
482     MPP_RET func_name(MppEncCfg cfg, const char *name, in_type *val) \
483     { \
484         if (NULL == cfg || NULL == name) { \
485             mpp_err_f("invalid input cfg %p name %p\n", cfg, name); \
486             return MPP_ERR_NULL_PTR; \
487         } \
488         MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
489         MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \
490         if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
491             return MPP_NOK; \
492         } \
493         mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \
494         MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \
495         return ret; \
496     }
497 
498 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_s32, RK_S32, S32);
499 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_u32, RK_U32, U32);
500 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_s64, RK_S64, S64);
501 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_u64, RK_U64, U64);
502 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_ptr, void *, Ptr);
503 ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_st,  void  , St);
504 
mpp_enc_cfg_show(void)505 void mpp_enc_cfg_show(void)
506 {
507     RK_S32 node_count = MppEncCfgService::get()->get_node_count();
508     RK_S32 info_count = MppEncCfgService::get()->get_info_count();
509     MppCfgInfoNode *info = MppEncCfgService::get()->get_info_root();
510 
511     mpp_log("dumping valid configure string start\n");
512 
513     if (info) {
514         char *p = (char *)info;
515         RK_S32 i;
516 
517         for (i = 0; i < info_count; i++) {
518             info = (MppCfgInfoNode *)p;
519 
520             mpp_log("%-25s type %s\n", info->name,
521                     cfg_type_names[info->data_type]);
522 
523             p += info->node_size;
524         }
525     }
526     mpp_log("dumping valid configure string done\n");
527 
528     mpp_log("total cfg count %d with %d node size %d\n",
529             info_count, node_count,
530             MppEncCfgService::get()->get_info_size());
531 }
532