feat[kmpp]: Add KmppBuffer module

1. Add buf_grp, buf_grp_cfg, buffer, buf_cfg objdef.
2. The buf_grp_cfg is binded to buf_grp and the buf_cfg is binded to
buffer. The binding cfg obj is stored in private data.

Change-Id: I9243c03f7b9519536fdc2f24b62761dc04baac85
Signed-off-by: Yanjun Liao <yanjun.liao@rock-chips.com>
Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
Yanjun Liao 2025-05-15 17:15:50 +08:00 committed by Herman Chen
parent 28f17c9ebf
commit 69191e72d3
8 changed files with 582 additions and 15 deletions

View file

@ -6,6 +6,7 @@
add_library(kmpp_base OBJECT
kmpp_obj.c
kmpp_frame.c
kmpp_buffer.c
kmpp_venc_cfg.c
kmpp_packet.c
)

100
kmpp/base/inc/kmpp_buffer.h Normal file
View file

@ -0,0 +1,100 @@
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#ifndef __KMPP_BUFFER_H__
#define __KMPP_BUFFER_H__
#include "mpp_buffer.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* KmppBufGrpCfg;
typedef void* KmppBufCfg;
typedef void* KmppDmaBuf;
typedef enum {
KMPP_BUFFER_INTERNAL,
KMPP_BUFFER_EXTERNAL,
KMPP_BUFFER_MODE_BUTT,
} KmppBufferMode;
/*
* KmppBufGrp is the ioctl entry for KmppBufGrpCfg
* KmppBufGrpCfg is the buffer group config data entry
* Usage:
* 1. kmpp_buf_grp_get() to get a buffer group
* 2. kmpp_buf_grp_to_cfg() to get the buffer group config data entry
* 3. kmpp_buf_grp_cfg_set_xxx to write buffer group config
* 4. kmpp_buf_grp_setup() to activate buffer group config
* 5. kmpp_buf_grp_put() to release buffer group with group config
*/
#define KMPP_OBJ_NAME kmpp_buf_grp
#define KMPP_OBJ_INTF_TYPE KmppBufGrp
#include "kmpp_obj_func.h"
KmppBufGrpCfg kmpp_buf_grp_to_cfg(KmppBufGrp grp);
rk_s32 kmpp_buf_grp_setup(KmppBufGrp grp);
#define KMPP_BUF_GRP_CFG_ENTRY_TABLE(prefix, ENTRY, STRCT, EHOOK, SHOOK, ALIAS) \
ENTRY(prefix, u32, rk_u32, flag, FLAG_NONE, flag) \
ENTRY(prefix, u32, rk_u32, count, FLAG_NONE, count) \
ENTRY(prefix, u32, rk_u32, size, FLAG_NONE, size) \
ENTRY(prefix, u32, KmppBufferMode, mode, FLAG_NONE, mode) \
ENTRY(prefix, s32, rk_s32, fd, FLAG_NONE, fd) \
ENTRY(prefix, s32, rk_s32, grp_id, FLAG_NONE, grp_id) \
ENTRY(prefix, s32, rk_s32, used, FLAG_NONE, used) \
ENTRY(prefix, s32, rk_s32, unused, FLAG_NONE, unused) \
STRCT(prefix, shm, KmppShmPtr, name, FLAG_NONE, name) \
STRCT(prefix, shm, KmppShmPtr, allocator, FLAG_NONE, allocator)
#define KMPP_OBJ_NAME kmpp_buf_grp_cfg
#define KMPP_OBJ_INTF_TYPE KmppBufGrpCfg
#define KMPP_OBJ_ENTRY_TABLE KMPP_BUF_GRP_CFG_ENTRY_TABLE
#include "kmpp_obj_func.h"
/*
* KmppBuffer is the ioctl entry for KmppBufCfg
* KmppBufCfg is the buffer config data entry
* Usage:
* 1. kmpp_buffer_get() to get a buffer
* 2. kmpp_buffer_to_cfg() to get the buffer config data entry
* 3. kmpp_buffer_cfg_set_xxx to write buffer config
* 4. kmpp_buffer_setup() to activate buffer config
* 5. kmpp_buffer_put() to release buffer with config
*/
#define KMPP_OBJ_NAME kmpp_buffer
#define KMPP_OBJ_INTF_TYPE KmppBuffer
#include "kmpp_obj_func.h"
KmppBufCfg kmpp_buffer_to_cfg(KmppBuffer buf);
rk_s32 kmpp_buffer_setup(KmppBuffer buffer);
#define KMPP_BUF_CFG_ENTRY_TABLE(prefix, ENTRY, STRCT, EHOOK, SHOOK, ALIAS) \
ENTRY(prefix, u32, rk_u32, size, FLAG_NONE, size) \
ENTRY(prefix, u32, rk_u32, offset, FLAG_NONE, offset) \
ENTRY(prefix, u32, rk_u32, flag, FLAG_NONE, flag) \
ENTRY(prefix, s32, rk_s32, fd, FLAG_NONE, fd) \
ENTRY(prefix, s32, rk_s32, index, FLAG_NONE, index) \
ENTRY(prefix, s32, rk_s32, grp_id, FLAG_NONE, grp_id) \
ENTRY(prefix, s32, rk_s32, buf_gid, FLAG_NONE, buf_gid) \
ENTRY(prefix, s32, rk_s32, buf_uid, FLAG_NONE, buf_uid) \
STRCT(prefix, shm, KmppShmPtr, sptr, FLAG_NONE, sptr) \
STRCT(prefix, shm, KmppShmPtr, group, FLAG_NONE, group) \
ALIAS(prefix, uptr, rk_u64, uptr, FLAG_NONE, uptr) \
ALIAS(prefix, uptr, rk_u64, upriv, FLAG_NONE, upriv) \
ALIAS(prefix, ufp, rk_u64, ufp, FLAG_NONE, ufp)
#define KMPP_OBJ_NAME kmpp_buf_cfg
#define KMPP_OBJ_INTF_TYPE KmppBufCfg
#define KMPP_OBJ_ENTRY_TABLE KMPP_BUF_CFG_ENTRY_TABLE
#include "kmpp_obj_func.h"
#ifdef __cplusplus
}
#endif
#endif /*__KMPP_BUFFER_H__*/

