diff --git a/inc/mpp_meta.h b/inc/mpp_meta.h index 995f45c6..3f69c92a 100644 --- a/inc/mpp_meta.h +++ b/inc/mpp_meta.h @@ -139,6 +139,18 @@ typedef enum MppMetaKey_e { KEY_DEC_TBN_EN = FOURCC_META('t', 'b', 'e', 'n'), KEY_DEC_TBN_Y_OFFSET = FOURCC_META('t', 'b', 'y', 'o'), KEY_DEC_TBN_UV_OFFSET = FOURCC_META('t', 'b', 'c', 'o'), + + /* combo frame */ + KEY_COMBO_FRAME = FOURCC_META('c', 'f', 'r', 'm'), + KEY_CHANNEL_ID = FOURCC_META('c', 'h', 'a', 'n'), + + /* Preprocess (pp) operation metat data */ + /* Motion Detection output buffer */ + KEY_PP_MD_BUF = FOURCC_META('m', 'd', 'b', 'f'), + /* Occlusion Detection output buffer */ + KEY_PP_OD_BUF = FOURCC_META('o', 'd', 'b', 'f'), + /* pp output data */ + KEY_PP_OUT = FOURCC_META('o', 'p', 'p', ' '), } MppMetaKey; #define mpp_meta_get(meta) mpp_meta_get_with_tag(meta, MODULE_TAG, __FUNCTION__) diff --git a/kmpp/base/CMakeLists.txt b/kmpp/base/CMakeLists.txt index 75199705..70a880cb 100644 --- a/kmpp/base/CMakeLists.txt +++ b/kmpp/base/CMakeLists.txt @@ -5,6 +5,7 @@ # ---------------------------------------------------------------------------- add_library(kmpp_base OBJECT kmpp_obj.c + kmpp_meta.c kmpp_frame.c kmpp_buffer.c kmpp_venc_cfg.c diff --git a/kmpp/base/inc/kmpp_meta.h b/kmpp/base/inc/kmpp_meta.h new file mode 100644 index 00000000..3fda0376 --- /dev/null +++ b/kmpp/base/inc/kmpp_meta.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#ifndef __KMPP_META_H__ +#define __KMPP_META_H__ + +#include "mpp_meta.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define KmppMetaKey MppMetaKey + +#define kmpp_meta_get_f(meta) kmpp_meta_get(meta, __FUNCTION__) +#define kmpp_meta_put_f(meta) kmpp_meta_put(meta, __FUNCTION__) +#define kmpp_meta_size_f(meta) kmpp_meta_size(meta, __FUNCTION__) +#define kmpp_meta_dump_f(meta) kmpp_meta_dump(meta, __FUNCTION__) + +rk_s32 kmpp_meta_get(KmppMeta *meta, const char *caller); +rk_s32 kmpp_meta_put(KmppMeta meta, const char *caller); +rk_s32 kmpp_meta_size(KmppMeta meta, const char *caller); +rk_s32 kmpp_meta_dump(KmppMeta meta, const char *caller); +rk_s32 kmpp_meta_dump_all(const char *caller); + +rk_s32 kmpp_meta_set_s32(KmppMeta meta, KmppMetaKey key, rk_s32 val); +rk_s32 kmpp_meta_set_s64(KmppMeta meta, KmppMetaKey key, rk_s64 val); +rk_s32 kmpp_meta_set_ptr(KmppMeta meta, KmppMetaKey key, void *val); +rk_s32 kmpp_meta_get_s32(KmppMeta meta, KmppMetaKey key, rk_s32 *val); +rk_s32 kmpp_meta_get_s64(KmppMeta meta, KmppMetaKey key, rk_s64 *val); +rk_s32 kmpp_meta_get_ptr(KmppMeta meta, KmppMetaKey key, void **val); +rk_s32 kmpp_meta_get_s32_d(KmppMeta meta, KmppMetaKey key, rk_s32 *val, rk_s32 def); +rk_s32 kmpp_meta_get_s64_d(KmppMeta meta, KmppMetaKey key, rk_s64 *val, rk_s64 def); +rk_s32 kmpp_meta_get_ptr_d(KmppMeta meta, KmppMetaKey key, void **val, void *def); + +rk_s32 kmpp_meta_set_obj(KmppMeta meta, KmppMetaKey key, KmppObj obj); +rk_s32 kmpp_meta_get_obj(KmppMeta meta, KmppMetaKey key, KmppObj *obj); +rk_s32 kmpp_meta_get_obj_d(KmppMeta meta, KmppMetaKey key, KmppObj *obj, KmppObj def); +rk_s32 kmpp_meta_set_shm(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr); +rk_s32 kmpp_meta_get_shm(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr); +rk_s32 kmpp_meta_get_shm_d(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr, KmppShmPtr *def); + +#ifdef __cplusplus +} +#endif + +#endif /*__KMPP_META_H__*/ diff --git a/kmpp/base/inc/kmpp_meta_impl.h b/kmpp/base/inc/kmpp_meta_impl.h new file mode 100644 index 00000000..463ed64c --- /dev/null +++ b/kmpp/base/inc/kmpp_meta_impl.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd. + */ + +#ifndef __KMPP_META_IMPL_H__ +#define __KMPP_META_IMPL_H__ + +#include "mpp_list.h" +#include "kmpp_meta.h" + +#define MPP_TAG_SIZE 32 + +typedef struct __attribute__((packed)) KmppMetaVal_t { + rk_u32 state; + union { + rk_s32 val_s32; + rk_s64 val_s64; + void *val_ptr; + }; +} KmppMetaVal; + +typedef struct __attribute__((packed)) KmppMetaShmVal_t { + rk_u32 state; + KmppShmPtr val_shm; +} KmppMetaObj; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET kmpp_meta_inc_ref(KmppMeta meta); + +#ifdef __cplusplus +} +#endif + +#endif /*__KMPP_META_IMPL_H__*/ diff --git a/kmpp/base/kmpp_meta.c b/kmpp/base/kmpp_meta.c new file mode 100644 index 00000000..6b91ec7c --- /dev/null +++ b/kmpp/base/kmpp_meta.c @@ -0,0 +1,474 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "kmpp_meta" + +#include +#include + +#include "mpp_mem.h" +#include "mpp_list.h" +#include "mpp_lock.h" +#include "mpp_debug.h" +#include "mpp_thread.h" +#include "mpp_singleton.h" + +#include "kmpp_obj.h" +#include "kmpp_meta_impl.h" + +#define KMETA_DBG_FUNC (0x00000001) +#define KMETA_DBG_SIZE (0x00000002) +#define KMETA_DBG_SET (0x00000004) +#define KMETA_DBG_GET (0x00000008) + +#define kmeta_dbg(flag, fmt, ...) _mpp_dbg_f(kmpp_meta_debug, flag, fmt, ## __VA_ARGS__) + +#define kmeta_dbg_func(fmt, ...) kmeta_dbg(KMETA_DBG_FUNC, fmt, ## __VA_ARGS__) +#define kmeta_dbg_size(fmt, ...) kmeta_dbg(KMETA_DBG_SIZE, fmt, ## __VA_ARGS__) +#define kmeta_dbg_set(fmt, ...) kmeta_dbg(KMETA_DBG_SET, fmt, ## __VA_ARGS__) +#define kmeta_dbg_get(fmt, ...) kmeta_dbg(KMETA_DBG_GET, fmt, ## __VA_ARGS__) + +#define META_ON_OPS (0x00010000) +#define META_VAL_INVALID (0x00000000) +#define META_VAL_VALID (0x00000001) +#define META_VAL_READY (0x00000002) +#define META_READY_MASK (META_VAL_VALID | META_VAL_READY) +/* property mask */ +#define META_VAL_IS_OBJ (0x00000010) +#define META_VAL_IS_SHM (0x00000020) +#define META_PROP_MASK (META_VAL_IS_OBJ | META_VAL_IS_SHM) +#define META_UNMASK_PROP(x) MPP_FETCH_AND(x, (~META_PROP_MASK)) + +#define META_KEY_TO_U64(key, type) ((rk_u64)((rk_u32)htobe32(key)) | ((rk_u64)type << 32)) + +typedef enum KmppMetaDataType_e { + /* kmpp meta data of normal data type */ + TYPE_VAL_32 = '3', + TYPE_VAL_64 = '6', + TYPE_KPTR = 'k', /* kernel pointer */ + TYPE_UPTR = 'u', /* userspace pointer */ + TYPE_SPTR = 's', /* share memory pointer */ +} KmppMetaType; + +typedef struct KmppMetaSrv_s { + pthread_mutex_t lock; + struct list_head list; + KmppObjDef def; + + rk_s32 offset_size; + rk_u32 meta_id; + rk_s32 meta_count; +} KmppMetaSrv; + +typedef struct KmppMetaPriv_s { + struct list_head list; + + KmppObj meta; + rk_u32 meta_id; +} KmppMetaPriv; + +static KmppMetaSrv *srv_meta = NULL; +static rk_u32 kmpp_meta_debug = 0; + +#define get_meta_srv(caller) \ + ({ \ + KmppMetaSrv *__tmp; \ + if (srv_meta) { \ + __tmp = srv_meta; \ + } else { \ + mpp_loge_f("kmpp meta srv not init at %s : %s\n", __FUNCTION__, caller); \ + __tmp = NULL; \ + } \ + __tmp; \ + }) + +static rk_s32 kmpp_meta_impl_init(void *entry, KmppObj obj, const char *caller) +{ + KmppMetaPriv *priv = (KmppMetaPriv *)kmpp_obj_to_priv(obj); + KmppMetaSrv *srv = get_meta_srv(caller); + (void)entry; + + if (srv) { + priv->meta = obj; + INIT_LIST_HEAD(&priv->list); + + pthread_mutex_lock(&srv->lock); + list_add_tail(&priv->list, &srv->list); + priv->meta_id = srv->meta_id++; + srv->meta_count++; + pthread_mutex_unlock(&srv->lock); + } + + return rk_ok; +} + +static rk_s32 kmpp_meta_impl_deinit(void *entry, KmppObj obj, const char *caller) +{ + KmppMetaPriv *priv = (KmppMetaPriv *)kmpp_obj_to_priv(obj); + KmppMetaSrv *srv = get_meta_srv(caller); + (void)entry; + + if (srv) { + pthread_mutex_lock(&srv->lock); + list_del_init(&priv->list); + srv->meta_count--; + pthread_mutex_unlock(&srv->lock); + } + + return rk_ok; +} + +static void kmpp_meta_deinit(void) +{ + KmppMetaSrv *srv = srv_meta; + + if (!srv) { + kmeta_dbg_func("kmpp meta already deinit\n"); + return; + } + + if (srv->def) { + kmpp_objdef_put(srv->def); + srv->def = NULL; + } + + pthread_mutex_destroy(&srv->lock); + + MPP_FREE(srv); + srv_meta = NULL; +} + +static void kmpp_meta_init(void) +{ + KmppMetaSrv *srv = srv_meta; + pthread_mutexattr_t attr; + + if (srv) { + kmeta_dbg_func("kmpp meta %p already init\n", srv); + kmpp_meta_deinit(); + } + + srv = mpp_calloc(KmppMetaSrv, 1); + if (!srv) { + mpp_loge_f("kmpp meta malloc failed\n"); + return; + } + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&srv->lock, &attr); + pthread_mutexattr_destroy(&attr); + + INIT_LIST_HEAD(&srv->list); + kmpp_objdef_get(&srv->def, "KmppMeta"); + if (!srv->def) { + mpp_loge_f("kmpp meta get objdef failed\n"); + MPP_FREE(srv); + return; + } + + kmpp_objdef_set_prop(srv->def, "priv_size", sizeof(KmppMetaPriv)); + kmpp_objdef_add_init(srv->def, kmpp_meta_impl_init); + kmpp_objdef_add_deinit(srv->def, kmpp_meta_impl_deinit); + + { + KmppEntry *tbl = NULL; + + kmpp_objdef_get_entry(srv->def, "size", &tbl); + srv->offset_size = tbl ? tbl->tbl.elem_offset : 0; + } + + srv_meta = srv; +} + +MPP_SINGLETON(MPP_SGLN_KMPP_META, kmpp_meta, kmpp_meta_init, kmpp_meta_deinit); + +static void *meta_key_to_addr(KmppObj meta, KmppMetaKey key, KmppMetaType type) +{ + if (meta) { + KmppMetaSrv *srv = srv_meta; + rk_u64 val = META_KEY_TO_U64(key, type); + KmppEntry *tbl = NULL; + + kmpp_objdef_get_entry(srv->def, (const char *)&val, &tbl); + if (tbl) + return ((rk_u8 *)kmpp_obj_to_entry(meta)) + tbl->tbl.elem_offset; + } + + return NULL; +} + +static rk_s32 meta_inc_size(KmppObj meta, rk_s32 val, const char *caller) +{ + rk_s32 ret = 0; + + if (meta && srv_meta) { + void *entry = kmpp_obj_to_entry(meta); + rk_s32 offset = srv_meta->offset_size; + + if (entry && offset) { + rk_s32 *p = (rk_s32 *)((rk_u8 *)entry + offset); + + ret = MPP_FETCH_ADD(p, val); + kmeta_dbg_size("meta %p size %d -> %d at %s\n", + meta, p[0], ret, caller); + } + } + + return ret; +} + +static rk_s32 meta_dec_size(KmppObj meta, rk_s32 val, const char *caller) +{ + rk_s32 ret = 0; + + if (meta && srv_meta) { + void *entry = kmpp_obj_to_entry(meta); + rk_s32 offset = srv_meta->offset_size; + + if (entry && offset) { + rk_s32 *p = (rk_s32 *)((rk_u8 *)entry + offset); + + ret = MPP_FETCH_SUB(p, val); + kmeta_dbg_size("meta %p size %d -> %d at %s\n", + meta, p[0], ret, caller); + } + } + + return ret; +} + +rk_s32 kmpp_meta_get(KmppMeta *meta, const char *caller) +{ + KmppMetaSrv *srv = get_meta_srv(caller); + + if (!srv) + return rk_nok; + + return kmpp_obj_get(meta, srv->def, caller); +} + +rk_s32 kmpp_meta_put(KmppMeta meta, const char *caller) +{ + KmppMetaSrv *srv = get_meta_srv(caller); + + if (!srv) + return rk_nok; + + return kmpp_obj_put(meta, caller); +} + +rk_s32 kmpp_meta_size(KmppMeta meta, const char *caller) +{ + return meta_inc_size(meta, 0, caller); +} + +rk_s32 kmpp_meta_dump(KmppMeta meta, const char *caller) +{ + return kmpp_obj_udump_f(meta, caller); +} + +rk_s32 kmpp_meta_dump_all(const char *caller) +{ + KmppMetaSrv *srv = get_meta_srv(caller); + + if (srv) { + KmppMeta meta = NULL; + KmppMetaPriv *pos, *n; + + pthread_mutex_lock(&srv->lock); + list_for_each_entry_safe(pos, n, &srv->list, KmppMetaPriv, list) { + meta = pos->meta; + mpp_logi("meta %p:%d size %d\n", meta, pos->meta_id, + kmpp_meta_size(meta, caller)); + kmpp_meta_dump(meta, caller); + } + } + + return rk_ok; +} + +#define KMPP_META_ACCESSOR(func_type, arg_type, key_type, key_field) \ + rk_s32 kmpp_meta_set_##func_type(KmppMeta meta, KmppMetaKey key, arg_type val) \ + { \ + KmppMetaVal *meta_val = meta_key_to_addr(meta, key, key_type); \ + if (!meta_val) \ + return rk_nok; \ + if (MPP_BOOL_CAS(&meta_val->state, META_VAL_INVALID, META_VAL_VALID)) \ + meta_inc_size(meta, 1, __FUNCTION__); \ + meta_val->key_field = val; \ + MPP_FETCH_OR(&meta_val->state, META_VAL_READY); \ + return rk_ok; \ + } \ + rk_s32 kmpp_meta_get_##func_type(KmppMeta meta, KmppMetaKey key, arg_type *val) \ + { \ + KmppMetaVal *meta_val = meta_key_to_addr(meta, key, key_type); \ + if (!meta_val) \ + return rk_nok; \ + if (MPP_BOOL_CAS(&meta_val->state, META_READY_MASK, META_VAL_INVALID)) { \ + if (val) *val = meta_val->key_field; \ + meta_dec_size(meta, 1, __FUNCTION__); \ + return rk_ok; \ + } \ + return rk_nok; \ + } \ + rk_s32 kmpp_meta_get_##func_type##_d(KmppMeta meta, KmppMetaKey key, arg_type *val, arg_type def) \ + { \ + KmppMetaVal *meta_val = meta_key_to_addr(meta, key, key_type); \ + if (!meta_val) \ + return rk_nok; \ + if (MPP_BOOL_CAS(&meta_val->state, META_READY_MASK, META_VAL_INVALID)) { \ + if (val) *val = meta_val->key_field; \ + meta_dec_size(meta, 1, __FUNCTION__); \ + } else { \ + if (val) *val = def; \ + } \ + return rk_ok; \ + } + +KMPP_META_ACCESSOR(s32, rk_s32, TYPE_VAL_32, val_s32) +KMPP_META_ACCESSOR(s64, rk_s64, TYPE_VAL_64, val_s64) +KMPP_META_ACCESSOR(ptr, void *, TYPE_KPTR, val_ptr) + +rk_s32 kmpp_meta_set_obj(KmppMeta meta, KmppMetaKey key, KmppObj val) +{ + KmppMetaObj *meta_obj = meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + if (MPP_BOOL_CAS(&meta_obj->state, META_VAL_INVALID, META_VAL_VALID)) + meta_inc_size(meta, 1, __FUNCTION__); + + { + KmppShmPtr *ptr = kmpp_obj_to_shm(val); + + if (ptr) { + meta_obj->val_shm.uaddr = ptr->uaddr; + meta_obj->val_shm.kaddr = ptr->kaddr;; + MPP_FETCH_OR(&meta_obj->state, META_VAL_IS_SHM); + } else { + meta_obj->val_shm.uaddr = 0; + meta_obj->val_shm.kptr = val; + MPP_FETCH_AND(&meta_obj->state, ~META_VAL_IS_SHM); + } + } + MPP_FETCH_OR(&meta_obj->state, META_VAL_READY); + return rk_ok; +} + +rk_s32 kmpp_meta_get_obj(KmppMeta meta, KmppMetaKey key, KmppObj *val) +{ + KmppMetaObj *meta_obj = meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + META_UNMASK_PROP(&meta_obj->state); + if (MPP_BOOL_CAS(&meta_obj->state, META_READY_MASK, META_VAL_INVALID)) { + if (val) + *val = meta_obj->val_shm.kptr; + meta_dec_size(meta, 1, __FUNCTION__); + return rk_ok; + } + + return rk_nok; +} + +rk_s32 kmpp_meta_get_obj_d(KmppMeta meta, KmppMetaKey key, KmppObj *val, KmppObj def) +{ + KmppMetaObj *meta_obj = meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + META_UNMASK_PROP(&meta_obj->state); + if (MPP_BOOL_CAS(&meta_obj->state, META_READY_MASK, META_VAL_INVALID)) { + if (val) + *val = meta_obj->val_shm.kptr; + meta_dec_size(meta, 1, __FUNCTION__); + } else { + if (val) + *val = def ? def : NULL; + } + + return rk_ok; +} + +rk_s32 kmpp_meta_set_shm(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr) +{ + KmppMetaObj *meta_obj = (KmppMetaObj *)meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + if (MPP_BOOL_CAS(&meta_obj->state, META_VAL_INVALID, META_VAL_VALID)) + meta_inc_size(meta, 1, __FUNCTION__); + + if (sptr) { + meta_obj->val_shm.uaddr = sptr->uaddr; + meta_obj->val_shm.kaddr = sptr->kaddr; + } else { + meta_obj->val_shm.uaddr = 0; + meta_obj->val_shm.kptr = 0; + } + + if (sptr && sptr->uaddr) + MPP_FETCH_OR(&meta_obj->state, META_VAL_IS_SHM); + else + MPP_FETCH_AND(&meta_obj->state, ~META_VAL_IS_SHM); + + MPP_FETCH_OR(&meta_obj->state, META_VAL_READY); + + return rk_ok; +} + +rk_s32 kmpp_meta_get_shm(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr) +{ + KmppMetaObj *meta_obj = meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + META_UNMASK_PROP(&meta_obj->state); + if (MPP_BOOL_CAS(&meta_obj->state, META_READY_MASK, META_VAL_INVALID)) { + if (sptr) { + sptr->uaddr = meta_obj->val_shm.uaddr; + sptr->kaddr = meta_obj->val_shm.kaddr; + } + meta_dec_size(meta, 1, __FUNCTION__); + return rk_ok; + } + return rk_nok; +} + +rk_s32 kmpp_meta_get_shm_d(KmppMeta meta, KmppMetaKey key, KmppShmPtr *sptr, KmppShmPtr *def) +{ + KmppMetaObj *meta_obj = meta_key_to_addr(meta, key, TYPE_SPTR); + + if (!meta_obj) + return rk_nok; + + META_UNMASK_PROP(&meta_obj->state); + if (MPP_BOOL_CAS(&meta_obj->state, META_READY_MASK, META_VAL_INVALID)) { + if (sptr) { + sptr->uaddr = meta_obj->val_shm.uaddr; + sptr->kaddr = meta_obj->val_shm.kaddr; + } + meta_dec_size(meta, 1, __FUNCTION__); + } else { + if (sptr) { + if (def) { + sptr->uaddr = def->uaddr; + sptr->kaddr = def->kaddr; + } else { + sptr->uaddr = 0; + sptr->kaddr = 0; + } + } + } + + return rk_ok; +} diff --git a/kmpp/base/test/CMakeLists.txt b/kmpp/base/test/CMakeLists.txt index d1579b84..20e58a7d 100644 --- a/kmpp/base/test/CMakeLists.txt +++ b/kmpp/base/test/CMakeLists.txt @@ -27,3 +27,6 @@ add_kmpp_base_test(kmpp_frame) # kmpp buffer unit test add_kmpp_base_test(kmpp_buffer) + +# kmpp meta unit test +add_kmpp_base_test(kmpp_meta) diff --git a/kmpp/base/test/kmpp_meta_test.c b/kmpp/base/test/kmpp_meta_test.c new file mode 100644 index 00000000..04dd9202 --- /dev/null +++ b/kmpp/base/test/kmpp_meta_test.c @@ -0,0 +1,154 @@ +/* SPDX-License-Identifier: Apache-2.0 OR MIT */ +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#define MODULE_TAG "kmpp_meta_test" + +#include + +#include "mpp_time.h" +#include "mpp_debug.h" +#include "kmpp_meta_impl.h" + +#define TEST_MAX 1 +#define LOOP_MAX 10 + +void *meta_test(void *param) +{ + RK_S32 loop_max = LOOP_MAX; + RK_S64 time_start; + RK_S64 time_end; + MppMeta meta[LOOP_MAX]; + MPP_RET ret = MPP_OK; + KmppShmPtr frame; + KmppShmPtr packet; + KmppShmPtr buffer; + KmppShmPtr sptr; + RK_S32 val; + RK_S32 i; + + time_start = mpp_time(); + + frame.uaddr = 0; + frame.kaddr = 0; + packet.uaddr = 0; + packet.kaddr = 0; + buffer.uaddr = 0; + buffer.kaddr = 0; + sptr.uaddr = 0; + sptr.kaddr = 0; + + for (i = 0; i < loop_max; i++) { + ret |= kmpp_meta_get_f(&meta[i]); + mpp_assert(meta[i]); + } + + for (i = 0; i < loop_max; i++) { + /* set */ + ret |= kmpp_meta_set_shm(meta[i], KEY_INPUT_FRAME, &frame); + ret |= kmpp_meta_set_shm(meta[i], KEY_INPUT_PACKET, &packet); + ret |= kmpp_meta_set_shm(meta[i], KEY_OUTPUT_FRAME, &frame); + ret |= kmpp_meta_set_shm(meta[i], KEY_OUTPUT_PACKET, &packet); + + ret |= kmpp_meta_set_shm(meta[i], KEY_MOTION_INFO, &sptr); + ret |= kmpp_meta_set_shm(meta[i], KEY_HDR_INFO, &sptr); + + ret |= kmpp_meta_set_s32(meta[i], KEY_INPUT_BLOCK, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_OUTPUT_BLOCK, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_INPUT_IDR_REQ, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_OUTPUT_INTRA, 0); + + ret |= kmpp_meta_set_s32(meta[i], KEY_TEMPORAL_ID, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_LONG_REF_IDX, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_ENC_AVERAGE_QP, 0); + + ret |= kmpp_meta_set_shm(meta[i], KEY_ROI_DATA, NULL); + ret |= kmpp_meta_set_shm(meta[i], KEY_OSD_DATA, NULL); + ret |= kmpp_meta_set_shm(meta[i], KEY_OSD_DATA2, NULL); + ret |= kmpp_meta_set_shm(meta[i], KEY_USER_DATA, NULL); + ret |= kmpp_meta_set_shm(meta[i], KEY_USER_DATAS, NULL); + + ret |= kmpp_meta_set_shm(meta[i], KEY_QPMAP0, NULL); + + ret |= kmpp_meta_set_s32(meta[i], KEY_ENC_MARK_LTR, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_ENC_USE_LTR, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_ENC_FRAME_QP, 0); + ret |= kmpp_meta_set_s32(meta[i], KEY_ENC_BASE_LAYER_PID, 0); + + /* get */ + ret |= kmpp_meta_get_shm(meta[i], KEY_INPUT_FRAME, &frame); + ret |= kmpp_meta_get_shm(meta[i], KEY_INPUT_PACKET, &packet); + ret |= kmpp_meta_get_shm(meta[i], KEY_OUTPUT_FRAME, &frame); + ret |= kmpp_meta_get_shm(meta[i], KEY_OUTPUT_PACKET, &packet); + + ret |= kmpp_meta_get_shm(meta[i], KEY_MOTION_INFO, &buffer); + ret |= kmpp_meta_get_shm(meta[i], KEY_HDR_INFO, &buffer); + + ret |= kmpp_meta_get_s32(meta[i], KEY_INPUT_BLOCK, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_OUTPUT_BLOCK, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_INPUT_IDR_REQ, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_OUTPUT_INTRA, &val); + + ret |= kmpp_meta_get_s32(meta[i], KEY_TEMPORAL_ID, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_LONG_REF_IDX, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_ENC_AVERAGE_QP, &val); + + ret |= kmpp_meta_get_shm(meta[i], KEY_ROI_DATA, &sptr); + ret |= kmpp_meta_get_shm(meta[i], KEY_OSD_DATA, &sptr); + ret |= kmpp_meta_get_shm(meta[i], KEY_OSD_DATA2, &sptr); + ret |= kmpp_meta_get_shm(meta[i], KEY_USER_DATA, &sptr); + ret |= kmpp_meta_get_shm(meta[i], KEY_USER_DATAS, &sptr); + + ret |= kmpp_meta_get_shm(meta[i], KEY_QPMAP0, &buffer); + + ret |= kmpp_meta_get_s32(meta[i], KEY_ENC_MARK_LTR, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_ENC_USE_LTR, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_ENC_FRAME_QP, &val); + ret |= kmpp_meta_get_s32(meta[i], KEY_ENC_BASE_LAYER_PID, &val); + } + + for (i = 0; i < loop_max; i++) { + ret |= kmpp_meta_put_f(meta[i]); + } + + time_end = mpp_time(); + + if (ret) + mpp_log("meta setting and getting, ret %d\n", ret); + + *((RK_S64 *)param) = (time_end - time_start) / loop_max; + + return NULL; +} + +int main() +{ + pthread_t thds[TEST_MAX]; + RK_S64 times[TEST_MAX]; + RK_S32 thd_cnt = TEST_MAX; + RK_S64 avg_time = 0; + pthread_attr_t attr; + RK_S32 i; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + mpp_log(MODULE_TAG " start\n"); + + for (i = 0; i < thd_cnt; i++) + pthread_create(&thds[i], &attr, meta_test, ×[i]); + + for (i = 0; i < thd_cnt; i++) + pthread_join(thds[i], NULL); + + for (i = 0; i < thd_cnt; i++) + avg_time += times[i]; + + mpp_log(MODULE_TAG " %d threads %d loop config avg %lld us", + thd_cnt, LOOP_MAX, avg_time / thd_cnt); + + mpp_log(MODULE_TAG " done\n"); + + return 0; +}