1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright 2015 Rockchip Electronics Co. LTD 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License"); 5*4882a593Smuzhiyun * you may not use this file except in compliance with the License. 6*4882a593Smuzhiyun * You may obtain a copy of the License at 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software 11*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS, 12*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*4882a593Smuzhiyun * See the License for the specific language governing permissions and 14*4882a593Smuzhiyun * limitations under the License. 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #ifndef __MPP_BUFFER_H__ 18*4882a593Smuzhiyun #define __MPP_BUFFER_H__ 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include "rk_type.h" 21*4882a593Smuzhiyun #include "mpp_err.h" 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* 24*4882a593Smuzhiyun * MppBuffer module has several functions: 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * 1. buffer get / put / reference management / external commit / get info. 27*4882a593Smuzhiyun * this part is the basic user interface for MppBuffer. 28*4882a593Smuzhiyun * 29*4882a593Smuzhiyun * function: 30*4882a593Smuzhiyun * 31*4882a593Smuzhiyun * mpp_buffer_get 32*4882a593Smuzhiyun * mpp_buffer_put 33*4882a593Smuzhiyun * mpp_buffer_inc_ref 34*4882a593Smuzhiyun * mpp_buffer_commit 35*4882a593Smuzhiyun * mpp_buffer_info_get 36*4882a593Smuzhiyun * 37*4882a593Smuzhiyun * 2. user buffer working flow control abstraction. 38*4882a593Smuzhiyun * buffer should attach to certain group, and buffer mode control the buffer usage flow. 39*4882a593Smuzhiyun * this part is also a part of user interface. 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * function: 42*4882a593Smuzhiyun * 43*4882a593Smuzhiyun * mpp_buffer_group_get 44*4882a593Smuzhiyun * mpp_buffer_group_normal_get 45*4882a593Smuzhiyun * mpp_buffer_group_limit_get 46*4882a593Smuzhiyun * mpp_buffer_group_put 47*4882a593Smuzhiyun * mpp_buffer_group_limit_config 48*4882a593Smuzhiyun * 49*4882a593Smuzhiyun * 3. buffer allocator management 50*4882a593Smuzhiyun * this part is for allocator on different os, it does not have user interface 51*4882a593Smuzhiyun * it will support normal buffer, Android ion buffer, Linux v4l2 vb2 buffer 52*4882a593Smuzhiyun * user can only use MppBufferType to choose. 53*4882a593Smuzhiyun * 54*4882a593Smuzhiyun */ 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun /* 57*4882a593Smuzhiyun * mpp buffer group support two work flow mode: 58*4882a593Smuzhiyun * 59*4882a593Smuzhiyun * normal flow: all buffer are generated by MPP 60*4882a593Smuzhiyun * under this mode, buffer pool is maintained internally 61*4882a593Smuzhiyun * 62*4882a593Smuzhiyun * typical call flow: 63*4882a593Smuzhiyun * 64*4882a593Smuzhiyun * mpp_buffer_group_get() return A 65*4882a593Smuzhiyun * mpp_buffer_get(A) return a ref +1 -> used 66*4882a593Smuzhiyun * mpp_buffer_inc_ref(a) ref +1 67*4882a593Smuzhiyun * mpp_buffer_put(a) ref -1 68*4882a593Smuzhiyun * mpp_buffer_put(a) ref -1 -> unused 69*4882a593Smuzhiyun * mpp_buffer_group_put(A) 70*4882a593Smuzhiyun * 71*4882a593Smuzhiyun * commit flow: all buffer are commited out of MPP 72*4882a593Smuzhiyun * under this mode, buffers is commit by external api. 73*4882a593Smuzhiyun * normally MPP only use it but not generate it. 74*4882a593Smuzhiyun * 75*4882a593Smuzhiyun * typical call flow: 76*4882a593Smuzhiyun * 77*4882a593Smuzhiyun * ==== external allocator ==== 78*4882a593Smuzhiyun * mpp_buffer_group_get() return A 79*4882a593Smuzhiyun * mpp_buffer_commit(A, x) 80*4882a593Smuzhiyun * mpp_buffer_commit(A, y) 81*4882a593Smuzhiyun * 82*4882a593Smuzhiyun * ======= internal user ====== 83*4882a593Smuzhiyun * mpp_buffer_get(A) return a 84*4882a593Smuzhiyun * mpp_buffer_get(A) return b 85*4882a593Smuzhiyun * mpp_buffer_put(a) 86*4882a593Smuzhiyun * mpp_buffer_put(b) 87*4882a593Smuzhiyun * 88*4882a593Smuzhiyun * ==== external allocator ==== 89*4882a593Smuzhiyun * mpp_buffer_group_put(A) 90*4882a593Smuzhiyun * 91*4882a593Smuzhiyun * NOTE: commit interface required group handle to record group information 92*4882a593Smuzhiyun */ 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /* 95*4882a593Smuzhiyun * mpp buffer group has two buffer limit mode: normal and limit 96*4882a593Smuzhiyun * 97*4882a593Smuzhiyun * normal mode: allows any buffer size and always general new buffer is no unused buffer 98*4882a593Smuzhiyun * is available. 99*4882a593Smuzhiyun * This mode normally use with normal flow and is used for table / stream buffer 100*4882a593Smuzhiyun * 101*4882a593Smuzhiyun * limit mode : restrict the buffer's size and count in the buffer group. if try to calloc 102*4882a593Smuzhiyun * buffer with different size or extra count it will fail. 103*4882a593Smuzhiyun * This mode normally use with commit flow and is used for frame buffer 104*4882a593Smuzhiyun */ 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* 107*4882a593Smuzhiyun * NOTE: normal mode is recommanded to work with normal flow, working with limit mode is not. 108*4882a593Smuzhiyun * limit mode is recommanded to work with commit flow, working with normal mode is not. 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun typedef enum { 111*4882a593Smuzhiyun MPP_BUFFER_INTERNAL, 112*4882a593Smuzhiyun MPP_BUFFER_EXTERNAL, 113*4882a593Smuzhiyun MPP_BUFFER_MODE_BUTT, 114*4882a593Smuzhiyun } MppBufferMode; 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun /* 117*4882a593Smuzhiyun * the mpp buffer has serval types: 118*4882a593Smuzhiyun * 119*4882a593Smuzhiyun * normal : normal malloc buffer for unit test or hardware simulation 120*4882a593Smuzhiyun * ion : use ion device under Android/Linux, MppBuffer will encapsulte ion file handle 121*4882a593Smuzhiyun * ext_dma : the DMABUF(DMA buffers) come from the application 122*4882a593Smuzhiyun * drm : use the drm device interface for memory management 123*4882a593Smuzhiyun */ 124*4882a593Smuzhiyun typedef enum { 125*4882a593Smuzhiyun MPP_BUFFER_TYPE_NORMAL, 126*4882a593Smuzhiyun MPP_BUFFER_TYPE_ION, 127*4882a593Smuzhiyun MPP_BUFFER_TYPE_EXT_DMA, 128*4882a593Smuzhiyun MPP_BUFFER_TYPE_DRM, 129*4882a593Smuzhiyun MPP_BUFFER_TYPE_DMA_HEAP, 130*4882a593Smuzhiyun MPP_BUFFER_TYPE_BUTT, 131*4882a593Smuzhiyun } MppBufferType; 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun #define MPP_BUFFER_TYPE_MASK 0x0000FFFF 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun /* 136*4882a593Smuzhiyun * MPP_BUFFER_FLAGS cooperate with MppBufferType 137*4882a593Smuzhiyun * 16 high bits of MppBufferType are used in flags 138*4882a593Smuzhiyun * 139*4882a593Smuzhiyun * eg: 140*4882a593Smuzhiyun * DRM CMA buffer : MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_CONTIG 141*4882a593Smuzhiyun * = 0x00010003 142*4882a593Smuzhiyun * DRM SECURE buffer: MPP_BUFFER_TYPE_DRM | MPP_BUFFER_FLAGS_SECURE 143*4882a593Smuzhiyun * = 0x00080003 144*4882a593Smuzhiyun * 145*4882a593Smuzhiyun * The dma buffer source can also be set by format: flags | type. 146*4882a593Smuzhiyun * dma buffer source flags: 147*4882a593Smuzhiyun * MPP_BUFFER_FLAGS_CONTIG means cma 148*4882a593Smuzhiyun * MPP_BUFFER_FLAGS_CACHABLE means cachable 149*4882a593Smuzhiyun * MPP_BUFFER_FLAGS_DMA32 means dma32 150*4882a593Smuzhiyun * 151*4882a593Smuzhiyun * flags originate from drm_rockchip_gem_mem_type 152*4882a593Smuzhiyun */ 153*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_MASK 0x003f0000 //ROCKCHIP_BO_MASK << 16 154*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_CONTIG 0x00010000 //ROCKCHIP_BO_CONTIG << 16 155*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_CACHABLE 0x00020000 //ROCKCHIP_BO_CACHABLE << 16 156*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_WC 0x00040000 //ROCKCHIP_BO_WC << 16 157*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_SECURE 0x00080000 //ROCKCHIP_BO_SECURE << 16 158*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_ALLOC_KMAP 0x00100000 //ROCKCHIP_BO_ALLOC_KMAP << 16 159*4882a593Smuzhiyun #define MPP_BUFFER_FLAGS_DMA32 0x00200000 //ROCKCHIP_BO_DMA32 << 16 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun /* 162*4882a593Smuzhiyun * MppBufferInfo variable's meaning is different in different MppBufferType 163*4882a593Smuzhiyun * 164*4882a593Smuzhiyun * Common 165*4882a593Smuzhiyun * index - the buffer index used to track buffer in buffer pool 166*4882a593Smuzhiyun * size - the buffer size 167*4882a593Smuzhiyun * 168*4882a593Smuzhiyun * MPP_BUFFER_TYPE_NORMAL 169*4882a593Smuzhiyun * 170*4882a593Smuzhiyun * ptr - virtual address of normal malloced buffer 171*4882a593Smuzhiyun * fd - unused and set to -1, the allocator would return its 172*4882a593Smuzhiyun * internal buffer counter number 173*4882a593Smuzhiyun * 174*4882a593Smuzhiyun * MPP_BUFFER_TYPE_ION 175*4882a593Smuzhiyun * 176*4882a593Smuzhiyun * ptr - virtual address of ion buffer in user space 177*4882a593Smuzhiyun * hnd - ion handle in user space 178*4882a593Smuzhiyun * fd - ion buffer file handle for map / unmap 179*4882a593Smuzhiyun * 180*4882a593Smuzhiyun */ 181*4882a593Smuzhiyun typedef struct MppBufferInfo_t { 182*4882a593Smuzhiyun MppBufferType type; 183*4882a593Smuzhiyun size_t size; 184*4882a593Smuzhiyun void *ptr; 185*4882a593Smuzhiyun void *hnd; 186*4882a593Smuzhiyun int fd; 187*4882a593Smuzhiyun int index; 188*4882a593Smuzhiyun } MppBufferInfo; 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun #define BUFFER_GROUP_SIZE_DEFAULT (SZ_1M*80) 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* 193*4882a593Smuzhiyun * mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer) 194*4882a593Smuzhiyun * 195*4882a593Smuzhiyun * 1. group - specified the MppBuffer to be attached to. 196*4882a593Smuzhiyun * group can be NULL then this buffer will attached to default legecy group 197*4882a593Smuzhiyun * Default to NULL on mpp_buffer_import case 198*4882a593Smuzhiyun * 199*4882a593Smuzhiyun * 2. info - input information for the output MppBuffer 200*4882a593Smuzhiyun * info can NOT be NULL. It must contain at least one of ptr/fd. 201*4882a593Smuzhiyun * 202*4882a593Smuzhiyun * 3. buffer - generated MppBuffer from MppBufferInfo. 203*4882a593Smuzhiyun * buffer can be NULL then the buffer is commit to group with unused status. 204*4882a593Smuzhiyun * Otherwise generated buffer will be directly got and ref_count increased. 205*4882a593Smuzhiyun * Default to NULL on mpp_buffer_commit case 206*4882a593Smuzhiyun * 207*4882a593Smuzhiyun * mpp_buffer_commit usage: 208*4882a593Smuzhiyun * 209*4882a593Smuzhiyun * Add a external buffer info to group. This buffer will be on unused status. 210*4882a593Smuzhiyun * Typical usage is on Android. MediaPlayer gralloc Graphic buffer then commit these buffer 211*4882a593Smuzhiyun * to decoder's buffer group. Then decoder will recycle these buffer and return buffer reference 212*4882a593Smuzhiyun * to MediaPlayer for display. 213*4882a593Smuzhiyun * 214*4882a593Smuzhiyun * mpp_buffer_import usage: 215*4882a593Smuzhiyun * 216*4882a593Smuzhiyun * Transfer a external buffer info to MppBuffer but it is not expected to attached to certain 217*4882a593Smuzhiyun * buffer group. So the group is set to NULL. Then this buffer can be used for MppFrame/MppPacket. 218*4882a593Smuzhiyun * Typical usage is for image processing. Image processing normally will be a oneshot operation 219*4882a593Smuzhiyun * It does not need complicated group management. But in other hand mpp still need to know the 220*4882a593Smuzhiyun * imported buffer is leak or not and trace its usage inside mpp process. So we attach this kind 221*4882a593Smuzhiyun * of buffer to default misc buffer group for management. 222*4882a593Smuzhiyun */ 223*4882a593Smuzhiyun #define mpp_buffer_commit(group, info) \ 224*4882a593Smuzhiyun mpp_buffer_import_with_tag(group, info, NULL, MODULE_TAG, __FUNCTION__) 225*4882a593Smuzhiyun 226*4882a593Smuzhiyun #define mpp_buffer_import(buffer, info) \ 227*4882a593Smuzhiyun mpp_buffer_import_with_tag(NULL, info, buffer, MODULE_TAG, __FUNCTION__) 228*4882a593Smuzhiyun 229*4882a593Smuzhiyun #define mpp_buffer_get(group, buffer, size) \ 230*4882a593Smuzhiyun mpp_buffer_get_with_tag(group, buffer, size, MODULE_TAG, __FUNCTION__) 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun #define mpp_buffer_put(buffer) \ 233*4882a593Smuzhiyun mpp_buffer_put_with_caller(buffer, __FUNCTION__) 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun #define mpp_buffer_inc_ref(buffer) \ 236*4882a593Smuzhiyun mpp_buffer_inc_ref_with_caller(buffer, __FUNCTION__) 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun #define mpp_buffer_info_get(buffer, info) \ 239*4882a593Smuzhiyun mpp_buffer_info_get_with_caller(buffer, info, __FUNCTION__) 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun #define mpp_buffer_read(buffer, offset, data, size) \ 242*4882a593Smuzhiyun mpp_buffer_read_with_caller(buffer, offset, data, size, __FUNCTION__) 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun #define mpp_buffer_write(buffer, offset, data, size) \ 245*4882a593Smuzhiyun mpp_buffer_write_with_caller(buffer, offset, data, size, __FUNCTION__) 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun #define mpp_buffer_get_ptr(buffer) \ 248*4882a593Smuzhiyun mpp_buffer_get_ptr_with_caller(buffer, __FUNCTION__) 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun #define mpp_buffer_get_fd(buffer) \ 251*4882a593Smuzhiyun mpp_buffer_get_fd_with_caller(buffer, __FUNCTION__) 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun #define mpp_buffer_get_size(buffer) \ 254*4882a593Smuzhiyun mpp_buffer_get_size_with_caller(buffer, __FUNCTION__) 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun #define mpp_buffer_get_index(buffer) \ 257*4882a593Smuzhiyun mpp_buffer_get_index_with_caller(buffer, __FUNCTION__) 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun #define mpp_buffer_set_index(buffer, index) \ 260*4882a593Smuzhiyun mpp_buffer_set_index_with_caller(buffer, index, __FUNCTION__) 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun #define mpp_buffer_get_offset(buffer) \ 263*4882a593Smuzhiyun mpp_buffer_get_offset_with_caller(buffer, __FUNCTION__) 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun #define mpp_buffer_set_offset(buffer, offset) \ 266*4882a593Smuzhiyun mpp_buffer_set_offset_with_caller(buffer, offset, __FUNCTION__) 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun #define mpp_buffer_group_get_internal(group, type, ...) \ 269*4882a593Smuzhiyun mpp_buffer_group_get(group, type, MPP_BUFFER_INTERNAL, MODULE_TAG, __FUNCTION__) 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun #define mpp_buffer_group_get_external(group, type, ...) \ 272*4882a593Smuzhiyun mpp_buffer_group_get(group, type, MPP_BUFFER_EXTERNAL, MODULE_TAG, __FUNCTION__) 273*4882a593Smuzhiyun 274*4882a593Smuzhiyun #ifdef __cplusplus 275*4882a593Smuzhiyun extern "C" { 276*4882a593Smuzhiyun #endif 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun /* 279*4882a593Smuzhiyun * MppBuffer interface 280*4882a593Smuzhiyun * these interface will change value of group and buffer so before calling functions 281*4882a593Smuzhiyun * parameter need to be checked. 282*4882a593Smuzhiyun * 283*4882a593Smuzhiyun * IMPORTANT: 284*4882a593Smuzhiyun * mpp_buffer_import_with_tag - compounded interface for commit and import 285*4882a593Smuzhiyun * 286*4882a593Smuzhiyun */ 287*4882a593Smuzhiyun MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, 288*4882a593Smuzhiyun const char *tag, const char *caller); 289*4882a593Smuzhiyun MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, 290*4882a593Smuzhiyun const char *tag, const char *caller); 291*4882a593Smuzhiyun MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller); 292*4882a593Smuzhiyun MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller); 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun MPP_RET mpp_buffer_info_get_with_caller(MppBuffer buffer, MppBufferInfo *info, const char *caller); 295*4882a593Smuzhiyun MPP_RET mpp_buffer_read_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller); 296*4882a593Smuzhiyun MPP_RET mpp_buffer_write_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller); 297*4882a593Smuzhiyun void *mpp_buffer_get_ptr_with_caller(MppBuffer buffer, const char *caller); 298*4882a593Smuzhiyun int mpp_buffer_get_fd_with_caller(MppBuffer buffer, const char *caller); 299*4882a593Smuzhiyun size_t mpp_buffer_get_size_with_caller(MppBuffer buffer, const char *caller); 300*4882a593Smuzhiyun int mpp_buffer_get_index_with_caller(MppBuffer buffer, const char *caller); 301*4882a593Smuzhiyun MPP_RET mpp_buffer_set_index_with_caller(MppBuffer buffer, int index, const char *caller); 302*4882a593Smuzhiyun size_t mpp_buffer_get_offset_with_caller(MppBuffer buffer, const char *caller); 303*4882a593Smuzhiyun MPP_RET mpp_buffer_set_offset_with_caller(MppBuffer buffer, size_t offset, const char *caller); 304*4882a593Smuzhiyun 305*4882a593Smuzhiyun MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, 306*4882a593Smuzhiyun const char *tag, const char *caller); 307*4882a593Smuzhiyun MPP_RET mpp_buffer_group_put(MppBufferGroup group); 308*4882a593Smuzhiyun MPP_RET mpp_buffer_group_clear(MppBufferGroup group); 309*4882a593Smuzhiyun RK_S32 mpp_buffer_group_unused(MppBufferGroup group); 310*4882a593Smuzhiyun size_t mpp_buffer_group_usage(MppBufferGroup group); 311*4882a593Smuzhiyun MppBufferMode mpp_buffer_group_mode(MppBufferGroup group); 312*4882a593Smuzhiyun MppBufferType mpp_buffer_group_type(MppBufferGroup group); 313*4882a593Smuzhiyun 314*4882a593Smuzhiyun /* 315*4882a593Smuzhiyun * size : 0 - no limit, other - max buffer size 316*4882a593Smuzhiyun * count : 0 - no limit, other - max buffer count 317*4882a593Smuzhiyun */ 318*4882a593Smuzhiyun MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count); 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun RK_U32 mpp_buffer_total_now(); 321*4882a593Smuzhiyun RK_U32 mpp_buffer_total_max(); 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun #ifdef __cplusplus 324*4882a593Smuzhiyun } 325*4882a593Smuzhiyun #endif 326*4882a593Smuzhiyun 327*4882a593Smuzhiyun #endif /*__MPP_BUFFER_H__*/ 328