/* * 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. */ #ifndef __MPP_BUFFER_IMPL_H__ #define __MPP_BUFFER_IMPL_H__ #include "mpp_list.h" #include "mpp_hash.h" #include "mpp_common.h" #include "mpp_allocator.h" #define MPP_BUF_DBG_FUNCTION (0x00000001) #define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) #define MPP_BUF_DBG_OPS_HISTORY (0x00000004) #define MPP_BUF_DBG_CLR_ON_EXIT (0x00000010) #define MPP_BUF_DBG_DUMP_ON_EXIT (0x00000020) #define MPP_BUF_DBG_CHECK_SIZE (0x00000100) #define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) #define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) #define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") #define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") #define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") #define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") typedef enum MppBufOps_e { GRP_CREATE, GRP_RELEASE, GRP_RESET, GRP_ORPHAN, GRP_DESTROY, GRP_OPS_BUTT = GRP_DESTROY, BUF_COMMIT, BUF_CREATE, BUF_MMAP, BUF_REF_INC, BUF_REF_DEC, BUF_DISCARD, BUF_DESTROY, BUF_OPS_BUTT, } MppBufOps; typedef struct MppBufLog_t { RK_U32 group_id; RK_S32 buffer_id; MppBufOps ops; RK_S32 ref_count; const char *caller; } MppBufLog; typedef struct MppBufLogs_t { pthread_mutex_t lock; RK_U16 max_count; RK_U16 log_count; RK_U16 log_write; RK_U16 log_read; MppBufLog *logs; } MppBufLogs; typedef struct MppBufferImpl_t MppBufferImpl; typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; typedef void (*MppBufCallback)(void *, void *); // use index instead of pointer to avoid invalid pointer struct MppBufferImpl_t { char tag[MPP_TAG_SIZE]; const char *caller; pthread_mutex_t lock; /* parameter store from MppBufferGroup */ MppAllocator allocator; MppAllocatorApi *alloc_api; RK_U32 log_runtime_en; RK_U32 log_history_en; RK_U32 group_id; RK_S32 buffer_id; MppBufferMode mode; MppBufferType type; MppBufLogs *logs; MppBufferInfo info; size_t offset; size_t length; /* * discard: * used for buf on group reset mode * set disard value to 1 when frame refcount no zero , * we will delay relesase buffer after refcount to zero, * not put this buf to unused list */ RK_S32 discard; // used flag is for used/unused list detection RK_U32 used; RK_S32 ref_count; struct list_head list_status; }; struct MppBufferGroupImpl_t { char tag[MPP_TAG_SIZE]; const char *caller; /* parameter store for MppBuffer */ MppAllocator allocator; MppAllocatorApi *alloc_api; RK_U32 log_runtime_en; RK_U32 log_history_en; RK_U32 group_id; MppBufferMode mode; MppBufferType type; /* group status flag */ // buffer force clear mode flag RK_U32 clear_on_exit; RK_U32 dump_on_exit; // is_misc: 0 - normal group 1 - misc group RK_U32 is_misc; // is_orphan: 0 - normal group 1 - orphan group RK_U32 is_orphan; RK_U32 is_finalizing; // used in limit mode only size_t limit_size; RK_S32 limit_count; // status record size_t limit; size_t usage; RK_S32 buffer_id; RK_S32 buffer_count; // thread that will be signal on buffer return MppBufCallback callback; void *arg; // link to list_status in MppBufferImpl pthread_mutex_t buf_lock; struct hlist_node hlist; struct list_head list_used; struct list_head list_unused; RK_S32 count_used; RK_S32 count_unused; // buffer log function MppBufLogs *logs; // link to the other MppBufferGroupImpl struct list_head list_group; }; #ifdef __cplusplus extern "C" { #endif extern RK_U32 mpp_buffer_debug; /* * mpp_buffer_create : create a unused buffer with parameter tag/size/data * if input buffer is NULL then buffer will be register to unused list * otherwise the buffer will be register to used list and set to paramter buffer * * mpp_buffer_mmap : The created mpp_buffer can not be accessed directly. * It required map to access. This is an optimization * for reducing virtual memory usage. * * mpp_buffer_get_unused : get unused buffer with size. it will first search * the unused list. if failed it will create on from * group allocator. * * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused * then it will be moved to used list. * * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference * reduce to zero buffer will be moved to unused list. * * normal call flow will be like this: * * mpp_buffer_create - create a unused buffer * mpp_buffer_get_unused - get the unused buffer * mpp_buffer_ref_inc/dec - use the buffer * mpp_buffer_destory - destroy the buffer */ MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); MPP_RET mpp_buffer_mmap(MppBufferImpl *buffer, const char* caller); MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size, const char* caller); RK_U32 mpp_buffer_to_addr(MppBuffer buffer, size_t offset); MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p, MppBufCallback callback, void *arg); // mpp_buffer_group helper function void mpp_buffer_group_dump(MppBufferGroupImpl *p); void mpp_buffer_service_dump(const char *info); MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); #ifdef __cplusplus } #endif #endif /*__MPP_BUFFER_IMPL_H__*/