diff --git a/inc/mpp_buffer.h b/inc/mpp_buffer.h index 08d93d3a..c7297246 100644 --- a/inc/mpp_buffer.h +++ b/inc/mpp_buffer.h @@ -140,17 +140,29 @@ typedef enum { MPP_BUFFER_TYPE_BUTT, } MppBufferType; -typedef union MppBufferData_t MppBufferData; -union MppBufferData_t { - void *ptr; - int fd; -}; - +/* + * MppBufferInfo variable's meaning is different in different MppBufferType + * + * MPP_BUFFER_TYPE_NORMAL + * + * ptr - virtual address of normal malloced buffer + * fd - unused and set to -1 + * + * MPP_BUFFER_TYPE_ION + * + * ptr - ion handle in user space + * fd - ion buffer file handle for map / unmap + * + * MPP_BUFFER_TYPE_V4L2 + * + * TODO: to be implemented. + */ typedef struct { MppBufferType type; size_t size; - MppBufferData data; -} MppBufferCommit; + void *ptr; + int fd; +} MppBufferInfo; #define BUFFER_GROUP_SIZE_DEFAULT (SZ_1M*80) @@ -172,10 +184,11 @@ extern "C" { * these interface will change value of group and buffer so before calling functions * parameter need to be checked. */ -MPP_RET mpp_buffer_commit(MppBufferGroup group, MppBufferCommit *info); +MPP_RET mpp_buffer_commit(MppBufferGroup group, MppBufferInfo *info); MPP_RET mpp_buffer_get_with_tag(const char *tag, MppBufferGroup group, MppBuffer *buffer, size_t size); MPP_RET mpp_buffer_put(MppBuffer *buffer); MPP_RET mpp_buffer_inc_ref(MppBuffer buffer); +MPP_RET mpp_buffer_info_get(MppBuffer buffer, MppBufferInfo *info); MPP_RET mpp_buffer_group_get(const char *tag, MppBufferMode mode, MppBufferGroup *group, MppBufferType type); MPP_RET mpp_buffer_group_put(MppBufferGroup *group); diff --git a/mpp/mpp_buffer.cpp b/mpp/mpp_buffer.cpp index a5a02d69..240d9639 100644 --- a/mpp/mpp_buffer.cpp +++ b/mpp/mpp_buffer.cpp @@ -22,7 +22,7 @@ #include "mpp_mem.h" #include "mpp_buffer_impl.h" -MPP_RET mpp_buffer_commit(MppBufferGroup group, MppBufferCommit *info) +MPP_RET mpp_buffer_commit(MppBufferGroup group, MppBufferInfo *info) { if (NULL == group || NULL == info) { mpp_err("mpp_buffer_commit input null pointer group %p info %p\n", @@ -37,7 +37,7 @@ MPP_RET mpp_buffer_commit(MppBufferGroup group, MppBufferCommit *info) return MPP_ERR_UNKNOW; } - return mpp_buffer_create(NULL, p->group_id, info->size, &info->data); + return mpp_buffer_create(NULL, p->group_id, info); } MPP_RET mpp_buffer_get_with_tag(const char *tag, MppBufferGroup group, MppBuffer *buffer, size_t size) @@ -52,8 +52,14 @@ MPP_RET mpp_buffer_get_with_tag(const char *tag, MppBufferGroup group, MppBuffer // try unused buffer first MppBufferImpl *buf = mpp_buffer_get_unused(tmp, size); if (NULL == buf) { + MppBufferInfo info = { + tmp->type, + size, + NULL, + -1, + }; // if failed try init a new buffer - mpp_buffer_create(tag, tmp->group_id, size, NULL); + mpp_buffer_create(tag, tmp->group_id, &info); buf = mpp_buffer_get_unused(tmp, size); } *buffer = buf; diff --git a/mpp/mpp_buffer_impl.cpp b/mpp/mpp_buffer_impl.cpp index 59f4d8d5..01735e87 100644 --- a/mpp/mpp_buffer_impl.cpp +++ b/mpp/mpp_buffer_impl.cpp @@ -75,16 +75,20 @@ MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer) list_del_init(&buffer->list_status); MppBufferGroupImpl *group = SEARCH_GROUP_NORMAL(buffer->group_id); if (group) { - if (MPP_BUFFER_MODE_NORMAL == buffer->mode) { - group->alloc_api->free(group->allocator, &buffer->data); + switch (group->mode) { + case MPP_BUFFER_MODE_NORMAL : { + group->alloc_api->free(group->allocator, &buffer->info); + } break; + default : { + } break; } - group->usage -= buffer->size; + group->usage -= buffer->info.size; } else { group = SEARCH_GROUP_ORPHAN(buffer->group_id); mpp_assert(group); mpp_assert(buffer->mode == MPP_BUFFER_MODE_NORMAL); - group->alloc_api->free(group->allocator, &buffer->data); - group->usage -= buffer->size; + group->alloc_api->free(group->allocator, &buffer->info); + group->usage -= buffer->info.size; group->count--; if (0 == group->usage) deinit_group_no_lock(group); @@ -127,7 +131,7 @@ static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer) return ret; } -MPP_RET mpp_buffer_create(const char *tag, RK_U32 group_id, size_t size, MppBufferData *data) +MPP_RET mpp_buffer_create(const char *tag, RK_U32 group_id, MppBufferInfo *info) { MppBufferImpl *p = mpp_malloc(MppBufferImpl, 1); if (NULL == p) { @@ -139,37 +143,32 @@ MPP_RET mpp_buffer_create(const char *tag, RK_U32 group_id, size_t size, MppBuff MppBufferGroupImpl *group = SEARCH_GROUP_NORMAL(group_id); if (group) { - if (NULL == data) { - MppBufferData tmp; - MPP_RET ret = group->alloc_api->alloc(group->allocator, &tmp, size); + if (NULL == info->ptr && info->fd == -1) { + MPP_RET ret = group->alloc_api->alloc(group->allocator, info); if (MPP_OK != ret) { - mpp_err("mpp_buffer_create failed to create buffer with size %d\n", size); + mpp_err("mpp_buffer_create failed to create buffer with size %d\n", info->size); mpp_free(p); MPP_BUFFER_SERVICE_UNLOCK(); return MPP_ERR_MALLOC; } - - p->data = tmp; - p->mode = MPP_BUFFER_MODE_NORMAL; - } else { - p->data = *data; - p->mode = MPP_BUFFER_MODE_LIMIT; } + p->info = *info; + p->mode = group->mode; + if (NULL == tag) tag = group->tag; strncpy(p->tag, tag, sizeof(p->tag)); p->group_id = group_id; - p->size = size; - p->type = group->type; p->used = 0; p->ref_count = 0; INIT_LIST_HEAD(&p->list_status); list_add_tail(&p->list_status, &group->list_unused); - group->usage += size; + group->usage += info->size; group->count++; } else { + mpp_err("mpp_buffer_create can not create buffer without group\n"); mpp_free(p); p = NULL; } @@ -238,7 +237,7 @@ MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size) if (!list_empty(&p->list_unused)) { MppBufferImpl *pos, *n; list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { - if (pos->size == size) { + if (pos->info.size == size) { buffer = pos; inc_buffer_ref_no_lock(buffer); break; diff --git a/mpp/mpp_buffer_impl.h b/mpp/mpp_buffer_impl.h index 36dc9474..75c496ec 100644 --- a/mpp/mpp_buffer_impl.h +++ b/mpp/mpp_buffer_impl.h @@ -37,11 +37,9 @@ typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; struct MppBufferImpl_t { char tag[MPP_TAG_SIZE]; RK_U32 group_id; - MppBufferType type; MppBufferMode mode; - MppBufferData data; - size_t size; + MppBufferInfo info; // used flag is for used/unused list detection RK_U32 used; @@ -102,7 +100,7 @@ extern RK_U32 mpp_buffer_debug; * mpp_buffer_ref_inc/dec - use the buffer * mpp_buffer_destory - destroy the buffer */ -MPP_RET mpp_buffer_create(const char *tag, RK_U32 group_id, size_t size, MppBufferData *data); +MPP_RET mpp_buffer_create(const char *tag, RK_U32 group_id, MppBufferInfo *info); MPP_RET mpp_buffer_destroy(MppBufferImpl *buffer); MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer); MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer); diff --git a/osal/android/os_allocator.c b/osal/android/os_allocator.c index c36dcaf0..0f56f3bf 100644 --- a/osal/android/os_allocator.c +++ b/osal/android/os_allocator.c @@ -161,7 +161,7 @@ MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type) return 0; } -MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) +MPP_RET os_allocator_alloc(void *ctx, MppBufferInfo *data, size_t size) { MPP_RET ret = MPP_OK; allocator_impl *p = NULL; @@ -188,7 +188,7 @@ MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) return ret; } -MPP_RET os_allocator_free(void *ctx, MppBufferData *data) +MPP_RET os_allocator_free(void *ctx, MppBufferInfo *data) { MPP_RET ret = MPP_OK; allocator_impl *p = NULL; diff --git a/osal/inc/mpp_allocator.h b/osal/inc/mpp_allocator.h index ed92f3cc..80180541 100644 --- a/osal/inc/mpp_allocator.h +++ b/osal/inc/mpp_allocator.h @@ -26,8 +26,8 @@ typedef struct { RK_U32 size; RK_U32 version; - MPP_RET (*alloc)(MppAllocator allocator, MppBufferData *data, size_t size); - MPP_RET (*free)(MppAllocator allocator, MppBufferData *data); + MPP_RET (*alloc)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*free)(MppAllocator allocator, MppBufferInfo *data); } MppAllocatorApi; #ifdef __cplusplus diff --git a/osal/linux/os_allocator.c b/osal/linux/os_allocator.c index 40bde9d8..eaf6556c 100644 --- a/osal/linux/os_allocator.c +++ b/osal/linux/os_allocator.c @@ -31,8 +31,9 @@ typedef struct { MppBufferType type; } allocator_impl; -MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type) +MPP_RET os_allocator_normal_open(void **ctx, size_t alignment) { + MPP_RET ret = MPP_OK; allocator_impl *p = NULL; if (NULL == ctx) { @@ -40,30 +41,19 @@ MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type) return MPP_ERR_NULL_PTR; } - switch (type) { - case MPP_BUFFER_TYPE_NORMAL : { - p = mpp_malloc(allocator_impl, 1); - if (NULL == p) { - *ctx = NULL; - mpp_err("os_allocator_open Linux failed to allocate context\n"); - return MPP_ERR_MALLOC; - } - + p = mpp_malloc(allocator_impl, 1); + if (NULL == p) { + mpp_err("os_allocator_open Linux failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + } else p->alignment = alignment; - p->type = type; - } break; - default : { - mpp_err("os_allocator_open Window do not accept type %d\n"); - } break; - } *ctx = p; - return MPP_OK; + return ret; } -MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) +MPP_RET os_allocator_normal_alloc(void *ctx, MppBufferInfo *info) { - MPP_RET ret = MPP_OK; allocator_impl *p = NULL; if (NULL == ctx) { @@ -72,31 +62,17 @@ MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) } p = (allocator_impl *)ctx; - switch (p->type) { - case MPP_BUFFER_TYPE_NORMAL : { - ret = os_malloc(&data->ptr, p->alignment, size); - } break; - case MPP_BUFFER_TYPE_V4L2 : { - // TODO: support v4l2 vb2 buffer queue - mpp_err("os_allocator_alloc Linux MPP_BUFFER_TYPE_V4L2 will support later\n"); - ret = MPP_ERR_UNKNOW; - } break; - default : { - mpp_err("os_allocator_alloc Linux do not accept type %d\n", p->type); - ret = MPP_ERR_UNKNOW; - } break; - } - return ret; + return os_malloc(&info->ptr, p->alignment, info->size); } -MPP_RET os_allocator_free(void *ctx, MppBufferData *data) +MPP_RET os_allocator_normal_free(void *ctx, MppBufferInfo *info) { (void) ctx; - os_free(data->ptr); + os_free(info->ptr); return MPP_OK; } -MPP_RET os_allocator_close(void *ctx) +MPP_RET os_allocator_normal_close(void *ctx) { if (ctx) { mpp_free(ctx); @@ -106,3 +82,36 @@ MPP_RET os_allocator_close(void *ctx) return MPP_NOK; } +static os_allocator allocator_normal = { + os_allocator_normal_open, + os_allocator_normal_alloc, + os_allocator_normal_free, + os_allocator_normal_close, +}; + +static os_allocator allocator_v4l2 = { + os_allocator_normal_open, + os_allocator_normal_alloc, + os_allocator_normal_free, + os_allocator_normal_close, +}; + +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) +{ + MPP_RET ret = MPP_OK; + switch (type) { + case MPP_BUFFER_TYPE_NORMAL : + case MPP_BUFFER_TYPE_ION : { + *api = allocator_normal; + } break; + case MPP_BUFFER_TYPE_V4L2 : { + mpp_err("os_allocator_get Linux MPP_BUFFER_TYPE_V4L2 do not implement yet\n"); + *api = allocator_v4l2; + } break; + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + diff --git a/osal/mpp_allocator.cpp b/osal/mpp_allocator.cpp index ceb997ff..f121d217 100644 --- a/osal/mpp_allocator.cpp +++ b/osal/mpp_allocator.cpp @@ -26,36 +26,40 @@ #define MPP_ALLOCATOR_LOCK(p) pthread_mutex_lock(&(p)->lock); #define MPP_ALLOCATOR_UNLOCK(p) pthread_mutex_unlock(&(p)->lock); -MPP_RET mpp_allocator_alloc(MppAllocator allocator, MppBufferData *data, size_t size) +MPP_RET mpp_allocator_alloc(MppAllocator allocator, MppBufferInfo *info) { - if (NULL == allocator || NULL == data || 0 == size) { - mpp_err("mpp_allocator_alloc invalid input: allocator %p data %p size %d\n", - allocator, data, size); + if (NULL == allocator || NULL == info) { + mpp_err("mpp_allocator_alloc invalid input: allocator %p info %p\n", + allocator, info); return MPP_ERR_UNKNOW; } - MppAllocatorImpl *palloc = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(palloc); - MPP_RET ret = os_allocator_alloc(palloc->allocator, data, size); - MPP_ALLOCATOR_UNLOCK(palloc); + MPP_RET ret = MPP_OK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.alloc) + ret = p->os_api.alloc(p->ctx, info); + MPP_ALLOCATOR_UNLOCK(p); return ret; } -MPP_RET mpp_allocator_free(MppAllocator allocator, MppBufferData *data) +MPP_RET mpp_allocator_free(MppAllocator allocator, MppBufferInfo *info) { - if (NULL == allocator || NULL == data) { - mpp_err("mpp_allocator_alloc invalid input: allocator %p data %p\n", - allocator, data); + if (NULL == allocator || NULL == info) { + mpp_err("mpp_allocator_alloc invalid input: allocator %p info %p\n", + allocator, info); return MPP_ERR_UNKNOW; } - MppAllocatorImpl *palloc = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(palloc); - os_allocator_free(palloc->allocator, data); - MPP_ALLOCATOR_UNLOCK(palloc); + MPP_RET ret = MPP_OK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.free) + ret = p->os_api.free(p->ctx, info); + MPP_ALLOCATOR_UNLOCK(p); - return MPP_OK; + return ret; } static MppAllocatorApi mpp_allocator_api = { @@ -73,26 +77,36 @@ MPP_RET mpp_alloctor_get(MppAllocator *allocator, MppAllocatorApi **api, MppBuff return MPP_ERR_UNKNOW; } - MppAllocatorImpl *palloc = mpp_malloc(MppAllocatorImpl, 1); - if (NULL == palloc) { + MppAllocatorImpl *p = mpp_malloc(MppAllocatorImpl, 1); + if (NULL == p) { mpp_err("mpp_alloctor_get failed to malloc allocator context\n"); return MPP_ERR_NULL_PTR; + } else + p->type = type; + + + MPP_RET ret = os_allocator_get(&p->os_api, type); + if (MPP_OK == ret) { + p->alignment = SZ_4K; + ret = p->os_api.open(&p->ctx, p->alignment); + } + if (MPP_OK == ret) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p->lock, &attr); + pthread_mutexattr_destroy(&attr); + + *allocator = p; + *api = &mpp_allocator_api; + } else { + mpp_err("mpp_alloctor_get type %d failed\n", type); + mpp_free(p); + *allocator = NULL; + *api = NULL; } - palloc->alignment = SZ_4K; - os_allocator_open(&palloc->allocator, palloc->alignment, type); - palloc->api = &mpp_allocator_api; - - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&palloc->lock, &attr); - pthread_mutexattr_destroy(&attr); - - *allocator = palloc; - *api = &mpp_allocator_api; - - return MPP_OK; + return ret; } MPP_RET mpp_alloctor_put(MppAllocator *allocator) @@ -104,8 +118,8 @@ MPP_RET mpp_alloctor_put(MppAllocator *allocator) MppAllocatorImpl *p = (MppAllocatorImpl *)*allocator; *allocator = NULL; - os_allocator_close(p->allocator); - + if (p->os_api.close) + p->os_api.close(p->ctx); if (p) mpp_free(p); diff --git a/osal/mpp_allocator_impl.h b/osal/mpp_allocator_impl.h index 98805fae..cb3f2b74 100644 --- a/osal/mpp_allocator_impl.h +++ b/osal/mpp_allocator_impl.h @@ -18,14 +18,14 @@ #define __MPP_ALLOCATOR_IMPL_H__ #include "mpp_thread.h" -#include "mpp_buffer.h" +#include "os_allocator.h" typedef struct { pthread_mutex_t lock; MppBufferType type; size_t alignment; - void *allocator; - void *api; + os_allocator os_api; + void *ctx; } MppAllocatorImpl; #endif /*__MPP_ALLOCATOR_IMPL_H__*/ diff --git a/osal/os_allocator.h b/osal/os_allocator.h index d56ef5aa..813289a7 100644 --- a/osal/os_allocator.h +++ b/osal/os_allocator.h @@ -19,14 +19,18 @@ #include "mpp_allocator.h" +typedef struct { + MPP_RET (*open)(void **ctx, size_t alignment); + MPP_RET (*alloc)(void *ctx, MppBufferInfo *info); + MPP_RET (*free)(void *ctx, MppBufferInfo *info); + MPP_RET (*close)(void *ctx); +} os_allocator; + #ifdef __cplusplus extern "C" { #endif -MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type); -MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size); -MPP_RET os_allocator_free(void *ctx, MppBufferData *data); -MPP_RET os_allocator_close(void *ctx); +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type); #ifdef __cplusplus } diff --git a/osal/window/os_allocator.c b/osal/window/os_allocator.c index 1f3637d7..f6058f0b 100644 --- a/osal/window/os_allocator.c +++ b/osal/window/os_allocator.c @@ -28,8 +28,9 @@ typedef struct { size_t alignment; } allocator_impl; -MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type) +MPP_RET os_allocator_open(void **ctx, size_t alignment) { + MPP_RET ret = MPP_OK; allocator_impl *p = NULL; if (NULL == ctx) { @@ -37,27 +38,18 @@ MPP_RET os_allocator_open(void **ctx, size_t alignment, MppBufferType type) return MPP_ERR_NULL_PTR; } - switch (type) { - case MPP_BUFFER_TYPE_NORMAL : { - p = mpp_malloc(allocator_impl, 1); - if (NULL == p) { - *ctx = NULL; - mpp_err("os_allocator_open Window failed to allocate context\n"); - return MPP_ERR_MALLOC; - } - + p = mpp_malloc(allocator_impl, 1); + if (NULL == p) { + mpp_err("os_allocator_open Window failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + } else p->alignment = alignment; - } break; - default : { - mpp_err("os_allocator_open Window do not accept type %d\n"); - } break; - } *ctx = p; - return MPP_OK; + return ret; } -MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) +MPP_RET os_allocator_alloc(void *ctx, MppBufferInfo *info) { allocator_impl *p = NULL; @@ -67,10 +59,10 @@ MPP_RET os_allocator_alloc(void *ctx, MppBufferData *data, size_t size) } p = (allocator_impl *)ctx; - return (MPP_RET)os_malloc(&data->ptr, p->alignment, size); + return (MPP_RET)os_malloc(&info->ptr, p->alignment, info->size); } -MPP_RET os_allocator_free(void *ctx, MppBufferData *data) +MPP_RET os_allocator_free(void *ctx, MppBufferInfo *data) { (void) ctx; os_free(data->ptr); @@ -87,3 +79,26 @@ MPP_RET os_allocator_close(void *ctx) return MPP_NOK; } +static os_allocator allocator_window = { + os_allocator_open, + os_allocator_alloc, + os_allocator_free, + os_allocator_close, +}; + +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) +{ + MPP_RET ret = MPP_OK; + switch (type) { + case MPP_BUFFER_TYPE_NORMAL : + case MPP_BUFFER_TYPE_ION : + case MPP_BUFFER_TYPE_V4L2 : { + *api = allocator_window; + } break; + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + diff --git a/test/mpp_buffer_test.c b/test/mpp_buffer_test.c index 952ec136..3f7ef5d7 100644 --- a/test/mpp_buffer_test.c +++ b/test/mpp_buffer_test.c @@ -28,7 +28,7 @@ int main() { MPP_RET ret = MPP_OK; - MppBufferCommit commit; + MppBufferInfo commit; MppBufferGroup group = NULL; MppBuffer commit_buffer[MPP_BUFFER_TEST_COMMIT_COUNT]; void *commit_ptr[MPP_BUFFER_TEST_COMMIT_COUNT]; @@ -63,7 +63,7 @@ int main() goto MPP_BUFFER_failed; } - commit.data.ptr = commit_ptr[i]; + commit.ptr = commit_ptr[i]; ret = mpp_buffer_commit(group, &commit); if (MPP_OK != ret) {