mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-21 16:19:23 +08:00
[mpp_cfg]: Add general MppCfgSet/Get function
1. Use flatten MppEncCfgInfo to replace MppCfgApi 2. Flatten the trie nodes and info nodes with string name together. 3. Refactor the encoder config setup process. Change-Id: Ia08f59167b033c99167f37e78571d9d2e402854c Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
|
||||
typedef struct MppEncCfgImpl_t {
|
||||
RK_S32 size;
|
||||
MppTrie api;
|
||||
MppEncCfgSet cfg;
|
||||
} MppEncCfgImpl;
|
||||
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
#define MODULE_TAG "mpp_cfg"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_cfg.h"
|
||||
|
||||
@@ -28,52 +30,161 @@ const char *cfg_type_names[] = {
|
||||
"struct",
|
||||
};
|
||||
|
||||
static void show_api_type_err(MppCfgApi *api, CfgType type)
|
||||
static void show_cfg_info_err(MppCfgInfoNode *node, CfgType type, const char *func)
|
||||
{
|
||||
mpp_err("cfg %s expect %s input NOT %s\n", api->name,
|
||||
cfg_type_names[api->info.type],
|
||||
mpp_err("%s cfg %s expect %s input NOT %s\n", func, node->name,
|
||||
cfg_type_names[node->data_type],
|
||||
cfg_type_names[type]);
|
||||
}
|
||||
|
||||
MPP_RET check_cfg_api_info(MppCfgApi *api, CfgType type)
|
||||
MPP_RET mpp_cfg_set(MppCfgInfoNode *info, void *cfg, void *val)
|
||||
{
|
||||
CfgType cfg_type = api->info.type;
|
||||
RK_S32 cfg_size = api->info.size;
|
||||
if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) {
|
||||
memcpy((char *)cfg + info->data_offset, val, info->data_size);
|
||||
*((RK_U32 *)((char *)cfg + info->flag_offset)) |= info->flag_value;
|
||||
}
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get(MppCfgInfoNode *info, void *cfg, void *val)
|
||||
{
|
||||
memcpy(val, (char *)cfg + info->data_offset, info->data_size);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_s32(MppCfgInfoNode *info, void *cfg, RK_S32 val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, &val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_s32(MppCfgInfoNode *info, void *cfg, RK_S32 *val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_u32(MppCfgInfoNode *info, void *cfg, RK_U32 val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, &val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_u32(MppCfgInfoNode *info, void *cfg, RK_U32 *val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_s64(MppCfgInfoNode *info, void *cfg, RK_S64 val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, &val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_s64(MppCfgInfoNode *info, void *cfg, RK_S64 *val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_u64(MppCfgInfoNode *info, void *cfg, RK_U64 val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, &val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_u64(MppCfgInfoNode *info, void *cfg, RK_U64 *val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_st(MppCfgInfoNode *info, void *cfg, void *val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_st(MppCfgInfoNode *info, void *cfg, void *val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_set_ptr(MppCfgInfoNode *info, void *cfg, void *val)
|
||||
{
|
||||
return mpp_cfg_set(info, cfg, val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_cfg_get_ptr(MppCfgInfoNode *info, void *cfg, void **val)
|
||||
{
|
||||
return mpp_cfg_get(info, cfg, val);
|
||||
}
|
||||
|
||||
MppCfgOps mpp_cfg_ops = {
|
||||
mpp_cfg_set_s32,
|
||||
mpp_cfg_get_s32,
|
||||
mpp_cfg_set_u32,
|
||||
mpp_cfg_get_u32,
|
||||
mpp_cfg_set_s64,
|
||||
mpp_cfg_get_s64,
|
||||
mpp_cfg_set_u64,
|
||||
mpp_cfg_get_u64,
|
||||
mpp_cfg_set_st,
|
||||
mpp_cfg_get_st,
|
||||
mpp_cfg_set_ptr,
|
||||
mpp_cfg_get_ptr,
|
||||
};
|
||||
|
||||
#define MPP_CFG_SET_OPS(type) ((long)(((void **)&mpp_cfg_ops)[type * 2 + 0]))
|
||||
#define MPP_CFG_GET_OPS(type) ((long)(((void **)&mpp_cfg_ops)[type * 2 + 1]))
|
||||
|
||||
MPP_RET mpp_cfg_node_fixup_func(MppCfgInfoNode *node)
|
||||
{
|
||||
RK_S32 data_type = node->data_type;
|
||||
|
||||
mpp_assert(data_type < CFG_FUNC_TYPE_BUTT);
|
||||
node->set_func = MPP_CFG_SET_OPS(data_type);
|
||||
node->get_func = MPP_CFG_GET_OPS(data_type);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type,
|
||||
const char *func)
|
||||
{
|
||||
if (NULL == node) {
|
||||
mpp_err("%s: cfg %s is invalid\n", func, name);
|
||||
return MPP_NOK;
|
||||
}
|
||||
|
||||
CfgType cfg_type = (CfgType)node->data_type;
|
||||
RK_S32 cfg_size = node->data_size;
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
switch (type) {
|
||||
case CFG_FUNC_TYPE_St : {
|
||||
if (cfg_type != type) {
|
||||
show_api_type_err(api, type);
|
||||
show_cfg_info_err(node, type, func);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
if (cfg_size <= 0) {
|
||||
mpp_err("cfg %s found invalid size %d\n", api->name, cfg_size);
|
||||
mpp_err("%s: cfg %s found invalid size %d\n", func, node->name, cfg_size);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
} break;
|
||||
case CFG_FUNC_TYPE_Ptr : {
|
||||
if (cfg_type != type) {
|
||||
show_api_type_err(api, type);
|
||||
show_cfg_info_err(node, type, func);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
} break;
|
||||
case CFG_FUNC_TYPE_S32 :
|
||||
case CFG_FUNC_TYPE_U32 : {
|
||||
if (cfg_size != sizeof(RK_S32)) {
|
||||
show_api_type_err(api, type);
|
||||
show_cfg_info_err(node, type, func);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
} break;
|
||||
case CFG_FUNC_TYPE_S64 :
|
||||
case CFG_FUNC_TYPE_U64 : {
|
||||
if (cfg_size != sizeof(RK_S64)) {
|
||||
show_api_type_err(api, type);
|
||||
show_cfg_info_err(node, type, func);
|
||||
ret = MPP_NOK;
|
||||
}
|
||||
} break;
|
||||
default : {
|
||||
mpp_err("cfg %s found invalid cfg type %d\n", api->name, type);
|
||||
mpp_err("%s: cfg %s found invalid cfg type %d\n", func, node->name, type);
|
||||
ret = MPP_NOK;
|
||||
} break;
|
||||
}
|
||||
|
@@ -44,73 +44,84 @@
|
||||
|
||||
RK_U32 mpp_enc_cfg_debug = 0;
|
||||
|
||||
#define EXPAND_AS_FUNC(base, name, cfg_type, in_type, flag, field_change, field_data) \
|
||||
MPP_RET set_##base##_##name(void *cfg, MppCfgApi *api, in_type name) \
|
||||
{ \
|
||||
char *base = (char *)cfg; \
|
||||
CfgDataInfo *info = &api->info; \
|
||||
CfgDataInfo *update = &api->update; \
|
||||
\
|
||||
mpp_enc_cfg_dbg_func("enter\n"); \
|
||||
switch (CFG_FUNC_TYPE_##cfg_type) { \
|
||||
case CFG_FUNC_TYPE_S32 : \
|
||||
case CFG_FUNC_TYPE_U32 : \
|
||||
case CFG_FUNC_TYPE_S64 : \
|
||||
case CFG_FUNC_TYPE_U64 : { \
|
||||
if (memcmp(base + info->offset, &name, info->size)) { \
|
||||
memcpy(base + info->offset, &name, info->size); \
|
||||
*((RK_U32 *)(base + update->offset)) |= flag; \
|
||||
} \
|
||||
} break; \
|
||||
case CFG_FUNC_TYPE_Ptr : { \
|
||||
memcpy(base + info->offset, &name, info->size); \
|
||||
*((RK_U32 *)(base + update->offset)) |= flag; \
|
||||
} break; \
|
||||
case CFG_FUNC_TYPE_St : { \
|
||||
if (memcmp(base + info->offset, (void *)((long)name), info->size)) { \
|
||||
memcpy(base + info->offset, (void *)((long)name), info->size); \
|
||||
*((RK_U32 *)(base + update->offset)) |= flag; \
|
||||
} \
|
||||
} break; \
|
||||
default : { \
|
||||
} break; \
|
||||
} \
|
||||
return MPP_OK; \
|
||||
} \
|
||||
MPP_RET get_##base##_##name(void *cfg, MppCfgApi *api, in_type *name) \
|
||||
{ \
|
||||
char *base = (char *)cfg; \
|
||||
CfgDataInfo *info = &api->info; \
|
||||
\
|
||||
mpp_enc_cfg_dbg_func("enter\n"); \
|
||||
memcpy(name, base + info->offset, info->size); \
|
||||
return MPP_OK; \
|
||||
/*
|
||||
* 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:
|
||||
MppEncCfgService();
|
||||
~MppEncCfgService();
|
||||
MppEncCfgService(const MppEncCfgService &);
|
||||
MppEncCfgService &operator=(const MppEncCfgService &);
|
||||
|
||||
MppEncCfgInfo *mInfo;
|
||||
RK_S32 mCfgSize;
|
||||
|
||||
public:
|
||||
static MppEncCfgService *get() {
|
||||
static Mutex lock;
|
||||
static MppEncCfgService instance;
|
||||
|
||||
AutoMutex auto_lock(&lock);
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MppCfgInfoNode *get_info(const char *name) { return mpp_enc_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) \
|
||||
static MppCfgApi api_##base##_##name = \
|
||||
MppCfgApi api_##base##_##name = \
|
||||
{ \
|
||||
#base":"#name, \
|
||||
{ \
|
||||
CFG_FUNC_TYPE_##cfg_type, \
|
||||
sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||
}, \
|
||||
{ \
|
||||
CFG_FUNC_TYPE_U32, \
|
||||
sizeof((((MppEncCfgSet *)0)->field_change.change)), \
|
||||
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \
|
||||
}, \
|
||||
(void *)set_##base##_##name, \
|
||||
(void *)get_##base##_##name, \
|
||||
CFG_FUNC_TYPE_##cfg_type, \
|
||||
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \
|
||||
flag, \
|
||||
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||
sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||
};
|
||||
|
||||
#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \
|
||||
&api_##base##_##name,
|
||||
|
||||
#define EXPAND_AS_STRLEN(base, name, cfg_type, in_type, flag, field_change, field_data) \
|
||||
const_strlen( #base":"#name ) +
|
||||
|
||||
#define ENTRY_TABLE(ENTRY) \
|
||||
/* base config */ \
|
||||
ENTRY(base, low_delay, S32, RK_S32, MPP_ENC_BASE_CFG_CHANGE_LOW_DELAY, base, low_delay) \
|
||||
@@ -242,72 +253,129 @@ RK_U32 mpp_enc_cfg_debug = 0;
|
||||
ENTRY(hw, aq_step_p, St, RK_S32 *, MPP_ENC_HW_CFG_CHANGE_AQ_STEP_P, hw, aq_step_p) \
|
||||
ENTRY(hw, mb_rc_disable, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_MB_RC, hw, mb_rc_disable)
|
||||
|
||||
ENTRY_TABLE(EXPAND_AS_FUNC)
|
||||
ENTRY_TABLE(EXPAND_AS_API)
|
||||
|
||||
static MppCfgApi *cfg_apis[] = {
|
||||
ENTRY_TABLE(EXPAND_AS_ARRAY)
|
||||
};
|
||||
|
||||
RK_S32 const_strlen(const char* str)
|
||||
static MppEncCfgInfo *mpp_enc_cfg_flaten(MppTrie trie, MppCfgApi **cfgs)
|
||||
{
|
||||
return *str ? 1 + const_strlen(str + 1) : 0;
|
||||
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;
|
||||
|
||||
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_enc_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_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;
|
||||
}
|
||||
|
||||
static RK_S32 node_len = ENTRY_TABLE(EXPAND_AS_STRLEN) - 52;
|
||||
|
||||
class MppEncCfgService
|
||||
{
|
||||
private:
|
||||
MppEncCfgService();
|
||||
~MppEncCfgService();
|
||||
MppEncCfgService(const MppEncCfgService &);
|
||||
MppEncCfgService &operator=(const MppEncCfgService &);
|
||||
|
||||
MppTrie mCfgApi;
|
||||
|
||||
public:
|
||||
static MppEncCfgService *get() {
|
||||
static Mutex lock;
|
||||
static MppEncCfgService instance;
|
||||
|
||||
AutoMutex auto_lock(&lock);
|
||||
return &instance;
|
||||
}
|
||||
|
||||
MppTrie get_api() { return mCfgApi; };
|
||||
};
|
||||
|
||||
MppEncCfgService::MppEncCfgService() :
|
||||
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(cfg_apis);
|
||||
|
||||
/*
|
||||
* NOTE: The 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, node_len, api_cnt);
|
||||
ret = mpp_trie_init(&trie, 1526, 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, &cfg_apis[i]->name);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (node_len < mpp_trie_get_node_count(mCfgApi))
|
||||
mpp_err_f("create info %d with not enough node %d -> %d info\n",
|
||||
api_cnt, node_len, mpp_trie_get_node_count(mCfgApi));
|
||||
for (i = 0; i < cfg_cnt; i++)
|
||||
mpp_trie_add_info(trie, &cfgs[i]->name);
|
||||
|
||||
mInfo = mpp_enc_cfg_flaten(trie, cfgs);
|
||||
mCfgSize = mInfo->head.cfg_size;
|
||||
|
||||
mpp_trie_deinit(trie);
|
||||
}
|
||||
|
||||
MppEncCfgService::~MppEncCfgService()
|
||||
{
|
||||
if (mCfgApi) {
|
||||
mpp_trie_deinit(mCfgApi);
|
||||
mCfgApi = NULL;
|
||||
}
|
||||
MPP_FREE(mInfo);
|
||||
}
|
||||
|
||||
MppCfgInfoNode *MppEncCfgService::get_info_root()
|
||||
{
|
||||
if (NULL == mInfo)
|
||||
return NULL;
|
||||
|
||||
return (MppCfgInfoNode *)(mInfo->trie_node + mInfo->head.node_count);
|
||||
}
|
||||
|
||||
static void mpp_enc_cfg_set_default(MppEncCfgSet *cfg)
|
||||
@@ -320,21 +388,23 @@ 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");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
p = mpp_calloc(MppEncCfgImpl, 1);
|
||||
cfg_size = MppEncCfgService::get()->get_cfg_size();
|
||||
p = mpp_calloc_size(MppEncCfgImpl, cfg_size + sizeof(p->size));
|
||||
if (NULL == p) {
|
||||
mpp_err_f("create encoder config failed %p\n", p);
|
||||
*cfg = NULL;
|
||||
return MPP_ERR_NOMEM;
|
||||
}
|
||||
|
||||
p->size = sizeof(*p);
|
||||
p->api = MppEncCfgService::get()->get_api();
|
||||
mpp_assert(cfg_size == sizeof(p->cfg));
|
||||
p->size = cfg_size;
|
||||
mpp_enc_cfg_set_default(&p->cfg);
|
||||
|
||||
mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0);
|
||||
@@ -364,17 +434,12 @@ MPP_RET mpp_enc_cfg_deinit(MppEncCfg cfg)
|
||||
return MPP_ERR_NULL_PTR; \
|
||||
} \
|
||||
MppEncCfgImpl *p = (MppEncCfgImpl *)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 = MppEncCfgService::get()->get_info(name); \
|
||||
if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||
return MPP_NOK; \
|
||||
} \
|
||||
MppCfgApi *api = (MppCfgApi *)info; \
|
||||
if (check_cfg_api_info(api, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||
return MPP_NOK; \
|
||||
} \
|
||||
mpp_enc_cfg_dbg_set("name %s type %s\n", api->name, cfg_type_names[api->info.type]); \
|
||||
MPP_RET ret = ((CfgSet##cfg_type)api->api_set)(&p->cfg, api, val); \
|
||||
mpp_enc_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; \
|
||||
}
|
||||
|
||||
@@ -393,17 +458,12 @@ ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_st, void *, St);
|
||||
return MPP_ERR_NULL_PTR; \
|
||||
} \
|
||||
MppEncCfgImpl *p = (MppEncCfgImpl *)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 = MppEncCfgService::get()->get_info(name); \
|
||||
if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||
return MPP_NOK; \
|
||||
} \
|
||||
MppCfgApi *api = (MppCfgApi *)info; \
|
||||
if (check_cfg_api_info(api, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||
return MPP_NOK; \
|
||||
} \
|
||||
mpp_enc_cfg_dbg_get("name %s type %s\n", api->name, cfg_type_names[api->info.type]); \
|
||||
MPP_RET ret = ((CfgGet##cfg_type)api->api_get)(&p->cfg, api, val); \
|
||||
mpp_enc_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; \
|
||||
}
|
||||
|
||||
@@ -416,17 +476,28 @@ ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_st, void , St);
|
||||
|
||||
void mpp_enc_cfg_show(void)
|
||||
{
|
||||
RK_U32 i;
|
||||
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();
|
||||
|
||||
mpp_log("dumping valid configure string start\n");
|
||||
|
||||
for (i = 0; i < MPP_ARRAY_ELEMS(cfg_apis); i++)
|
||||
mpp_log("%-25s type %s\n", cfg_apis[i]->name,
|
||||
cfg_type_names[cfg_apis[i]->info.type]);
|
||||
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(cfg_apis), node_len,
|
||||
mpp_trie_get_node_count(MppEncCfgService::get()->get_api()));
|
||||
mpp_log("total cfg count %d with %d node size %d\n",
|
||||
info_count, node_count,
|
||||
MppEncCfgService::get()->get_info_size());
|
||||
}
|
||||
|
@@ -25,44 +25,106 @@ typedef enum CfgType_e {
|
||||
CFG_FUNC_TYPE_U32,
|
||||
CFG_FUNC_TYPE_S64,
|
||||
CFG_FUNC_TYPE_U64,
|
||||
CFG_FUNC_TYPE_Ptr,
|
||||
CFG_FUNC_TYPE_St,
|
||||
CFG_FUNC_TYPE_Ptr,
|
||||
CFG_FUNC_TYPE_BUTT,
|
||||
} CfgType;
|
||||
|
||||
typedef struct CfgDataInfo_s {
|
||||
CfgType type : 4;
|
||||
RK_U32 size : 12;
|
||||
RK_U32 offset : 16;
|
||||
} CfgDataInfo;
|
||||
|
||||
typedef struct MppCfgApi_t {
|
||||
const char *name;
|
||||
CfgDataInfo info;
|
||||
CfgDataInfo update;
|
||||
void *api_set;
|
||||
void *api_get;
|
||||
CfgType data_type;
|
||||
RK_S32 flag_offset;
|
||||
RK_U32 flag_value;
|
||||
RK_S32 data_offset;
|
||||
RK_S32 data_size;
|
||||
} MppCfgApi;
|
||||
|
||||
typedef MPP_RET (*CfgSetS32)(void *cfg, MppCfgApi *api, RK_S32 val);
|
||||
typedef MPP_RET (*CfgGetS32)(void *cfg, MppCfgApi *api, RK_S32 *val);
|
||||
typedef MPP_RET (*CfgSetU32)(void *cfg, MppCfgApi *api, RK_U32 val);
|
||||
typedef MPP_RET (*CfgGetU32)(void *cfg, MppCfgApi *api, RK_U32 *val);
|
||||
typedef MPP_RET (*CfgSetS64)(void *cfg, MppCfgApi *api, RK_S64 val);
|
||||
typedef MPP_RET (*CfgGetS64)(void *cfg, MppCfgApi *api, RK_S64 *val);
|
||||
typedef MPP_RET (*CfgSetU64)(void *cfg, MppCfgApi *api, RK_U64 val);
|
||||
typedef MPP_RET (*CfgGetU64)(void *cfg, MppCfgApi *api, RK_U64 *val);
|
||||
typedef MPP_RET (*CfgSetPtr)(void *cfg, MppCfgApi *api, void *val);
|
||||
typedef MPP_RET (*CfgGetPtr)(void *cfg, MppCfgApi *api, void **val);
|
||||
typedef MPP_RET (*CfgSetSt) (void *cfg, MppCfgApi *api, void *val);
|
||||
typedef MPP_RET (*CfgGetSt) (void *cfg, MppCfgApi *api, void *val);
|
||||
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 */
|
||||
RK_S32 flag_offset;
|
||||
RK_U32 flag_value;
|
||||
/* 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[];
|
||||
} MppCfgInfoNode;
|
||||
|
||||
typedef MPP_RET (*CfgSetS32)(MppCfgInfoNode *info, void *cfg, RK_S32 val);
|
||||
typedef MPP_RET (*CfgGetS32)(MppCfgInfoNode *info, void *cfg, RK_S32 *val);
|
||||
typedef MPP_RET (*CfgSetU32)(MppCfgInfoNode *info, void *cfg, RK_U32 val);
|
||||
typedef MPP_RET (*CfgGetU32)(MppCfgInfoNode *info, void *cfg, RK_U32 *val);
|
||||
typedef MPP_RET (*CfgSetS64)(MppCfgInfoNode *info, void *cfg, RK_S64 val);
|
||||
typedef MPP_RET (*CfgGetS64)(MppCfgInfoNode *info, void *cfg, RK_S64 *val);
|
||||
typedef MPP_RET (*CfgSetU64)(MppCfgInfoNode *info, void *cfg, RK_U64 val);
|
||||
typedef MPP_RET (*CfgGetU64)(MppCfgInfoNode *info, void *cfg, RK_U64 *val);
|
||||
typedef MPP_RET (*CfgSetSt) (MppCfgInfoNode *info, void *cfg, void *val);
|
||||
typedef MPP_RET (*CfgGetSt) (MppCfgInfoNode *info, void *cfg, void *val);
|
||||
typedef MPP_RET (*CfgSetPtr)(MppCfgInfoNode *info, void *cfg, void *val);
|
||||
typedef MPP_RET (*CfgGetPtr)(MppCfgInfoNode *info, void *cfg, void **val);
|
||||
|
||||
#define MPP_CFG_SET_S32(info, cfg, val) (mpp_cfg_ops.fp_SetS32)(info, cfg, val)
|
||||
#define MPP_CFG_GET_S32(info, cfg, val) (mpp_cfg_ops.fp_GetS32)(info, cfg, (RK_S32 *)(val))
|
||||
#define MPP_CFG_SET_U32(info, cfg, val) (mpp_cfg_ops.fp_SetU32)(info, cfg, val)
|
||||
#define MPP_CFG_GET_U32(info, cfg, val) (mpp_cfg_ops.fp_GetU32)(info, cfg, (RK_U32 *)(val))
|
||||
#define MPP_CFG_SET_S64(info, cfg, val) (mpp_cfg_ops.fp_SetS64)(info, cfg, val)
|
||||
#define MPP_CFG_GET_S64(info, cfg, val) (mpp_cfg_ops.fp_GetS64)(info, cfg, (RK_S64 *)(val))
|
||||
#define MPP_CFG_SET_U64(info, cfg, val) (mpp_cfg_ops.fp_SetU64)(info, cfg, val)
|
||||
#define MPP_CFG_GET_U64(info, cfg, val) (mpp_cfg_ops.fp_GetU64)(info, cfg, (RK_U64 *)(val))
|
||||
#define MPP_CFG_SET_St(info, cfg, val) (mpp_cfg_ops.fp_SetSt )(info, cfg, val)
|
||||
#define MPP_CFG_GET_St(info, cfg, val) (mpp_cfg_ops.fp_GetSt )(info, cfg, (void *)(val))
|
||||
#define MPP_CFG_SET_Ptr(info, cfg, val) (mpp_cfg_ops.fp_SetPtr)(info, cfg, val)
|
||||
#define MPP_CFG_GET_Ptr(info, cfg, val) (mpp_cfg_ops.fp_GetPtr)(info, cfg, (void **)(val))
|
||||
|
||||
/* header size 128 byte */
|
||||
typedef struct MppCfgInfoHead_t {
|
||||
char version[112];
|
||||
RK_S32 info_size;
|
||||
RK_S32 info_count;
|
||||
RK_S32 node_count;
|
||||
RK_S32 cfg_size;
|
||||
} MppCfgInfoHead;
|
||||
|
||||
typedef struct MppCfgOps_t {
|
||||
CfgSetS32 fp_SetS32;
|
||||
CfgGetS32 fp_GetS32;
|
||||
CfgSetU32 fp_SetU32;
|
||||
CfgGetU32 fp_GetU32;
|
||||
CfgSetS64 fp_SetS64;
|
||||
CfgGetS64 fp_GetS64;
|
||||
CfgSetU64 fp_SetU64;
|
||||
CfgGetU64 fp_GetU64;
|
||||
CfgSetSt fp_SetSt;
|
||||
CfgGetSt fp_GetSt;
|
||||
CfgSetPtr fp_SetPtr;
|
||||
CfgGetPtr fp_GetPtr;
|
||||
} MppCfgOps;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const char *cfg_type_names[];
|
||||
MPP_RET check_cfg_api_info(MppCfgApi *api, CfgType type);
|
||||
|
||||
extern MppCfgOps mpp_cfg_ops;
|
||||
MPP_RET mpp_cfg_node_fixup_func(MppCfgInfoNode *node);
|
||||
|
||||
#define CHECK_CFG_INFO(node, name, type) \
|
||||
check_cfg_info(node, name, type, __FUNCTION__)
|
||||
|
||||
MPP_RET check_cfg_info(MppCfgInfoNode *node, const char *name, CfgType type,
|
||||
const char *func);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Reference in New Issue
Block a user