xref: /OK3568_Linux_fs/external/mpp/mpp/base/mpp_buffer.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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