1 /* 2 * Copyright 2015 Rockchip Electronics Co. LTD 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef __MPP_BUFFER_IMPL_H__ 18 #define __MPP_BUFFER_IMPL_H__ 19 20 #include "mpp_list.h" 21 #include "mpp_hash.h" 22 #include "mpp_common.h" 23 #include "mpp_allocator.h" 24 25 #define MPP_BUF_DBG_FUNCTION (0x00000001) 26 #define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) 27 #define MPP_BUF_DBG_OPS_HISTORY (0x00000004) 28 #define MPP_BUF_DBG_CLR_ON_EXIT (0x00000010) 29 #define MPP_BUF_DBG_DUMP_ON_EXIT (0x00000020) 30 #define MPP_BUF_DBG_CHECK_SIZE (0x00000100) 31 32 #define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) 33 #define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) 34 35 #define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") 36 #define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") 37 #define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") 38 #define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") 39 40 typedef enum MppBufOps_e { 41 GRP_CREATE, 42 GRP_RELEASE, 43 GRP_RESET, 44 GRP_ORPHAN, 45 GRP_DESTROY, 46 47 GRP_OPS_BUTT = GRP_DESTROY, 48 BUF_COMMIT, 49 BUF_CREATE, 50 BUF_MMAP, 51 BUF_REF_INC, 52 BUF_REF_DEC, 53 BUF_DISCARD, 54 BUF_DESTROY, 55 BUF_OPS_BUTT, 56 } MppBufOps; 57 58 typedef struct MppBufLog_t { 59 RK_U32 group_id; 60 RK_S32 buffer_id; 61 MppBufOps ops; 62 RK_S32 ref_count; 63 const char *caller; 64 } MppBufLog; 65 66 typedef struct MppBufLogs_t { 67 pthread_mutex_t lock; 68 RK_U16 max_count; 69 RK_U16 log_count; 70 RK_U16 log_write; 71 RK_U16 log_read; 72 MppBufLog *logs; 73 } MppBufLogs; 74 75 typedef struct MppBufferImpl_t MppBufferImpl; 76 typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; 77 typedef void (*MppBufCallback)(void *, void *); 78 79 // use index instead of pointer to avoid invalid pointer 80 struct MppBufferImpl_t { 81 char tag[MPP_TAG_SIZE]; 82 const char *caller; 83 pthread_mutex_t lock; 84 /* parameter store from MppBufferGroup */ 85 MppAllocator allocator; 86 MppAllocatorApi *alloc_api; 87 RK_U32 log_runtime_en; 88 RK_U32 log_history_en; 89 RK_U32 group_id; 90 RK_S32 buffer_id; 91 MppBufferMode mode; 92 MppBufferType type; 93 MppBufLogs *logs; 94 95 MppBufferInfo info; 96 size_t offset; 97 size_t length; 98 99 /* 100 * discard: 101 * used for buf on group reset mode 102 * set disard value to 1 when frame refcount no zero , 103 * we will delay relesase buffer after refcount to zero, 104 * not put this buf to unused list 105 */ 106 RK_S32 discard; 107 // used flag is for used/unused list detection 108 RK_U32 used; 109 RK_S32 ref_count; 110 struct list_head list_status; 111 }; 112 113 struct MppBufferGroupImpl_t { 114 char tag[MPP_TAG_SIZE]; 115 const char *caller; 116 /* parameter store for MppBuffer */ 117 MppAllocator allocator; 118 MppAllocatorApi *alloc_api; 119 RK_U32 log_runtime_en; 120 RK_U32 log_history_en; 121 RK_U32 group_id; 122 MppBufferMode mode; 123 MppBufferType type; 124 125 /* group status flag */ 126 // buffer force clear mode flag 127 RK_U32 clear_on_exit; 128 RK_U32 dump_on_exit; 129 // is_misc: 0 - normal group 1 - misc group 130 RK_U32 is_misc; 131 // is_orphan: 0 - normal group 1 - orphan group 132 RK_U32 is_orphan; 133 RK_U32 is_finalizing; 134 // used in limit mode only 135 size_t limit_size; 136 RK_S32 limit_count; 137 // status record 138 size_t limit; 139 size_t usage; 140 RK_S32 buffer_id; 141 RK_S32 buffer_count; 142 143 // thread that will be signal on buffer return 144 MppBufCallback callback; 145 void *arg; 146 147 // link to list_status in MppBufferImpl 148 pthread_mutex_t buf_lock; 149 struct hlist_node hlist; 150 struct list_head list_used; 151 struct list_head list_unused; 152 RK_S32 count_used; 153 RK_S32 count_unused; 154 155 // buffer log function 156 MppBufLogs *logs; 157 158 // link to the other MppBufferGroupImpl 159 struct list_head list_group; 160 }; 161 162 #ifdef __cplusplus 163 extern "C" { 164 #endif 165 166 extern RK_U32 mpp_buffer_debug; 167 168 /* 169 * mpp_buffer_create : create a unused buffer with parameter tag/size/data 170 * if input buffer is NULL then buffer will be register to unused list 171 * otherwise the buffer will be register to used list and set to paramter buffer 172 * 173 * mpp_buffer_mmap : The created mpp_buffer can not be accessed directly. 174 * It required map to access. This is an optimization 175 * for reducing virtual memory usage. 176 * 177 * mpp_buffer_get_unused : get unused buffer with size. it will first search 178 * the unused list. if failed it will create on from 179 * group allocator. 180 * 181 * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused 182 * then it will be moved to used list. 183 * 184 * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference 185 * reduce to zero buffer will be moved to unused list. 186 * 187 * normal call flow will be like this: 188 * 189 * mpp_buffer_create - create a unused buffer 190 * mpp_buffer_get_unused - get the unused buffer 191 * mpp_buffer_ref_inc/dec - use the buffer 192 * mpp_buffer_destory - destroy the buffer 193 */ 194 MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); 195 MPP_RET mpp_buffer_mmap(MppBufferImpl *buffer, const char* caller); 196 MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); 197 MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); 198 MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size, const char* caller); 199 RK_U32 mpp_buffer_to_addr(MppBuffer buffer, size_t offset); 200 201 MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); 202 MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); 203 MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); 204 MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p, 205 MppBufCallback callback, void *arg); 206 // mpp_buffer_group helper function 207 void mpp_buffer_group_dump(MppBufferGroupImpl *p); 208 void mpp_buffer_service_dump(const char *info); 209 MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); 210 211 #ifdef __cplusplus 212 } 213 #endif 214 215 #endif /*__MPP_BUFFER_IMPL_H__*/ 216