diff --git a/mpp/base/inc/mpp_trie.h b/mpp/base/inc/mpp_trie.h index 807ba28f..90b8cc3f 100644 --- a/mpp/base/inc/mpp_trie.h +++ b/mpp/base/inc/mpp_trie.h @@ -23,33 +23,30 @@ typedef void* MppTrie; #define MPP_TRIE_KEY_LEN (4) -#define MPP_TRIE_KEY_MAX (MPP_TRIE_KEY_LEN << 4) +#define MPP_TRIE_KEY_MAX (1 << (MPP_TRIE_KEY_LEN)) /* - * MppTire node buffer layout + * MppTrie node buffer layout * +---------------+ * | MppTrieImpl | * +---------------+ - * | MppTireNodes | + * | MppTrieNodes | * +---------------+ * | MppTrieInfos | * +---------------+ * * MppTrieInfo element layout * +---------------+ - * | User context | - * +---------------+ * | MppTrieInfo | * +---------------+ + * | User context | + * +---------------+ * | name string | * +---------------+ */ typedef struct MppTrieInfo_t { - /* original name string address, maybe invalid stack address */ const char *name; - /* original context address, maybe invalid stack address */ void *ctx; - /* always valid data */ RK_S16 index; RK_S16 str_len; } MppTrieInfo; @@ -58,11 +55,11 @@ typedef struct MppTrieInfo_t { extern "C" { #endif -MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count); +MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size); MPP_RET mpp_trie_deinit(MppTrie trie); +/* Add NULL info to mark the last trie entry */ MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx); -MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 info_size); RK_S32 mpp_trie_get_node_count(MppTrie trie); RK_S32 mpp_trie_get_info_count(MppTrie trie); @@ -70,13 +67,11 @@ RK_S32 mpp_trie_get_buf_size(MppTrie trie); /* trie lookup function */ MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name); -/* trie lookup slot function for context filling */ -void *mpp_trie_get_slot(MppTrie trie, const char *name); -void *mpp_trie_get_slot_first(MppTrie trie); -void *mpp_trie_get_slot_next(MppTrie trie, void *slot); +MppTrieInfo *mpp_trie_get_info_first(MppTrie trie); +MppTrieInfo *mpp_trie_get_info_next(MppTrie trie, MppTrieInfo *info); void mpp_trie_dump(MppTrie trie, const char *func); -#define mpp_trie_dump_f(tire) mpp_trie_dump(tire, __FUNCTION__) +#define mpp_trie_dump_f(trie) mpp_trie_dump(trie, __FUNCTION__) #ifdef __cplusplus } diff --git a/mpp/base/mpp_cfg.cpp b/mpp/base/mpp_cfg.cpp index f8d23e4a..e89bf66a 100644 --- a/mpp/base/mpp_cfg.cpp +++ b/mpp/base/mpp_cfg.cpp @@ -31,33 +31,37 @@ #define mpp_cfg_dbg_get(fmt, ...) mpp_cfg_dbg(MPP_CFG_DBG_GET, fmt, ## __VA_ARGS__) #define CFG_TO_PTR(info, cfg) ((char *)cfg + info->data_offset) -#define CFG_TO_S32_PTR(info, cfg) ((RK_S32 *)CFG_TO_PTR(info, cfg)) -#define CFG_TO_U32_PTR(info, cfg) ((RK_U32 *)CFG_TO_PTR(info, cfg)) -#define CFG_TO_S64_PTR(info, cfg) ((RK_S64 *)CFG_TO_PTR(info, cfg)) -#define CFG_TO_U64_PTR(info, cfg) ((RK_U64 *)CFG_TO_PTR(info, cfg)) -#define CFG_TO_PTR_PTR(info, cfg) ((void **)CFG_TO_PTR(info, cfg)) +#define CFG_TO_s32_PTR(info, cfg) ((RK_S32 *)CFG_TO_PTR(info, cfg)) +#define CFG_TO_u32_PTR(info, cfg) ((RK_U32 *)CFG_TO_PTR(info, cfg)) +#define CFG_TO_s64_PTR(info, cfg) ((RK_S64 *)CFG_TO_PTR(info, cfg)) +#define CFG_TO_u64_PTR(info, cfg) ((RK_U64 *)CFG_TO_PTR(info, cfg)) +#define CFG_TO_ptr_PTR(info, cfg) ((void **)CFG_TO_PTR(info, cfg)) #define CFG_TO_FLAG_PTR(info, cfg) ((RK_U32 *)((char *)cfg + info->flag_offset)) -const char *cfg_type_names[] = { - "RK_S32", - "RK_U32", - "RK_S64", - "RK_U64", - "void *", - "struct", -}; - static RK_U32 mpp_cfg_debug = 0; -static void show_cfg_info_err(MppCfgInfoNode *node, CfgType type, const char *func) +const char *strof_cfg_type(CfgType type) { - mpp_err("%s cfg %s expect %s input NOT %s\n", func, node->name, - cfg_type_names[node->data_type], - cfg_type_names[type]); + static const char *cfg_type_names[] = { + "RK_S32", + "RK_U32", + "RK_S64", + "RK_U64", + "struct", + "void *", + }; + + return cfg_type_names[type]; } -static MPP_RET mpp_cfg_set(MppCfgInfoNode *info, void *cfg, void *val) +static void show_cfg_info_err(MppCfgInfo *node, CfgType type, const char *func, const char *name) +{ + mpp_err("%s cfg %s expect %s input NOT %s\n", func, name, + strof_cfg_type(node->data_type), strof_cfg_type(type)); +} + +static MPP_RET mpp_cfg_set(MppCfgInfo *info, void *cfg, void *val) { if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) { memcpy((char *)cfg + info->data_offset, val, info->data_size); @@ -66,119 +70,59 @@ static MPP_RET mpp_cfg_set(MppCfgInfoNode *info, void *cfg, void *val) return MPP_OK; } -static MPP_RET mpp_cfg_get(MppCfgInfoNode *info, void *cfg, void *val) +static MPP_RET mpp_cfg_get(MppCfgInfo *info, void *cfg, void *val) { memcpy(val, (char *)cfg + info->data_offset, info->data_size); return MPP_OK; } -MPP_RET mpp_cfg_set_s32(MppCfgInfoNode *info, void *cfg, RK_S32 val) -{ - RK_S32 *dst = CFG_TO_S32_PTR(info, cfg); - - if (dst[0] != val) { - mpp_cfg_dbg_set("set s32 %-25s update %d -> %d\n", info->name, dst[0], val); - dst[0] = val; - CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; - } else { - mpp_cfg_dbg_set("set s32 %-25s keep %d\n", info->name, dst[0]); +#define MPP_CFG_ACCESS(type, base_type) \ + MPP_RET mpp_cfg_set_##type(MppCfgInfo *info, void *cfg, base_type val) \ + { \ + base_type *dst = CFG_TO_##type##_PTR(info, cfg); \ + base_type old = dst[0]; \ + dst[0] = val; \ + if (!info->flag_type) { \ + mpp_cfg_dbg_set("%p + %d set " #type " change %d -> %d\n", cfg, info->data_offset, old, val); \ + } else { \ + if (old != val) { \ + mpp_cfg_dbg_set("%p + %d set " #type " update %d -> %d flag %d|%x\n", \ + cfg, info->data_offset, old, val, info->flag_offset, info->flag_value); \ + CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; \ + } else { \ + mpp_cfg_dbg_set("%p + %d set " #type " keep %d\n", cfg, info->data_offset, old); \ + } \ + } \ + return MPP_OK; \ + } \ + MPP_RET mpp_cfg_get_##type(MppCfgInfo *info, void *cfg, base_type *val) \ + { \ + if (info && info->data_size) { \ + base_type *src = CFG_TO_##type##_PTR(info, cfg); \ + mpp_cfg_dbg_set("%p + %d get " #type " value %d\n", cfg, info->data_offset, src[0]); \ + val[0] = src[0]; \ + return MPP_OK; \ + } \ + return MPP_NOK; \ } - return MPP_OK; -} +MPP_CFG_ACCESS(s32, RK_S32) +MPP_CFG_ACCESS(u32, RK_U32) +MPP_CFG_ACCESS(s64, RK_S64) +MPP_CFG_ACCESS(u64, RK_U64) +MPP_CFG_ACCESS(ptr, void *) -MPP_RET mpp_cfg_get_s32(MppCfgInfoNode *info, void *cfg, RK_S32 *val) -{ - return mpp_cfg_get(info, cfg, val); -} - -MPP_RET mpp_cfg_set_u32(MppCfgInfoNode *info, void *cfg, RK_U32 val) -{ - RK_U32 *dst = CFG_TO_U32_PTR(info, cfg); - - if (dst[0] != val) { - mpp_cfg_dbg_set("set u32 %-25s update %u -> %u\n", info->name, dst[0], val); - dst[0] = val; - CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; - } else { - mpp_cfg_dbg_set("set u32 %-25s keep %u\n", info->name, dst[0]); - } - - return MPP_OK; -} - -MPP_RET mpp_cfg_get_u32(MppCfgInfoNode *info, void *cfg, RK_U32 *val) -{ - return mpp_cfg_get(info, cfg, val); -} - -MPP_RET mpp_cfg_set_s64(MppCfgInfoNode *info, void *cfg, RK_S64 val) -{ - RK_S64 *dst = CFG_TO_S64_PTR(info, cfg); - - if (dst[0] != val) { - mpp_cfg_dbg_set("set s64 %-25s update %lld -> %lld\n", info->name, dst[0], val); - dst[0] = val; - CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; - } else { - mpp_cfg_dbg_set("set s64 %-25s keep %lld\n", info->name, dst[0]); - } - - return MPP_OK; -} - -MPP_RET mpp_cfg_get_s64(MppCfgInfoNode *info, void *cfg, RK_S64 *val) -{ - return mpp_cfg_get(info, cfg, val); -} - -MPP_RET mpp_cfg_set_u64(MppCfgInfoNode *info, void *cfg, RK_U64 val) -{ - RK_U64 *dst = CFG_TO_U64_PTR(info, cfg); - - if (dst[0] != val) { - mpp_cfg_dbg_set("set u64 %-25s update %llu -> %llu\n", info->name, dst[0], val); - dst[0] = val; - CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; - } else { - mpp_cfg_dbg_set("set u64 %-25s keep %llu\n", info->name, dst[0]); - } - - return MPP_OK; -} - -MPP_RET mpp_cfg_get_u64(MppCfgInfoNode *info, void *cfg, RK_U64 *val) -{ - return mpp_cfg_get(info, cfg, val); -} - -MPP_RET mpp_cfg_set_st(MppCfgInfoNode *info, void *cfg, void *val) +MPP_RET mpp_cfg_set_st(MppCfgInfo *info, void *cfg, void *val) { return mpp_cfg_set(info, cfg, val); } -MPP_RET mpp_cfg_get_st(MppCfgInfoNode *info, void *cfg, void *val) +MPP_RET mpp_cfg_get_st(MppCfgInfo *info, void *cfg, void *val) { return mpp_cfg_get(info, cfg, val); } -MPP_RET mpp_cfg_set_ptr(MppCfgInfoNode *info, void *cfg, void *val) -{ - void **dst = CFG_TO_PTR_PTR(info, cfg); - - mpp_cfg_dbg_set("set ptr %-25s update %p -> %p\n", info->name, dst[0], val); - dst[0] = val; - CFG_TO_FLAG_PTR(info, cfg)[0] |= info->flag_value; - - return MPP_OK; -} - -MPP_RET mpp_cfg_get_ptr(MppCfgInfoNode *info, void *cfg, void **val) -{ - return mpp_cfg_get(info, cfg, val); -} - -MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type, +MPP_RET check_cfg_info(MppCfgInfo *node, const char *name, CfgType type, const char *func) { if (NULL == node) { @@ -193,36 +137,36 @@ MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type, switch (type) { case CFG_FUNC_TYPE_St : { if (cfg_type != type) { - show_cfg_info_err(node, type, func); + show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } if (cfg_size <= 0) { - mpp_err("%s: cfg %s found invalid size %d\n", func, node->name, cfg_size); + mpp_err("%s: cfg %s found invalid size %d\n", func, name, cfg_size); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_Ptr : { if (cfg_type != type) { - show_cfg_info_err(node, type, func); + show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_S32 : case CFG_FUNC_TYPE_U32 : { if (cfg_size != sizeof(RK_S32)) { - show_cfg_info_err(node, type, func); + show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; case CFG_FUNC_TYPE_S64 : case CFG_FUNC_TYPE_U64 : { if (cfg_size != sizeof(RK_S64)) { - show_cfg_info_err(node, type, func); + show_cfg_info_err(node, type, func, name); ret = MPP_NOK; } } break; default : { - mpp_err("%s: cfg %s found invalid cfg type %d\n", func, node->name, type); + mpp_err("%s: cfg %s found invalid cfg type %d\n", func, name, type); ret = MPP_NOK; } break; } diff --git a/mpp/base/mpp_dec_cfg.cpp b/mpp/base/mpp_dec_cfg.cpp index bb3a0057..56ba5654 100644 --- a/mpp/base/mpp_dec_cfg.cpp +++ b/mpp/base/mpp_dec_cfg.cpp @@ -64,9 +64,9 @@ public: return &instance; } - MppCfgInfoNode *get_info(const char *name); - MppCfgInfoNode *get_info_first(); - MppCfgInfoNode *get_info_next(MppCfgInfoNode *node); + MppTrieInfo *get_info(const char *name); + MppTrieInfo *get_info_first(); + MppTrieInfo *get_info_next(MppTrieInfo *info); RK_S32 get_node_count() { return mHead.node_count; }; RK_S32 get_info_count() { return mHead.info_count; }; @@ -74,19 +74,18 @@ public: RK_S32 get_cfg_size() { return mCfgSize; }; }; -#define EXPAND_AS_API(base, name, cfg_type, in_type, flag, field_change, field_data) \ - MppCfgApi api_##base##_##name = \ - { \ - #base":"#name, \ - CFG_FUNC_TYPE_##cfg_type, \ - (RK_U32)((long)&(((MppDecCfgSet *)0)->field_change.change)), \ - flag, \ - (RK_U32)((long)&(((MppDecCfgSet *)0)->field_change.field_data)), \ - sizeof((((MppDecCfgSet *)0)->field_change.field_data)), \ - }; - -#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \ - &api_##base##_##name, +#define EXPAND_AS_TRIE(base, name, cfg_type, in_type, flag, field_change, field_data) \ + do { \ + MppCfgInfo tmp = { \ + CFG_FUNC_TYPE_##cfg_type, \ + flag ? 1 : 0, \ + (RK_U32)((long)&(((MppDecCfgSet *)0)->field_change.change)), \ + flag, \ + (RK_U32)((long)&(((MppDecCfgSet *)0)->field_change.field_data)), \ + sizeof((((MppDecCfgSet *)0)->field_change.field_data)), \ + }; \ + mpp_trie_add_info(mTrie, #base":"#name, &tmp); \ + } while (0); #define ENTRY_TABLE(ENTRY) \ /* rc config */ \ @@ -115,60 +114,24 @@ public: ENTRY(cb, frm_rdy_ctx, Ptr, MppExtCbCtx, MPP_DEC_CB_CFG_CHANGE_FRM_RDY, cb, frm_rdy_ctx) \ ENTRY(cb, frm_rdy_cmd, S32, RK_S32, MPP_DEC_CB_CFG_CHANGE_FRM_RDY, cb, frm_rdy_cmd) -static void mpp_dec_cfg_fill(MppTrie trie, MppCfgApi **cfgs) -{ - RK_S32 info_count = mpp_trie_get_info_count(trie); - RK_S32 i; - - for (i = 0; i < info_count; i++) { - MppCfgApi *api = cfgs[i]; - const char *name = api->name; - MppCfgInfoNode *node_info = (MppCfgInfoNode *)mpp_trie_get_slot(trie, name); - MppTrieInfo *info = (MppTrieInfo *)(node_info + 1); - - node_info->data_type = api->data_type; - node_info->flag_offset = api->flag_offset; - node_info->flag_value = api->flag_value; - node_info->data_offset = api->data_offset; - node_info->data_size = api->data_size; - node_info->name = (RK_U8 *)(info + 1); - - mpp_dec_cfg_dbg_info("cfg %s offset %d size %d update %d flag %x\n", name, - node_info->data_offset, node_info->data_size, - node_info->flag_offset, node_info->flag_value); - } -} - MppDecCfgService::MppDecCfgService() : mTrie(NULL) { - ENTRY_TABLE(EXPAND_AS_API); - - MppCfgApi *cfgs[] = { - ENTRY_TABLE(EXPAND_AS_ARRAY) - }; - - RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs); - MPP_RET ret; - RK_S32 i; - - ret = mpp_trie_init(&mTrie, 340, cfg_cnt); + MPP_RET ret = mpp_trie_init(&mTrie, sizeof(MppCfgInfo)); if (ret) { mpp_err_f("failed to init dec cfg set trie\n"); return ; } - for (i = 0; i < cfg_cnt; i++) - mpp_trie_add_info(mTrie, cfgs[i]->name, &cfgs[i]); - mpp_trie_shrink(mTrie, sizeof(MppCfgInfoNode)); + ENTRY_TABLE(EXPAND_AS_TRIE) - mpp_dec_cfg_fill(mTrie, cfgs); + mpp_trie_add_info(mTrie, NULL, NULL); mHead.node_count = mpp_trie_get_node_count(mTrie); mHead.info_count = mpp_trie_get_info_count(mTrie); mHead.info_size = mpp_trie_get_buf_size(mTrie); - mpp_dec_cfg_dbg_func("node cnt: %d\n", mpp_trie_get_node_count(mTrie)); + mpp_dec_cfg_dbg_func("node cnt: %d\n", mHead.node_count); } MppDecCfgService::~MppDecCfgService() @@ -179,25 +142,25 @@ MppDecCfgService::~MppDecCfgService() } } -MppCfgInfoNode *MppDecCfgService::get_info(const char *name) +MppTrieInfo *MppDecCfgService::get_info(const char *name) { - return (MppCfgInfoNode *)mpp_trie_get_slot(mTrie, name); + return mpp_trie_get_info(mTrie, name); } -MppCfgInfoNode *MppDecCfgService::get_info_first() +MppTrieInfo *MppDecCfgService::get_info_first() { if (NULL == mTrie) return NULL; - return (MppCfgInfoNode *)mpp_trie_get_slot_first(mTrie); + return mpp_trie_get_info_first(mTrie); } -MppCfgInfoNode *MppDecCfgService::get_info_next(MppCfgInfoNode *node) +MppTrieInfo *MppDecCfgService::get_info_next(MppTrieInfo *node) { if (NULL == mTrie) return NULL; - return (MppCfgInfoNode *)mpp_trie_get_slot_next(mTrie, (void *)node); + return mpp_trie_get_info_next(mTrie, node); } void mpp_dec_cfg_set_default(MppDecCfgSet *cfg) @@ -259,11 +222,12 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg) return MPP_ERR_NULL_PTR; \ } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ - MppCfgInfoNode *info = MppDecCfgService::get()->get_info(name); \ + MppTrieInfo *node = MppDecCfgService::get()->get_info(name); \ + MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_dec_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -283,11 +247,12 @@ DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_st, void *, St); return MPP_ERR_NULL_PTR; \ } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ - MppCfgInfoNode *info = MppDecCfgService::get()->get_info(name); \ + MppTrieInfo *node = MppDecCfgService::get()->get_info(name); \ + MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_dec_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -302,16 +267,17 @@ DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_st, void , St); void mpp_dec_cfg_show(void) { MppDecCfgService *srv = MppDecCfgService::get(); - MppCfgInfoNode *root = srv->get_info_first(); + MppTrieInfo *root = srv->get_info_first(); mpp_log("dumping valid configure string start\n"); if (root) { - MppCfgInfoNode *node = root; + MppTrieInfo *node = root; do { - mpp_log("%-25s type %s\n", node->name, - cfg_type_names[node->data_type]); + MppCfgInfo *info = (MppCfgInfo *)node->ctx; + + mpp_log("%-25s type %s\n", node->name, strof_cfg_type(info->data_type)); node = srv->get_info_next(node); if (!node) diff --git a/mpp/base/mpp_enc_cfg.cpp b/mpp/base/mpp_enc_cfg.cpp index 083d8df4..70eacd70 100644 --- a/mpp/base/mpp_enc_cfg.cpp +++ b/mpp/base/mpp_enc_cfg.cpp @@ -65,9 +65,9 @@ public: return &instance; } - MppCfgInfoNode *get_info(const char *name); - MppCfgInfoNode *get_info_first(); - MppCfgInfoNode *get_info_next(MppCfgInfoNode *node); + MppTrieInfo *get_info(const char *name); + MppTrieInfo *get_info_first(); + MppTrieInfo *get_info_next(MppTrieInfo *node); RK_S32 get_node_count() { return mHead.node_count; }; RK_S32 get_info_count() { return mHead.info_count; }; @@ -75,19 +75,18 @@ public: RK_S32 get_cfg_size() { return mCfgSize; }; }; -#define EXPAND_AS_API(base, name, cfg_type, in_type, flag, field_change, field_data) \ - MppCfgApi api_##base##_##name = \ - { \ - #base":"#name, \ - CFG_FUNC_TYPE_##cfg_type, \ - (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \ - flag, \ - (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \ - sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \ - }; - -#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \ - &api_##base##_##name, +#define EXPAND_AS_TRIE(base, name, cfg_type, in_type, flag, field_change, field_data) \ + do { \ + MppCfgInfo tmp = { \ + CFG_FUNC_TYPE_##cfg_type, \ + flag ? 1 : 0, \ + (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \ + flag, \ + (RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \ + sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \ + }; \ + mpp_trie_add_info(mTrie, #base":"#name, &tmp); \ + } while (0); #define ENTRY_TABLE(ENTRY) \ /* base config */ \ @@ -271,63 +270,28 @@ public: ENTRY(tune, rc_container, S32, RK_S32, MPP_ENC_TUNE_CFG_CHANGE_RC_CONTAINER, tune, rc_container) \ ENTRY(tune, vmaf_opt, S32, RK_S32, MPP_ENC_TUNE_CFG_CHANGE_VMAF_OPT, tune, vmaf_opt) -static void mpp_enc_cfg_fill(MppTrie trie, MppCfgApi **cfgs) -{ - RK_S32 info_count = mpp_trie_get_info_count(trie); - RK_S32 i; - - for (i = 0; i < info_count; i++) { - MppCfgApi *api = cfgs[i]; - const char *name = api->name; - MppCfgInfoNode *node_info = (MppCfgInfoNode *)mpp_trie_get_slot(trie, name); - MppTrieInfo *info = (MppTrieInfo *)(node_info + 1); - - node_info->data_type = api->data_type; - node_info->flag_offset = api->flag_offset; - node_info->flag_value = api->flag_value; - node_info->data_offset = api->data_offset; - node_info->data_size = api->data_size; - node_info->name = (RK_U8 *)(info + 1); - - mpp_enc_cfg_dbg_info("cfg %s offset %d size %d update %d flag %x\n", name, - node_info->data_offset, node_info->data_size, - node_info->flag_offset, node_info->flag_value); - } -} - MppEncCfgService::MppEncCfgService() : mTrie(NULL) { - ENTRY_TABLE(EXPAND_AS_API); - - MppCfgApi *cfgs[] = { - ENTRY_TABLE(EXPAND_AS_ARRAY) - }; - - RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs); MPP_RET ret; - RK_S32 i; mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0); - ret = mpp_trie_init(&mTrie, 512, cfg_cnt); + ret = mpp_trie_init(&mTrie, sizeof(MppCfgInfo)); if (ret) { mpp_err_f("failed to init enc cfg set trie ret %d\n", ret); return ; } - for (i = 0; i < cfg_cnt; i++) - mpp_trie_add_info(mTrie, cfgs[i]->name, &cfgs[i]); + ENTRY_TABLE(EXPAND_AS_TRIE) - mpp_trie_shrink(mTrie, sizeof(MppCfgInfoNode)); - - mpp_enc_cfg_fill(mTrie, cfgs); + mpp_trie_add_info(mTrie, NULL, NULL); mHead.node_count = mpp_trie_get_node_count(mTrie); mHead.info_count = mpp_trie_get_info_count(mTrie); mHead.info_size = mpp_trie_get_buf_size(mTrie); - mpp_enc_cfg_dbg_func("node cnt: %d\n", mpp_trie_get_node_count(mTrie)); + mpp_enc_cfg_dbg_func("node cnt: %d\n", mHead.node_count); } MppEncCfgService::~MppEncCfgService() @@ -338,25 +302,25 @@ MppEncCfgService::~MppEncCfgService() } } -MppCfgInfoNode *MppEncCfgService::get_info(const char *name) +MppTrieInfo *MppEncCfgService::get_info(const char *name) { - return (MppCfgInfoNode *)mpp_trie_get_slot(mTrie, name); + return mpp_trie_get_info(mTrie, name); } -MppCfgInfoNode *MppEncCfgService::get_info_first() +MppTrieInfo *MppEncCfgService::get_info_first() { if (NULL == mTrie) return NULL; - return (MppCfgInfoNode *)mpp_trie_get_slot_first(mTrie); + return mpp_trie_get_info_first(mTrie); } -MppCfgInfoNode *MppEncCfgService::get_info_next(MppCfgInfoNode *node) +MppTrieInfo *MppEncCfgService::get_info_next(MppTrieInfo *node) { if (NULL == mTrie) return NULL; - return (MppCfgInfoNode *)mpp_trie_get_slot_next(mTrie, (void *)node); + return mpp_trie_get_info_next(mTrie, node); } static void mpp_enc_cfg_set_default(MppEncCfgSet *cfg) @@ -426,11 +390,12 @@ MPP_RET mpp_enc_cfg_deinit(MppEncCfg cfg) return MPP_ERR_NULL_PTR; \ } \ MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \ - MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \ + MppTrieInfo *node = MppEncCfgService::get()->get_info(name); \ + MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + mpp_enc_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -450,11 +415,12 @@ ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_st, void *, St); return MPP_ERR_NULL_PTR; \ } \ MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \ - MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \ + MppTrieInfo *node = MppEncCfgService::get()->get_info(name); \ + MppCfgInfo *info = (MppCfgInfo *)(node ? node->ctx : NULL); \ if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + mpp_enc_cfg_dbg_set("name %s type %s\n", node->name, strof_cfg_type(info->data_type)); \ MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \ return ret; \ } @@ -469,16 +435,17 @@ ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_st, void , St); void mpp_enc_cfg_show(void) { MppEncCfgService *srv = MppEncCfgService::get(); - MppCfgInfoNode *root = srv->get_info_first(); + MppTrieInfo *root = srv->get_info_first(); mpp_log("dumping valid configure string start\n"); if (root) { - MppCfgInfoNode *node = root; + MppTrieInfo *node = root; do { - mpp_log("%-25s type %s\n", node->name, - cfg_type_names[node->data_type]); + MppCfgInfo *info = (MppCfgInfo *)node->ctx; + + mpp_log("%-25s type %s\n", node->name, strof_cfg_type(info->data_type)); node = srv->get_info_next(node); if (!node) diff --git a/mpp/base/mpp_trie.cpp b/mpp/base/mpp_trie.cpp index 1f024b1e..a9ea2ac5 100644 --- a/mpp/base/mpp_trie.cpp +++ b/mpp/base/mpp_trie.cpp @@ -31,9 +31,9 @@ #define MPP_TRIE_DBG_GET (0x00000004) #define MPP_TRIE_DBG_CNT (0x00000008) #define MPP_TRIE_DBG_WALK (0x00000010) -#define MPP_TRIE_DBG_SHRINK (0x00000020) -#define MPP_TRIE_DBG_SHRINK_STEP (0x00000040) -#define MPP_TRIE_DBG_SHRINK_CHECK (0x00000080) +#define MPP_TRIE_DBG_LAST (0x00000020) +#define MPP_TRIE_DBG_LAST_STEP (0x00000040) +#define MPP_TRIE_DBG_LAST_CHECK (0x00000080) #define trie_dbg(flag, fmt, ...) _mpp_dbg_f(mpp_trie_debug, flag, fmt, ## __VA_ARGS__) #define trie_dbg_func(fmt, ...) trie_dbg(MPP_TRIE_DBG_FUNC, fmt, ## __VA_ARGS__) @@ -41,48 +41,66 @@ #define trie_dbg_get(fmt, ...) trie_dbg(MPP_TRIE_DBG_GET, fmt, ## __VA_ARGS__) #define trie_dbg_cnt(fmt, ...) trie_dbg(MPP_TRIE_DBG_CNT, fmt, ## __VA_ARGS__) #define trie_dbg_walk(fmt, ...) trie_dbg(MPP_TRIE_DBG_WALK, fmt, ## __VA_ARGS__) -#define trie_dbg_shrink(fmt, ...) trie_dbg(MPP_TRIE_DBG_SHRINK, fmt, ## __VA_ARGS__) +#define trie_dbg_last(fmt, ...) trie_dbg(MPP_TRIE_DBG_LAST, fmt, ## __VA_ARGS__) #define DEFAULT_NODE_COUNT 900 #define DEFAULT_INFO_COUNT 80 #define INVALID_NODE_ID (-1) #define MPP_TRIE_TAG_LEN_MAX ((sizeof(RK_U64) * 8) / MPP_TRIE_KEY_LEN) -/* spatial optimized tire tree */ +/* spatial optimized trie tree */ typedef struct MppTrieNode_t { - /* next - next tire node index */ - RK_S16 next[MPP_TRIE_KEY_MAX]; - /* id - payload data offset of current tire node */ - RK_S32 id; - /* idx - tire node index in ascending order */ - RK_S16 idx; - /* prev - previous tire node index */ - RK_S16 prev; + /* next - next trie node index */ + RK_S16 next[MPP_TRIE_KEY_MAX]; + /* id - payload data offset of current trie node */ + RK_S32 id; + /* idx - trie node index in ascending order */ + RK_S16 idx; + /* prev - previous trie node index */ + RK_S16 prev; - /* tag_val - prefix tag */ - RK_U64 tag_val; - /* key - current key value in previous node as next */ - RK_U16 key; + /* tag_val - prefix tag */ + RK_U64 tag_val; + /* key - current key value in previous node as next */ + RK_U16 key; /* - * tag len - prefix tag length - * zero - normal node with 16 next node - * positive - tag node with 64bit prefix tag + * tag len - prefix tag length + * zero - normal node with 16 next node + * positive - tag node with 64bit prefix tag */ - RK_S16 tag_len; + RK_S16 tag_len; - /* next_cnt - valid next node count */ - RK_U16 next_cnt; + /* next_cnt - valid next node count */ + RK_U16 next_cnt; } MppTrieNode; +typedef struct MppTrieInfoInt_t { + RK_S32 ctx_offset; + RK_S32 name_offset; + RK_S32 index; + RK_S32 str_len; +} MppTrieInfoInt; + typedef struct MppTrieImpl_t { + RK_S32 ctx_size; + RK_S32 buf_size; + + RK_S32 nodes_size; + RK_S32 infos_size; + RK_S32 info_count; RK_S32 info_used; - MppTrieInfo *info; + MppTrieInfoInt *info; RK_S32 node_count; RK_S32 node_used; MppTrieNode *nodes; - RK_S32 ctx_size; - RK_S32 buf_size; + + /* info and name record buffer */ + void *info_buf; + void *name_buf; + RK_S32 info_buf_size; + RK_S32 name_buf_size; + RK_S32 name_buf_pos; } MppTrieImpl; RK_U32 mpp_trie_debug = 0; @@ -94,7 +112,7 @@ static RK_S32 trie_get_node(MppTrieImpl *trie, RK_S32 prev, RK_U64 key) RK_S32 new_count = old_count * 2; MppTrieNode *new_nodes = mpp_realloc(trie->nodes, MppTrieNode, new_count); - if (NULL == new_nodes) { + if (!new_nodes) { mpp_err_f("failed to realloc new nodes %d\n", new_count); return -1; } @@ -125,9 +143,9 @@ static RK_S32 trie_get_node(MppTrieImpl *trie, RK_S32 prev, RK_U64 key) return idx; } -MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count) +MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 info_size) { - if (NULL == trie) { + if (!trie) { mpp_err_f("invalid NULL input trie automation\n"); return MPP_ERR_NULL_PTR; } @@ -136,24 +154,37 @@ MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count) MPP_RET ret = MPP_ERR_NOMEM; MppTrieImpl *p = mpp_calloc(MppTrieImpl, 1); - if (NULL == p) { + if (!p) { mpp_err_f("create trie impl failed\n"); goto DONE; } - p->node_count = node_count ? node_count : DEFAULT_NODE_COUNT; - if (p->node_count) { - p->nodes = mpp_calloc(MppTrieNode, p->node_count); - if (NULL == p->nodes) { - mpp_err_f("create %d nodes failed\n", p->node_count); - goto DONE; - } + p->node_count = DEFAULT_NODE_COUNT; + p->nodes = mpp_calloc(MppTrieNode, p->node_count); + if (!p->nodes) { + mpp_err_f("create %d nodes failed\n", p->node_count); + goto DONE; } - p->info_count = info_count ? info_count : DEFAULT_INFO_COUNT; - p->info = mpp_calloc(MppTrieInfo, p->info_count); - if (NULL == p->info) { - mpp_err_f("failed to alloc %d storage\n", p->info_count); + p->info_count = DEFAULT_INFO_COUNT; + p->info = mpp_calloc(MppTrieInfoInt, p->info_count); + if (!p->info) { + mpp_err_f("failed to alloc %d info\n", p->info_count); + goto DONE; + } + + p->ctx_size = info_size; + p->info_buf_size = p->ctx_size * p->info_count; + p->info_buf = mpp_calloc_size(void, p->info_buf_size); + if (!p->info_buf) { + mpp_err_f("failed to alloc %d info buffer\n", p->info_buf_size); + goto DONE; + } + + p->name_buf_size = SZ_4K; + p->name_buf = mpp_calloc_size(void, p->name_buf_size); + if (!p->name_buf) { + mpp_err_f("failed to alloc %d name buffer\n", p->info_buf_size); goto DONE; } @@ -164,6 +195,8 @@ MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count) DONE: if (ret && p) { MPP_FREE(p->info); + MPP_FREE(p->info_buf); + MPP_FREE(p->name_buf); MPP_FREE(p->nodes); MPP_FREE(p); } @@ -174,7 +207,7 @@ DONE: MPP_RET mpp_trie_deinit(MppTrie trie) { - if (NULL == trie) { + if (!trie) { mpp_err_f("invalid NULL input trie\n"); return MPP_ERR_NULL_PTR; } @@ -183,107 +216,13 @@ MPP_RET mpp_trie_deinit(MppTrie trie) MPP_FREE(p->nodes); MPP_FREE(p->info); + MPP_FREE(p->info_buf); + MPP_FREE(p->name_buf); MPP_FREE(p); return MPP_OK; } -MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx) -{ - if (!trie || !name || !ctx) { - mpp_err_f("invalid trie %p name %s ctx %p\n", trie, name, ctx); - return MPP_ERR_NULL_PTR; - } - - MppTrieImpl *p = (MppTrieImpl *)trie; - - /* create */ - if (p->info_used >= p->info_count) { - RK_S32 new_count = p->info_count * 2; - MppTrieInfo *ptr = mpp_realloc(p->info, MppTrieInfo, new_count); - - if (NULL == ptr) { - mpp_err_f("failed to realloc new action %d\n", new_count); - return MPP_ERR_MALLOC; - } - - trie_dbg_cnt("trie %p enlarge info %p:%d -> %p:%d\n", - trie, p->info, p->info_count, ptr, new_count); - - p->info = ptr; - p->info_count = new_count; - } - - MppTrieNode *node = NULL; - const char *s = name; - RK_S32 len = strnlen(s, SZ_1K); - RK_S32 next = 0; - RK_S32 idx = 0; - RK_S32 i; - - trie_dbg_set("trie %p add info %s len %d\n", trie, s, len); - - for (i = 0; i < len && s[i]; i++) { - RK_U32 key = s[i]; - RK_S32 key0 = (key >> 4) & 0xf; - RK_S32 key1 = (key >> 0) & 0xf; - - node = p->nodes + idx; - next = node->next[key0]; - - trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d\n", - trie, s, i, key, key, key0, key1, idx, next); - - if (!next) { - next = trie_get_node(p, idx, key0); - /* realloc may cause memory address change */ - node = p->nodes + idx; - node->next[key0] = next; - - trie_dbg_set("trie %p add %s at %2d char %c:%3d node %d -> %d as new key0\n", - trie, s, i, key, key, node->idx, next); - } - - idx = next; - node = p->nodes + idx; - next = node->next[key1]; - - trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d as key0\n", - trie, s, i, key, key, key0, key1, idx, next); - - if (!next) { - next = trie_get_node(p, idx, key1); - /* realloc may cause memory address change */ - node = p->nodes + idx; - node->next[key1] = next; - - trie_dbg_set("trie %p add %s at %2d char %c:%3d node %d -> %d as new child\n", - trie, s, i, key, key, node->idx, next); - } - - idx = next; - - trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d as key1\n", - trie, s, i, key, key, key0, key1, idx, next); - } - - RK_S32 act_id = p->info_used++; - - p->nodes[idx].id = act_id; - - MppTrieInfo *info = &p->info[act_id]; - - info->name = name; - info->ctx = ctx; - info->index = act_id; - info->str_len = MPP_ALIGN(len + 1, sizeof(RK_U64)); - - trie_dbg_set("trie %p add %d info %s at node %d pos %d action %p done\n", - trie, i, s, idx, act_id, ctx); - - return MPP_OK; -} - static RK_S32 mpp_trie_walk(MppTrieNode *node, RK_U64 *tag_val, RK_S32 *tag_len, RK_U32 key) { RK_U64 val = *tag_val; @@ -330,7 +269,7 @@ static MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name) RK_S32 tag_len = 0; RK_S32 idx = 0; - if (NULL == root || NULL == name) { + if (!root || !name) { mpp_err_f("invalid root %p name %p\n", root, name); return NULL; } @@ -362,10 +301,11 @@ static MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name) static RK_S32 mpp_trie_check(MppTrie trie, const char *log) { MppTrieImpl *p = (MppTrieImpl *)trie; + char *buf = (char *)p->name_buf; RK_S32 i; for (i = 0; i < p->info_used; i++) { - const char *name = (const char *)p->info[i].name; + const char *name = buf + p->info[i].name_offset; MppTrieNode *node = mpp_trie_get_node(p->nodes, name); if (node && node->id >= 0 && node->id == i) @@ -379,7 +319,7 @@ static RK_S32 mpp_trie_check(MppTrie trie, const char *log) return MPP_OK; } -MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) +MPP_RET mpp_trie_last_info(MppTrie trie) { MppTrieImpl *p = (MppTrieImpl *)trie; MppTrieNode *root; @@ -394,7 +334,7 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) RK_S32 j; if (!trie) { - mpp_err_f("invalid trie %p info size %d\n", trie, ctx_size); + mpp_err_f("invalid NULL trie\n"); return MPP_ERR_NULL_PTR; } @@ -402,9 +342,9 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) node_count = p->node_used; node_valid = node_count; - trie_dbg_shrink("shrink trie node start node %d info %d\n", node_count, p->info_used); + trie_dbg_last("shrink trie node start node %d info %d\n", node_count, p->info_used); - if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP) + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_STEP) mpp_trie_dump_f(trie); for (i = node_count - 1; i > 0; i--) { @@ -416,20 +356,20 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) prev = &root[prev_idx]; if (prev->next_cnt > 1) { - trie_dbg_shrink("node %d:%d prev %d next count %d stop shrinking for multi next\n", - i, node->id, prev_idx, prev->next_cnt); + trie_dbg_last("node %d:%d prev %d next count %d stop shrinking for multi next\n", + i, node->id, prev_idx, prev->next_cnt); continue; } if (node->tag_len >= (RK_S16)MPP_TRIE_TAG_LEN_MAX) { - trie_dbg_shrink("node %d:%d tag %d - %016llx stop shrinking for max tag len\n", - i, node->id, node->tag_len, node->tag_val); + trie_dbg_last("node %d:%d tag %d - %016llx stop shrinking for max tag len\n", + i, node->id, node->tag_len, node->tag_val); continue; } if (prev->id >= 0) { - trie_dbg_shrink("node %d:%d tag %d - %016llx stop shrinking for valid info node\n", - i, node->id, node->tag_len, node->tag_val); + trie_dbg_last("node %d:%d tag %d - %016llx stop shrinking for valid info node\n", + i, node->id, node->tag_len, node->tag_val); continue; } @@ -440,8 +380,8 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) prev->next_cnt = node->next_cnt; memcpy(prev->next, node->next, sizeof(node->next)); - trie_dbg_shrink("node %d:%d shrink prev %d key %x tag %016llx -> %016llx\n", - i, node->id, prev->idx, prev->key, node->tag_val, prev->tag_val); + trie_dbg_last("node %d:%d shrink prev %d key %x tag %016llx -> %016llx\n", + i, node->id, prev->idx, prev->key, node->tag_val, prev->tag_val); for (j = 0; j < MPP_TRIE_KEY_MAX; j++) { if (!prev->next[j]) @@ -455,15 +395,15 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) node_valid--; } - trie_dbg_shrink("shrink trie node finish count %d -> %d\n", node_count, node_valid); + trie_dbg_last("shrink trie node finish count %d -> %d\n", node_count, node_valid); - if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP) + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_STEP) mpp_trie_dump_f(trie); - if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_CHECK) + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_CHECK) mpp_trie_check(trie, "shrink merge tag stage"); - trie_dbg_shrink("move trie node start to reduce memory %d -> %d\n", node_count, node_valid); + trie_dbg_last("move trie node start to reduce memory %d -> %d\n", node_count, node_valid); for (i = 1; i < node_valid; i++) { node = &root[i]; @@ -481,7 +421,7 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) if (!tmp->idx) continue; - trie_dbg_shrink("move node %d to %d prev %d\n", j, i, tmp->prev); + trie_dbg_last("move node %d to %d prev %d\n", j, i, tmp->prev); prev = &root[tmp->prev]; @@ -512,24 +452,25 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) p->node_used = node_valid; - trie_dbg_shrink("move trie node finish used %d\n", p->node_used); + trie_dbg_last("move trie node finish used %d\n", p->node_used); - if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP) + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_STEP) mpp_trie_dump_f(trie); - if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_CHECK) + if (mpp_trie_debug & MPP_TRIE_DBG_LAST_CHECK) mpp_trie_check(trie, "shrink move node stage"); - trie_dbg_shrink("create user buffer start\n"); + trie_dbg_last("create user buffer start\n"); - p->ctx_size = ctx_size; nodes_size = sizeof(MppTrieNode) * p->node_used; + p->nodes_size = nodes_size; + p->infos_size = (sizeof(MppTrieInfo) + p->ctx_size) * p->info_used; pos += nodes_size; /* update info size and string name size */ for (i = 0; i < p->info_used; i++) { len = p->info[i].str_len; - pos += ctx_size + sizeof(MppTrieInfo) + len; + pos += sizeof(MppTrieInfo) + p->ctx_size + len; } len = pos; @@ -546,49 +487,183 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size) for (i = 0; i < p->info_used; i++) { MppTrieInfo *info; - const char *name = p->info[i].name; + const char *name = (char *)p->name_buf + p->info[i].name_offset; node = mpp_trie_get_node(p->nodes, name); node->id = pos; - /* reserve user context space */ - pos += ctx_size; - /* reserve node info */ info = (MppTrieInfo *)(buf + pos); - memcpy(info, &p->info[i], sizeof(MppTrieInfo)); + info->index = p->info[i].index; + info->str_len = p->info[i].str_len; pos += sizeof(MppTrieInfo); + /* reserve user context space */ + info->ctx = (void *)(buf + pos); + memcpy(buf + pos, (char *)p->info_buf + p->info[i].ctx_offset, p->ctx_size); + pos += p->ctx_size; + /* copy info name */ + info->name = (char *)(buf + pos); strncpy(buf + pos, name, info->str_len); pos += info->str_len; } MPP_FREE(root); + MPP_FREE(p->info); + MPP_FREE(p->info_buf); + MPP_FREE(p->name_buf); + + return MPP_OK; +} + +MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx) +{ + MppTrieImpl *p; + MppTrieInfoInt *info; + MppTrieNode *node; + const char *s; + RK_S32 act_id; + RK_S32 next; + RK_S32 len; + RK_S32 idx; + RK_S32 i; + + if (!trie) { + mpp_err_f("invalid trie %p name %s ctx %p\n", trie, name, ctx); + return MPP_ERR_NULL_PTR; + } + + if (!name) + return mpp_trie_last_info(trie); + + p = (MppTrieImpl *)trie; + + /* create */ + if (p->info_used >= p->info_count) { + RK_S32 new_count = p->info_count * 2; + void *ptr = mpp_realloc_size(p->info, void, sizeof(MppTrieInfoInt) * new_count); + + if (!ptr) { + mpp_err_f("failed to realloc new info %d\n", new_count); + return MPP_ERR_MALLOC; + } + p->info = (MppTrieInfoInt *)ptr; + trie_dbg_cnt("trie %p enlarge info %p:%d -> %p:%d\n", + trie, p->info, p->info_count, ptr, new_count); + + ptr = mpp_realloc_size(p->info_buf, void, p->ctx_size * new_count); + if (!ptr) { + mpp_err_f("failed to realloc new info buffer %d\n", new_count); + return MPP_ERR_MALLOC; + } + p->info_buf = ptr; + trie_dbg_cnt("trie %p enlarge info_buf %p:%d -> %p:%d\n", + trie, p->info_buf, p->info_count, ptr, new_count); + + p->info_count = new_count; + } + + node = NULL; + s = name; + len = strnlen(s, SZ_1K); + next = 0; + idx = 0; + + trie_dbg_set("trie %p add info %s len %d\n", trie, s, len); + + for (i = 0; i < len && s[i]; i++) { + RK_U32 key = s[i]; + RK_S32 key0 = (key >> 4) & 0xf; + RK_S32 key1 = (key >> 0) & 0xf; + + node = p->nodes + idx; + next = node->next[key0]; + + trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d\n", + trie, s, i, key, key, key0, key1, idx, next); + + if (!next) { + next = trie_get_node(p, idx, key0); + /* realloc may cause memory address change */ + node = p->nodes + idx; + node->next[key0] = next; + + trie_dbg_set("trie %p add %s at %2d char %c:%3d node %d -> %d as new key0\n", + trie, s, i, key, key, node->idx, next); + } + + idx = next; + node = p->nodes + idx; + next = node->next[key1]; + + trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d as key0\n", + trie, s, i, key, key, key0, key1, idx, next); + + if (!next) { + next = trie_get_node(p, idx, key1); + /* realloc may cause memory address change */ + node = p->nodes + idx; + node->next[key1] = next; + + trie_dbg_set("trie %p add %s at %2d char %c:%3d node %d -> %d as new child\n", + trie, s, i, key, key, node->idx, next); + } + + idx = next; + + trie_dbg_set("trie %p add %s at %2d char %c:%3d:%x:%x node %d -> %d as key1\n", + trie, s, i, key, key, key0, key1, idx, next); + } + + act_id = p->info_used++; + p->nodes[idx].id = act_id; + + info = &p->info[act_id]; + info->index = act_id; + info->str_len = MPP_ALIGN(len + 1, sizeof(RK_U64)); + info->ctx_offset = act_id * p->ctx_size; + info->name_offset = p->name_buf_pos; + + memcpy((RK_U8 *)p->info_buf + info->ctx_offset, ctx, p->ctx_size); + + if (p->name_buf_pos + len + 1 >= p->name_buf_size) { + RK_S32 new_size = p->name_buf_size * 2; + void *ptr = mpp_realloc(p->name_buf, RK_U8, new_size); + + if (!ptr) { + mpp_err_f("failed to realloc new name buffer %d\n", new_size); + return MPP_ERR_MALLOC; + } + + trie_dbg_cnt("trie %p enlarge name %p:%d -> %p:%d\n", + trie, p->name_buf, p->name_buf_size, ptr, new_size); + + p->name_buf = ptr; + p->name_buf_size = new_size; + } + + snprintf((char *)p->name_buf + p->name_buf_pos, p->name_buf_size - p->name_buf_pos - 1, "%s", name); + p->name_buf_pos += info->str_len; + + trie_dbg_set("trie %p add %d info %s at node %d pos %d action %p done\n", + trie, i, s, idx, act_id, ctx); return MPP_OK; } RK_S32 mpp_trie_get_node_count(MppTrie trie) { - if (NULL == trie) { - mpp_err_f("invalid NULL trie\n"); - return 0; - } - MppTrieImpl *p = (MppTrieImpl *)trie; - return p->node_used; + + return (p) ? p->node_used : 0; } RK_S32 mpp_trie_get_info_count(MppTrie trie) { - if (NULL == trie) { - mpp_err_f("invalid NULL trie\n"); - return 0; - } - MppTrieImpl *p = (MppTrieImpl *)trie; - return p->info_used; + + return (p) ? p->info_used : 0; } RK_S32 mpp_trie_get_buf_size(MppTrie trie) @@ -598,23 +673,12 @@ RK_S32 mpp_trie_get_buf_size(MppTrie trie) return (p) ? p->buf_size : 0; } -MppTrieNode *mpp_trie_node_root(MppTrie trie) -{ - if (NULL == trie) { - mpp_err_f("invalid NULL trie\n"); - return NULL; - } - - MppTrieImpl *p = (MppTrieImpl *)trie; - return p->nodes; -} - MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name) { MppTrieImpl *p = (MppTrieImpl *)trie; MppTrieNode *node; - if (NULL == trie || NULL == name) { + if (!trie || !name) { mpp_err_f("invalid trie %p name %p\n", trie, name); return NULL; } @@ -623,51 +687,24 @@ MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name) if (!node || node->id < 0) return NULL; - return (MppTrieInfo *)(((RK_U8 *)p->nodes) + node->id + p->ctx_size); + return (MppTrieInfo *)(((RK_U8 *)p->nodes) + node->id); } -void *mpp_trie_get_slot(MppTrie trie, const char *name) -{ - MppTrieImpl *p = (MppTrieImpl *)trie; - MppTrieNode *node; - - if (NULL == trie || NULL == name) { - mpp_err_f("invalid trie %p name %p\n", trie, name); - return NULL; - } - - if (!p->buf_size) { - mpp_err_f("trie %p buffer is not shrinked and not ready for usage\n", trie); - return NULL; - } - - node = mpp_trie_get_node(p->nodes, name); - if (!node || node->id < 0) - return NULL; - - return (void *)(((RK_U8 *)p->nodes) + node->id); -} - -void *mpp_trie_get_slot_first(MppTrie trie) +MppTrieInfo *mpp_trie_get_info_first(MppTrie trie) { MppTrieImpl *p = (MppTrieImpl *)trie; - return (p) ? ((RK_U8 *)p->nodes) + p->node_used * sizeof(MppTrieNode) : NULL; + return (p) ? (MppTrieInfo *)(((RK_U8 *)p->nodes) + p->node_used * sizeof(MppTrieNode)) : NULL; } -void *mpp_trie_get_slot_next(MppTrie trie, void *slot) +MppTrieInfo *mpp_trie_get_info_next(MppTrie trie, MppTrieInfo *info) { MppTrieImpl *p = (MppTrieImpl *)trie; - MppTrieInfo *info; - if (!p || !slot) + if (!p || !info || info->index >= p->info_used - 1) return NULL; - info = (MppTrieInfo *)((RK_U8 *)slot + p->ctx_size); - if (info->index < 0 || info->index >= p->info_used - 1) - return NULL; - - return (void *)((RK_U8 *)slot + p->ctx_size + sizeof(MppTrieInfo) + info->str_len); + return (MppTrieInfo *)(info->name + info->str_len); } void mpp_trie_dump(MppTrie trie, const char *func) @@ -690,9 +727,15 @@ void mpp_trie_dump(MppTrie trie, const char *func) if (i && !node->idx) continue; - if (node->id >= 0) - mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, p->info[node->id].name); - else + if (node->id >= 0) { + /* check before and after last info */ + if (node->id < p->node_used * sizeof(MppTrieNode)) + mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, + (char *)p->name_buf + p->info[node->id].name_offset); + else + mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, + ((MppTrieInfo *)((char *)p->nodes + node->id))->name); + } else mpp_logi("node %d key %x\n", node->idx, node->key); if (node->tag_len) diff --git a/mpp/base/test/mpp_trie_test.c b/mpp/base/test/mpp_trie_test.c index df458f1c..ee2de293 100644 --- a/mpp/base/test/mpp_trie_test.c +++ b/mpp/base/test/mpp_trie_test.c @@ -73,12 +73,11 @@ int main() RK_S64 end = 0; RK_S64 start = 0; RK_S32 info_cnt = MPP_ARRAY_ELEMS(test_info); - RK_S32 node_cnt = 100; RK_S32 ret = MPP_OK; mpp_log("mpp_trie_test start\n"); - mpp_trie_init(&trie, node_cnt, info_cnt); + mpp_trie_init(&trie, sizeof(TestAction)); start = mpp_time(); for (i = 0; i < info_cnt; i++) @@ -86,9 +85,9 @@ int main() end = mpp_time(); mpp_log("add act time %lld us\n", end - start); - ret = mpp_trie_shrink(trie, 0); + ret = mpp_trie_add_info(trie, NULL, NULL); if (ret) { - mpp_loge("mpp_trie_shrink failed\n"); + mpp_loge("mpp_trie_add_info last failed\n"); goto DONE; } diff --git a/mpp/inc/mpp_cfg.h b/mpp/inc/mpp_cfg.h index cefbb291..2f4b7908 100644 --- a/mpp/inc/mpp_cfg.h +++ b/mpp/inc/mpp_cfg.h @@ -30,39 +30,29 @@ typedef enum CfgType_e { CFG_FUNC_TYPE_BUTT, } CfgType; -typedef struct MppCfgApi_t { - const char *name; +typedef struct MppCfgInfo_t { CfgType data_type; + /* update flag info 32bit */ + RK_U32 flag_type; RK_U32 flag_offset; RK_U32 flag_value; + /* data access info */ RK_U32 data_offset; RK_S32 data_size; -} MppCfgApi; +} MppCfgInfo; -typedef struct MppCfgInfo_t { - /* CfgType */ - RK_S32 data_type; - /* update flag info 32bit */ - RK_S32 flag_offset; - RK_U32 flag_value; - /* data access info */ - RK_S32 data_offset; - RK_S32 data_size; - RK_U8 *name; -} MppCfgInfoNode; - -MPP_RET mpp_cfg_set_s32(MppCfgInfoNode *info, void *cfg, RK_S32 val); -MPP_RET mpp_cfg_get_s32(MppCfgInfoNode *info, void *cfg, RK_S32 *val); -MPP_RET mpp_cfg_set_u32(MppCfgInfoNode *info, void *cfg, RK_U32 val); -MPP_RET mpp_cfg_get_u32(MppCfgInfoNode *info, void *cfg, RK_U32 *val); -MPP_RET mpp_cfg_set_s64(MppCfgInfoNode *info, void *cfg, RK_S64 val); -MPP_RET mpp_cfg_get_s64(MppCfgInfoNode *info, void *cfg, RK_S64 *val); -MPP_RET mpp_cfg_set_u64(MppCfgInfoNode *info, void *cfg, RK_U64 val); -MPP_RET mpp_cfg_get_u64(MppCfgInfoNode *info, void *cfg, RK_U64 *val); -MPP_RET mpp_cfg_set_st(MppCfgInfoNode *info, void *cfg, void *val); -MPP_RET mpp_cfg_get_st(MppCfgInfoNode *info, void *cfg, void *val); -MPP_RET mpp_cfg_set_ptr(MppCfgInfoNode *info, void *cfg, void *val); -MPP_RET mpp_cfg_get_ptr(MppCfgInfoNode *info, void *cfg, void **val); +MPP_RET mpp_cfg_set_s32(MppCfgInfo *info, void *cfg, RK_S32 val); +MPP_RET mpp_cfg_get_s32(MppCfgInfo *info, void *cfg, RK_S32 *val); +MPP_RET mpp_cfg_set_u32(MppCfgInfo *info, void *cfg, RK_U32 val); +MPP_RET mpp_cfg_get_u32(MppCfgInfo *info, void *cfg, RK_U32 *val); +MPP_RET mpp_cfg_set_s64(MppCfgInfo *info, void *cfg, RK_S64 val); +MPP_RET mpp_cfg_get_s64(MppCfgInfo *info, void *cfg, RK_S64 *val); +MPP_RET mpp_cfg_set_u64(MppCfgInfo *info, void *cfg, RK_U64 val); +MPP_RET mpp_cfg_get_u64(MppCfgInfo *info, void *cfg, RK_U64 *val); +MPP_RET mpp_cfg_set_st(MppCfgInfo *info, void *cfg, void *val); +MPP_RET mpp_cfg_get_st(MppCfgInfo *info, void *cfg, void *val); +MPP_RET mpp_cfg_set_ptr(MppCfgInfo *info, void *cfg, void *val); +MPP_RET mpp_cfg_get_ptr(MppCfgInfo *info, void *cfg, void **val); #define MPP_CFG_SET_S32(info, cfg, val) (mpp_cfg_set_s32)(info, cfg, val) #define MPP_CFG_GET_S32(info, cfg, val) (mpp_cfg_get_s32)(info, cfg, (RK_S32 *)(val)) @@ -89,12 +79,12 @@ typedef struct MppCfgInfoHead_t { extern "C" { #endif -extern const char *cfg_type_names[]; +const char *strof_cfg_type(CfgType type); #define CHECK_CFG_INFO(node, name, type) \ check_cfg_info(node, name, type, __FUNCTION__) -MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type, +MPP_RET check_cfg_info(MppCfgInfo *node, const char *name, CfgType type, const char *func); #ifdef __cplusplus diff --git a/utils/mpp_opt.c b/utils/mpp_opt.c index 97b166fb..05d03e51 100644 --- a/utils/mpp_opt.c +++ b/utils/mpp_opt.c @@ -62,7 +62,7 @@ MPP_RET mpp_opt_setup(MppOpt opt, void *ctx) if (NULL == impl) return MPP_NOK; - mpp_trie_init(&impl->trie, 128, 16); + mpp_trie_init(&impl->trie, sizeof(MppOptInfo)); if (impl->trie) { impl->ctx = ctx; return MPP_OK; @@ -79,7 +79,7 @@ MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info) return MPP_NOK; if (NULL == info) - return mpp_trie_shrink(impl->trie, 0); + return mpp_trie_add_info(impl->trie, NULL, NULL); return mpp_trie_add_info(impl->trie, info->name, info); }