hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
 * 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__*/