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