From db6ce4fb76a841a2754d3b05707b2c95e7cae65e Mon Sep 17 00:00:00 2001 From: Hongjin Li Date: Tue, 10 Jun 2025 09:29:07 +0800 Subject: [PATCH] refactor[base]: Refactor C++ mpp_meta to C Signed-off-by: Chandler Chen Signed-off-by: Hongjin Li Signed-off-by: Herman Chen Change-Id: Ice500e67c4d2a4faa75873f73e537fd9659fffe8 --- inc/mpp_meta.h | 15 +- mpp/base/CMakeLists.txt | 2 +- mpp/base/mpp_meta.c | 500 ++++++++++++++++++++++++++++++++++ mpp/base/mpp_meta.cpp | 378 ------------------------- mpp/base/test/mpp_meta_test.c | 173 ++++++------ 5 files changed, 597 insertions(+), 471 deletions(-) create mode 100644 mpp/base/mpp_meta.c delete mode 100644 mpp/base/mpp_meta.cpp diff --git a/inc/mpp_meta.h b/inc/mpp_meta.h index 71e00cc8..63d313db 100644 --- a/inc/mpp_meta.h +++ b/inc/mpp_meta.h @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. */ #ifndef __MPP_META_H__ diff --git a/mpp/base/CMakeLists.txt b/mpp/base/CMakeLists.txt index 0d94ac61..b710019e 100644 --- a/mpp/base/CMakeLists.txt +++ b/mpp/base/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(mpp_base OBJECT mpp_frame.c mpp_task_impl.cpp mpp_task.cpp - mpp_meta.cpp + mpp_meta.c mpp_trie.c mpp_bitwrite.c mpp_bitread.c diff --git a/mpp/base/mpp_meta.c b/mpp/base/mpp_meta.c new file mode 100644 index 00000000..a13649e4 --- /dev/null +++ b/mpp/base/mpp_meta.c @@ -0,0 +1,500 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2015 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "mpp_meta" + +#include +#include + +#include "mpp_env.h" +#include "mpp_lock.h" +#include "mpp_debug.h" +#include "mpp_mem_pool.h" +#include "mpp_singleton.h" + +#include "mpp_trie.h" +#include "mpp_meta_impl.h" + +#define META_DBG_FLOW (0x00000001) +#define META_DBG_KEYS (0x00000002) + +#define meta_dbg(flag, fmt, ...) _mpp_dbg(mpp_meta_debug, flag, fmt, ## __VA_ARGS__) +#define meta_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_meta_debug, flag, fmt, ## __VA_ARGS__) + +#define meta_dbg_flow(fmt, ...) meta_dbg(META_DBG_FLOW, fmt, ## __VA_ARGS__) + +#define META_VAL_INVALID (0x00000000) +#define META_VAL_VALID (0x00000001) +#define META_VAL_READY (0x00000002) + +#define WRITE_ONCE(x, val) ((*(volatile typeof(x) *) &(x)) = (val)) +#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) + +#define get_srv_meta(caller) \ + ({ \ + MppMetaSrv *__tmp; \ + if (srv_meta || srv_finalized) { \ + __tmp = srv_meta; \ + } else { \ + mpp_meta_srv_init(); \ + __tmp = srv_meta; \ + if (!__tmp) { \ + mpp_err("mpp meta srv not init at %s : %s\n", __FUNCTION__, caller); \ + } \ + } \ + __tmp; \ + }) + +#define get_srv_meta_f() \ + ({ \ + MppMetaSrv *__tmp; \ + if (srv_meta || srv_finalized) { \ + __tmp = srv_meta; \ + } else { \ + mpp_meta_srv_init(); \ + __tmp = srv_meta; \ + if (!__tmp) { \ + mpp_err("mpp meta srv not init at %s\n", __FUNCTION__); \ + } \ + } \ + __tmp; \ + }) + +typedef enum MppMetaDataType_e { + /* mpp meta data of normal data type */ + TYPE_VAL_32 = '3', + TYPE_VAL_64 = '6', + TYPE_KPTR = 'k', + TYPE_UPTR = 'u', + TYPE_SPTR = 's', +} MppMetaType; + +static inline RK_U64 META_KEY_TO_U64(RK_U32 key, RK_U32 type) +{ + return (RK_U64)((RK_U32)htobe32(key)) | ((RK_U64)type << 32); +} + +#define EXPAND_AS_TRIE(key, type) \ + do { \ + RK_U64 val = META_KEY_TO_U64(key, type); \ + mpp_trie_add_info(srv->trie, (const char *)&val, NULL, 0); \ + meta_key_count++; \ + } while (0); + +#define EXPAND_AS_LOG(key, type) \ + do { \ + RK_U32 key_val = htobe32(key); \ + char *str = (char *)&key_val; \ + mpp_logi("%2d - %-24s (%c%c%c%c) : %-12s\n", \ + i++, #key, str[0], str[1], str[2], str[3], #type); \ + } while (0); + +#define META_ENTRY_TABLE(ENTRY) \ + /* categorized by type */ \ + /* data flow type */ \ + ENTRY(KEY_INPUT_FRAME, TYPE_SPTR) \ + ENTRY(KEY_OUTPUT_FRAME, TYPE_SPTR) \ + ENTRY(KEY_INPUT_PACKET, TYPE_SPTR) \ + ENTRY(KEY_OUTPUT_PACKET, TYPE_SPTR) \ + /* buffer for motion detection */ \ + ENTRY(KEY_MOTION_INFO, TYPE_SPTR) \ + /* buffer storing the HDR information for current frame*/ \ + ENTRY(KEY_HDR_INFO, TYPE_SPTR) \ + /* the offset of HDR meta data in frame buffer */ \ + ENTRY(KEY_HDR_META_OFFSET, TYPE_VAL_32) \ + ENTRY(KEY_HDR_META_SIZE, TYPE_VAL_32) \ + \ + ENTRY(KEY_OUTPUT_INTRA, TYPE_VAL_32) \ + ENTRY(KEY_INPUT_BLOCK, TYPE_VAL_32) \ + ENTRY(KEY_OUTPUT_BLOCK, TYPE_VAL_32) \ + ENTRY(KEY_INPUT_IDR_REQ, TYPE_VAL_32) \ + \ + /* extra information for tsvc */ \ + ENTRY(KEY_TEMPORAL_ID, TYPE_VAL_32) \ + ENTRY(KEY_LONG_REF_IDX, TYPE_VAL_32) \ + ENTRY(KEY_ENC_AVERAGE_QP, TYPE_VAL_32) \ + ENTRY(KEY_ENC_START_QP, TYPE_VAL_32) \ + ENTRY(KEY_ENC_BPS_RT, TYPE_VAL_32) \ + \ + ENTRY(KEY_ROI_DATA, TYPE_UPTR) \ + ENTRY(KEY_ROI_DATA2, TYPE_UPTR) \ + ENTRY(KEY_OSD_DATA, TYPE_UPTR) \ + ENTRY(KEY_OSD_DATA2, TYPE_UPTR) \ + ENTRY(KEY_OSD_DATA3, TYPE_UPTR) \ + ENTRY(KEY_USER_DATA, TYPE_UPTR) \ + ENTRY(KEY_USER_DATAS, TYPE_UPTR) \ + ENTRY(KEY_QPMAP0, TYPE_SPTR) \ + ENTRY(KEY_MV_LIST, TYPE_UPTR) \ + \ + ENTRY(KEY_LVL64_INTER_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL32_INTER_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL16_INTER_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL8_INTER_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL32_INTRA_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL16_INTRA_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL8_INTRA_NUM, TYPE_VAL_32) \ + ENTRY(KEY_LVL4_INTRA_NUM, TYPE_VAL_32) \ + ENTRY(KEY_INPUT_PSKIP, TYPE_VAL_32) \ + ENTRY(KEY_OUTPUT_PSKIP, TYPE_VAL_32) \ + ENTRY(KEY_INPUT_PSKIP_NON_REF, TYPE_VAL_32) \ + ENTRY(KEY_ENC_SSE, TYPE_VAL_64) \ + \ + ENTRY(KEY_ENC_MARK_LTR, TYPE_VAL_32) \ + ENTRY(KEY_ENC_USE_LTR, TYPE_VAL_32) \ + ENTRY(KEY_ENC_FRAME_QP, TYPE_VAL_32) \ + ENTRY(KEY_ENC_BASE_LAYER_PID, TYPE_VAL_32) \ + \ + ENTRY(KEY_DEC_TBN_EN, TYPE_VAL_32) \ + ENTRY(KEY_DEC_TBN_Y_OFFSET, TYPE_VAL_32) \ + ENTRY(KEY_DEC_TBN_UV_OFFSET, TYPE_VAL_32) + +typedef struct MppMetaSrv_t { + spinlock_t lock; + struct list_head list_meta; + MppTrie trie; + + RK_U32 meta_id; + RK_S32 meta_count; +} MppMetaSrv; + +static MppMetaSrv *srv_meta = NULL; +static MppMemPool pool_meta = NULL; +static RK_U32 srv_finalized = 0; +static RK_U32 meta_key_count = 0; +static RK_U32 mpp_meta_debug = 0; + +static void put_meta(MppMetaSrv *srv, MppMetaImpl *meta); + +static void mpp_meta_srv_init() +{ + MppMetaSrv *srv = srv_meta; + + mpp_env_get_u32("mpp_meta_debug", &mpp_meta_debug, 0); + + if (srv) + return; + + srv = mpp_calloc(MppMetaSrv, 1); + if (!srv) { + mpp_err_f("failed to malloc meta service\n"); + return; + } + + srv_meta = srv; + + mpp_spinlock_init(&srv->lock); + INIT_LIST_HEAD(&srv->list_meta); + + mpp_trie_init(&srv->trie, "MppMetaDef"); + if (srv->trie) { + meta_key_count = 0; + META_ENTRY_TABLE(EXPAND_AS_TRIE) + mpp_trie_add_info(srv->trie, NULL, NULL, 0); + } + + pool_meta = mpp_mem_pool_init_f("MppMeta", sizeof(MppMetaImpl) + + sizeof(MppMetaVal) * meta_key_count); + + meta_dbg_flow("meta key count %d\n", meta_key_count); + if (mpp_meta_debug & META_DBG_KEYS) { + RK_S32 i = 0; + + META_ENTRY_TABLE(EXPAND_AS_LOG) + } +} + +static void mpp_meta_srv_deinit() +{ + MppMetaSrv *srv = srv_meta; + + if (!srv) + return; + + if (!list_empty(&srv->list_meta)) { + MppMetaImpl *pos, *n; + + mpp_log_f("cleaning leaked metadata\n"); + + list_for_each_entry_safe(pos, n, &srv->list_meta, MppMetaImpl, list_meta) { + put_meta(srv, pos); + } + } + + mpp_assert(srv->meta_count == 0); + + if (srv->trie) { + mpp_trie_deinit(srv->trie); + srv->trie = NULL; + } + + MPP_FREE(srv_meta); + + if (pool_meta) { + mpp_mem_pool_deinit_f(pool_meta); + pool_meta = NULL; + } + + srv_finalized = 1; + + meta_dbg_flow("meta srv deinited\n"); +} + +MPP_SINGLETON(MPP_SGLN_META, mpp_meta, mpp_meta_srv_init, mpp_meta_srv_deinit) + +static inline RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type, const char *caller) +{ + MppMetaSrv *srv = get_srv_meta(caller); + MppTrieInfo *info = NULL; + + if (srv) { + RK_U64 val = META_KEY_TO_U64(key, type); + + info = mpp_trie_get_info(srv->trie, (const char *)&val); + } + + return info ? info->index : -1; +} + +#define get_index_of_key_f(key, type) get_index_of_key(key, type, __FUNCTION__) + +static MppMetaImpl *get_meta(MppMetaSrv *srv, const char *tag, const char *caller) +{ + MppMetaImpl *impl = (MppMetaImpl *)mpp_mem_pool_get(pool_meta, caller); + + if (impl) { + const char *tag_src = (tag) ? (tag) : (MODULE_TAG); + RK_U32 i; + + strncpy(impl->tag, tag_src, sizeof(impl->tag) - 1); + impl->caller = caller; + impl->meta_id = MPP_FETCH_ADD(&srv->meta_id, 1); + INIT_LIST_HEAD(&impl->list_meta); + impl->ref_count = 1; + impl->node_count = 0; + + for (i = 0; i < meta_key_count; i++) + impl->vals[i].state = 0; + + mpp_spinlock_lock(&srv->lock); + list_add_tail(&impl->list_meta, &srv->list_meta); + mpp_spinlock_unlock(&srv->lock); + MPP_FETCH_ADD(&srv->meta_count, 1); + } else { + mpp_err_f("failed to malloc meta data\n"); + } + + return impl; +} + +static void put_meta(MppMetaSrv *srv, MppMetaImpl *meta) +{ + RK_S32 ref_count; + + if (!srv) + return; + + ref_count = MPP_SUB_FETCH(&meta->ref_count, 1); + if (ref_count > 0) + return; + + if (ref_count < 0) { + mpp_err_f("invalid negative ref_count %d\n", ref_count); + return; + } + + mpp_spinlock_lock(&srv->lock); + list_del_init(&meta->list_meta); + mpp_spinlock_unlock(&srv->lock); + MPP_FETCH_SUB(&srv->meta_count, 1); + + if (pool_meta) + mpp_mem_pool_put_f(pool_meta, meta); +} + +MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller) +{ + MppMetaSrv *srv = get_srv_meta(caller); + MppMetaImpl *impl; + + if (!srv) + return MPP_NOK; + + if (!meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + impl = get_meta(srv, tag, caller); + *meta = (MppMeta) impl; + return (impl) ? (MPP_OK) : (MPP_NOK); +} + +MPP_RET mpp_meta_put(MppMeta meta) +{ + MppMetaImpl *impl = (MppMetaImpl *)meta; + + if (!impl) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + put_meta(get_srv_meta_f(), impl); + return MPP_OK; +} + +MPP_RET mpp_meta_inc_ref(MppMeta meta) +{ + MppMetaImpl *impl = (MppMetaImpl *)meta; + + if (!impl) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MPP_FETCH_ADD(&impl->ref_count, 1); + return MPP_OK; +} + +RK_S32 mpp_meta_size(MppMeta meta) +{ + MppMetaImpl *impl = (MppMetaImpl *)meta; + + if (!impl) { + mpp_err_f("found NULL input\n"); + return -1; + } + + return MPP_FETCH_ADD(&impl->node_count, 0); +} + +MPP_RET mpp_meta_dump(MppMeta meta) +{ + MppMetaSrv *srv = get_srv_meta_f(); + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppTrieInfo *root; + + if (!impl) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + mpp_logi("dumping meta %d node count %d\n", impl->meta_id, impl->node_count); + + if (!srv || !srv->trie) + return MPP_NOK; + + root = mpp_trie_get_info_first(srv->trie); + if (root) { + MppTrieInfo *node = root; + const char *key = NULL; + char log_str[256]; + RK_S32 pos; + + do { + if (mpp_trie_info_is_self(node)) + continue; + + key = mpp_trie_info_name(node); + + pos = snprintf(log_str, sizeof(log_str) - 1, "key %c%c%c%c - ", + key[0], key[1], key[2], key[3]); + + switch (key[4]) { + case '3' : { + snprintf(log_str + pos, sizeof(log_str) - pos - 1, "s32 - %d", + impl->vals[node->index].val_s32); + } break; + case '6' : { + snprintf(log_str + pos, sizeof(log_str) - pos - 1, "s64 - %lld", + impl->vals[node->index].val_s64); + } break; + case 'k' : + case 'u' : + case 's' : { + snprintf(log_str + pos, sizeof(log_str) - pos - 1, "ptr - %p", + impl->vals[node->index].val_ptr); + } break; + default : { + } break; + } + + mpp_logi("%s\n", log_str); + } while ((node = mpp_trie_get_info_next(srv->trie, node))); + } + + return MPP_OK; +} + +#define MPP_META_ACCESSOR(func_type, arg_type, key_type, key_field) \ + MPP_RET mpp_meta_set_##func_type(MppMeta meta, MppMetaKey key, arg_type val) \ + { \ + MppMetaImpl *impl = (MppMetaImpl *)meta; \ + MppMetaVal *meta_val; \ + RK_S32 index; \ + if (!impl) { \ + mpp_err_f("found NULL input\n"); \ + return MPP_ERR_NULL_PTR; \ + } \ + index = get_index_of_key_f(key, key_type); \ + if (index < 0) \ + return MPP_NOK; \ + meta_val = &impl->vals[index]; \ + if (MPP_BOOL_CAS(&meta_val->state, META_VAL_INVALID, META_VAL_VALID)) \ + MPP_FETCH_ADD(&impl->node_count, 1); \ + meta_val->key_field = val; \ + MPP_FETCH_OR(&meta_val->state, META_VAL_READY); \ + return MPP_OK; \ + } \ + MPP_RET mpp_meta_get_##func_type(MppMeta meta, MppMetaKey key, arg_type *val) \ + { \ + MppMetaImpl *impl = (MppMetaImpl *)meta; \ + MppMetaVal *meta_val; \ + RK_S32 index; \ + MPP_RET ret = MPP_NOK; \ + if (!impl) { \ + mpp_err_f("found NULL input\n"); \ + return MPP_ERR_NULL_PTR; \ + } \ + index = get_index_of_key_f(key, key_type); \ + if (index < 0) \ + return MPP_NOK; \ + meta_val = &impl->vals[index]; \ + if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \ + *val = meta_val->key_field; \ + MPP_FETCH_SUB(&impl->node_count, 1); \ + ret = MPP_OK; \ + } \ + return ret; \ + } \ + MPP_RET mpp_meta_get_##func_type##_d(MppMeta meta, MppMetaKey key, arg_type *val, arg_type def) \ + { \ + MppMetaImpl *impl = (MppMetaImpl *)meta; \ + MppMetaVal *meta_val; \ + RK_S32 index; \ + MPP_RET ret = MPP_NOK; \ + if (!impl) { \ + mpp_err_f("found NULL input\n"); \ + return MPP_ERR_NULL_PTR; \ + } \ + index = get_index_of_key_f(key, key_type); \ + if (index < 0) \ + return MPP_NOK; \ + meta_val = &impl->vals[index]; \ + if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \ + *val = meta_val->key_field; \ + MPP_FETCH_SUB(&impl->node_count, 1); \ + ret = MPP_OK; \ + } else { \ + *val = def; \ + } \ + return ret; \ + } + +MPP_META_ACCESSOR(s32, RK_S32, TYPE_VAL_32, val_s32) +MPP_META_ACCESSOR(s64, RK_S64, TYPE_VAL_64, val_s64) +MPP_META_ACCESSOR(ptr, void *, TYPE_UPTR, val_ptr) +MPP_META_ACCESSOR(frame, MppFrame, TYPE_SPTR, frame) +MPP_META_ACCESSOR(packet, MppPacket, TYPE_SPTR, packet) +MPP_META_ACCESSOR(buffer, MppBuffer, TYPE_SPTR, buffer) diff --git a/mpp/base/mpp_meta.cpp b/mpp/base/mpp_meta.cpp deleted file mode 100644 index 3e90281d..00000000 --- a/mpp/base/mpp_meta.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_meta" - -#include -#include - -#include "mpp_mem.h" -#include "mpp_list.h" -#include "mpp_lock.h" -#include "mpp_debug.h" - -#include "mpp_meta_impl.h" -#include "mpp_trie.h" - -#define META_VAL_INVALID (0x00000000) -#define META_VAL_VALID (0x00000001) -#define META_VAL_READY (0x00000002) - -#define WRITE_ONCE(x, val) ((*(volatile typeof(x) *) &(x)) = (val)) -#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) - -typedef enum MppMetaDataType_e { - /* mpp meta data of normal data type */ - TYPE_VAL_32 = '3', - TYPE_VAL_64 = '6', - TYPE_KPTR = 'k', - TYPE_UPTR = 'u', - TYPE_SPTR = 's', -} MppMetaType; - -static inline RK_U64 META_KEY_TO_U64(RK_U32 key, RK_U32 type) -{ - return (RK_U64)((RK_U32)htobe32(key)) | ((RK_U64)type << 32); -} - -static RK_U64 meta_defs[] = { - /* categorized by type */ - /* data flow type */ - META_KEY_TO_U64(KEY_INPUT_FRAME, TYPE_SPTR), - META_KEY_TO_U64(KEY_OUTPUT_FRAME, TYPE_SPTR), - META_KEY_TO_U64(KEY_INPUT_PACKET, TYPE_SPTR), - META_KEY_TO_U64(KEY_OUTPUT_PACKET, TYPE_SPTR), - /* buffer for motion detection */ - META_KEY_TO_U64(KEY_MOTION_INFO, TYPE_SPTR), - /* buffer storing the HDR information for current frame*/ - META_KEY_TO_U64(KEY_HDR_INFO, TYPE_SPTR), - /* the offset of HDR meta data in frame buffer */ - META_KEY_TO_U64(KEY_HDR_META_OFFSET, TYPE_VAL_32), - META_KEY_TO_U64(KEY_HDR_META_SIZE, TYPE_VAL_32), - - META_KEY_TO_U64(KEY_OUTPUT_INTRA, TYPE_VAL_32), - META_KEY_TO_U64(KEY_INPUT_BLOCK, TYPE_VAL_32), - META_KEY_TO_U64(KEY_OUTPUT_BLOCK, TYPE_VAL_32), - META_KEY_TO_U64(KEY_INPUT_IDR_REQ, TYPE_VAL_32), - - /* extra information for tsvc */ - META_KEY_TO_U64(KEY_TEMPORAL_ID, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LONG_REF_IDX, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_AVERAGE_QP, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_START_QP, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_BPS_RT, TYPE_VAL_32), - - META_KEY_TO_U64(KEY_ROI_DATA, TYPE_UPTR), - META_KEY_TO_U64(KEY_ROI_DATA2, TYPE_UPTR), - META_KEY_TO_U64(KEY_OSD_DATA, TYPE_UPTR), - META_KEY_TO_U64(KEY_OSD_DATA2, TYPE_UPTR), - META_KEY_TO_U64(KEY_OSD_DATA3, TYPE_UPTR), - META_KEY_TO_U64(KEY_USER_DATA, TYPE_UPTR), - META_KEY_TO_U64(KEY_USER_DATAS, TYPE_UPTR), - META_KEY_TO_U64(KEY_QPMAP0, TYPE_SPTR), - META_KEY_TO_U64(KEY_MV_LIST, TYPE_UPTR), - - META_KEY_TO_U64(KEY_LVL64_INTER_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL32_INTER_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL16_INTER_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL8_INTER_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL32_INTRA_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL16_INTRA_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL8_INTRA_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_LVL4_INTRA_NUM, TYPE_VAL_32), - META_KEY_TO_U64(KEY_INPUT_PSKIP, TYPE_VAL_32), - META_KEY_TO_U64(KEY_OUTPUT_PSKIP, TYPE_VAL_32), - META_KEY_TO_U64(KEY_INPUT_PSKIP_NON_REF, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_SSE, TYPE_VAL_64), - - META_KEY_TO_U64(KEY_ENC_MARK_LTR, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_USE_LTR, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_FRAME_QP, TYPE_VAL_32), - META_KEY_TO_U64(KEY_ENC_BASE_LAYER_PID, TYPE_VAL_32), - - META_KEY_TO_U64(KEY_DEC_TBN_EN, TYPE_VAL_32), - META_KEY_TO_U64(KEY_DEC_TBN_Y_OFFSET, TYPE_VAL_32), - META_KEY_TO_U64(KEY_DEC_TBN_UV_OFFSET, TYPE_VAL_32), -}; - -class MppMetaService -{ -private: - // avoid any unwanted function - MppMetaService(); - ~MppMetaService(); - MppMetaService(const MppMetaService &); - MppMetaService &operator=(const MppMetaService &); - - spinlock_t mLock; - struct list_head mlist_meta; - MppTrie mTrie; - - RK_U32 meta_id; - RK_S32 meta_count; - RK_U32 finished; - -public: - static MppMetaService *get_inst() { - static MppMetaService instance; - return &instance; - } - - RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type); - - MppMetaImpl *get_meta(const char *tag, const char *caller); - void put_meta(MppMetaImpl *meta); -}; - -MppMetaService::MppMetaService() - : meta_id(0), - meta_count(0), - finished(0) -{ - RK_U32 i; - - mpp_spinlock_init(&mLock); - INIT_LIST_HEAD(&mlist_meta); - - mpp_trie_init(&mTrie, "MppMetaDef"); - for (i = 0; i < MPP_ARRAY_ELEMS(meta_defs); i++) { - mpp_trie_add_info(mTrie, (const char *)&meta_defs[i], NULL, 0); - } - mpp_trie_add_info(mTrie, NULL, NULL, 0); -} - -MppMetaService::~MppMetaService() -{ - if (!list_empty(&mlist_meta)) { - MppMetaImpl *pos, *n; - - mpp_log_f("cleaning leaked metadata\n"); - - list_for_each_entry_safe(pos, n, &mlist_meta, MppMetaImpl, list_meta) { - put_meta(pos); - } - } - - if (mTrie) { - mpp_trie_deinit(mTrie); - mTrie = NULL; - } - - mpp_assert(meta_count == 0); - finished = 1; -} - -RK_S32 MppMetaService::get_index_of_key(MppMetaKey key, MppMetaType type) -{ - RK_U64 val = META_KEY_TO_U64(key, type); - MppTrieInfo *info = mpp_trie_get_info(mTrie, (const char *)&val); - - return info ? info->index : -1; -} - -MppMetaImpl *MppMetaService::get_meta(const char *tag, const char *caller) -{ - MppMetaImpl *impl = mpp_malloc_size(MppMetaImpl, sizeof(MppMetaImpl) + - sizeof(MppMetaVal) * MPP_ARRAY_ELEMS(meta_defs)); - if (impl) { - const char *tag_src = (tag) ? (tag) : (MODULE_TAG); - RK_U32 i; - - strncpy(impl->tag, tag_src, sizeof(impl->tag) - 1); - impl->caller = caller; - impl->meta_id = MPP_FETCH_ADD(&meta_id, 1); - INIT_LIST_HEAD(&impl->list_meta); - impl->ref_count = 1; - impl->node_count = 0; - - for (i = 0; i < MPP_ARRAY_ELEMS(meta_defs); i++) - impl->vals[i].state = 0; - - mpp_spinlock_lock(&mLock); - list_add_tail(&impl->list_meta, &mlist_meta); - mpp_spinlock_unlock(&mLock); - MPP_FETCH_ADD(&meta_count, 1); - } else { - mpp_err_f("failed to malloc meta data\n"); - } - return impl; -} - -void MppMetaService::put_meta(MppMetaImpl *meta) -{ - if (finished) - return ; - - RK_S32 ref_count = MPP_SUB_FETCH(&meta->ref_count, 1); - - if (ref_count > 0) - return; - - if (ref_count < 0) { - mpp_err_f("invalid negative ref_count %d\n", ref_count); - return; - } - - mpp_spinlock_lock(&mLock); - list_del_init(&meta->list_meta); - mpp_spinlock_unlock(&mLock); - MPP_FETCH_SUB(&meta_count, 1); - - mpp_free(meta); -} - -MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaService *service = MppMetaService::get_inst(); - MppMetaImpl *impl = service->get_meta(tag, caller); - *meta = (MppMeta) impl; - return (impl) ? (MPP_OK) : (MPP_NOK); -} - -MPP_RET mpp_meta_put(MppMeta meta) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaService *service = MppMetaService::get_inst(); - MppMetaImpl *impl = (MppMetaImpl *)meta; - - service->put_meta(impl); - return MPP_OK; -} - -MPP_RET mpp_meta_inc_ref(MppMeta meta) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - - MPP_FETCH_ADD(&impl->ref_count, 1); - return MPP_OK; -} - -RK_S32 mpp_meta_size(MppMeta meta) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return -1; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - - return MPP_FETCH_ADD(&impl->node_count, 0); -} - -MPP_RET mpp_meta_dump(MppMeta meta) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - RK_U32 i; - - mpp_log("dumping meta %d node count %d\n", impl->meta_id, impl->node_count); - - for (i = 0; i < MPP_ARRAY_ELEMS(meta_defs); i++) { - if (!impl->vals[i].state) - continue; - - const char *key = (const char *)&meta_defs[i]; - - mpp_log("key %c%c%c%c - %c\n", key[0], key[1], key[2], key[3], - (meta_defs[i] >> 32) & 0xff); - } - - return MPP_OK; -} - -#define MPP_META_ACCESSOR(func_type, arg_type, key_type, key_field) \ - MPP_RET mpp_meta_set_##func_type(MppMeta meta, MppMetaKey key, arg_type val) \ - { \ - if (NULL == meta) { \ - mpp_err_f("found NULL input\n"); \ - return MPP_ERR_NULL_PTR; \ - } \ - RK_S32 index = MppMetaService::get_inst()->get_index_of_key(key, key_type); \ - if (index < 0) \ - return MPP_NOK; \ - MppMetaImpl *impl = (MppMetaImpl *)meta; \ - MppMetaVal *meta_val = &impl->vals[index]; \ - if (MPP_BOOL_CAS(&meta_val->state, META_VAL_INVALID, META_VAL_VALID)) \ - MPP_FETCH_ADD(&impl->node_count, 1); \ - meta_val->key_field = val; \ - MPP_FETCH_OR(&meta_val->state, META_VAL_READY); \ - return MPP_OK; \ - } \ - MPP_RET mpp_meta_get_##func_type(MppMeta meta, MppMetaKey key, arg_type *val) \ - { \ - if (NULL == meta) { \ - mpp_err_f("found NULL input\n"); \ - return MPP_ERR_NULL_PTR; \ - } \ - RK_S32 index = MppMetaService::get_inst()->get_index_of_key(key, key_type); \ - if (index < 0) \ - return MPP_NOK; \ - MppMetaImpl *impl = (MppMetaImpl *)meta; \ - MppMetaVal *meta_val = &impl->vals[index]; \ - MPP_RET ret = MPP_NOK; \ - if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \ - *val = meta_val->key_field; \ - MPP_FETCH_SUB(&impl->node_count, 1); \ - ret = MPP_OK; \ - } \ - return ret; \ - } \ - MPP_RET mpp_meta_get_##func_type##_d(MppMeta meta, MppMetaKey key, arg_type *val, arg_type def) \ - { \ - if (NULL == meta) { \ - mpp_err_f("found NULL input\n"); \ - return MPP_ERR_NULL_PTR; \ - } \ - RK_S32 index = MppMetaService::get_inst()->get_index_of_key(key, key_type); \ - if (index < 0) \ - return MPP_NOK; \ - MppMetaImpl *impl = (MppMetaImpl *)meta; \ - MppMetaVal *meta_val = &impl->vals[index]; \ - MPP_RET ret = MPP_NOK; \ - if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \ - *val = meta_val->key_field; \ - MPP_FETCH_SUB(&impl->node_count, 1); \ - ret = MPP_OK; \ - } else { \ - *val = def; \ - } \ - return ret; \ - } - -MPP_META_ACCESSOR(s32, RK_S32, TYPE_VAL_32, val_s32) -MPP_META_ACCESSOR(s64, RK_S64, TYPE_VAL_64, val_s64) -MPP_META_ACCESSOR(ptr, void *, TYPE_UPTR, val_ptr) -MPP_META_ACCESSOR(frame, MppFrame, TYPE_SPTR, frame) -MPP_META_ACCESSOR(packet, MppPacket, TYPE_SPTR, packet) -MPP_META_ACCESSOR(buffer, MppBuffer, TYPE_SPTR, buffer) diff --git a/mpp/base/test/mpp_meta_test.c b/mpp/base/test/mpp_meta_test.c index 34a1fabf..8692428e 100644 --- a/mpp/base/test/mpp_meta_test.c +++ b/mpp/base/test/mpp_meta_test.c @@ -1,17 +1,6 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ /* - * Copyright 2021 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. */ #define MODULE_TAG "mpp_meta_test" @@ -25,89 +14,107 @@ #define TEST_MAX 200 #define LOOP_MAX 100000 -void *meta_test(void *param) +static MPP_RET meta_set(MppMeta meta) { - RK_S32 loop_max = LOOP_MAX; - RK_S64 time_start; - RK_S64 time_end; - MppMeta meta = NULL; MPP_RET ret = MPP_OK; + + ret |= mpp_meta_set_frame(meta, KEY_INPUT_FRAME, NULL); + ret |= mpp_meta_set_packet(meta, KEY_INPUT_PACKET, NULL); + ret |= mpp_meta_set_frame(meta, KEY_OUTPUT_FRAME, NULL); + ret |= mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, NULL); + + ret |= mpp_meta_set_buffer(meta, KEY_MOTION_INFO, NULL); + ret |= mpp_meta_set_buffer(meta, KEY_HDR_INFO, NULL); + + ret |= mpp_meta_set_s32(meta, KEY_INPUT_BLOCK, 0); + ret |= mpp_meta_set_s32(meta, KEY_OUTPUT_BLOCK, 0); + ret |= mpp_meta_set_s32(meta, KEY_INPUT_IDR_REQ, 0); + ret |= mpp_meta_set_s32(meta, KEY_OUTPUT_INTRA, 0); + + ret |= mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, 0); + ret |= mpp_meta_set_s32(meta, KEY_LONG_REF_IDX, 0); + ret |= mpp_meta_set_s32(meta, KEY_ENC_AVERAGE_QP, 0); + + ret |= mpp_meta_set_ptr(meta, KEY_ROI_DATA, NULL); + ret |= mpp_meta_set_ptr(meta, KEY_OSD_DATA, NULL); + ret |= mpp_meta_set_ptr(meta, KEY_OSD_DATA2, NULL); + ret |= mpp_meta_set_ptr(meta, KEY_USER_DATA, NULL); + ret |= mpp_meta_set_ptr(meta, KEY_USER_DATAS, NULL); + + ret |= mpp_meta_set_buffer(meta, KEY_QPMAP0, NULL); + ret |= mpp_meta_set_ptr(meta, KEY_MV_LIST, NULL); + + ret |= mpp_meta_set_s32(meta, KEY_ENC_MARK_LTR, 0); + ret |= mpp_meta_set_s32(meta, KEY_ENC_USE_LTR, 0); + ret |= mpp_meta_set_s32(meta, KEY_ENC_FRAME_QP, 0); + ret |= mpp_meta_set_s32(meta, KEY_ENC_BASE_LAYER_PID, 0); + + return ret; +} + +static MPP_RET meta_get(MppMeta meta) +{ MppFrame frame; MppPacket packet; MppBuffer buffer; void *ptr; RK_S32 val; + MPP_RET ret = MPP_OK; + + ret |= mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frame); + ret |= mpp_meta_get_packet(meta, KEY_INPUT_PACKET, &packet); + ret |= mpp_meta_get_frame(meta, KEY_OUTPUT_FRAME, &frame); + ret |= mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet); + + ret |= mpp_meta_get_buffer(meta, KEY_MOTION_INFO, &buffer); + ret |= mpp_meta_get_buffer(meta, KEY_HDR_INFO, &buffer); + + ret |= mpp_meta_get_s32(meta, KEY_INPUT_BLOCK, &val); + ret |= mpp_meta_get_s32(meta, KEY_OUTPUT_BLOCK, &val); + ret |= mpp_meta_get_s32(meta, KEY_INPUT_IDR_REQ, &val); + ret |= mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &val); + + ret |= mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &val); + ret |= mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, &val); + ret |= mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &val); + + ret |= mpp_meta_get_ptr(meta, KEY_ROI_DATA, &ptr); + ret |= mpp_meta_get_ptr(meta, KEY_OSD_DATA, &ptr); + ret |= mpp_meta_get_ptr(meta, KEY_OSD_DATA2, &ptr); + ret |= mpp_meta_get_ptr(meta, KEY_USER_DATA, &ptr); + ret |= mpp_meta_get_ptr(meta, KEY_USER_DATAS, &ptr); + + ret |= mpp_meta_get_buffer(meta, KEY_QPMAP0, &buffer); + ret |= mpp_meta_get_ptr(meta, KEY_MV_LIST, &ptr); + + ret |= mpp_meta_get_s32(meta, KEY_ENC_MARK_LTR, &val); + ret |= mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &val); + ret |= mpp_meta_get_s32(meta, KEY_ENC_FRAME_QP, &val); + ret |= mpp_meta_get_s32(meta, KEY_ENC_BASE_LAYER_PID, &val); + + return ret; +} + +void *meta_test(void *param) +{ + RK_S32 loop_max = LOOP_MAX; + RK_S64 time_start; + RK_S64 time_end; + MPP_RET ret = MPP_OK; RK_S32 i; time_start = mpp_time(); for (i = 0; i < loop_max; i++) { + MppMeta meta = NULL; + ret |= mpp_meta_get(&meta); mpp_assert(meta); /* set */ - ret |= mpp_meta_set_frame(meta, KEY_INPUT_FRAME, NULL); - ret |= mpp_meta_set_packet(meta, KEY_INPUT_PACKET, NULL); - ret |= mpp_meta_set_frame(meta, KEY_OUTPUT_FRAME, NULL); - ret |= mpp_meta_set_packet(meta, KEY_OUTPUT_PACKET, NULL); - - ret |= mpp_meta_set_buffer(meta, KEY_MOTION_INFO, NULL); - ret |= mpp_meta_set_buffer(meta, KEY_HDR_INFO, NULL); - - ret |= mpp_meta_set_s32(meta, KEY_INPUT_BLOCK, 0); - ret |= mpp_meta_set_s32(meta, KEY_OUTPUT_BLOCK, 0); - ret |= mpp_meta_set_s32(meta, KEY_INPUT_IDR_REQ, 0); - ret |= mpp_meta_set_s32(meta, KEY_OUTPUT_INTRA, 0); - - ret |= mpp_meta_set_s32(meta, KEY_TEMPORAL_ID, 0); - ret |= mpp_meta_set_s32(meta, KEY_LONG_REF_IDX, 0); - ret |= mpp_meta_set_s32(meta, KEY_ENC_AVERAGE_QP, 0); - - ret |= mpp_meta_set_ptr(meta, KEY_ROI_DATA, NULL); - ret |= mpp_meta_set_ptr(meta, KEY_OSD_DATA, NULL); - ret |= mpp_meta_set_ptr(meta, KEY_OSD_DATA2, NULL); - ret |= mpp_meta_set_ptr(meta, KEY_USER_DATA, NULL); - ret |= mpp_meta_set_ptr(meta, KEY_USER_DATAS, NULL); - - ret |= mpp_meta_set_buffer(meta, KEY_QPMAP0, NULL); - ret |= mpp_meta_set_ptr(meta, KEY_MV_LIST, NULL); - - ret |= mpp_meta_set_s32(meta, KEY_ENC_MARK_LTR, 0); - ret |= mpp_meta_set_s32(meta, KEY_ENC_USE_LTR, 0); - ret |= mpp_meta_set_s32(meta, KEY_ENC_FRAME_QP, 0); - ret |= mpp_meta_set_s32(meta, KEY_ENC_BASE_LAYER_PID, 0); - + ret |= meta_set(meta); /* get */ - ret |= mpp_meta_get_frame(meta, KEY_INPUT_FRAME, &frame); - ret |= mpp_meta_get_packet(meta, KEY_INPUT_PACKET, &packet); - ret |= mpp_meta_get_frame(meta, KEY_OUTPUT_FRAME, &frame); - ret |= mpp_meta_get_packet(meta, KEY_OUTPUT_PACKET, &packet); - - ret |= mpp_meta_get_buffer(meta, KEY_MOTION_INFO, &buffer); - ret |= mpp_meta_get_buffer(meta, KEY_HDR_INFO, &buffer); - - ret |= mpp_meta_get_s32(meta, KEY_INPUT_BLOCK, &val); - ret |= mpp_meta_get_s32(meta, KEY_OUTPUT_BLOCK, &val); - ret |= mpp_meta_get_s32(meta, KEY_INPUT_IDR_REQ, &val); - ret |= mpp_meta_get_s32(meta, KEY_OUTPUT_INTRA, &val); - - ret |= mpp_meta_get_s32(meta, KEY_TEMPORAL_ID, &val); - ret |= mpp_meta_get_s32(meta, KEY_LONG_REF_IDX, &val); - ret |= mpp_meta_get_s32(meta, KEY_ENC_AVERAGE_QP, &val); - - ret |= mpp_meta_get_ptr(meta, KEY_ROI_DATA, &ptr); - ret |= mpp_meta_get_ptr(meta, KEY_OSD_DATA, &ptr); - ret |= mpp_meta_get_ptr(meta, KEY_OSD_DATA2, &ptr); - ret |= mpp_meta_get_ptr(meta, KEY_USER_DATA, &ptr); - ret |= mpp_meta_get_ptr(meta, KEY_USER_DATAS, &ptr); - - ret |= mpp_meta_get_buffer(meta, KEY_QPMAP0, &buffer); - ret |= mpp_meta_get_ptr(meta, KEY_MV_LIST, &ptr); - - ret |= mpp_meta_get_s32(meta, KEY_ENC_MARK_LTR, &val); - ret |= mpp_meta_get_s32(meta, KEY_ENC_USE_LTR, &val); - ret |= mpp_meta_get_s32(meta, KEY_ENC_FRAME_QP, &val); - ret |= mpp_meta_get_s32(meta, KEY_ENC_BASE_LAYER_PID, &val); + ret |= meta_get(meta); ret |= mpp_meta_put(meta); } @@ -129,6 +136,7 @@ int main() RK_S32 thd_cnt = TEST_MAX; RK_S64 avg_time = 0; pthread_attr_t attr; + MppMeta meta = NULL; RK_S32 i; pthread_attr_init(&attr); @@ -136,6 +144,13 @@ int main() mpp_log("mpp_meta_test start\n"); + mpp_meta_get(&meta); + if (meta) { + meta_set(meta); + mpp_meta_dump(meta); + mpp_meta_put(meta); + } + for (i = 0; i < thd_cnt; i++) pthread_create(&thds[i], &attr, meta_test, ×[i]);