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:
Herman Chen 2024-08-16 11:33:23 +08:00
parent 8bfa0916e2
commit c367dd1609
10 changed files with 440 additions and 453 deletions

View File

@ -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__)

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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]);

View File

@ -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]);

View File

@ -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);

View File

@ -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);