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