View file

@ -0,0 +1,153 @@
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#ifndef __KMPP_BUFFER_IMPL_H__
#define __KMPP_BUFFER_IMPL_H__
#include "mpp_list.h"
#include "kmpp_obj.h"
#include "kmpp_buffer.h"
#define BUF_ST_NONE (0)
#define BUF_ST_INIT (1)
#define BUF_ST_INIT_TO_USED (2)
#define BUF_ST_USED (3)
#define BUF_ST_UNUSED (4)
#define BUF_ST_USED_TO_DEINIT (5)
#define BUF_ST_DEINIT_AT_GRP (6)
#define BUF_ST_DEINIT_AT_SRV (7)
/* buffer group share name storage for both name and allocator */
#define BUF_GRP_STR_BUF_SIZE (64)
typedef struct KmppBufGrpCfgImpl_t {
rk_u32 flag;
rk_u32 count;
rk_u32 size;
KmppBufferMode mode;
rk_s32 fd;
rk_s32 grp_id;
rk_s32 used;
rk_s32 unused;
void *device;
KmppShmPtr allocator;
KmppShmPtr name;
void *grp_impl;
} KmppBufGrpCfgImpl;
typedef struct KmppBufGrpPriv_t {
KmppObj obj;
KmppBufGrpCfgImpl *impl;
} KmppBufGrpPriv;
typedef struct KmppBufGrpImpl_t {
/* group share config pointer */
KmppShmPtr cfg;
KmppBufGrpCfg cfg_ext;
KmppBufGrpCfgImpl *cfg_usr;
KmppObj obj;
/* internal parameter set on used */
rk_u32 flag;
rk_u32 count;
rk_u32 size;
KmppBufferMode mode;
pthread_mutex_t lock;
struct list_head list_srv;
struct list_head list_used;
struct list_head list_unused;
rk_s32 count_used;
rk_s32 count_unused;
/* allocator */
void* heap;
rk_s32 heap_fd;
rk_s32 grp_id;
rk_s32 buf_id;
rk_s32 buf_cnt;
rk_s32 buffer_count;
/* status status */
rk_s32 log_runtime_en;
rk_s32 log_history_en;
rk_s32 clear_on_exit;
rk_s32 dump_on_exit;
rk_s32 is_orphan;
rk_s32 is_finalizing;
rk_s32 is_default;
/* string storage */
rk_s32 name_offset;
rk_u8 str_buf[BUF_GRP_STR_BUF_SIZE];
/* buffer group config for internal usage */
KmppBufGrpCfgImpl cfg_int;
} KmppBufGrpImpl;
typedef struct KmppBufCfgImpl_t {
rk_u32 size;
rk_u32 offset;
rk_u32 flag;
rk_s32 fd;
rk_s32 index; /* index for external user buffer match */
rk_s32 grp_id;
rk_s32 buf_gid;
rk_s32 buf_uid;
void *hnd;
void *dmabuf;
void *kdev;
void *dev;
rk_u64 iova;
void *kptr;
void *kpriv;
void *kfp;
rk_u64 uptr;
rk_u64 upriv;
rk_u64 ufp;
KmppShmPtr sptr;
KmppShmPtr group;
void *buf_impl;
} KmppBufCfgImpl;
typedef struct KmppBufPriv_t {
KmppObj obj;
KmppBufCfgImpl *impl;
} KmppBufPriv;
typedef struct KmppBufferImpl_t {
KmppShmPtr cfg;
KmppBufCfg cfg_ext;
KmppBufCfgImpl *cfg_usr;
KmppBufGrpImpl *grp;
/* when grp is valid used grp lock else use srv lock */
pthread_mutex_t lock;
struct list_head list_status;
KmppObj obj;
KmppDmaBuf buf;
void *kptr;
rk_u64 uaddr;
rk_u32 size;
rk_s32 grp_id;
rk_s32 buf_gid;
rk_s32 buf_uid;
rk_s32 ref_cnt;
rk_u32 status;
rk_u32 discard;
/* mutex for list_maps */
void *mutex_maps;
/* list for list in KmppBufIovaMap */
struct list_head list_maps;
KmppBufCfgImpl cfg_int;
} KmppBufferImpl;
#endif /* __KMPP_BUF_GRP_IMPL_H__ */

