mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-23 01:00:31 +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 {
|
typedef struct MppEncCfgImpl_t {
|
||||||
RK_S32 size;
|
RK_S32 size;
|
||||||
MppTrie api;
|
|
||||||
MppEncCfgSet cfg;
|
MppEncCfgSet cfg;
|
||||||
} MppEncCfgImpl;
|
} MppEncCfgImpl;
|
||||||
|
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#define MODULE_TAG "mpp_cfg"
|
#define MODULE_TAG "mpp_cfg"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "mpp_log.h"
|
#include "mpp_log.h"
|
||||||
#include "mpp_cfg.h"
|
#include "mpp_cfg.h"
|
||||||
|
|
||||||
@@ -28,52 +30,161 @@ const char *cfg_type_names[] = {
|
|||||||
"struct",
|
"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,
|
mpp_err("%s cfg %s expect %s input NOT %s\n", func, node->name,
|
||||||
cfg_type_names[api->info.type],
|
cfg_type_names[node->data_type],
|
||||||
cfg_type_names[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;
|
if (memcmp((char *)cfg + info->data_offset, val, info->data_size)) {
|
||||||
RK_S32 cfg_size = api->info.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;
|
MPP_RET ret = MPP_OK;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CFG_FUNC_TYPE_St : {
|
case CFG_FUNC_TYPE_St : {
|
||||||
if (cfg_type != type) {
|
if (cfg_type != type) {
|
||||||
show_api_type_err(api, type);
|
show_cfg_info_err(node, type, func);
|
||||||
ret = MPP_NOK;
|
ret = MPP_NOK;
|
||||||
}
|
}
|
||||||
if (cfg_size <= 0) {
|
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;
|
ret = MPP_NOK;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CFG_FUNC_TYPE_Ptr : {
|
case CFG_FUNC_TYPE_Ptr : {
|
||||||
if (cfg_type != type) {
|
if (cfg_type != type) {
|
||||||
show_api_type_err(api, type);
|
show_cfg_info_err(node, type, func);
|
||||||
ret = MPP_NOK;
|
ret = MPP_NOK;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CFG_FUNC_TYPE_S32 :
|
case CFG_FUNC_TYPE_S32 :
|
||||||
case CFG_FUNC_TYPE_U32 : {
|
case CFG_FUNC_TYPE_U32 : {
|
||||||
if (cfg_size != sizeof(RK_S32)) {
|
if (cfg_size != sizeof(RK_S32)) {
|
||||||
show_api_type_err(api, type);
|
show_cfg_info_err(node, type, func);
|
||||||
ret = MPP_NOK;
|
ret = MPP_NOK;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case CFG_FUNC_TYPE_S64 :
|
case CFG_FUNC_TYPE_S64 :
|
||||||
case CFG_FUNC_TYPE_U64 : {
|
case CFG_FUNC_TYPE_U64 : {
|
||||||
if (cfg_size != sizeof(RK_S64)) {
|
if (cfg_size != sizeof(RK_S64)) {
|
||||||
show_api_type_err(api, type);
|
show_cfg_info_err(node, type, func);
|
||||||
ret = MPP_NOK;
|
ret = MPP_NOK;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
default : {
|
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;
|
ret = MPP_NOK;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@@ -44,73 +44,84 @@
|
|||||||
|
|
||||||
RK_U32 mpp_enc_cfg_debug = 0;
|
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) \
|
* MppEncCfgInfo data struct
|
||||||
{ \
|
*
|
||||||
char *base = (char *)cfg; \
|
* +----------+
|
||||||
CfgDataInfo *info = &api->info; \
|
* | head |
|
||||||
CfgDataInfo *update = &api->update; \
|
* +----------+
|
||||||
\
|
* | trie |
|
||||||
mpp_enc_cfg_dbg_func("enter\n"); \
|
* | node |
|
||||||
switch (CFG_FUNC_TYPE_##cfg_type) { \
|
* | .... |
|
||||||
case CFG_FUNC_TYPE_S32 : \
|
* +----------+
|
||||||
case CFG_FUNC_TYPE_U32 : \
|
* | info |
|
||||||
case CFG_FUNC_TYPE_S64 : \
|
* | node |
|
||||||
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; \
|
typedef struct MppEncCfgInfo_t {
|
||||||
} \
|
MppCfgInfoHead head;
|
||||||
} break; \
|
MppTrieNode trie_node[];
|
||||||
case CFG_FUNC_TYPE_Ptr : { \
|
/* MppCfgInfoNode is following trie_node */
|
||||||
memcpy(base + info->offset, &name, info->size); \
|
} MppEncCfgInfo;
|
||||||
*((RK_U32 *)(base + update->offset)) |= flag; \
|
|
||||||
} break; \
|
static MppCfgInfoNode *mpp_enc_cfg_find(MppEncCfgInfo *info, const char *name)
|
||||||
case CFG_FUNC_TYPE_St : { \
|
{
|
||||||
if (memcmp(base + info->offset, (void *)((long)name), info->size)) { \
|
MppTrieNode *node;
|
||||||
memcpy(base + info->offset, (void *)((long)name), info->size); \
|
|
||||||
*((RK_U32 *)(base + update->offset)) |= flag; \
|
if (NULL == info || NULL == name)
|
||||||
} \
|
return NULL;
|
||||||
} break; \
|
|
||||||
default : { \
|
node = mpp_trie_get_node(info->trie_node, name);
|
||||||
} break; \
|
if (NULL == node)
|
||||||
} \
|
return NULL;
|
||||||
return MPP_OK; \
|
|
||||||
} \
|
return (MppCfgInfoNode *)(((char *)info->trie_node) + node->id);
|
||||||
MPP_RET get_##base##_##name(void *cfg, MppCfgApi *api, in_type *name) \
|
}
|
||||||
{ \
|
|
||||||
char *base = (char *)cfg; \
|
class MppEncCfgService
|
||||||
CfgDataInfo *info = &api->info; \
|
{
|
||||||
\
|
private:
|
||||||
mpp_enc_cfg_dbg_func("enter\n"); \
|
MppEncCfgService();
|
||||||
memcpy(name, base + info->offset, info->size); \
|
~MppEncCfgService();
|
||||||
return MPP_OK; \
|
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) \
|
#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, \
|
#base":"#name, \
|
||||||
{ \
|
|
||||||
CFG_FUNC_TYPE_##cfg_type, \
|
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)), \
|
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.change)), \
|
||||||
}, \
|
flag, \
|
||||||
(void *)set_##base##_##name, \
|
(RK_U32)((long)&(((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||||
(void *)get_##base##_##name, \
|
sizeof((((MppEncCfgSet *)0)->field_change.field_data)), \
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \
|
#define EXPAND_AS_ARRAY(base, name, cfg_type, in_type, flag, field_change, field_data) \
|
||||||
&api_##base##_##name,
|
&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) \
|
#define ENTRY_TABLE(ENTRY) \
|
||||||
/* base config */ \
|
/* base config */ \
|
||||||
ENTRY(base, low_delay, S32, RK_S32, MPP_ENC_BASE_CFG_CHANGE_LOW_DELAY, base, low_delay) \
|
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, 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(hw, mb_rc_disable, S32, RK_S32, MPP_ENC_HW_CFG_CHANGE_MB_RC, hw, mb_rc_disable)
|
||||||
|
|
||||||
ENTRY_TABLE(EXPAND_AS_FUNC)
|
static MppEncCfgInfo *mpp_enc_cfg_flaten(MppTrie trie, MppCfgApi **cfgs)
|
||||||
ENTRY_TABLE(EXPAND_AS_API)
|
|
||||||
|
|
||||||
static MppCfgApi *cfg_apis[] = {
|
|
||||||
ENTRY_TABLE(EXPAND_AS_ARRAY)
|
|
||||||
};
|
|
||||||
|
|
||||||
RK_S32 const_strlen(const char* str)
|
|
||||||
{
|
{
|
||||||
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() :
|
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;
|
MPP_RET ret;
|
||||||
RK_S32 i;
|
RK_S32 i;
|
||||||
RK_S32 api_cnt = MPP_ARRAY_ELEMS(cfg_apis);
|
|
||||||
|
|
||||||
/*
|
ret = mpp_trie_init(&trie, 1526, cfg_cnt);
|
||||||
* 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);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mpp_err_f("failed to init enc cfg set trie\n");
|
mpp_err_f("failed to init enc cfg set trie\n");
|
||||||
} else {
|
return ;
|
||||||
for (i = 0; i < api_cnt; i++)
|
|
||||||
mpp_trie_add_info(mCfgApi, &cfg_apis[i]->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node_len < mpp_trie_get_node_count(mCfgApi))
|
for (i = 0; i < cfg_cnt; i++)
|
||||||
mpp_err_f("create info %d with not enough node %d -> %d info\n",
|
mpp_trie_add_info(trie, &cfgs[i]->name);
|
||||||
api_cnt, node_len, mpp_trie_get_node_count(mCfgApi));
|
|
||||||
|
mInfo = mpp_enc_cfg_flaten(trie, cfgs);
|
||||||
|
mCfgSize = mInfo->head.cfg_size;
|
||||||
|
|
||||||
|
mpp_trie_deinit(trie);
|
||||||
}
|
}
|
||||||
|
|
||||||
MppEncCfgService::~MppEncCfgService()
|
MppEncCfgService::~MppEncCfgService()
|
||||||
{
|
{
|
||||||
if (mCfgApi) {
|
MPP_FREE(mInfo);
|
||||||
mpp_trie_deinit(mCfgApi);
|
}
|
||||||
mCfgApi = NULL;
|
|
||||||
}
|
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)
|
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)
|
MPP_RET mpp_enc_cfg_init(MppEncCfg *cfg)
|
||||||
{
|
{
|
||||||
MppEncCfgImpl *p = NULL;
|
MppEncCfgImpl *p = NULL;
|
||||||
|
RK_S32 cfg_size;
|
||||||
|
|
||||||
if (NULL == cfg) {
|
if (NULL == cfg) {
|
||||||
mpp_err_f("invalid NULL input config\n");
|
mpp_err_f("invalid NULL input config\n");
|
||||||
return MPP_ERR_NULL_PTR;
|
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) {
|
if (NULL == p) {
|
||||||
mpp_err_f("create encoder config failed %p\n", p);
|
mpp_err_f("create encoder config failed %p\n", p);
|
||||||
*cfg = NULL;
|
*cfg = NULL;
|
||||||
return MPP_ERR_NOMEM;
|
return MPP_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->size = sizeof(*p);
|
mpp_assert(cfg_size == sizeof(p->cfg));
|
||||||
p->api = MppEncCfgService::get()->get_api();
|
p->size = cfg_size;
|
||||||
mpp_enc_cfg_set_default(&p->cfg);
|
mpp_enc_cfg_set_default(&p->cfg);
|
||||||
|
|
||||||
mpp_env_get_u32("mpp_enc_cfg_debug", &mpp_enc_cfg_debug, 0);
|
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; \
|
return MPP_ERR_NULL_PTR; \
|
||||||
} \
|
} \
|
||||||
MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
|
MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
|
||||||
const char **info = mpp_trie_get_info(p->api, name); \
|
MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \
|
||||||
if (NULL == info) { \
|
if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||||
mpp_err_f("failed to set %s to %d\n", name, val); \
|
|
||||||
return MPP_NOK; \
|
return MPP_NOK; \
|
||||||
} \
|
} \
|
||||||
MppCfgApi *api = (MppCfgApi *)info; \
|
mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \
|
||||||
if (check_cfg_api_info(api, CFG_FUNC_TYPE_##cfg_type)) { \
|
MPP_RET ret = MPP_CFG_SET_##cfg_type(info, &p->cfg, val); \
|
||||||
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); \
|
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,17 +458,12 @@ ENC_CFG_SET_ACCESS(mpp_enc_cfg_set_st, void *, St);
|
|||||||
return MPP_ERR_NULL_PTR; \
|
return MPP_ERR_NULL_PTR; \
|
||||||
} \
|
} \
|
||||||
MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
|
MppEncCfgImpl *p = (MppEncCfgImpl *)cfg; \
|
||||||
const char **info = mpp_trie_get_info(p->api, name); \
|
MppCfgInfoNode *info = MppEncCfgService::get()->get_info(name); \
|
||||||
if (NULL == info) { \
|
if (CHECK_CFG_INFO(info, name, CFG_FUNC_TYPE_##cfg_type)) { \
|
||||||
mpp_err_f("failed to set %s to %d\n", name, val); \
|
|
||||||
return MPP_NOK; \
|
return MPP_NOK; \
|
||||||
} \
|
} \
|
||||||
MppCfgApi *api = (MppCfgApi *)info; \
|
mpp_enc_cfg_dbg_set("name %s type %s\n", info->name, cfg_type_names[info->data_type]); \
|
||||||
if (check_cfg_api_info(api, CFG_FUNC_TYPE_##cfg_type)) { \
|
MPP_RET ret = MPP_CFG_GET_##cfg_type(info, &p->cfg, val); \
|
||||||
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); \
|
|
||||||
return ret; \
|
return ret; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,17 +476,28 @@ ENC_CFG_GET_ACCESS(mpp_enc_cfg_get_st, void , St);
|
|||||||
|
|
||||||
void mpp_enc_cfg_show(void)
|
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");
|
mpp_log("dumping valid configure string start\n");
|
||||||
|
|
||||||
for (i = 0; i < MPP_ARRAY_ELEMS(cfg_apis); i++)
|
if (info) {
|
||||||
mpp_log("%-25s type %s\n", cfg_apis[i]->name,
|
char *p = (char *)info;
|
||||||
cfg_type_names[cfg_apis[i]->info.type]);
|
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("dumping valid configure string done\n");
|
||||||
|
|
||||||
mpp_log("total api count %d with node %d -> %d info\n",
|
mpp_log("total cfg count %d with %d node size %d\n",
|
||||||
MPP_ARRAY_ELEMS(cfg_apis), node_len,
|
info_count, node_count,
|
||||||
mpp_trie_get_node_count(MppEncCfgService::get()->get_api()));
|
MppEncCfgService::get()->get_info_size());
|
||||||
}
|
}
|
||||||
|
@@ -25,44 +25,106 @@ typedef enum CfgType_e {
|
|||||||
CFG_FUNC_TYPE_U32,
|
CFG_FUNC_TYPE_U32,
|
||||||
CFG_FUNC_TYPE_S64,
|
CFG_FUNC_TYPE_S64,
|
||||||
CFG_FUNC_TYPE_U64,
|
CFG_FUNC_TYPE_U64,
|
||||||
CFG_FUNC_TYPE_Ptr,
|
|
||||||
CFG_FUNC_TYPE_St,
|
CFG_FUNC_TYPE_St,
|
||||||
|
CFG_FUNC_TYPE_Ptr,
|
||||||
CFG_FUNC_TYPE_BUTT,
|
CFG_FUNC_TYPE_BUTT,
|
||||||
} CfgType;
|
} CfgType;
|
||||||
|
|
||||||
typedef struct CfgDataInfo_s {
|
|
||||||
CfgType type : 4;
|
|
||||||
RK_U32 size : 12;
|
|
||||||
RK_U32 offset : 16;
|
|
||||||
} CfgDataInfo;
|
|
||||||
|
|
||||||
typedef struct MppCfgApi_t {
|
typedef struct MppCfgApi_t {
|
||||||
const char *name;
|
const char *name;
|
||||||
CfgDataInfo info;
|
CfgType data_type;
|
||||||
CfgDataInfo update;
|
RK_S32 flag_offset;
|
||||||
void *api_set;
|
RK_U32 flag_value;
|
||||||
void *api_get;
|
RK_S32 data_offset;
|
||||||
|
RK_S32 data_size;
|
||||||
} MppCfgApi;
|
} MppCfgApi;
|
||||||
|
|
||||||
typedef MPP_RET (*CfgSetS32)(void *cfg, MppCfgApi *api, RK_S32 val);
|
typedef struct MppCfgInfo_t {
|
||||||
typedef MPP_RET (*CfgGetS32)(void *cfg, MppCfgApi *api, RK_S32 *val);
|
/* size for the whole node including name */
|
||||||
typedef MPP_RET (*CfgSetU32)(void *cfg, MppCfgApi *api, RK_U32 val);
|
RK_S32 node_size;
|
||||||
typedef MPP_RET (*CfgGetU32)(void *cfg, MppCfgApi *api, RK_U32 *val);
|
RK_U32 name_len;
|
||||||
typedef MPP_RET (*CfgSetS64)(void *cfg, MppCfgApi *api, RK_S64 val);
|
/* CfgType */
|
||||||
typedef MPP_RET (*CfgGetS64)(void *cfg, MppCfgApi *api, RK_S64 *val);
|
RK_S32 data_type;
|
||||||
typedef MPP_RET (*CfgSetU64)(void *cfg, MppCfgApi *api, RK_U64 val);
|
/* update flag info 32bit */
|
||||||
typedef MPP_RET (*CfgGetU64)(void *cfg, MppCfgApi *api, RK_U64 *val);
|
RK_S32 flag_offset;
|
||||||
typedef MPP_RET (*CfgSetPtr)(void *cfg, MppCfgApi *api, void *val);
|
RK_U32 flag_value;
|
||||||
typedef MPP_RET (*CfgGetPtr)(void *cfg, MppCfgApi *api, void **val);
|
/* data access info */
|
||||||
typedef MPP_RET (*CfgSetSt) (void *cfg, MppCfgApi *api, void *val);
|
RK_S32 data_offset;
|
||||||
typedef MPP_RET (*CfgGetSt) (void *cfg, MppCfgApi *api, void *val);
|
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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const char *cfg_type_names[];
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user