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 #define MODULE_TAG "mpp_buffer"
18
19 #include <string.h>
20
21 #include "mpp_mem.h"
22 #include "mpp_debug.h"
23 #include "mpp_buffer_impl.h"
24
mpp_buffer_import_with_tag(MppBufferGroup group,MppBufferInfo * info,MppBuffer * buffer,const char * tag,const char * caller)25 MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer,
26 const char *tag, const char *caller)
27 {
28 if (NULL == info) {
29 mpp_err("mpp_buffer_commit invalid input: info NULL from %s\n", caller);
30 return MPP_ERR_NULL_PTR;
31 }
32
33 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
34
35 if (p) {
36 // if group is specified we need to check the parameter
37 if ((p->type & MPP_BUFFER_TYPE_MASK) != info->type ||
38 (p->type & MPP_BUFFER_TYPE_MASK) >= MPP_BUFFER_TYPE_BUTT ||
39 p->mode != MPP_BUFFER_EXTERNAL) {
40 mpp_err("mpp_buffer_commit invalid type found group %d info %d group mode %d from %s\n",
41 p->type, info->type, p->mode, caller);
42 return MPP_ERR_UNKNOW;
43 }
44 } else {
45 // otherwise use default external group to manage them
46 p = mpp_buffer_get_misc_group(MPP_BUFFER_EXTERNAL, info->type);
47 }
48
49 mpp_assert(p);
50
51 MPP_RET ret = MPP_OK;
52 if (buffer) {
53 MppBufferImpl *buf = NULL;
54 ret = mpp_buffer_create(tag, caller, p, info, &buf);
55 *buffer = buf;
56 } else {
57 ret = mpp_buffer_create(tag, caller, p, info, NULL);
58 }
59 return ret;
60 }
61
mpp_buffer_get_with_tag(MppBufferGroup group,MppBuffer * buffer,size_t size,const char * tag,const char * caller)62 MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size,
63 const char *tag, const char *caller)
64 {
65 if (NULL == buffer || 0 == size) {
66 mpp_err("mpp_buffer_get invalid input: group %p buffer %p size %u from %s\n",
67 group, buffer, size, caller);
68 return MPP_ERR_UNKNOW;
69 }
70
71 if (NULL == group) {
72 // deprecated, only for libvpu support
73 group = mpp_buffer_get_misc_group(MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION);
74 }
75
76 mpp_assert(group);
77
78 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
79 // try unused buffer first
80 MppBufferImpl *buf = mpp_buffer_get_unused(p, size, caller);
81 if (NULL == buf && MPP_BUFFER_INTERNAL == p->mode) {
82 MppBufferInfo info = {
83 p->type,
84 size,
85 NULL,
86 NULL,
87 -1,
88 -1,
89 };
90 // if failed try init a new buffer
91 mpp_buffer_create(tag, caller, p, &info, &buf);
92 }
93 *buffer = buf;
94 return (buf) ? (MPP_OK) : (MPP_NOK);
95 }
96
97
mpp_buffer_put_with_caller(MppBuffer buffer,const char * caller)98 MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller)
99 {
100 if (NULL == buffer) {
101 mpp_err("mpp_buffer_put invalid input: buffer NULL from %s\n", caller);
102 return MPP_ERR_UNKNOW;
103 }
104
105 return mpp_buffer_ref_dec((MppBufferImpl*)buffer, caller);
106 }
107
mpp_buffer_inc_ref_with_caller(MppBuffer buffer,const char * caller)108 MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller)
109 {
110 if (NULL == buffer) {
111 mpp_err("mpp_buffer_inc_ref invalid input: buffer NULL from %s\n", caller);
112 return MPP_ERR_UNKNOW;
113 }
114
115 return mpp_buffer_ref_inc((MppBufferImpl*)buffer, caller);
116 }
117
mpp_buffer_read_with_caller(MppBuffer buffer,size_t offset,void * data,size_t size,const char * caller)118 MPP_RET mpp_buffer_read_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller)
119 {
120 if (NULL == buffer || NULL == data) {
121 mpp_err("mpp_buffer_read invalid input: buffer %p data %p from %s\n",
122 buffer, data, caller);
123 return MPP_ERR_UNKNOW;
124 }
125
126 if (0 == size)
127 return MPP_OK;
128
129 MppBufferImpl *p = (MppBufferImpl*)buffer;
130 if (NULL == p->info.ptr)
131 mpp_buffer_mmap(p, caller);
132
133 void *src = p->info.ptr;
134 mpp_assert(src != NULL);
135 if (src)
136 memcpy(data, (char*)src + offset, size);
137
138 return MPP_OK;
139 }
140
mpp_buffer_write_with_caller(MppBuffer buffer,size_t offset,void * data,size_t size,const char * caller)141 MPP_RET mpp_buffer_write_with_caller(MppBuffer buffer, size_t offset, void *data, size_t size, const char *caller)
142 {
143 if (NULL == buffer || NULL == data) {
144 mpp_err("mpp_buffer_write invalid input: buffer %p data %p from %s\n",
145 buffer, data, caller);
146 return MPP_ERR_UNKNOW;
147 }
148
149 if (0 == size)
150 return MPP_OK;
151
152 MppBufferImpl *p = (MppBufferImpl*)buffer;
153 if (offset + size > p->info.size)
154 return MPP_ERR_VALUE;
155 if (NULL == p->info.ptr)
156 mpp_buffer_mmap(p, caller);
157
158 void *dst = p->info.ptr;
159 mpp_assert(dst != NULL);
160 if (dst)
161 memcpy((char*)dst + offset, data, size);
162
163 return MPP_OK;
164 }
165
mpp_buffer_get_ptr_with_caller(MppBuffer buffer,const char * caller)166 void *mpp_buffer_get_ptr_with_caller(MppBuffer buffer, const char *caller)
167 {
168 if (NULL == buffer) {
169 mpp_err("mpp_buffer_get_ptr invalid NULL input from %s\n", caller);
170 return NULL;
171 }
172
173 MppBufferImpl *p = (MppBufferImpl*)buffer;
174 if (NULL == p->info.ptr)
175 mpp_buffer_mmap(p, caller);
176
177 mpp_assert(p->info.ptr != NULL);
178 if (NULL == p->info.ptr)
179 mpp_err("mpp_buffer_get_ptr buffer %p ret NULL from %s\n", buffer, caller);
180
181 return p->info.ptr;
182 }
183
mpp_buffer_get_fd_with_caller(MppBuffer buffer,const char * caller)184 int mpp_buffer_get_fd_with_caller(MppBuffer buffer, const char *caller)
185 {
186 if (NULL == buffer) {
187 mpp_err("mpp_buffer_get_fd invalid NULL input from %s\n", caller);
188 return -1;
189 }
190
191 MppBufferImpl *p = (MppBufferImpl*)buffer;
192 int fd = p->info.fd;
193 mpp_assert(fd >= 0);
194 if (fd < 0)
195 mpp_err("mpp_buffer_get_fd buffer %p fd %d from %s\n", buffer, fd, caller);
196
197 return fd;
198 }
199
mpp_buffer_get_size_with_caller(MppBuffer buffer,const char * caller)200 size_t mpp_buffer_get_size_with_caller(MppBuffer buffer, const char *caller)
201 {
202 if (NULL == buffer) {
203 mpp_err("mpp_buffer_get_size invalid NULL input from %s\n", caller);
204 return 0;
205 }
206
207 MppBufferImpl *p = (MppBufferImpl*)buffer;
208 if (p->info.size == 0)
209 mpp_err("mpp_buffer_get_size buffer %p ret zero size from %s\n", buffer, caller);
210
211 return p->info.size;
212 }
213
mpp_buffer_get_index_with_caller(MppBuffer buffer,const char * caller)214 int mpp_buffer_get_index_with_caller(MppBuffer buffer, const char *caller)
215 {
216 if (NULL == buffer) {
217 mpp_err("mpp_buffer_get_index invalid NULL input from %s\n", caller);
218 return -1;
219 }
220
221 MppBufferImpl *p = (MppBufferImpl*)buffer;
222 return p->info.index;
223 }
224
mpp_buffer_set_index_with_caller(MppBuffer buffer,int index,const char * caller)225 MPP_RET mpp_buffer_set_index_with_caller(MppBuffer buffer, int index,
226 const char *caller)
227 {
228 if (NULL == buffer) {
229 mpp_err("mpp_buffer_set_index invalid NULL input from %s\n", caller);
230 return MPP_ERR_UNKNOW;
231 }
232
233 MppBufferImpl *p = (MppBufferImpl*)buffer;
234 p->info.index = index;
235 return MPP_OK;
236 }
237
mpp_buffer_get_offset_with_caller(MppBuffer buffer,const char * caller)238 size_t mpp_buffer_get_offset_with_caller(MppBuffer buffer, const char *caller)
239 {
240 if (NULL == buffer) {
241 mpp_err("mpp_buffer_get_offset invalid NULL input from %s\n", caller);
242 return -1;
243 }
244
245 MppBufferImpl *p = (MppBufferImpl*)buffer;
246 return p->offset;
247 }
248
mpp_buffer_set_offset_with_caller(MppBuffer buffer,size_t offset,const char * caller)249 MPP_RET mpp_buffer_set_offset_with_caller(MppBuffer buffer, size_t offset, const char *caller)
250 {
251 if (NULL == buffer) {
252 mpp_err("mpp_buffer_set_offset invalid NULL input from %s\n", caller);
253 return MPP_ERR_UNKNOW;
254 }
255
256 MppBufferImpl *p = (MppBufferImpl*)buffer;
257 p->offset = offset;
258 return MPP_OK;
259 }
260
mpp_buffer_info_get_with_caller(MppBuffer buffer,MppBufferInfo * info,const char * caller)261 MPP_RET mpp_buffer_info_get_with_caller(MppBuffer buffer, MppBufferInfo *info, const char *caller)
262 {
263 if (NULL == buffer || NULL == info) {
264 mpp_err("mpp_buffer_info_get invalid input buffer %p info %p from %s\n",
265 buffer, info, caller);
266 return MPP_ERR_UNKNOW;
267 }
268
269 MppBufferImpl *p = (MppBufferImpl*)buffer;
270 if (NULL == p->info.ptr)
271 mpp_buffer_mmap(p, caller);
272
273 *info = p->info;
274 (void)caller;
275 return MPP_OK;
276 }
277
mpp_buffer_group_get(MppBufferGroup * group,MppBufferType type,MppBufferMode mode,const char * tag,const char * caller)278 MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode,
279 const char *tag, const char *caller)
280 {
281 if (NULL == group ||
282 mode >= MPP_BUFFER_MODE_BUTT ||
283 (type & MPP_BUFFER_TYPE_MASK) >= MPP_BUFFER_TYPE_BUTT) {
284 mpp_err_f("input invalid group %p mode %d type %d from %s\n",
285 group, mode, type, caller);
286 return MPP_ERR_UNKNOW;
287 }
288
289 return mpp_buffer_group_init((MppBufferGroupImpl**)group, tag, caller, mode, type);
290 }
291
mpp_buffer_group_put(MppBufferGroup group)292 MPP_RET mpp_buffer_group_put(MppBufferGroup group)
293 {
294 if (NULL == group) {
295 mpp_err_f("input invalid group %p\n", group);
296 return MPP_NOK;
297 }
298
299 return mpp_buffer_group_deinit((MppBufferGroupImpl *)group);
300 }
301
mpp_buffer_group_clear(MppBufferGroup group)302 MPP_RET mpp_buffer_group_clear(MppBufferGroup group)
303 {
304 if (NULL == group) {
305 mpp_err_f("input invalid group %p\n", group);
306 return MPP_NOK;
307 }
308
309 return mpp_buffer_group_reset((MppBufferGroupImpl *)group);
310 }
311
mpp_buffer_group_unused(MppBufferGroup group)312 RK_S32 mpp_buffer_group_unused(MppBufferGroup group)
313 {
314 if (NULL == group) {
315 mpp_err_f("input invalid group %p\n", group);
316 return MPP_NOK;
317 }
318
319 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
320 RK_S32 unused = 0;
321
322 if (p->mode == MPP_BUFFER_INTERNAL) {
323 if (p->limit_count)
324 unused = p->limit_count - p->count_used;
325 else
326 unused = 3; /* NOTE: 3 for 1 decoding 2 deinterlace buffer */
327 } else
328 unused = p->count_unused;
329
330 return unused;
331 }
332
mpp_buffer_group_usage(MppBufferGroup group)333 size_t mpp_buffer_group_usage(MppBufferGroup group)
334 {
335 if (NULL == group) {
336 mpp_err_f("input invalid group %p\n", group);
337 return MPP_BUFFER_MODE_BUTT;
338 }
339
340 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
341 return p->usage;
342 }
343
mpp_buffer_group_mode(MppBufferGroup group)344 MppBufferMode mpp_buffer_group_mode(MppBufferGroup group)
345 {
346 if (NULL == group) {
347 mpp_err_f("input invalid group %p\n", group);
348 return MPP_BUFFER_MODE_BUTT;
349 }
350
351 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
352 return p->mode;
353 }
354
mpp_buffer_group_type(MppBufferGroup group)355 MppBufferType mpp_buffer_group_type(MppBufferGroup group)
356 {
357 if (NULL == group) {
358 mpp_err_f("input invalid group %p\n", group);
359 return MPP_BUFFER_TYPE_BUTT;
360 }
361
362 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
363 return p->type;
364 }
365
mpp_buffer_group_limit_config(MppBufferGroup group,size_t size,RK_S32 count)366 MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count)
367 {
368 if (NULL == group) {
369 mpp_err_f("input invalid group %p\n", group);
370 return MPP_NOK;
371 }
372
373 MppBufferGroupImpl *p = (MppBufferGroupImpl *)group;
374 mpp_assert(p->mode == MPP_BUFFER_INTERNAL);
375 p->limit_size = size;
376 p->limit_count = count;
377 return MPP_OK;
378 }
379
380