184
kmpp/base/kmpp_buffer.c Normal file
View file

@ -0,0 +1,184 @@
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#define MODULE_TAG "kmpp_buffer"
#include <asm/ioctl.h>
#include "mpp_mem.h"
#include "mpp_list.h"
#include "mpp_log.h"
#include "mpp_lock.h"
#include "mpp_thread.h"
#include "kmpp_obj.h"
#include "kmpp_buffer_impl.h"
#define KMPP_OBJ_NAME kmpp_buf_grp_cfg
#define KMPP_OBJ_INTF_TYPE KmppBufGrpCfg
#define KMPP_OBJ_IMPL_TYPE KmppBufGrpCfgImpl
#define KMPP_OBJ_SGLN_ID MPP_SGLN_KMPP_BUF_GRP_CFG
#define KMPP_OBJ_ENTRY_TABLE KMPP_BUF_GRP_CFG_ENTRY_TABLE
#include "kmpp_obj_helper.h"
KmppBufGrpCfg kmpp_buf_grp_to_cfg(KmppBufGrp grp)
{
if (grp) {
KmppBufGrpPriv *priv = (KmppBufGrpPriv *)kmpp_obj_to_priv((KmppObj)grp);
if (priv)
return (KmppBufGrpCfg)(priv->obj);
}
return NULL;
}
rk_s32 kmpp_buf_grp_setup(KmppBufGrp group)
{
KmppBufGrpImpl *impl = kmpp_obj_to_entry(group);
if (!impl)
mpp_loge_f("invalid NULL group\n");
return kmpp_obj_ioctl_f(group, 0, group, NULL);
}
rk_s32 kmpp_buf_grp_impl_init(void *entry, KmppObj obj, const char *caller)
{
KmppBufGrpPriv *priv = (KmppBufGrpPriv *)kmpp_obj_to_priv(obj);
(void)entry;
if (!priv) {
mpp_loge_f("invalid grp %p without priv at %s\n", obj, caller);
return rk_nok;
}
{
KmppBufGrpCfg cfg;
KmppShmPtr sptr;
kmpp_obj_get_shm(obj, "cfg", &sptr);
kmpp_obj_get_by_sptr_f(&cfg, &sptr);
mpp_assert(cfg);
priv->obj = cfg;
priv->impl = kmpp_obj_to_entry(cfg);
}
return rk_ok;
}
rk_s32 kmpp_buf_grp_impl_deinit(void *entry, KmppObj obj, const char *caller)
{
KmppBufGrpPriv *priv = (KmppBufGrpPriv *)kmpp_obj_to_priv(obj);
(void)entry;
if (!priv) {
mpp_loge_f("invalid grp %p without priv at %s\n", obj, caller);
return rk_nok;
}
if (priv->obj) {
kmpp_obj_put_impl(priv->obj, caller);
priv->obj = NULL;
}
priv->impl = NULL;
return rk_ok;
}
#define KMPP_OBJ_NAME kmpp_buf_grp
#define KMPP_OBJ_INTF_TYPE KmppBufGrp
#define KMPP_OBJ_IMPL_TYPE KmppBufGrpImpl
#define KMPP_OBJ_SGLN_ID MPP_SGLN_KMPP_BUF_GRP
#define KMPP_OBJ_FUNC_INIT kmpp_buf_grp_impl_init
#define KMPP_OBJ_FUNC_DEINIT kmpp_buf_grp_impl_deinit
#define KMPP_OBJ_PRIV_SIZE sizeof(KmppBufGrpPriv)
#include "kmpp_obj_helper.h"
#define KMPP_OBJ_NAME kmpp_buf_cfg
#define KMPP_OBJ_INTF_TYPE KmppBufCfg
#define KMPP_OBJ_IMPL_TYPE KmppBufCfgImpl
#define KMPP_OBJ_SGLN_ID MPP_SGLN_KMPP_BUF_CFG
#define KMPP_OBJ_ENTRY_TABLE KMPP_BUF_CFG_ENTRY_TABLE
#include "kmpp_obj_helper.h"
KmppBufCfg kmpp_buffer_to_cfg(KmppBuffer buf)
{
if (buf) {
KmppBufPriv *priv = (KmppBufPriv *)kmpp_obj_to_priv((KmppObj)buf);
if (priv)
return (KmppBufCfg)(priv->obj);
}
return NULL;
}
rk_s32 kmpp_buffer_setup(KmppBuffer buffer)
{
KmppBufferImpl *impl = (KmppBufferImpl *)kmpp_obj_to_entry(buffer);
if (!impl)
mpp_loge_f("invalid NULL buffer\n");
return kmpp_obj_ioctl_f(buffer, 0, buffer, NULL);
}
rk_s32 kmpp_buffer_impl_init(void *entry, KmppObj obj, const char *caller)
{
KmppBufPriv *priv = (KmppBufPriv *)kmpp_obj_to_priv(obj);
(void)entry;
if (!priv) {
mpp_loge_f("invalid buf %p without priv at %s\n", obj, caller);
return rk_nok;
}
{
KmppBufCfg cfg;
KmppShmPtr sptr;
kmpp_obj_get_shm(obj, "cfg", &sptr);
kmpp_obj_get_by_sptr_f(&cfg, &sptr);
mpp_assert(cfg);
priv->obj = cfg;
priv->impl = kmpp_obj_to_entry(cfg);
}
return rk_ok;
}
rk_s32 kmpp_buffer_impl_deinit(void *entry, KmppObj obj, const char *caller)
{
KmppBufPriv *priv = (KmppBufPriv *)kmpp_obj_to_priv(obj);
(void)entry;
if (!priv) {
mpp_loge_f("invalid buf %p without priv at %s\n", obj, caller);
return rk_nok;
}
if (priv->obj) {
kmpp_obj_put_impl(priv->obj, caller);
priv->obj = NULL;
}
priv->impl = NULL;
return rk_ok;
}
#define KMPP_OBJ_NAME kmpp_buffer
#define KMPP_OBJ_INTF_TYPE KmppBuffer
#define KMPP_OBJ_IMPL_TYPE KmppBufferImpl
#define KMPP_OBJ_SGLN_ID MPP_SGLN_KMPP_BUFFER
#define KMPP_OBJ_FUNC_INIT kmpp_buffer_impl_init
#define KMPP_OBJ_FUNC_DEINIT kmpp_buffer_impl_deinit
#define KMPP_OBJ_PRIV_SIZE sizeof(KmppBufPriv)
#include "kmpp_obj_helper.h"

