xref: /OK3568_Linux_fs/external/mpp/mpp/base/mpp_packet.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_packet"
18 
19 #include <string.h>
20 
21 #include "mpp_debug.h"
22 #include "mpp_mem_pool.h"
23 #include "mpp_packet_impl.h"
24 #include "mpp_meta_impl.h"
25 
26 static const char *module_name = MODULE_TAG;
27 static MppMemPool mpp_packet_pool = mpp_mem_pool_init_f(module_name, sizeof(MppPacketImpl));
28 
29 #define setup_mpp_packet_name(packet) \
30     ((MppPacketImpl*)packet)->name = module_name;
31 
check_is_mpp_packet(void * packet)32 MPP_RET check_is_mpp_packet(void *packet)
33 {
34     if (packet && ((MppPacketImpl*)packet)->name == module_name)
35         return MPP_OK;
36 
37     mpp_err_f("pointer %p failed on check\n", packet);
38     mpp_abort();
39     return MPP_NOK;
40 }
41 
mpp_packet_new(MppPacket * packet)42 MPP_RET mpp_packet_new(MppPacket *packet)
43 {
44     if (NULL == packet) {
45         mpp_err_f("invalid NULL input\n");
46         return MPP_ERR_NULL_PTR;
47     }
48 
49     MppPacketImpl *p = (MppPacketImpl*)mpp_mem_pool_get(mpp_packet_pool);
50     *packet = p;
51     if (NULL == p) {
52         mpp_err_f("malloc failed\n");
53         return MPP_ERR_NULL_PTR;
54     }
55     setup_mpp_packet_name(p);
56     p->segment_buf_cnt = MPP_PKT_SEG_CNT_DEFAULT;
57 
58     return MPP_OK;
59 }
60 
mpp_packet_init(MppPacket * packet,void * data,size_t size)61 MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size)
62 {
63     if (NULL == packet) {
64         mpp_err_f("invalid NULL input packet\n");
65         return MPP_ERR_NULL_PTR;
66     }
67 
68     MPP_RET ret = mpp_packet_new(packet);
69     if (ret) {
70         mpp_err_f("new packet failed\n");
71         return ret;
72     }
73     MppPacketImpl *p = (MppPacketImpl *)*packet;
74     p->data = p->pos    = data;
75     p->size = p->length = size;
76 
77     return MPP_OK;
78 }
79 
mpp_packet_init_with_buffer(MppPacket * packet,MppBuffer buffer)80 MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer)
81 {
82     if (NULL == packet || NULL == buffer) {
83         mpp_err_f("invalid input packet %p buffer %p\n", packet, buffer);
84         return MPP_ERR_NULL_PTR;
85     }
86 
87     MPP_RET ret = mpp_packet_new(packet);
88     if (ret) {
89         mpp_err_f("new packet failed\n");
90         return ret;
91     }
92     MppPacketImpl *p = (MppPacketImpl *)*packet;
93     p->data = p->pos    = mpp_buffer_get_ptr(buffer);
94     p->size = p->length = mpp_buffer_get_size(buffer);
95     p->buffer = buffer;
96     mpp_buffer_inc_ref(buffer);
97 
98     return MPP_OK;
99 }
100 
mpp_packet_copy_init(MppPacket * packet,const MppPacket src)101 MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src)
102 {
103     if (NULL == packet || check_is_mpp_packet(src)) {
104         mpp_err_f("found invalid input %p %p\n", packet, src);
105         return MPP_ERR_UNKNOW;
106     }
107 
108     *packet = NULL;
109 
110     MppPacketImpl *src_impl = (MppPacketImpl *)src;
111     MppPacket pkt;
112     MPP_RET ret = mpp_packet_new(&pkt);
113     if (ret)
114         return ret;
115 
116     /* copy the source data */
117     memcpy(pkt, src_impl, sizeof(*src_impl));
118 
119     /* increase reference of meta data */
120     if (src_impl->meta)
121         mpp_meta_inc_ref(src_impl->meta);
122 
123     if (src_impl->buffer) {
124         /* if source packet has buffer just create a new reference to buffer */
125         mpp_buffer_inc_ref(src_impl->buffer);
126     } else {
127         /*
128          * NOTE: only copy valid data
129          */
130         size_t length = mpp_packet_get_length(src);
131         /*
132          * due to parser may be read 32 bit interface so we must alloc more size
133          * then real size to avoid read carsh
134          */
135         void *pos = mpp_malloc_size(void, length + 256);
136         if (NULL == pos) {
137             mpp_err_f("malloc failed, size %d\n", length);
138             mpp_packet_deinit(&pkt);
139             return MPP_ERR_MALLOC;
140         }
141 
142         MppPacketImpl *p = (MppPacketImpl *)pkt;
143         p->data = p->pos = pos;
144         p->size = p->length = length;
145         p->flag |= MPP_PACKET_FLAG_INTERNAL;
146 
147         if (length) {
148             memcpy(pos, src_impl->pos, length);
149             /*
150              * clean more alloc byte to zero
151              */
152             memset((RK_U8*)pos + length, 0, 256);
153         }
154     }
155 
156     *packet = pkt;
157     return MPP_OK;
158 }
159 
mpp_packet_deinit(MppPacket * packet)160 MPP_RET mpp_packet_deinit(MppPacket *packet)
161 {
162     if (NULL == packet || check_is_mpp_packet(*packet)) {
163         mpp_err_f("found NULL input\n");
164         return MPP_ERR_NULL_PTR;
165     }
166 
167     MppPacketImpl *p = (MppPacketImpl *)(*packet);
168 
169     /* release buffer reference */
170     if (p->buffer)
171         mpp_buffer_put(p->buffer);
172 
173     if (p->flag & MPP_PACKET_FLAG_INTERNAL)
174         mpp_free(p->data);
175 
176     if (p->meta)
177         mpp_meta_put(p->meta);
178 
179     MPP_FREE(p->segments_ext);
180 
181     mpp_mem_pool_put(mpp_packet_pool, *packet);
182     *packet = NULL;
183     return MPP_OK;
184 }
185 
mpp_packet_set_pos(MppPacket packet,void * pos)186 void mpp_packet_set_pos(MppPacket packet, void *pos)
187 {
188     if (check_is_mpp_packet(packet))
189         return ;
190 
191     MppPacketImpl *p = (MppPacketImpl *)packet;
192     size_t offset = (RK_U8 *)pos - (RK_U8 *)p->data;
193     size_t diff = (RK_U8 *)pos - (RK_U8 *)p->pos;
194 
195     /*
196      * If set pos is a simple update on original buffer update the length
197      * If set pos setup a new buffer reset length to size - offset
198      * This will avoid assert on change "data" in mpp_packet
199      */
200     if (diff <= p->length)
201         p->length -= diff;
202     else
203         p->length = p->size - offset;
204 
205     p->pos = pos;
206     mpp_assert(p->data <= p->pos);
207     mpp_assert(p->size >= p->length);
208 }
209 
mpp_packet_get_pos(const MppPacket packet)210 void *mpp_packet_get_pos(const MppPacket packet)
211 {
212     if (check_is_mpp_packet(packet))
213         return NULL;
214 
215     MppPacketImpl *p = (MppPacketImpl *)packet;
216     return p->pos;
217 }
218 
mpp_packet_set_eos(MppPacket packet)219 MPP_RET mpp_packet_set_eos(MppPacket packet)
220 {
221     if (check_is_mpp_packet(packet))
222         return MPP_ERR_UNKNOW;
223 
224     MppPacketImpl *p = (MppPacketImpl *)packet;
225     p->flag |= MPP_PACKET_FLAG_EOS;
226     return MPP_OK;
227 }
228 
mpp_packet_clr_eos(MppPacket packet)229 MPP_RET mpp_packet_clr_eos(MppPacket packet)
230 {
231     if (check_is_mpp_packet(packet))
232         return MPP_ERR_UNKNOW;
233 
234     MppPacketImpl *p = (MppPacketImpl *)packet;
235     p->flag &= ~MPP_PACKET_FLAG_EOS;
236     return MPP_OK;
237 }
238 
mpp_packet_get_eos(MppPacket packet)239 RK_U32 mpp_packet_get_eos(MppPacket packet)
240 {
241     if (check_is_mpp_packet(packet))
242         return 0;
243 
244     MppPacketImpl *p = (MppPacketImpl *)packet;
245     return (p->flag & MPP_PACKET_FLAG_EOS) ? (1) : (0);
246 }
247 
mpp_packet_set_extra_data(MppPacket packet)248 MPP_RET mpp_packet_set_extra_data(MppPacket packet)
249 {
250     if (check_is_mpp_packet(packet))
251         return MPP_ERR_UNKNOW;
252 
253     MppPacketImpl *p = (MppPacketImpl *)packet;
254     p->flag |= MPP_PACKET_FLAG_EXTRA_DATA;
255     return MPP_OK;
256 }
257 
mpp_packet_reset(MppPacketImpl * packet)258 MPP_RET mpp_packet_reset(MppPacketImpl *packet)
259 {
260     if (check_is_mpp_packet(packet))
261         return MPP_ERR_UNKNOW;
262 
263     void *data = packet->data;
264     size_t size = packet->size;
265 
266     memset(packet, 0, sizeof(*packet));
267 
268     packet->data = data;
269     packet->pos  = data;
270     packet->size = size;
271     setup_mpp_packet_name(packet);
272     mpp_packet_reset_segment(packet);
273     return MPP_OK;
274 }
275 
mpp_packet_set_buffer(MppPacket packet,MppBuffer buffer)276 void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer)
277 {
278     if (check_is_mpp_packet(packet))
279         return ;
280 
281     MppPacketImpl *p = (MppPacketImpl *)packet;
282     if (p->buffer != buffer) {
283         if (buffer)
284             mpp_buffer_inc_ref(buffer);
285 
286         if (p->buffer)
287             mpp_buffer_put(p->buffer);
288 
289         p->buffer = buffer;
290     }
291 }
292 
mpp_packet_get_buffer(const MppPacket packet)293 MppBuffer mpp_packet_get_buffer(const MppPacket packet)
294 {
295     if (check_is_mpp_packet(packet))
296         return NULL;
297 
298     MppPacketImpl *p = (MppPacketImpl *)packet;
299     return p->buffer;
300 }
301 
mpp_packet_has_meta(const MppPacket packet)302 RK_S32 mpp_packet_has_meta(const MppPacket packet)
303 {
304     if (check_is_mpp_packet(packet))
305         return 0;
306 
307     MppPacketImpl *p = (MppPacketImpl *)packet;
308 
309     return (NULL != p->meta);
310 }
311 
mpp_packet_get_meta(const MppPacket packet)312 MppMeta mpp_packet_get_meta(const MppPacket packet)
313 {
314     if (check_is_mpp_packet(packet))
315         return NULL;
316 
317     MppPacketImpl *p = (MppPacketImpl *)packet;
318     if (NULL == p->meta)
319         mpp_meta_get(&p->meta);
320 
321     return p->meta;
322 }
323 
mpp_packet_set_status(MppPacket packet,MppPacketStatus status)324 MPP_RET mpp_packet_set_status(MppPacket packet, MppPacketStatus status)
325 {
326     if (check_is_mpp_packet(packet))
327         return MPP_ERR_UNKNOW;
328 
329     MppPacketImpl *p = (MppPacketImpl *)packet;
330 
331     p->status.val = status.val;
332     return MPP_OK;
333 }
334 
mpp_packet_get_status(MppPacket packet,MppPacketStatus * status)335 MPP_RET mpp_packet_get_status(MppPacket packet, MppPacketStatus *status)
336 {
337     if (check_is_mpp_packet(packet)) {
338         status->val = 0;
339         return MPP_ERR_UNKNOW;
340     }
341 
342     MppPacketImpl *p = (MppPacketImpl *)packet;
343 
344     status->val = p->status.val;
345     return MPP_OK;
346 }
347 
mpp_packet_is_partition(const MppPacket packet)348 RK_U32 mpp_packet_is_partition(const MppPacket packet)
349 {
350     if (check_is_mpp_packet(packet))
351         return 0;
352 
353     MppPacketImpl *p = (MppPacketImpl *)packet;
354 
355     return p->status.partition;
356 }
357 
mpp_packet_is_soi(const MppPacket packet)358 RK_U32 mpp_packet_is_soi(const MppPacket packet)
359 {
360     if (check_is_mpp_packet(packet))
361         return 0;
362 
363     MppPacketImpl *p = (MppPacketImpl *)packet;
364 
365     return p->status.soi;
366 }
367 
mpp_packet_is_eoi(const MppPacket packet)368 RK_U32 mpp_packet_is_eoi(const MppPacket packet)
369 {
370     if (check_is_mpp_packet(packet))
371         return 0;
372 
373     MppPacketImpl *p = (MppPacketImpl *)packet;
374 
375     return p->status.eoi;
376 }
377 
mpp_packet_read(MppPacket packet,size_t offset,void * data,size_t size)378 MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size)
379 {
380     if (check_is_mpp_packet(packet) || NULL == data) {
381         mpp_err_f("invalid input: packet %p data %p\n", packet, data);
382         return MPP_ERR_UNKNOW;
383     }
384 
385     if (0 == size)
386         return MPP_OK;
387 
388     void *src = mpp_packet_get_data(packet);
389     mpp_assert(src != NULL);
390     memcpy(data, (char*)src + offset, size);
391     return MPP_OK;
392 }
393 
mpp_packet_write(MppPacket packet,size_t offset,void * data,size_t size)394 MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size)
395 {
396     if (check_is_mpp_packet(packet) || NULL == data) {
397         mpp_err_f("invalid input: packet %p data %p\n", packet, data);
398         return MPP_ERR_UNKNOW;
399     }
400 
401     if (0 == size)
402         return MPP_OK;
403 
404     void *dst = mpp_packet_get_data(packet);
405     mpp_assert(dst != NULL);
406     memcpy((char*)dst + offset, data, size);
407     return MPP_OK;
408 }
409 
mpp_packet_copy(MppPacket dst,MppPacket src)410 MPP_RET mpp_packet_copy(MppPacket dst, MppPacket src)
411 {
412     if (check_is_mpp_packet(dst) || check_is_mpp_packet(src)) {
413         mpp_err_f("invalid input: dst %p src %p\n", dst, src);
414         return MPP_ERR_UNKNOW;
415     }
416 
417     MppPacketImpl *dst_impl = (MppPacketImpl *)dst;
418     MppPacketImpl *src_impl = (MppPacketImpl *)src;
419 
420     memcpy(dst_impl->pos, src_impl->pos, src_impl->length);
421     dst_impl->length = src_impl->length;
422 
423     if (src_impl->segment_nb)
424         mpp_packet_copy_segment_info(dst, src);
425 
426     return MPP_OK;
427 }
428 
mpp_packet_append(MppPacket dst,MppPacket src)429 MPP_RET mpp_packet_append(MppPacket dst, MppPacket src)
430 {
431     if (check_is_mpp_packet(dst) || check_is_mpp_packet(src)) {
432         mpp_err_f("invalid input: dst %p src %p\n", dst, src);
433         return MPP_ERR_UNKNOW;
434     }
435 
436     MppPacketImpl *dst_impl = (MppPacketImpl *)dst;
437     MppPacketImpl *src_impl = (MppPacketImpl *)src;
438 
439     memcpy((RK_U8 *)dst_impl->pos + dst_impl->length, src_impl->pos,
440            src_impl->length);
441 
442     if (src_impl->segment_nb) {
443         MppPktSeg *segs = src_impl->segments;
444         RK_U32 offset = dst_impl->length;
445         RK_U32 i;
446 
447         for (i = 0; i < src_impl->segment_nb; i++, segs++) {
448             mpp_packet_add_segment_info(dst, segs->type, offset, segs->len);
449             offset += segs->len;
450         }
451     }
452 
453     dst_impl->length += src_impl->length;
454     return MPP_OK;
455 }
456 
mpp_packet_reset_segment(MppPacket packet)457 void mpp_packet_reset_segment(MppPacket packet)
458 {
459     MppPacketImpl *p = (MppPacketImpl *)packet;
460 
461     p->segment_nb = 0;
462     p->segment_buf_cnt = MPP_PKT_SEG_CNT_DEFAULT;
463     memset(p->segments_def, 0, sizeof(p->segments_def));
464     p->segments = NULL;
465     MPP_FREE(p->segments_ext);
466 }
467 
mpp_packet_set_segment_nb(MppPacket packet,RK_U32 segment_nb)468 void mpp_packet_set_segment_nb(MppPacket packet, RK_U32 segment_nb)
469 {
470     MppPacketImpl *p = (MppPacketImpl *)packet;
471     MppPktSeg *segs = p->segments;
472     RK_S32 i;
473 
474     if (segment_nb >= p->segment_nb || !segs)
475         return;
476 
477     if (!segment_nb) {
478         mpp_packet_reset_segment(packet);
479         return;
480     }
481 
482     /* truncate segment member and drop later segment info */
483     if (segment_nb <= MPP_PKT_SEG_CNT_DEFAULT) {
484         if (p->segments_ext) {
485             memcpy(p->segments_def, segs, sizeof(*segs) * segment_nb);
486             segs = p->segments_def;
487             p->segments = segs;
488             MPP_FREE(p->segments_ext);
489         }
490 
491         p->segment_buf_cnt = MPP_PKT_SEG_CNT_DEFAULT;
492     }
493 
494     /* relink segment info */
495     for (i = 0; i < (RK_S32)segment_nb - 1; i++)
496         segs[i].next = &segs[i + 1];
497 
498     segs[segment_nb - 1].next = NULL;
499 
500     p->segment_nb = segment_nb;
501 }
502 
mpp_packet_add_segment_info(MppPacket packet,RK_S32 type,RK_S32 offset,RK_S32 len)503 MPP_RET mpp_packet_add_segment_info(MppPacket packet, RK_S32 type, RK_S32 offset, RK_S32 len)
504 {
505     MppPacketImpl *p = (MppPacketImpl *)packet;
506     RK_U32 old_buf_cnt = p->segment_buf_cnt;
507     RK_U32 segment_nb  = p->segment_nb;
508     MppPktSeg *seg_buf = p->segments;
509 
510     if (segment_nb >= old_buf_cnt) {
511         RK_U32 i;
512 
513         /* realloc segment info buffer. default 8 segments */
514         old_buf_cnt *= 2;
515 
516         if (NULL == p->segments_ext) {
517             seg_buf = mpp_calloc(MppPktSeg, old_buf_cnt);
518             if (seg_buf)
519                 memcpy(seg_buf, p->segments_def, sizeof(p->segments_def));
520         } else {
521             seg_buf = mpp_realloc(p->segments_ext, MppPktSeg, old_buf_cnt);
522         }
523 
524         if (NULL == seg_buf)
525             return MPP_NOK;
526 
527         for (i = 0; i < segment_nb - 1; i++)
528             seg_buf[i].next = &seg_buf[i + 1];
529 
530         p->segments_ext = seg_buf;
531         p->segments = seg_buf;
532         p->segment_buf_cnt = old_buf_cnt;
533     } else {
534         if (NULL == seg_buf) {
535             seg_buf = p->segments_def;
536             p->segments = seg_buf;
537         }
538     }
539 
540     mpp_assert(seg_buf);
541     seg_buf += segment_nb;
542     seg_buf->index  = segment_nb;
543     seg_buf->type   = type;
544     seg_buf->offset = offset;
545     seg_buf->len    = len;
546     seg_buf->next   = NULL;
547 
548     if (segment_nb)
549         seg_buf[-1].next = seg_buf;
550 
551     p->segment_nb++;
552     mpp_assert(p->segment_nb <= p->segment_buf_cnt);
553 
554     return MPP_OK;
555 }
556 
mpp_packet_copy_segment_info(MppPacket dst,MppPacket src)557 void mpp_packet_copy_segment_info(MppPacket dst, MppPacket src)
558 {
559     MppPacketImpl *dst_impl = (MppPacketImpl *)dst;
560     MppPacketImpl *src_impl = (MppPacketImpl *)src;
561 
562     mpp_packet_reset_segment(dst);
563 
564     if (src_impl->segment_nb) {
565         MppPktSeg *src_segs = src_impl->segments;
566         MppPktSeg *dst_segs = NULL;
567         RK_U32 segment_nb = src_impl->segment_nb;
568         RK_U32 i;
569 
570         dst_impl->segment_nb = segment_nb;
571         dst_impl->segment_buf_cnt = src_impl->segment_buf_cnt;
572 
573         if (segment_nb <= MPP_PKT_SEG_CNT_DEFAULT) {
574             dst_segs = dst_impl->segments_def;
575 
576             memcpy(dst_segs, src_segs, sizeof(*dst_segs) * segment_nb);
577         } else {
578             dst_segs = mpp_calloc(MppPktSeg, dst_impl->segment_buf_cnt);
579 
580             mpp_assert(dst_segs);
581             dst_impl->segments_ext = dst_segs;
582             memcpy(dst_segs, src_segs, sizeof(*dst_segs) * segment_nb);
583         }
584 
585         for (i = 0; i < segment_nb - 1; i++)
586             dst_segs[i].next = &dst_segs[i + 1];
587 
588         dst_impl->segments = dst_segs;
589     }
590 }
591 
mpp_packet_get_segment_info(const MppPacket packet)592 const MppPktSeg *mpp_packet_get_segment_info(const MppPacket packet)
593 {
594     if (check_is_mpp_packet(packet))
595         return NULL;
596 
597     MppPacketImpl *p = (MppPacketImpl *)packet;
598 
599     if (!p->segment_nb)
600         return NULL;
601 
602     return (const MppPktSeg *)p->segments;
603 }
604 
605 /*
606  * object access function macro
607  */
608 #define MPP_PACKET_ACCESSORS(type, field) \
609     type mpp_packet_get_##field(const MppPacket s) \
610     { \
611         check_is_mpp_packet(s); \
612         return ((MppPacketImpl*)s)->field; \
613     } \
614     void mpp_packet_set_##field(MppPacket s, type v) \
615     { \
616         check_is_mpp_packet(s); \
617         ((MppPacketImpl*)s)->field = v; \
618     }
619 
620 #define MPP_PACKET_ACCESSOR_GET(type, field) \
621     type mpp_packet_get_##field(const MppPacket s) \
622     { \
623         check_is_mpp_packet(s); \
624         return ((MppPacketImpl*)s)->field; \
625     }
626 
627 MPP_PACKET_ACCESSORS(void *, data)
628 MPP_PACKET_ACCESSORS(size_t, size)
629 MPP_PACKET_ACCESSORS(size_t, length)
630 MPP_PACKET_ACCESSORS(RK_S64, pts)
631 MPP_PACKET_ACCESSORS(RK_S64, dts)
632 MPP_PACKET_ACCESSORS(RK_U32, flag)
633 MPP_PACKET_ACCESSORS(MppTask, task)
634 MPP_PACKET_ACCESSOR_GET(RK_U32, segment_nb)
635