diff --git a/mpp/base/mpp_dec_cfg.cpp b/mpp/base/mpp_dec_cfg.cpp index 75335857..957db1ab 100644 --- a/mpp/base/mpp_dec_cfg.cpp +++ b/mpp/base/mpp_dec_cfg.cpp @@ -17,6 +17,7 @@ #define MODULE_TAG "mpp_dec_cfg" #include "rk_vdec_cfg.h" +#include #include "mpp_env.h" #include "mpp_mem.h" @@ -25,6 +26,7 @@ #include "mpp_common.h" #include "mpp_thread.h" +#include "mpp_cfg.h" #include "mpp_dec_cfg_impl.h" #define MPP_DEC_CFG_DBG_FUNC (0x00000001) @@ -41,113 +43,69 @@ RK_U32 mpp_dec_cfg_debug = 0; -#define EXPAND_AS_ENUM(name, func, type) \ - SET_##name, \ - GET_##name, +typedef struct MppDecCfgInfo_t { + MppCfgInfoHead head; + MppTrieNode trie_node[]; + /* MppCfgInfoNode is following trie_node */ +} MppDecCfgInfo; -/* Expand to enum - typedef enum CfgType_e { - SET_S32, - GET_S32, - SET_U32, - GET_U32, - SET_S64, - GET_S64, - SET_U64, - GET_U64, - SET_PTR, - GET_PTR, - CFG_FUNC_TYPE_BUTT, - } CfgType; - */ +static MppCfgInfoNode *mpp_dec_cfg_find(MppDecCfgInfo *info, const char *name) +{ + MppTrieNode *node; -#define EXPAND_AS_TYPE(name, func, type) \ - typedef MPP_RET (*CfgSet##func)(void *ctx, type val); \ - typedef MPP_RET (*CfgGet##func)(void *ctx, type *val); + if (NULL == info || NULL == name) + return NULL; -/* Expand to function type - typedef MPP_RET (*CfgSetS32)(void *ctx, RK_S32 val); - typedef MPP_RET (*CfgGetS32)(void *ctx, RK_S32 *val); - typedef MPP_RET (*CfgSetU32)(void *ctx, RK_U32 val); - typedef MPP_RET (*CfgGetU32)(void *ctx, RK_U32 *val); - typedef MPP_RET (*CfgSetS64)(void *ctx, RK_S64 val); - typedef MPP_RET (*CfgGetS64)(void *ctx, RK_S64 *val); - typedef MPP_RET (*CfgSetU64)(void *ctx, RK_U64 val); - typedef MPP_RET (*CfgGetU64)(void *ctx, RK_U64 *val); - typedef MPP_RET (*CfgSetPtr)(void *ctx, void *val); - typedef MPP_RET (*CfgGetPtr)(void *ctx, void **val); - */ + node = mpp_trie_get_node(info->trie_node, name); + if (NULL == node) + return NULL; -#define EXPAND_AS_NAME(name, func, type) \ - #type, \ - #type"*", + return (MppCfgInfoNode *)(((char *)info->trie_node) + node->id); +} -/* Expand to name - static const char *dec_cfg_func_names[] = { - "RK_S32", - "RK_S32*", - "RK_U32", - "RK_U32*", - "RK_S64", - "RK_S64*", - "RK_U64", - "RK_U64*", - "void *", - "void **", - }; - */ +class MppDecCfgService +{ +private: + MppDecCfgService(); + ~MppDecCfgService(); + MppDecCfgService(const MppDecCfgService &); + MppDecCfgService &operator=(const MppDecCfgService &); -#define TYPE_ENTRY_TABLE(ENTRY) \ - ENTRY(S32, S32, RK_S32) \ - ENTRY(U32, U32, RK_U32) \ - ENTRY(S64, S64, RK_S64) \ - ENTRY(U64, U64, RK_U64) \ - ENTRY(PTR, Ptr, void *) + MppDecCfgInfo *mInfo; + RK_S32 mCfgSize; -typedef enum CfgType_e { - TYPE_ENTRY_TABLE(EXPAND_AS_ENUM) - CFG_FUNC_TYPE_BUTT, -} CfgType; +public: + static MppDecCfgService *get() { + static Mutex lock; + static MppDecCfgService instance; -TYPE_ENTRY_TABLE(EXPAND_AS_TYPE) - -static const char *dec_cfg_func_names[] = { - TYPE_ENTRY_TABLE(EXPAND_AS_NAME) -}; - -#define EXPAND_AS_FUNC(base, name, func_type, in_type, flag, field0, field1) \ - MPP_RET set_##base##_##name(MppDecCfgSet *cfg, in_type name) \ - { \ - mpp_dec_cfg_dbg_func("enter\n"); \ - if (cfg->field0.field1 != (in_type)name || SET_##func_type == SET_PTR) { \ - cfg->field0.field1 = (in_type)name; \ - cfg->field0.change |= flag; \ - } \ - return MPP_OK; \ - } \ - MPP_RET get_##base##_##name(MppDecCfgSet *cfg, in_type *name) \ - { \ - mpp_dec_cfg_dbg_func("enter\n"); \ - *name = (in_type)cfg->field0.field1; \ - return MPP_OK; \ + AutoMutex auto_lock(&lock); + return &instance; } -#define EXPAND_AS_API(base, name, func_type, in_type, flag, field0, field1) \ - static MppDecCfgApi api_##base##_##name = \ + MppCfgInfoNode *get_info(const char *name) { return mpp_dec_cfg_find(mInfo, name); }; + MppCfgInfoNode *get_info_root(); + + 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_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, \ - SET_##func_type, \ - GET_##func_type, \ - (void *)set_##base##_##name, \ - (void *)get_##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, func_type, in_type, flag, field0, field1) \ +#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \ &api_##base##_##name, -#define EXPAND_AS_STRLEN(base, name, func_type, in_type, flag, field0, field1) \ - dec_const_strlen( #base":"#name ) + - #define ENTRY_TABLE(ENTRY) \ /* rc config */ \ ENTRY(base, type, U32, MppCtxType, MPP_DEC_CFG_CHANGE_TYPE, base, type) \ @@ -163,79 +121,138 @@ static const char *dec_cfg_func_names[] = { ENTRY(base, disable_error, U32, RK_U32, MPP_DEC_CFG_CHANGE_DISABLE_ERROR, base, disable_error) \ ENTRY(base, enable_vproc, U32, RK_U32, MPP_DEC_CFG_CHANGE_ENABLE_VPROC, base, enable_vproc) \ ENTRY(base, enable_fast_play, U32, RK_U32, MPP_DEC_CFG_CHANGE_ENABLE_FAST_PLAY, base, enable_fast_play) \ - ENTRY(cb, pkt_rdy_cb, PTR, MppExtCbFunc, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_cb) \ - ENTRY(cb, pkt_rdy_ctx, PTR, MppExtCbCtx, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_ctx) \ + ENTRY(cb, pkt_rdy_cb, Ptr, MppExtCbFunc, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_cb) \ + ENTRY(cb, pkt_rdy_ctx, Ptr, MppExtCbCtx, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_ctx) \ ENTRY(cb, pkt_rdy_cmd, S32, RK_S32, MPP_DEC_CB_CFG_CHANGE_PKT_RDY, cb, pkt_rdy_cmd) \ - ENTRY(cb, frm_rdy_cb, PTR, MppExtCbFunc, MPP_DEC_CB_CFG_CHANGE_FRM_RDY, cb, frm_rdy_cb) \ - ENTRY(cb, frm_rdy_ctx, PTR, MppExtCbCtx, MPP_DEC_CB_CFG_CHANGE_FRM_RDY, cb, frm_rdy_ctx) \ + ENTRY(cb, frm_rdy_cb, Ptr, MppExtCbFunc, MPP_DEC_CB_CFG_CHANGE_FRM_RDY, cb, frm_rdy_cb) \ + 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) -ENTRY_TABLE(EXPAND_AS_FUNC) -ENTRY_TABLE(EXPAND_AS_API) - -static MppDecCfgApi *dec_cfg_apis[] = { - ENTRY_TABLE(EXPAND_AS_ARRAY) -}; - -RK_S32 dec_const_strlen(const char* str) +static MppDecCfgInfo *mpp_dec_cfg_flaten(MppTrie trie, MppCfgApi **cfgs) { - return *str ? 1 + dec_const_strlen(str + 1) : 0; -} + 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; -static RK_S32 dec_node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) + 16; + pos += node_count * sizeof(*node_root); -class MppDecCfgService -{ -private: - MppDecCfgService(); - ~MppDecCfgService(); - MppDecCfgService(const MppDecCfgService &); - MppDecCfgService &operator=(const MppDecCfgService &); + mpp_dec_cfg_dbg_info("info node offset %d\n", pos); - MppTrie mCfgApi; + /* 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); -public: - static MppDecCfgService *get() { - static Mutex lock; - static MppDecCfgService instance; - - AutoMutex auto_lock(&lock); - return &instance; + mpp_assert(*info_trie == name); + len = strlen(name); + pos += sizeof(MppCfgInfoNode) + MPP_ALIGN(len + 1, sizeof(RK_U64)); } - MppTrie get_api() { return mCfgApi; }; -}; + 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; + + 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; + + 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, + 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() : - mCfgApi(NULL) + mInfo(NULL), + mCfgSize(0) { + ENTRY_TABLE(EXPAND_AS_API); + + MppCfgApi *cfgs[] = { + ENTRY_TABLE(EXPAND_AS_ARRAY) + }; + + RK_S32 cfg_cnt = MPP_ARRAY_ELEMS(cfgs); + MppTrie trie; MPP_RET ret; RK_S32 i; - RK_S32 api_cnt = MPP_ARRAY_ELEMS(dec_cfg_apis); - /* * 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(&mCfgApi, dec_node_len, api_cnt); + ret = mpp_trie_init(&trie, 284, cfg_cnt); if (ret) { - mpp_err_f("failed to init enc cfg set trie\n"); - } else { - for (i = 0; i < api_cnt; i++) - mpp_trie_add_info(mCfgApi, &dec_cfg_apis[i]->name); + 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); - if (dec_node_len < mpp_trie_get_node_count(mCfgApi)) - mpp_err_f("create info %d with not enough node %d -> %d info\n", - api_cnt, dec_node_len, mpp_trie_get_node_count(mCfgApi)); + mInfo = mpp_dec_cfg_flaten(trie, cfgs); + mCfgSize = mInfo->head.cfg_size; + + mpp_trie_deinit(trie); } MppDecCfgService::~MppDecCfgService() { - if (mCfgApi) { - mpp_trie_deinit(mCfgApi); - mCfgApi = NULL; - } + MPP_FREE(mInfo); +} + +MppCfgInfoNode *MppDecCfgService::get_info_root() +{ + if (NULL == mInfo) + return NULL; + + return (MppCfgInfoNode *)(mInfo->trie_node + mInfo->head.node_count); } void mpp_dec_cfg_set_default(MppDecCfgSet *cfg) @@ -249,21 +266,23 @@ 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; } - p = mpp_calloc(MppDecCfgImpl, 1); + cfg_size = MppDecCfgService::get()->get_cfg_size(); + p = mpp_calloc_size(MppDecCfgImpl, cfg_size + sizeof(p->size)); if (NULL == p) { - mpp_err_f("create encoder config failed %p\n", p); + mpp_err_f("create decoder config failed %p\n", p); *cfg = NULL; return MPP_ERR_NOMEM; } - p->size = sizeof(*p); - p->api = MppDecCfgService::get()->get_api(); + mpp_assert(cfg_size == sizeof(p->cfg)); + p->size = cfg_size; mpp_dec_cfg_set_default(&p->cfg); mpp_env_get_u32("mpp_dec_cfg_debug", &mpp_dec_cfg_debug, 0); @@ -285,7 +304,7 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg) return MPP_OK; } -#define ENC_CFG_SET_ACCESS(func_name, in_type, func_enum, func_type) \ +#define ENC_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) { \ @@ -293,29 +312,23 @@ MPP_RET mpp_dec_cfg_deinit(MppDecCfg cfg) return MPP_ERR_NULL_PTR; \ } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ - const char **info = mpp_trie_get_info(p->api, name); \ - if (NULL == info) { \ - mpp_err_f("failed to set %s to %d\n", name, val); \ + MppCfgInfoNode *info = MppDecCfgService::get()->get_info(name); \ + if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - MppDecCfgApi *api = (MppDecCfgApi *)info; \ - if (api->type_set != func_enum) { \ - mpp_err_f("%s expect %s input NOT %s\n", api->name, \ - dec_cfg_func_names[api->type_set], \ - dec_cfg_func_names[func_enum]); \ - } \ - mpp_dec_cfg_dbg_set("name %s type %s\n", api->name, dec_cfg_func_names[api->type_set]); \ - MPP_RET ret = ((func_type)api->api_set)(&p->cfg, val); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \ return ret; \ } -ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_s32, RK_S32, SET_S32, CfgSetS32); -ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_u32, RK_U32, SET_U32, CfgSetU32); -ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_s64, RK_S64, SET_S64, CfgSetS64); -ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_u64, RK_U64, SET_U64, CfgSetU64); -ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_ptr, void *, SET_PTR, CfgSetPtr); +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); -#define ENC_CFG_GET_ACCESS(func_name, in_type, func_enum, func_type) \ +#define ENC_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) { \ @@ -323,42 +336,46 @@ ENC_CFG_SET_ACCESS(mpp_dec_cfg_set_ptr, void *, SET_PTR, CfgSetPtr); return MPP_ERR_NULL_PTR; \ } \ MppDecCfgImpl *p = (MppDecCfgImpl *)cfg; \ - const char **info = mpp_trie_get_info(p->api, name); \ - if (NULL == info) { \ - mpp_err_f("failed to set %s to %d\n", name, val); \ + MppCfgInfoNode *info = MppDecCfgService::get()->get_info(name); \ + if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \ return MPP_NOK; \ } \ - MppDecCfgApi *api = (MppDecCfgApi *)info; \ - if (api->type_get != func_enum) { \ - mpp_err_f("%s expect %s input not %s\n", api->name, \ - dec_cfg_func_names[api->type_get], \ - dec_cfg_func_names[func_enum]); \ - } \ - mpp_dec_cfg_dbg_get("name %s type %s\n", api->name, dec_cfg_func_names[api->type_get]); \ - MPP_RET ret = ((func_type)api->api_get)(&p->cfg, val); \ + mpp_dec_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \ + MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \ return ret; \ } -ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_s32, RK_S32, GET_S32, CfgGetS32); -ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_u32, RK_U32, GET_U32, CfgGetU32); -ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_s64, RK_S64, GET_S64, CfgGetS64); -ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_u64, RK_U64, GET_U64, CfgGetU64); -ENC_CFG_GET_ACCESS(mpp_dec_cfg_get_ptr, void *, GET_PTR, CfgGetPtr); +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); void mpp_dec_cfg_show(void) { - RK_U32 i; + 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(); mpp_log("dumping valid configure string start\n"); - for (i = 0; i < MPP_ARRAY_ELEMS(dec_cfg_apis); i++) - mpp_log("%-25s type set:%s get:%s\n", dec_cfg_apis[i]->name, - dec_cfg_func_names[dec_cfg_apis[i]->type_set], - dec_cfg_func_names[dec_cfg_apis[i]->type_get]); + if (info) { + char *p = (char *)info; + RK_S32 i; + for (i = 0; i < info_count; i++) { + info = (MppCfgInfoNode *)p; + + mpp_log("%-25s type %s\n", info->name, + cfg_type_names[info->data_type]); + + p += info->node_size; + } + } mpp_log("dumping valid configure string done\n"); - mpp_log("total api count %d with node %d -> %d info\n", - MPP_ARRAY_ELEMS(dec_cfg_apis), dec_node_len, - mpp_trie_get_node_count(MppDecCfgService::get()->get_api())); + mpp_log("total cfg count %d with %d node size %d\n", + info_count, node_count, + MppDecCfgService::get()->get_info_size()); } diff --git a/mpp/inc/mpp_dec_cfg.h b/mpp/inc/mpp_dec_cfg.h index 8112cec7..734dc9e7 100644 --- a/mpp/inc/mpp_dec_cfg.h +++ b/mpp/inc/mpp_dec_cfg.h @@ -91,15 +91,4 @@ typedef struct MppDecCfgSet_t { MppDecCbCfg cb; } MppDecCfgSet; -/* - * MppDecCfgApi is the function set for configure MppDecCfgSet by name - */ -typedef struct MppDecCfgApi_t { - const char *name; - RK_S32 type_set; - RK_S32 type_get; - void *api_set; - void *api_get; -} MppDecCfgApi; - #endif /* __MPP_DEC_CFG_H__ */