View file

@ -24,3 +24,6 @@ add_kmpp_base_test(kmpp_obj)
# kmpp frame unit test
add_kmpp_base_test(kmpp_frame)
# kmpp buffer unit test
add_kmpp_base_test(kmpp_buffer)

View file

@ -0,0 +1,128 @@
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#define MODULE_TAG "kmpp_buffer_test"
#include "mpp_debug.h"
#include "kmpp_obj.h"
#include "kmpp_buffer.h"
int main()
{
KmppShmPtr sptr;
KmppBufGrp grp = NULL;
KmppBufGrpCfg grp_cfg = NULL;
KmppBuffer buf = NULL;
KmppBufCfg buf_cfg = NULL;
rk_s32 used = 0;
rk_s32 unused = 0;
rk_u32 size = 1920 * 1080 * 3 / 2;
rk_s32 ret = rk_ok;
mpp_logi(MODULE_TAG " start\n");
/* KmppBufGrp object ready */
ret = kmpp_buf_grp_get(&grp);
mpp_logi("object %s ready\n", kmpp_obj_get_name(grp));
/* get KmppBufGrpCfg from KmppBufGrp to config */
grp_cfg = kmpp_buf_grp_to_cfg(grp);
mpp_logi("object %s ready\n", kmpp_obj_get_name(grp_cfg));
/* write parameters to KmppBufGrpCfg */
ret |= kmpp_buf_grp_cfg_set_flag(grp_cfg, 0);
ret |= kmpp_buf_grp_cfg_set_count(grp_cfg, 10);
ret |= kmpp_buf_grp_cfg_set_size(grp_cfg, size);
ret |= kmpp_buf_grp_cfg_set_fd(grp_cfg, -1);
sptr.uaddr = 0;
sptr.kptr = "rk dma heap";
ret |= kmpp_buf_grp_cfg_set_allocator(grp_cfg, &sptr);
sptr.uaddr = 0;
sptr.kptr = "test";
ret |= kmpp_buf_grp_cfg_set_name(grp_cfg, &sptr);
if (ret)
mpp_loge("set buf grp cfg failed\n");
/* enable KmppBufGrpCfg by ioctl */
ret = kmpp_buf_grp_setup(grp);
if (ret)
mpp_loge("setup buf grp cfg failed\n");
/* get KmppBuffer for buffer allocation */
ret = kmpp_buffer_get(&buf);
mpp_logi("object %s ready\n", kmpp_obj_get_name(buf));
/* get KmppBufCfg to setup */
buf_cfg = kmpp_buffer_to_cfg(buf);
mpp_logi("object %s ready\n", kmpp_obj_get_name(buf_cfg));
/* setup buffer config parameters */
ret = kmpp_buf_cfg_set_group(buf_cfg, kmpp_obj_to_shm(grp));
if (ret)
mpp_loge("set kmpp_buf_cfg_set_group failed\n");
/* set buffer size */
kmpp_buf_cfg_set_size(buf_cfg, size);
/* enable KmppBufCfg by ioctl */
kmpp_buffer_setup(buf);
if (ret)
mpp_loge("setup buf grp cfg failed\n");
/* get buffer group from buf_cfg */
ret = kmpp_buf_cfg_get_group(buf_cfg, &sptr);
if (ret)
mpp_loge("get buf cfg grp failed");
/* get buffer share pointer and access */
ret = kmpp_buf_cfg_get_sptr(buf_cfg, &sptr);
if (ret || !sptr.uptr)
mpp_loge("get buf cfg sptr failed");
ret = kmpp_buf_grp_cfg_get_used(grp_cfg, &used);
ret |= kmpp_buf_grp_cfg_get_unused(grp_cfg, &unused);
if (ret)
mpp_loge("get buf grp cfg used failed");
mpp_logi("buf grp cfg used %d unused %d after buffer_setup\n", used, unused);
mpp_assert(used == 1);
if (sptr.uptr) {
rk_u32 *val = sptr.uptr;
memset(sptr.uptr, 0xff, size);
*val = 0x12345678;
if (*val != 0x12345678)
mpp_loge("buf cfg sptr access failed");
else
mpp_logi("buf sptr [u:k] %p:%llx access success", sptr.uptr, sptr.kaddr);
}
if (buf) {
kmpp_buffer_put(buf);
buf = NULL;
}
ret = kmpp_buf_grp_cfg_get_used(grp_cfg, &used);
ret |= kmpp_buf_grp_cfg_get_unused(grp_cfg, &unused);
if (ret)
mpp_loge("get buf grp cfg used failed");
mpp_logi("buf grp cfg used %d unused %d after buffer_put\n", used, unused);
if (grp) {
kmpp_buf_grp_put(grp);
grp = NULL;
}
mpp_logi(MODULE_TAG " %s\n", ret ? "failed" : "success");
return ret;
}

