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