mirror of
https://github.com/rockchip-linux/mpp.git
synced 2024-11-23 10:04:07 +08:00
feat[mpp_trie]: Add trie context filling feature
1. Add context space reserving on trie shrink. 2. Remove MppTrieNode on trie interface. 3. Fix MppTrie usage on tests. Signed-off-by: Herman Chen <herman.chen@rock-chips.com> Change-Id: Ie2f568785a78499b394d298c3833dd04c6f9a9bd
This commit is contained in:
parent
8bfa0916e2
commit
c367dd1609
@ -25,28 +25,34 @@ typedef void* MppTrie;
|
||||
#define MPP_TRIE_KEY_LEN (4)
|
||||
#define MPP_TRIE_KEY_MAX (MPP_TRIE_KEY_LEN << 4)
|
||||
|
||||
/* spatial optimized tire tree */
|
||||
typedef struct MppAcNode_t {
|
||||
/* id - tire node carried payload data */
|
||||
RK_S32 id;
|
||||
/* idx - tire node index in ascending order */
|
||||
RK_S16 idx;
|
||||
/* prev - tire node index in ascending order */
|
||||
RK_S16 prev;
|
||||
/* key - current key value in previous node as next */
|
||||
RK_S16 key;
|
||||
|
||||
/* tag len - common tag length
|
||||
* zero - normal node with 16 next node
|
||||
* positive - single path node with 4bit unit tag length */
|
||||
RK_S16 tag_len;
|
||||
/* id_tag - last tag index */
|
||||
RK_U64 tag_val;
|
||||
|
||||
/* valid next position bitmap */
|
||||
RK_U16 next_cnt;
|
||||
RK_S16 next[MPP_TRIE_KEY_MAX];
|
||||
} MppTrieNode;
|
||||
/*
|
||||
* MppTire node buffer layout
|
||||
* +---------------+
|
||||
* | MppTrieImpl |
|
||||
* +---------------+
|
||||
* | MppTireNodes |
|
||||
* +---------------+
|
||||
* | MppTrieInfos |
|
||||
* +---------------+
|
||||
*
|
||||
* MppTrieInfo element layout
|
||||
* +---------------+
|
||||
* | User context |
|
||||
* +---------------+
|
||||
* | MppTrieInfo |
|
||||
* +---------------+
|
||||
* | 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;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -55,15 +61,19 @@ extern "C" {
|
||||
MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count);
|
||||
MPP_RET mpp_trie_deinit(MppTrie trie);
|
||||
|
||||
MPP_RET mpp_trie_add_info(MppTrie trie, const char **info);
|
||||
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);
|
||||
RK_S32 mpp_trie_get_buf_size(MppTrie trie);
|
||||
|
||||
MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name);
|
||||
const char **mpp_trie_get_info(MppTrie trie, const char *name);
|
||||
MppTrieNode *mpp_trie_node_root(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);
|
||||
|
||||
void mpp_trie_dump(MppTrie trie, const char *func);
|
||||
#define mpp_trie_dump_f(tire) mpp_trie_dump(tire, __FUNCTION__)
|
||||
|
@ -43,26 +43,6 @@
|
||||
|
||||
RK_U32 mpp_dec_cfg_debug = 0;
|
||||
|
||||
typedef struct MppDecCfgInfo_t {
|
||||
MppCfgInfoHead head;
|
||||
MppTrieNode trie_node[];
|
||||
/* MppCfgInfoNode is following trie_node */
|
||||
} MppDecCfgInfo;
|
||||
|
||||
static MppCfgInfoNode *mpp_dec_cfg_find(MppDecCfgInfo *info, const char *name)
|
||||
{
|
||||
MppTrieNode *node;
|
||||
|
||||
if (NULL == info || NULL == name)
|
||||
return NULL;
|
||||
|
||||
node = mpp_trie_get_node(info->trie_node, name);
|
||||
if (NULL == node)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)(((char *)info->trie_node) + node->id);
|
||||
}
|
||||
|
||||
class MppDecCfgService
|
||||
{
|
||||
private:
|
||||
@ -71,7 +51,8 @@ private:
|
||||
MppDecCfgService(const MppDecCfgService &);
|
||||
MppDecCfgService &operator=(const MppDecCfgService &);
|
||||
|
||||
MppDecCfgInfo *mInfo;
|
||||
MppCfgInfoHead mHead;
|
||||
MppTrie mTrie;
|
||||
RK_S32 mCfgSize;
|
||||
|
||||
public:
|
||||
@ -83,12 +64,13 @@ public:
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MppCfgInfoNode *get_info(const char *name) { return mpp_dec_cfg_find(mInfo, name); };
|
||||
MppCfgInfoNode *get_info_root();
|
||||
MppCfgInfoNode *get_info(const char *name);
|
||||
MppCfgInfoNode *get_info_first();
|
||||
MppCfgInfoNode *get_info_next(MppCfgInfoNode *node);
|
||||
|
||||
RK_S32 get_node_count() { return mInfo ? mInfo->head.node_count : 0; };
|
||||
RK_S32 get_info_count() { return mInfo ? mInfo->head.info_count : 0; };
|
||||
RK_S32 get_info_size() { return mInfo ? mInfo->head.info_size : 0; };
|
||||
RK_S32 get_node_count() { return mHead.node_count; };
|
||||
RK_S32 get_info_count() { return mHead.info_count; };
|
||||
RK_S32 get_info_size() { return mHead.info_size; };
|
||||
RK_S32 get_cfg_size() { return mCfgSize; };
|
||||
};
|
||||
|
||||
@ -133,91 +115,34 @@ 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 MppDecCfgInfo *mpp_dec_cfg_flaten(MppTrie trie, MppCfgApi **cfgs)
|
||||
static void mpp_dec_cfg_fill(MppTrie trie, MppCfgApi **cfgs)
|
||||
{
|
||||
MppDecCfgInfo *info = NULL;
|
||||
MppTrieNode *node_root = mpp_trie_node_root(trie);
|
||||
RK_S32 node_count = mpp_trie_get_node_count(trie);
|
||||
RK_S32 info_count = mpp_trie_get_info_count(trie);
|
||||
MppTrieNode *node_trie;
|
||||
char *buf = NULL;
|
||||
RK_S32 pos = 0;
|
||||
RK_S32 len = 0;
|
||||
RK_S32 i;
|
||||
|
||||
pos += node_count * sizeof(*node_root);
|
||||
|
||||
mpp_dec_cfg_dbg_info("info node offset %d\n", pos);
|
||||
|
||||
/* update info size and string name size */
|
||||
for (i = 0; i < info_count; i++) {
|
||||
const char *name = cfgs[i]->name;
|
||||
const char **info_trie = mpp_trie_get_info(trie, name);
|
||||
|
||||
mpp_assert(*info_trie == name);
|
||||
len = strlen(name);
|
||||
pos += sizeof(MppCfgInfoNode) + MPP_ALIGN(len + 1, sizeof(RK_U64));
|
||||
}
|
||||
|
||||
len = pos + sizeof(*info);
|
||||
mpp_dec_cfg_dbg_info("tire + info size %d total %d\n", pos, len);
|
||||
|
||||
info = mpp_malloc_size(MppDecCfgInfo, len);
|
||||
if (NULL == info)
|
||||
return NULL;
|
||||
|
||||
memcpy(info->trie_node, node_root, sizeof(*node_root) * node_count);
|
||||
|
||||
node_root = info->trie_node;
|
||||
pos = node_count * sizeof(*node_root);
|
||||
buf = (char *)node_root + pos;
|
||||
|
||||
for (i = 0; i < info_count; i++) {
|
||||
MppCfgInfoNode *node_info = (MppCfgInfoNode *)buf;
|
||||
MppCfgApi *api = cfgs[i];
|
||||
const char *name = api->name;
|
||||
RK_S32 node_size;
|
||||
MppCfgInfoNode *node_info = (MppCfgInfoNode *)mpp_trie_get_slot(trie, name);
|
||||
MppTrieInfo *info = (MppTrieInfo *)(node_info + 1);
|
||||
|
||||
node_trie = mpp_trie_get_node(node_root, name);
|
||||
node_trie->id = pos;
|
||||
|
||||
node_info->name_len = MPP_ALIGN(strlen(name) + 1, sizeof(RK_U64));
|
||||
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->node_next = 0;
|
||||
|
||||
node_size = node_info->name_len + sizeof(*node_info);
|
||||
node_info->node_size = node_size;
|
||||
node_info->name = (RK_U8 *)(info + 1);
|
||||
|
||||
mpp_cfg_node_fixup_func(node_info);
|
||||
|
||||
strcpy(node_info->name, name);
|
||||
|
||||
mpp_dec_cfg_dbg_info("cfg %s offset %d size %d update %d flag %x\n",
|
||||
node_info->name,
|
||||
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);
|
||||
|
||||
pos += node_size;
|
||||
buf += node_size;
|
||||
}
|
||||
|
||||
mpp_dec_cfg_dbg_info("total size %d +H %d\n", pos, pos + sizeof(info->head));
|
||||
|
||||
info->head.info_size = pos;
|
||||
info->head.info_count = info_count;
|
||||
info->head.node_count = node_count;
|
||||
info->head.cfg_size = sizeof(MppDecCfgSet);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
MppDecCfgService::MppDecCfgService() :
|
||||
mInfo(NULL),
|
||||
mCfgSize(0)
|
||||
mTrie(NULL)
|
||||
{
|
||||
ENTRY_TABLE(EXPAND_AS_API);
|
||||
|
||||
@ -226,38 +151,55 @@ MppDecCfgService::MppDecCfgService() :
|
||||
};
|
||||
|
||||
RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs);
|
||||
MppTrie trie;
|
||||
MPP_RET ret;
|
||||
RK_S32 i;
|
||||
/*
|
||||
* NOTE: The dec_node_len is not the real node count should be allocated
|
||||
* The max node count should be stream lengthg * 2 if each word is different.
|
||||
*/
|
||||
ret = mpp_trie_init(&trie, 340, cfg_cnt);
|
||||
|
||||
ret = mpp_trie_init(&mTrie, 340, cfg_cnt);
|
||||
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(trie, &cfgs[i]->name);
|
||||
mpp_trie_add_info(mTrie, cfgs[i]->name, &cfgs[i]);
|
||||
|
||||
mInfo = mpp_dec_cfg_flaten(trie, cfgs);
|
||||
mCfgSize = mInfo->head.cfg_size;
|
||||
mpp_trie_shrink(mTrie, sizeof(MppCfgInfoNode));
|
||||
|
||||
mpp_trie_deinit(trie);
|
||||
mpp_dec_cfg_fill(mTrie, cfgs);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
MppDecCfgService::~MppDecCfgService()
|
||||
{
|
||||
MPP_FREE(mInfo);
|
||||
if (mTrie) {
|
||||
mpp_trie_deinit(mTrie);
|
||||
mTrie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppDecCfgService::get_info_root()
|
||||
MppCfgInfoNode *MppDecCfgService::get_info(const char *name)
|
||||
{
|
||||
if (NULL == mInfo)
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot(mTrie, name);
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppDecCfgService::get_info_first()
|
||||
{
|
||||
if (NULL == mTrie)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)(mInfo->trie_node + mInfo->head.node_count);
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot_first(mTrie);
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppDecCfgService::get_info_next(MppCfgInfoNode *node)
|
||||
{
|
||||
if (NULL == mTrie)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot_next(mTrie, (void *)node);
|
||||
}
|
||||
|
||||
void mpp_dec_cfg_set_default(MppDecCfgSet *cfg)
|
||||
@ -276,14 +218,14 @@ void mpp_dec_cfg_set_default(MppDecCfgSet *cfg)
|
||||
MPP_RET mpp_dec_cfg_init(MppDecCfg *cfg)
|
||||
{
|
||||
MppDecCfgImpl *p = NULL;
|
||||
RK_S32 cfg_size;
|
||||
|
||||
if (NULL == cfg) {
|
||||
mpp_err_f("invalid NULL input config\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
cfg_size = MppDecCfgService::get()->get_cfg_size();
|
||||
mpp_env_get_u32("mpp_dec_cfg_debug", &mpp_dec_cfg_debug, 0);
|
||||
|
||||
p = mpp_calloc(MppDecCfgImpl, 1);
|
||||
if (NULL == p) {
|
||||
mpp_err_f("create decoder config failed %p\n", p);
|
||||
@ -291,12 +233,9 @@ MPP_RET mpp_dec_cfg_init(MppDecCfg *cfg)
|
||||
return MPP_ERR_NOMEM;
|
||||
}
|
||||
|
||||
mpp_assert(cfg_size == sizeof(p->cfg));
|
||||
p->size = cfg_size;
|
||||
p->size = sizeof(p->cfg);
|
||||
mpp_dec_cfg_set_default(&p->cfg);
|
||||
|
||||
mpp_env_get_u32("mpp_dec_cfg_debug", &mpp_dec_cfg_debug, 0);
|
||||
|
||||
*cfg = p;
|
||||
|
||||
return MPP_OK;
|
||||
@ -314,7 +253,7 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
#define ENC_CFG_SET_ACCESS(func_name, in_type, cfg_type) \
|
||||
#define DEC_CFG_SET_ACCESS(func_name, in_type, cfg_type) \
|
||||
MPP_RET func_name(MppDecCfg cfg, const char *name, in_type val) \
|
||||
{ \
|
||||
if (NULL == cfg || NULL == name) { \
|
||||
@ -331,14 +270,14 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg)
|
||||
return ret; \
|
||||
}
|
||||
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_s32, RK_S32, S32);
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_u32, RK_U32, U32);
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_s64, RK_S64, S64);
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_u64, RK_U64, U64);
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_ptr, void *, Ptr);
|
||||
ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_st, void *, St);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_s32, RK_S32, S32);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_u32, RK_U32, U32);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_s64, RK_S64, S64);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_u64, RK_U64, U64);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_ptr, void *, Ptr);
|
||||
DEC_CFG_SET_ACCESS(mpp_dec_cfg_set_st, void *, St);
|
||||
|
||||
#define ENC_CFG_GET_ACCESS(func_name, in_type, cfg_type) \
|
||||
#define DEC_CFG_GET_ACCESS(func_name, in_type, cfg_type) \
|
||||
MPP_RET func_name(MppDecCfg cfg, const char *name, in_type *val) \
|
||||
{ \
|
||||
if (NULL == cfg || NULL == name) { \
|
||||
@ -355,37 +294,34 @@ ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_st, void *, St);
|
||||
return ret; \
|
||||
}
|
||||
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_s32, RK_S32, S32);
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_u32, RK_U32, U32);
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_s64, RK_S64, S64);
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_u64, RK_U64, U64);
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_ptr, void *, Ptr);
|
||||
ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_st, void , St);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_s32, RK_S32, S32);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_u32, RK_U32, U32);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_s64, RK_S64, S64);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_u64, RK_U64, U64);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_ptr, void *, Ptr);
|
||||
DEC_CFG_GET_ACCESS(mpp_dec_cfg_get_st, void , St);
|
||||
|
||||
void mpp_dec_cfg_show(void)
|
||||
{
|
||||
RK_S32 node_count = MppDecCfgService::get()->get_node_count();
|
||||
RK_S32 info_count = MppDecCfgService::get()->get_info_count();
|
||||
MppCfgInfoNode *info = MppDecCfgService::get()->get_info_root();
|
||||
MppDecCfgService *srv = MppDecCfgService::get();
|
||||
MppCfgInfoNode *root = srv->get_info_first();
|
||||
|
||||
mpp_log("dumping valid configure string start\n");
|
||||
|
||||
if (info) {
|
||||
char *p = (char *)info;
|
||||
RK_S32 i;
|
||||
if (root) {
|
||||
MppCfgInfoNode *node = root;
|
||||
|
||||
for (i = 0; i < info_count; i++) {
|
||||
info = (MppCfgInfoNode *)p;
|
||||
do {
|
||||
mpp_log("%-25s type %s\n", node->name,
|
||||
cfg_type_names[node->data_type]);
|
||||
|
||||
mpp_log("%-25s type %s\n", info->name,
|
||||
cfg_type_names[info->data_type]);
|
||||
|
||||
p += info->node_size;
|
||||
}
|
||||
node = srv->get_info_next(node);
|
||||
if (!node)
|
||||
break;
|
||||
} while (1);
|
||||
}
|
||||
mpp_log("dumping valid configure string done\n");
|
||||
|
||||
mpp_log("total cfg count %d with %d node size %d\n",
|
||||
info_count, node_count,
|
||||
MppDecCfgService::get()->get_info_size());
|
||||
}
|
||||
srv->get_info_count(), srv->get_node_count(), srv->get_info_size());
|
||||
}
|
@ -44,41 +44,6 @@
|
||||
|
||||
RK_U32 mpp_enc_cfg_debug = 0;
|
||||
|
||||
/*
|
||||
* MppEncCfgInfo data struct
|
||||
*
|
||||
* +----------+
|
||||
* | head |
|
||||
* +----------+
|
||||
* | trie |
|
||||
* | node |
|
||||
* | .... |
|
||||
* +----------+
|
||||
* | info |
|
||||
* | node |
|
||||
* | .... |
|
||||
* +----------+
|
||||
*/
|
||||
typedef struct MppEncCfgInfo_t {
|
||||
MppCfgInfoHead head;
|
||||
MppTrieNode trie_node[];
|
||||
/* MppCfgInfoNode is following trie_node */
|
||||
} MppEncCfgInfo;
|
||||
|
||||
static MppCfgInfoNode *mpp_enc_cfg_find(MppEncCfgInfo *info, const char *name)
|
||||
{
|
||||
MppTrieNode *node;
|
||||
|
||||
if (NULL == info || NULL == name)
|
||||
return NULL;
|
||||
|
||||
node = mpp_trie_get_node(info->trie_node, name);
|
||||
if (NULL == node)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)(((char *)info->trie_node) + node->id);
|
||||
}
|
||||
|
||||
class MppEncCfgService
|
||||
{
|
||||
private:
|
||||
@ -87,7 +52,8 @@ private:
|
||||
MppEncCfgService(const MppEncCfgService &);
|
||||
MppEncCfgService &operator=(const MppEncCfgService &);
|
||||
|
||||
MppEncCfgInfo *mInfo;
|
||||
MppCfgInfoHead mHead;
|
||||
MppTrie mTrie;
|
||||
RK_S32 mCfgSize;
|
||||
|
||||
public:
|
||||
@ -99,12 +65,13 @@ public:
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MppCfgInfoNode *get_info(const char *name) { return mpp_enc_cfg_find(mInfo, name); };
|
||||
MppCfgInfoNode *get_info_root();
|
||||
MppCfgInfoNode *get_info(const char *name);
|
||||
MppCfgInfoNode *get_info_first();
|
||||
MppCfgInfoNode *get_info_next(MppCfgInfoNode *node);
|
||||
|
||||
RK_S32 get_node_count() { return mInfo ? mInfo->head.node_count : 0; };
|
||||
RK_S32 get_info_count() { return mInfo ? mInfo->head.info_count : 0; };
|
||||
RK_S32 get_info_size() { return mInfo ? mInfo->head.info_size : 0; };
|
||||
RK_S32 get_node_count() { return mHead.node_count; };
|
||||
RK_S32 get_info_count() { return mHead.info_count; };
|
||||
RK_S32 get_info_size() { return mHead.info_size; };
|
||||
RK_S32 get_cfg_size() { return mCfgSize; };
|
||||
};
|
||||
|
||||
@ -290,91 +257,34 @@ public:
|
||||
/* quality fine tuning config */ \
|
||||
ENTRY(tune, scene_mode, S32, MppEncSceneMode, MPP_ENC_TUNE_CFG_CHANGE_SCENE_MODE, tune, scene_mode)
|
||||
|
||||
static MppEncCfgInfo *mpp_enc_cfg_flaten(MppTrie trie, MppCfgApi **cfgs)
|
||||
static void mpp_enc_cfg_fill(MppTrie trie, MppCfgApi **cfgs)
|
||||
{
|
||||
MppEncCfgInfo *info = NULL;
|
||||
MppTrieNode *node_root = mpp_trie_node_root(trie);
|
||||
RK_S32 node_count = mpp_trie_get_node_count(trie);
|
||||
RK_S32 info_count = mpp_trie_get_info_count(trie);
|
||||
MppTrieNode *node_trie;
|
||||
char *buf = NULL;
|
||||
RK_S32 pos = 0;
|
||||
RK_S32 len = 0;
|
||||
RK_S32 i;
|
||||
|
||||
pos += node_count * sizeof(*node_root);
|
||||
|
||||
mpp_enc_cfg_dbg_info("info node offset %d\n", pos);
|
||||
|
||||
/* update info size and string name size */
|
||||
for (i = 0; i < info_count; i++) {
|
||||
const char *name = cfgs[i]->name;
|
||||
const char **info_trie = mpp_trie_get_info(trie, name);
|
||||
|
||||
mpp_assert(*info_trie == name);
|
||||
len = strlen(name);
|
||||
pos += sizeof(MppCfgInfoNode) + MPP_ALIGN(len + 1, sizeof(RK_U64));
|
||||
}
|
||||
|
||||
len = pos + sizeof(*info);
|
||||
mpp_enc_cfg_dbg_info("tire + info size %d total %d\n", pos, len);
|
||||
|
||||
info = mpp_malloc_size(MppEncCfgInfo, len);
|
||||
if (NULL == info)
|
||||
return NULL;
|
||||
|
||||
memcpy(info->trie_node, node_root, sizeof(*node_root) * node_count);
|
||||
|
||||
node_root = info->trie_node;
|
||||
pos = node_count * sizeof(*node_root);
|
||||
buf = (char *)node_root + pos;
|
||||
|
||||
for (i = 0; i < info_count; i++) {
|
||||
MppCfgInfoNode *node_info = (MppCfgInfoNode *)buf;
|
||||
MppCfgApi *api = cfgs[i];
|
||||
const char *name = api->name;
|
||||
RK_S32 node_size;
|
||||
MppCfgInfoNode *node_info = (MppCfgInfoNode *)mpp_trie_get_slot(trie, name);
|
||||
MppTrieInfo *info = (MppTrieInfo *)(node_info + 1);
|
||||
|
||||
node_trie = mpp_trie_get_node(node_root, name);
|
||||
node_trie->id = pos;
|
||||
|
||||
node_info->name_len = MPP_ALIGN(strlen(name) + 1, sizeof(RK_U64));
|
||||
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->node_next = 0;
|
||||
|
||||
node_size = node_info->name_len + sizeof(*node_info);
|
||||
node_info->node_size = node_size;
|
||||
node_info->name = (RK_U8 *)(info + 1);
|
||||
|
||||
mpp_cfg_node_fixup_func(node_info);
|
||||
|
||||
strcpy(node_info->name, name);
|
||||
|
||||
mpp_enc_cfg_dbg_info("cfg %s offset %d size %d update %d flag %x\n",
|
||||
node_info->name,
|
||||
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);
|
||||
|
||||
pos += node_size;
|
||||
buf += node_size;
|
||||
}
|
||||
|
||||
mpp_enc_cfg_dbg_info("total size %d +H %d\n", pos, pos + sizeof(info->head));
|
||||
|
||||
info->head.info_size = pos;
|
||||
info->head.info_count = info_count;
|
||||
info->head.node_count = node_count;
|
||||
info->head.cfg_size = sizeof(MppEncCfgSet);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
MppEncCfgService::MppEncCfgService() :
|
||||
mInfo(NULL),
|
||||
mCfgSize(0)
|
||||
mTrie(NULL)
|
||||
{
|
||||
ENTRY_TABLE(EXPAND_AS_API);
|
||||
|
||||
@ -383,42 +293,58 @@ MppEncCfgService::MppEncCfgService() :
|
||||
};
|
||||
|
||||
RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs);
|
||||
MppTrie trie;
|
||||
MPP_RET ret;
|
||||
RK_S32 i;
|
||||
|
||||
mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0);
|
||||
|
||||
ret = mpp_trie_init(&trie, 1887, cfg_cnt);
|
||||
ret = mpp_trie_init(&mTrie, 512, cfg_cnt);
|
||||
if (ret) {
|
||||
mpp_err_f("failed to init enc cfg set trie\n");
|
||||
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(trie, &cfgs[i]->name);
|
||||
mpp_trie_add_info(mTrie, cfgs[i]->name, &cfgs[i]);
|
||||
|
||||
mpp_trie_shrink(trie, 120);
|
||||
mpp_trie_shrink(mTrie, sizeof(MppCfgInfoNode));
|
||||
|
||||
mInfo = mpp_enc_cfg_flaten(trie, cfgs);
|
||||
mCfgSize = mInfo->head.cfg_size;
|
||||
mpp_enc_cfg_fill(mTrie, cfgs);
|
||||
|
||||
mpp_enc_cfg_dbg_func("node cnt: %d\n", get_node_count());
|
||||
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_trie_deinit(trie);
|
||||
mpp_enc_cfg_dbg_func("node cnt: %d\n", mpp_trie_get_node_count(mTrie));
|
||||
}
|
||||
|
||||
MppEncCfgService::~MppEncCfgService()
|
||||
{
|
||||
MPP_FREE(mInfo);
|
||||
if (mTrie) {
|
||||
mpp_trie_deinit(mTrie);
|
||||
mTrie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppEncCfgService::get_info_root()
|
||||
MppCfgInfoNode *MppEncCfgService::get_info(const char *name)
|
||||
{
|
||||
if (NULL == mInfo)
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot(mTrie, name);
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppEncCfgService::get_info_first()
|
||||
{
|
||||
if (NULL == mTrie)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)(mInfo->trie_node + mInfo->head.node_count);
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot_first(mTrie);
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppEncCfgService::get_info_next(MppCfgInfoNode *node)
|
||||
{
|
||||
if (NULL == mTrie)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)mpp_trie_get_slot_next(mTrie, (void *)node);
|
||||
}
|
||||
|
||||
static void mpp_enc_cfg_set_default(MppEncCfgSet *cfg)
|
||||
@ -445,7 +371,6 @@ static void mpp_enc_cfg_set_default(MppEncCfgSet *cfg)
|
||||
MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg)
|
||||
{
|
||||
MppEncCfgImpl *p = NULL;
|
||||
RK_S32 cfg_size;
|
||||
|
||||
if (NULL == cfg) {
|
||||
mpp_err_f("invalid NULL input config\n");
|
||||
@ -454,7 +379,6 @@ MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg)
|
||||
|
||||
mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0);
|
||||
|
||||
cfg_size = MppEncCfgService::get()->get_cfg_size();
|
||||
p = mpp_calloc(MppEncCfgImpl, 1);
|
||||
if (NULL == p) {
|
||||
mpp_err_f("create encoder config failed %p\n", p);
|
||||
@ -462,8 +386,7 @@ MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg)
|
||||
return MPP_ERR_NOMEM;
|
||||
}
|
||||
|
||||
mpp_assert(cfg_size == sizeof(p->cfg));
|
||||
p->size = cfg_size;
|
||||
p->size = sizeof(p->cfg);
|
||||
mpp_enc_cfg_set_default(&p->cfg);
|
||||
|
||||
*cfg = p;
|
||||
@ -533,28 +456,25 @@ ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_st, void , St);
|
||||
|
||||
void mpp_enc_cfg_show(void)
|
||||
{
|
||||
RK_S32 node_count = MppEncCfgService::get()->get_node_count();
|
||||
RK_S32 info_count = MppEncCfgService::get()->get_info_count();
|
||||
MppCfgInfoNode *info = MppEncCfgService::get()->get_info_root();
|
||||
MppEncCfgService *srv = MppEncCfgService::get();
|
||||
MppCfgInfoNode *root = srv->get_info_first();
|
||||
|
||||
mpp_log("dumping valid configure string start\n");
|
||||
|
||||
if (info) {
|
||||
char *p = (char *)info;
|
||||
RK_S32 i;
|
||||
if (root) {
|
||||
MppCfgInfoNode *node = root;
|
||||
|
||||
for (i = 0; i < info_count; i++) {
|
||||
info = (MppCfgInfoNode *)p;
|
||||
do {
|
||||
mpp_log("%-25s type %s\n", node->name,
|
||||
cfg_type_names[node->data_type]);
|
||||
|
||||
mpp_log("%-25s type %s\n", info->name,
|
||||
cfg_type_names[info->data_type]);
|
||||
|
||||
p += info->node_size;
|
||||
}
|
||||
node = srv->get_info_next(node);
|
||||
if (!node)
|
||||
break;
|
||||
} while (1);
|
||||
}
|
||||
mpp_log("dumping valid configure string done\n");
|
||||
|
||||
mpp_log("total cfg count %d with %d node size %d\n",
|
||||
info_count, node_count,
|
||||
MppEncCfgService::get()->get_info_size());
|
||||
srv->get_info_count(), srv->get_node_count(), srv->get_info_size());
|
||||
}
|
||||
|
@ -48,13 +48,41 @@
|
||||
#define INVALID_NODE_ID (-1)
|
||||
#define MPP_TRIE_TAG_LEN_MAX ((sizeof(RK_U64) * 8) / MPP_TRIE_KEY_LEN)
|
||||
|
||||
/* spatial optimized tire 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;
|
||||
|
||||
/* 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
|
||||
*/
|
||||
RK_S16 tag_len;
|
||||
|
||||
/* next_cnt - valid next node count */
|
||||
RK_U16 next_cnt;
|
||||
} MppTrieNode;
|
||||
|
||||
typedef struct MppAcImpl_t {
|
||||
RK_S32 info_count;
|
||||
RK_S32 info_used;
|
||||
const char ***info;
|
||||
MppTrieInfo *info;
|
||||
RK_S32 node_count;
|
||||
RK_S32 node_used;
|
||||
MppTrieNode *nodes;
|
||||
RK_S32 ctx_size;
|
||||
RK_S32 buf_size;
|
||||
} MppTrieImpl;
|
||||
|
||||
RK_U32 mpp_trie_debug = 0;
|
||||
@ -123,7 +151,7 @@ MPP_RET mpp_trie_init(MppTrie *trie, RK_S32 node_count, RK_S32 info_count)
|
||||
}
|
||||
|
||||
p->info_count = info_count ? info_count : DEFAULT_INFO_COUNT;
|
||||
p->info = mpp_calloc(const char **, p->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);
|
||||
goto DONE;
|
||||
@ -160,10 +188,10 @@ MPP_RET mpp_trie_deinit(MppTrie trie)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_trie_add_info(MppTrie trie, const char **info)
|
||||
MPP_RET mpp_trie_add_info(MppTrie trie, const char *name, void *ctx)
|
||||
{
|
||||
if (NULL == trie || NULL == info) {
|
||||
mpp_err_f("invalid trie %p info %p\n", trie, info);
|
||||
if (!trie || !name || !ctx) {
|
||||
mpp_err_f("invalid trie %p name %s ctx %p\n", trie, name, ctx);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
@ -172,7 +200,8 @@ MPP_RET mpp_trie_add_info(MppTrie trie, const char **info)
|
||||
/* create */
|
||||
if (p->info_used >= p->info_count) {
|
||||
RK_S32 new_count = p->info_count * 2;
|
||||
const char ***ptr = mpp_realloc(p->info, const char **, new_count);
|
||||
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;
|
||||
@ -186,7 +215,7 @@ MPP_RET mpp_trie_add_info(MppTrie trie, const char **info)
|
||||
}
|
||||
|
||||
MppTrieNode *node = NULL;
|
||||
const char *s = *info;
|
||||
const char *s = name;
|
||||
RK_S32 len = strnlen(s, SZ_1K);
|
||||
RK_S32 next = 0;
|
||||
RK_S32 idx = 0;
|
||||
@ -239,62 +268,147 @@ MPP_RET mpp_trie_add_info(MppTrie trie, const char **info)
|
||||
}
|
||||
|
||||
RK_S32 act_id = p->info_used++;
|
||||
|
||||
p->nodes[idx].id = act_id;
|
||||
p->info[act_id] = info;
|
||||
|
||||
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, info);
|
||||
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;
|
||||
RK_S32 len = *tag_len;
|
||||
|
||||
if (node->tag_len > len) {
|
||||
*tag_val = (val << 4) | key;
|
||||
*tag_len = len + 1;
|
||||
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> key %x -> tag fill\n",
|
||||
node->idx, node->id, node->tag_len, *tag_len, node->tag_val, *tag_val, key);
|
||||
|
||||
return node->idx;
|
||||
}
|
||||
|
||||
/* normal next switch node */
|
||||
if (!node->tag_len) {
|
||||
trie_dbg_walk("node %d:%d -> key %x -> next %d\n",
|
||||
node->idx, node->id, key, node->next[key]);
|
||||
|
||||
return node->next[key];
|
||||
}
|
||||
|
||||
*tag_val = 0;
|
||||
*tag_len = 0;
|
||||
|
||||
if (node->tag_val != val) {
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> tag mismatch\n",
|
||||
node->idx, node->id, node->tag_len, len, node->tag_val, val);
|
||||
return INVALID_NODE_ID;
|
||||
}
|
||||
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> tag match -> key %d next %d\n",
|
||||
node->idx, node->id, node->tag_len, len, node->tag_val, val, key, node->next[key]);
|
||||
|
||||
return node->next[key];
|
||||
}
|
||||
|
||||
static MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name)
|
||||
{
|
||||
MppTrieNode *ret = NULL;
|
||||
const char *s = name;
|
||||
RK_U64 tag_val = 0;
|
||||
RK_S32 tag_len = 0;
|
||||
RK_S32 idx = 0;
|
||||
|
||||
if (NULL == root || NULL == name) {
|
||||
mpp_err_f("invalid root %p name %p\n", root, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trie_dbg_get("root %p search %s start\n", root, name);
|
||||
|
||||
do {
|
||||
RK_U8 key = *s++;
|
||||
RK_U32 key0 = (key >> 4) & 0xf;
|
||||
RK_U32 key1 = key & 0xf;
|
||||
RK_S32 end = (s[0] == '\0');
|
||||
|
||||
idx = mpp_trie_walk(&root[idx], &tag_val, &tag_len, key0);
|
||||
if (idx < 0)
|
||||
break;
|
||||
|
||||
idx = mpp_trie_walk(&root[idx], &tag_val, &tag_len, key1);
|
||||
if (idx < 0 || end)
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
ret = (idx >= 0) ? &root[idx] : NULL;
|
||||
|
||||
trie_dbg_get("get node %d:%d\n", idx, ret ? ret->id : INVALID_NODE_ID);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RK_S32 mpp_trie_check(MppTrie trie, const char *log)
|
||||
{
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
RK_S32 i;
|
||||
|
||||
for (i = 0; i < p->info_used; i++) {
|
||||
const char *name = p->info[i][0];
|
||||
const char **info_trie = mpp_trie_get_info(trie, name);
|
||||
const char *name = (const char *)p->info[i].name;
|
||||
MppTrieNode *node = mpp_trie_get_node(p->nodes, name);
|
||||
|
||||
if (!info_trie || *info_trie != name) {
|
||||
mpp_loge("shrinked trie %s found mismatch info %s:%p - %p\n",
|
||||
log, name, name, info_trie ? *info_trie : NULL);
|
||||
return MPP_NOK;
|
||||
}
|
||||
if (node && node->id >= 0 && node->id == i)
|
||||
continue;
|
||||
|
||||
mpp_loge("trie check on %s found mismatch info %s %d - %d\n",
|
||||
log, name, i, node ? node->id : -1);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 info_size)
|
||||
MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 ctx_size)
|
||||
{
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
MppTrieNode *root;
|
||||
MppTrieNode *node;
|
||||
MppTrieNode *prev;
|
||||
char *buf;
|
||||
RK_S32 node_count;
|
||||
RK_S32 node_valid;
|
||||
RK_S32 info_count;
|
||||
RK_S32 nodes_size;
|
||||
RK_S32 len = 0;
|
||||
RK_S32 pos = 0;
|
||||
RK_S32 i;
|
||||
RK_S32 j;
|
||||
|
||||
if (!trie || !info_size) {
|
||||
mpp_err_f("invalid trie %p info size %d\n", trie, info_size);
|
||||
if (!trie) {
|
||||
mpp_err_f("invalid trie %p info size %d\n", trie, ctx_size);
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
root = mpp_trie_node_root(trie);
|
||||
node_count = mpp_trie_get_node_count(trie);
|
||||
info_count = mpp_trie_get_info_count(trie);
|
||||
root = p->nodes;
|
||||
node_count = p->node_used;
|
||||
node_valid = node_count;
|
||||
|
||||
trie_dbg_shrink("shrink trie node start node %d info %d\n", node_count, info_count);
|
||||
trie_dbg_shrink("shrink trie node start node %d info %d\n", node_count, p->info_used);
|
||||
|
||||
if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP)
|
||||
mpp_trie_dump_f(trie);
|
||||
|
||||
for (i = node_count - 1; i > 0; i--) {
|
||||
MppTrieNode *prev;
|
||||
RK_S32 prev_idx;
|
||||
|
||||
node = &root[i];
|
||||
@ -341,13 +455,15 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 info_size)
|
||||
node_valid--;
|
||||
}
|
||||
|
||||
trie_dbg_shrink("shrink done node count %d -> %d\n", node_count, node_valid);
|
||||
trie_dbg_shrink("shrink trie node finish count %d -> %d\n", node_count, node_valid);
|
||||
|
||||
if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP)
|
||||
mpp_trie_dump_f(trie);
|
||||
|
||||
if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_CHECK)
|
||||
mpp_trie_check(trie, "merge tag stage");
|
||||
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);
|
||||
|
||||
for (i = 1; i < node_valid; i++) {
|
||||
node = &root[i];
|
||||
@ -358,6 +474,7 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 info_size)
|
||||
|
||||
for (j = i; j < node_count; j++) {
|
||||
MppTrieNode *tmp = &root[j];
|
||||
MppTrieNode *prev;
|
||||
RK_S32 k;
|
||||
|
||||
/* skip empty node */
|
||||
@ -395,13 +512,59 @@ MPP_RET mpp_trie_shrink(MppTrie trie, RK_S32 info_size)
|
||||
|
||||
p->node_used = node_valid;
|
||||
|
||||
trie_dbg_shrink("shrink trie node finish valid %d\n", p->node_used);
|
||||
trie_dbg_shrink("move trie node finish used %d\n", p->node_used);
|
||||
|
||||
if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_STEP)
|
||||
mpp_trie_dump_f(trie);
|
||||
|
||||
if (mpp_trie_debug & MPP_TRIE_DBG_SHRINK_CHECK)
|
||||
mpp_trie_check(trie, "move node stage");
|
||||
mpp_trie_check(trie, "shrink move node stage");
|
||||
|
||||
trie_dbg_shrink("create user buffer start\n");
|
||||
|
||||
p->ctx_size = ctx_size;
|
||||
nodes_size = sizeof(MppTrieNode) * p->node_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;
|
||||
}
|
||||
|
||||
len = pos;
|
||||
buf = mpp_calloc_size(char, len);
|
||||
if (!buf) {
|
||||
mpp_loge("failed to alloc trie buffer size %d\n", len);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
p->nodes = (MppTrieNode *)buf;
|
||||
p->buf_size = len;
|
||||
memcpy(p->nodes, root, nodes_size);
|
||||
pos = nodes_size;
|
||||
|
||||
for (i = 0; i < p->info_used; i++) {
|
||||
MppTrieInfo *info;
|
||||
const char *name = p->info[i].name;
|
||||
|
||||
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));
|
||||
pos += sizeof(MppTrieInfo);
|
||||
|
||||
/* copy info name */
|
||||
strncpy(buf + pos, name, info->str_len);
|
||||
pos += info->str_len;
|
||||
}
|
||||
|
||||
MPP_FREE(root);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
@ -428,79 +591,11 @@ RK_S32 mpp_trie_get_info_count(MppTrie trie)
|
||||
return p->info_used;
|
||||
}
|
||||
|
||||
static RK_S32 mpp_trie_walk(MppTrieNode *node, RK_U64 *tag_val, RK_S32 *tag_len, RK_U32 key)
|
||||
RK_S32 mpp_trie_get_buf_size(MppTrie trie)
|
||||
{
|
||||
RK_U64 val = *tag_val;
|
||||
RK_S32 len = *tag_len;
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
|
||||
if (node->tag_len > len) {
|
||||
*tag_val = (val << 4) | key;
|
||||
*tag_len = len + 1;
|
||||
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> key %x -> tag fill\n",
|
||||
node->idx, node->id, node->tag_len, *tag_len, node->tag_val, *tag_val, key);
|
||||
|
||||
return node->idx;
|
||||
}
|
||||
|
||||
/* normal next switch node */
|
||||
if (!node->tag_len) {
|
||||
trie_dbg_walk("node %d:%d -> key %x -> next %d\n",
|
||||
node->idx, node->id, key, node->next[key]);
|
||||
|
||||
return node->next[key];
|
||||
}
|
||||
|
||||
*tag_val = 0;
|
||||
*tag_len = 0;
|
||||
|
||||
if (node->tag_val != val) {
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> tag mismatch\n",
|
||||
node->idx, node->id, node->tag_len, len, node->tag_val, val);
|
||||
return INVALID_NODE_ID;
|
||||
}
|
||||
|
||||
trie_dbg_walk("node %d:%d tag len %d - %d val %016llx - %016llx -> tag match -> key %d next %d\n",
|
||||
node->idx, node->id, node->tag_len, len, node->tag_val, val, key, node->next[key]);
|
||||
|
||||
return node->next[key];
|
||||
}
|
||||
|
||||
MppTrieNode *mpp_trie_get_node(MppTrieNode *root, const char *name)
|
||||
{
|
||||
MppTrieNode *ret = NULL;
|
||||
const char *s = name;
|
||||
RK_U64 tag_val = 0;
|
||||
RK_S32 tag_len = 0;
|
||||
RK_S32 idx = 0;
|
||||
|
||||
if (NULL == root || NULL == name) {
|
||||
mpp_err_f("invalid root %p name %p\n", root, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trie_dbg_get("root %p search %s start\n", root, name);
|
||||
|
||||
do {
|
||||
RK_U8 key = *s++;
|
||||
RK_U32 key0 = (key >> 4) & 0xf;
|
||||
RK_U32 key1 = key & 0xf;
|
||||
RK_S32 end = (s[0] == '\0');
|
||||
|
||||
idx = mpp_trie_walk(&root[idx], &tag_val, &tag_len, key0);
|
||||
if (idx < 0)
|
||||
break;
|
||||
|
||||
idx = mpp_trie_walk(&root[idx], &tag_val, &tag_len, key1);
|
||||
if (idx < 0 || end)
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
ret = (idx >= 0) ? &root[idx] : NULL;
|
||||
|
||||
trie_dbg_get("get node %d:%d\n", idx, ret ? ret->id : INVALID_NODE_ID);
|
||||
|
||||
return ret;
|
||||
return (p) ? p->buf_size : 0;
|
||||
}
|
||||
|
||||
MppTrieNode *mpp_trie_node_root(MppTrie trie)
|
||||
@ -514,7 +609,7 @@ MppTrieNode *mpp_trie_node_root(MppTrie trie)
|
||||
return p->nodes;
|
||||
}
|
||||
|
||||
const char **mpp_trie_get_info(MppTrie trie, const char *name)
|
||||
MppTrieInfo *mpp_trie_get_info(MppTrie trie, const char *name)
|
||||
{
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
MppTrieNode *node;
|
||||
@ -525,8 +620,54 @@ const char **mpp_trie_get_info(MppTrie trie, const char *name)
|
||||
}
|
||||
|
||||
node = mpp_trie_get_node(p->nodes, name);
|
||||
if (!node || node->id < 0)
|
||||
return NULL;
|
||||
|
||||
return (node && node->id >= 0) ? p->info[node->id] : NULL;
|
||||
return (MppTrieInfo *)(((RK_U8 *)p->nodes) + node->id + p->ctx_size);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
|
||||
return (p) ? ((RK_U8 *)p->nodes) + p->node_used * sizeof(MppTrieNode) : NULL;
|
||||
}
|
||||
|
||||
void *mpp_trie_get_slot_next(MppTrie trie, void *slot)
|
||||
{
|
||||
MppTrieImpl *p = (MppTrieImpl *)trie;
|
||||
MppTrieInfo *info;
|
||||
|
||||
if (!p || !slot)
|
||||
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);
|
||||
}
|
||||
|
||||
void mpp_trie_dump(MppTrie trie, const char *func)
|
||||
@ -550,7 +691,7 @@ void mpp_trie_dump(MppTrie trie, const char *func)
|
||||
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][0]);
|
||||
mpp_logi("node %d key %x info %d - %s\n", node->idx, node->key, node->id, p->info[node->id].name);
|
||||
else
|
||||
mpp_logi("node %d key %x\n", node->idx, node->key);
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "mpp_trie.h"
|
||||
|
||||
typedef void *(*TestProc)(void *);
|
||||
typedef void *(*TestProc)(void *, RK_S64 time);
|
||||
|
||||
typedef struct TestAction_t {
|
||||
const char *name;
|
||||
@ -38,12 +38,12 @@ typedef struct TestCase_t {
|
||||
MPP_RET ret;
|
||||
} TestCase;
|
||||
|
||||
void *print_opt(void *ctx)
|
||||
void *print_opt(void *ctx, RK_S64 time)
|
||||
{
|
||||
RK_U8 **str = (RK_U8 **)ctx;
|
||||
|
||||
if (str && *str)
|
||||
mpp_log("get option %s\n", *str);
|
||||
mpp_log("get option %-16s time %lld us\n", *str, time);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -69,7 +69,6 @@ TestCase test_case[] = {
|
||||
int main()
|
||||
{
|
||||
MppTrie trie = NULL;
|
||||
void *info = NULL;
|
||||
RK_S32 i;
|
||||
RK_S64 end = 0;
|
||||
RK_S64 start = 0;
|
||||
@ -83,31 +82,32 @@ int main()
|
||||
|
||||
start = mpp_time();
|
||||
for (i = 0; i < info_cnt; i++)
|
||||
mpp_trie_add_info(trie, &test_info[i].name);
|
||||
mpp_trie_add_info(trie, test_info[i].name, &test_info[i]);
|
||||
end = mpp_time();
|
||||
mpp_log("add act time %lld us\n", end - start);
|
||||
|
||||
ret = mpp_trie_shrink(trie, sizeof(TestAction));
|
||||
ret = mpp_trie_shrink(trie, 0);
|
||||
if (ret) {
|
||||
mpp_loge("mpp_trie_shrink failed\n");
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(test_case); i++) {
|
||||
MppTrieInfo *info = NULL;
|
||||
TestAction *act = NULL;
|
||||
const char *name = test_case[i].name;
|
||||
|
||||
start = mpp_time();
|
||||
info = mpp_trie_get_info(trie, test_case[i].name);
|
||||
info = mpp_trie_get_info(trie, name);
|
||||
end = mpp_time();
|
||||
|
||||
if (info) {
|
||||
TestAction *act = (TestAction *)info;
|
||||
if (info && info->ctx)
|
||||
act = (TestAction *)info->ctx;
|
||||
|
||||
if (act && act->proc) {
|
||||
act->proc(act->ctx);
|
||||
mpp_log("search time %lld us\n", end - start);
|
||||
}
|
||||
} else {
|
||||
mpp_loge("search %s failed\n", test_case[i]);
|
||||
}
|
||||
if (act && act->proc)
|
||||
act->proc(act->ctx, end - start);
|
||||
else
|
||||
mpp_loge("search %s failed time %lld us\n", name, end - start);
|
||||
|
||||
ret |= ((info && !test_case[i].ret) ||
|
||||
(!info && test_case[i].ret)) ? MPP_OK : MPP_NOK;
|
||||
|
@ -40,9 +40,6 @@ typedef struct MppCfgApi_t {
|
||||
} MppCfgApi;
|
||||
|
||||
typedef struct MppCfgInfo_t {
|
||||
/* size for the whole node including name */
|
||||
RK_S32 node_size;
|
||||
RK_U32 name_len;
|
||||
/* CfgType */
|
||||
RK_S32 data_type;
|
||||
/* update flag info 32bit */
|
||||
@ -51,14 +48,10 @@ typedef struct MppCfgInfo_t {
|
||||
/* data access info */
|
||||
RK_S32 data_offset;
|
||||
RK_S32 data_size;
|
||||
/* linked next node offset for pointer type */
|
||||
RK_S32 node_next;
|
||||
/* function pointer for get / put accessor (user filled) */
|
||||
RK_U64 set_func;
|
||||
RK_U64 get_func;
|
||||
/* reserve for extension */
|
||||
RK_U64 stuff[2];
|
||||
char name[];
|
||||
RK_U8 *name;
|
||||
} MppCfgInfoNode;
|
||||
|
||||
typedef MPP_RET (*CfgSetS32)(MppCfgInfoNode *info, void *cfg, RK_S32 val);
|
||||
@ -89,11 +82,10 @@ typedef MPP_RET (*CfgGetPtr)(MppCfgInfoNode *info, void *cfg, void **val);
|
||||
|
||||
/* header size 128 byte */
|
||||
typedef struct MppCfgInfoHead_t {
|
||||
char version[112];
|
||||
char version[116];
|
||||
RK_S32 info_size;
|
||||
RK_S32 info_count;
|
||||
RK_S32 node_count;
|
||||
RK_S32 cfg_size;
|
||||
} MppCfgInfoHead;
|
||||
|
||||
typedef struct MppCfgOps_t {
|
||||
|
@ -696,7 +696,7 @@ RK_S32 mpi_dec_test_cmd_init(MpiDecTestCmd* cmd, int argc, char **argv)
|
||||
|
||||
mpp_opt_init(&opts);
|
||||
/* should change node count when option increases */
|
||||
mpp_opt_setup(opts, cmd, 35, dec_opt_cnt);
|
||||
mpp_opt_setup(opts, cmd);
|
||||
|
||||
for (i = 0; i < dec_opt_cnt; i++)
|
||||
mpp_opt_add(opts, &dec_opts[i]);
|
||||
|
@ -590,7 +590,7 @@ MPP_RET mpi_enc_test_cmd_update_by_args(MpiEncTestArgs* cmd, int argc, char **ar
|
||||
|
||||
mpp_opt_init(&opts);
|
||||
/* should change node count when option increases */
|
||||
mpp_opt_setup(opts, cmd, 71, enc_opt_cnt);
|
||||
mpp_opt_setup(opts, cmd);
|
||||
|
||||
for (i = 0; i < enc_opt_cnt; i++)
|
||||
mpp_opt_add(opts, &enc_opts[i]);
|
||||
|
@ -55,23 +55,19 @@ MPP_RET mpp_opt_deinit(MppOpt opt)
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_opt_setup(MppOpt opt, void *ctx, RK_S32 node_cnt, RK_S32 opt_cnt)
|
||||
MPP_RET mpp_opt_setup(MppOpt opt, void *ctx)
|
||||
{
|
||||
MppOptImpl *impl = (MppOptImpl *)opt;
|
||||
|
||||
if (NULL == impl)
|
||||
return MPP_NOK;
|
||||
|
||||
mpp_trie_init(&impl->trie, node_cnt, opt_cnt);
|
||||
mpp_trie_init(&impl->trie, 128, 16);
|
||||
if (impl->trie) {
|
||||
impl->ctx = ctx;
|
||||
impl->node_cnt = node_cnt;
|
||||
impl->info_cnt = opt_cnt;
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
mpp_err_f("failed to setup node %d opt %d\n", node_cnt, opt_cnt);
|
||||
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
@ -82,18 +78,10 @@ MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info)
|
||||
if (NULL == impl || NULL == impl->trie)
|
||||
return MPP_NOK;
|
||||
|
||||
if (NULL == info) {
|
||||
RK_S32 node_cnt = mpp_trie_get_node_count(impl->trie);
|
||||
RK_S32 info_cnt = mpp_trie_get_info_count(impl->trie);
|
||||
if (NULL == info)
|
||||
return mpp_trie_shrink(impl->trie, 0);
|
||||
|
||||
if (impl->node_cnt != node_cnt || impl->info_cnt != info_cnt)
|
||||
mpp_log("setup:real node %d:%d info %d:%d\n",
|
||||
impl->node_cnt, node_cnt, impl->info_cnt, info_cnt);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
return mpp_trie_add_info(impl->trie, &info->name);
|
||||
return mpp_trie_add_info(impl->trie, info->name, info);
|
||||
}
|
||||
|
||||
MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
|
||||
@ -117,15 +105,15 @@ MPP_RET mpp_opt_parse(MppOpt opt, int argc, char **argv)
|
||||
|
||||
if (opts[0] == '-' && opts[1] != '\0') {
|
||||
MppOptInfo *info = NULL;
|
||||
const char **name = mpp_trie_get_info(impl->trie, opts + 1);
|
||||
MppTrieInfo *node = mpp_trie_get_info(impl->trie, opts + 1);
|
||||
RK_S32 step = 0;
|
||||
|
||||
if (NULL == name) {
|
||||
if (NULL == node) {
|
||||
mpp_err("invalid option %s\n", opts + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
info = container_of(name, MppOptInfo, name);
|
||||
info = node->ctx;
|
||||
if (info->proc)
|
||||
step = info->proc(impl->ctx, next);
|
||||
|
||||
|
@ -41,7 +41,7 @@ extern "C" {
|
||||
MPP_RET mpp_opt_init(MppOpt *opt);
|
||||
MPP_RET mpp_opt_deinit(MppOpt opt);
|
||||
|
||||
MPP_RET mpp_opt_setup(MppOpt opt, void *ctx, RK_S32 node_cnt, RK_S32 opt_cnt);
|
||||
MPP_RET mpp_opt_setup(MppOpt opt, void *ctx);
|
||||
/* Add NULL info to mark end of options */
|
||||
MPP_RET mpp_opt_add(MppOpt opt, MppOptInfo *info);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user