View file

@ -9,6 +9,7 @@
#include "mpp_common.h"
#include "kmpp_obj.h"
#include "kmpp_buffer.h"
#define TEST_DETAIL 1
#define TEST_DEF_DUMP 2
@ -126,9 +127,10 @@ static rk_s32 kmpp_buffer_test(const char *name, rk_u32 flag)
test_detail("object %s ready\n", kmpp_obj_get_name(grp));
/* get KmppBufGrpCfg from KmppBufGrp to config */
ret = kmpp_obj_get_shm_obj(grp, "cfg", &grp_cfg);
if (ret) {
mpp_log("buf grp get cfg failed ret %d\n", ret);
grp_cfg = kmpp_buf_grp_to_cfg(grp);
if (!grp_cfg) {
mpp_log("buf grp to cfg failed ret %d\n", ret);
ret = MPP_NOK;
goto done;
}
@ -188,7 +190,7 @@ static rk_s32 kmpp_buffer_test(const char *name, rk_u32 flag)
test_detail("object %s write parameters ready\n", kmpp_obj_get_name(grp_cfg));
/* enable KmppBufGrpCfg by ioctl */
ret = kmpp_obj_ioctl_f(grp, 0, grp, NULL);
ret = kmpp_buf_grp_setup(grp);
test_detail("object %s ioctl ret %d\n", kmpp_obj_get_name(grp), ret);
@ -202,11 +204,10 @@ static rk_s32 kmpp_buffer_test(const char *name, rk_u32 flag)
test_detail("object %s ready\n", kmpp_obj_get_name(buf));
/* get KmppBufGrpCfg to setup */
sptr.uaddr = 0;
sptr.kaddr = 0;
ret = kmpp_obj_get_shm_obj(buf, "cfg", &buf_cfg);
if (ret) {
mpp_log("buf get cfg failed ret %d\n", ret);
buf_cfg = kmpp_buffer_to_cfg(buf);
if (!buf_cfg) {
mpp_log("buf to cfg failed ret %d\n", ret);
ret = MPP_NOK;
goto done;
}
@ -236,15 +237,9 @@ done:
if (grp)
kmpp_obj_put_f(grp);
if (grp_cfg)
kmpp_obj_put_impl_f(grp_cfg);
if (buf)
kmpp_obj_put_f(buf);
if (buf_cfg)
kmpp_obj_put_impl_f(buf_cfg);
return ret;
}