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_buf_slot"
18
19 #include <string.h>
20
21 #include "mpp_mem.h"
22 #include "mpp_env.h"
23 #include "mpp_list.h"
24 #include "mpp_debug.h"
25 #include "mpp_common.h"
26
27 #include "mpp_frame_impl.h"
28 #include "mpp_buf_slot.h"
29 #include "mpp_compat_impl.h"
30
31 #define BUF_SLOT_DBG_FUNCTION (0x00000001)
32 #define BUF_SLOT_DBG_SETUP (0x00000002)
33 #define BUF_SLOT_DBG_INFO_CHANGE (0x00000004)
34 #define BUF_SLOT_DBG_OPS_RUNTIME (0x00000010)
35 #define BUF_SLOT_DBG_BUFFER (0x00000100)
36 #define BUF_SLOT_DBG_FRAME (0x00000200)
37 #define BUF_SLOT_DBG_BUF_UESD (0x00000400)
38 #define BUF_SLOT_DBG_OPS_HISTORY (0x10000000)
39 #define BUF_SLOT_DBG_ALL (0x10000011)
40
41 #define buf_slot_dbg(flag, fmt, ...) _mpp_dbg(buf_slot_debug, flag, fmt, ## __VA_ARGS__)
42
43 static RK_U32 buf_slot_debug = 0;
44 static RK_U32 buf_slot_idx = 0;
45
46 #define slot_assert(impl, cond) do { \
47 if (!(cond)) { \
48 dump_slots(impl); \
49 mpp_err("Assertion %s failed at %s:%d\n", \
50 MPP_STRINGS(cond), __FUNCTION__, __LINE__); \
51 abort(); \
52 } \
53 } while (0)
54
55 typedef struct MppBufSlotEntry_t MppBufSlotEntry;
56 typedef struct MppBufSlotsImpl_t MppBufSlotsImpl;
57
58 #define SLOT_OPS_MAX_COUNT 1024
59
60 typedef enum MppBufSlotOps_e {
61 // status opertaion
62 SLOT_INIT,
63 SLOT_SET_ON_USE,
64 SLOT_CLR_ON_USE,
65 SLOT_SET_NOT_READY,
66 SLOT_CLR_NOT_READY,
67 SLOT_SET_CODEC_READY,
68 SLOT_CLR_CODEC_READY,
69 SLOT_SET_CODEC_USE,
70 SLOT_CLR_CODEC_USE,
71 SLOT_SET_HAL_INPUT,
72 SLOT_CLR_HAL_INPUT,
73 SLOT_SET_HAL_OUTPUT,
74 SLOT_CLR_HAL_OUTPUT,
75 SLOT_SET_QUEUE_USE,
76 SLOT_CLR_QUEUE_USE,
77
78 // queue operation
79 SLOT_ENQUEUE,
80 SLOT_ENQUEUE_OUTPUT = SLOT_ENQUEUE,
81 SLOT_ENQUEUE_DISPLAY,
82 SLOT_ENQUEUE_DEINTER,
83 SLOT_ENQUEUE_CONVERT,
84 SLOT_DEQUEUE,
85 SLOT_DEQUEUE_OUTPUT = SLOT_DEQUEUE,
86 SLOT_DEQUEUE_DISPLAY,
87 SLOT_DEQUEUE_DEINTER,
88 SLOT_DEQUEUE_CONVERT,
89
90 // value operation
91 SLOT_SET_EOS,
92 SLOT_CLR_EOS,
93 SLOT_SET_FRAME,
94 SLOT_CLR_FRAME,
95 SLOT_SET_BUFFER,
96 SLOT_CLR_BUFFER,
97 } MppBufSlotOps;
98
99 static const char op_string[][16] = {
100 "init ",
101 "set on use ",
102 "clr on use ",
103 "set not ready ",
104 "set ready ",
105 "set codec ready",
106 "clr codec ready",
107 "set codec use ",
108 "clr codec use ",
109 "set hal input ",
110 "clr hal input ",
111 "set hal output ",
112 "clr hal output ",
113 "set queue use ",
114 "clr queue use ",
115
116 "enqueue output ",
117 "enqueue display",
118 "enqueue deint ",
119 "enqueue convert",
120 "dequeue output ",
121 "dequeue display",
122 "dequeue deint ",
123 "dequeue convert",
124
125 "set eos ",
126 "clr eos ",
127 "set frame ",
128 "clr frame ",
129 "set buffer ",
130 "clr buffer ",
131 };
132
133 static const MppBufSlotOps set_flag_op[SLOT_USAGE_BUTT] = {
134 SLOT_SET_CODEC_READY,
135 SLOT_SET_CODEC_USE,
136 SLOT_SET_HAL_INPUT,
137 SLOT_SET_HAL_OUTPUT,
138 SLOT_SET_QUEUE_USE,
139 };
140
141 static const MppBufSlotOps clr_flag_op[SLOT_USAGE_BUTT] = {
142 SLOT_CLR_CODEC_READY,
143 SLOT_CLR_CODEC_USE,
144 SLOT_CLR_HAL_INPUT,
145 SLOT_CLR_HAL_OUTPUT,
146 SLOT_CLR_QUEUE_USE,
147 };
148
149 static const MppBufSlotOps set_val_op[SLOT_PROP_BUTT] = {
150 SLOT_SET_EOS,
151 SLOT_SET_FRAME,
152 SLOT_SET_BUFFER,
153 };
154
155 typedef union SlotStatus_u {
156 RK_U32 val;
157 struct {
158 // status flags
159 RK_U32 on_used : 1;
160 RK_U32 not_ready : 1; // buffer slot is filled or not
161 RK_U32 codec_use : 1; // buffer slot is used by codec ( dpb reference )
162 RK_U32 hal_output : 2; // buffer slot is set to hw output will ready when hw done
163 RK_U32 hal_use : 8; // buffer slot is used by hardware
164 RK_U32 queue_use : 5; // buffer slot is used in different queue
165
166 // value flags
167 RK_U32 eos : 1; // buffer slot is last buffer slot from codec
168 RK_U32 has_buffer : 1;
169 RK_U32 has_frame : 1;
170 };
171 } SlotStatus;
172
173 typedef struct MppBufSlotLog_t {
174 RK_S32 index;
175 MppBufSlotOps ops;
176 SlotStatus status_in;
177 SlotStatus status_out;
178 } MppBufSlotLog;
179
180 typedef struct MppBufSlotLogs_t {
181 pthread_mutex_t lock;
182 RK_U16 max_count;
183 RK_U16 log_count;
184 RK_U16 log_write;
185 RK_U16 log_read;
186 MppBufSlotLog *logs;
187 } MppBufSlotLogs;
188
189 struct MppBufSlotEntry_t {
190 MppBufSlotsImpl *slots;
191 struct list_head list;
192 SlotStatus status;
193 RK_S32 index;
194
195 RK_U32 eos;
196 MppFrame frame;
197 MppBuffer buffer;
198 };
199
200 struct MppBufSlotsImpl_t {
201 Mutex *lock;
202 RK_U32 slots_idx;
203
204 // status tracing
205 RK_U32 decode_count;
206 RK_U32 display_count;
207
208 // if slot changed, all will be hold until all slot is unused
209 RK_U32 info_changed;
210 RK_S32 new_count;
211
212 // slot infomation for info change and eos
213 RK_U32 eos;
214
215 // buffer parameter, default alignement is 16
216 AlignFunc hal_hor_align; // default NULL
217 AlignFunc hal_ver_align; // default NULL
218 AlignFunc hal_len_align; // default NULL
219 size_t buf_size;
220 RK_S32 buf_count;
221 RK_S32 used_count;
222 // buffer size equal to (h_stride * v_stride) * numerator / denominator
223 // internal parameter
224 RK_U32 numerator;
225 RK_U32 denominator;
226
227 // callback for free slot notify
228 MppCbCtx callback;
229
230 // NOTE: use MppFrame to store the buffer/display infomation
231 // any buffer related infomation change comparing to previous frame will
232 // trigger a buffer info changed requirement
233 // any display related infomation change comparing to pevious frame will
234 // trigger a display info changed requirement
235 MppFrame info;
236 MppFrame info_set;
237
238 // list for display
239 struct list_head queue[QUEUE_BUTT];
240
241 // list for log
242 MppBufSlotLogs *logs;
243
244 MppBufSlotEntry *slots;
245 };
246
default_align_16(RK_U32 val)247 static RK_U32 default_align_16(RK_U32 val)
248 {
249 return MPP_ALIGN(val, 16);
250 }
251
252 /* Based on drm_gem_framebuffer_helper.c drm_gem_afbc_min_size() */
get_afbc_min_size(RK_S32 width,RK_S32 height,RK_S32 bpp)253 static RK_S32 get_afbc_min_size(RK_S32 width, RK_S32 height, RK_S32 bpp)
254 {
255 #define AFBC_HEADER_SIZE 16
256 #define AFBC_HDR_ALIGN 64
257 #define AFBC_SUPERBLOCK_PIXELS 256
258 #define AFBC_SUPERBLOCK_ALIGNMENT 128
259
260 RK_S32 n_blocks, hdr_alignment, size;
261
262 /* AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 and !AFBC_FORMAT_MOD_TILED */
263 width = MPP_ALIGN(width, 16);
264 height = MPP_ALIGN(height, 16);
265 hdr_alignment = AFBC_HDR_ALIGN;
266
267 n_blocks = (width * height) / AFBC_SUPERBLOCK_PIXELS;
268
269 size = MPP_ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
270 size += n_blocks * MPP_ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8,
271 AFBC_SUPERBLOCK_ALIGNMENT);
272 return size;
273 }
274
generate_info_set(MppBufSlotsImpl * impl,MppFrame frame,RK_U32 force_default_align)275 static void generate_info_set(MppBufSlotsImpl *impl, MppFrame frame, RK_U32 force_default_align)
276 {
277 RK_U32 width = mpp_frame_get_width(frame);
278 RK_U32 height = mpp_frame_get_height(frame);
279 MppFrameFormat fmt = mpp_frame_get_fmt(frame);
280 RK_U32 depth = ((fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV420SP_10BIT ||
281 (fmt & MPP_FRAME_FMT_MASK) == MPP_FMT_YUV422SP_10BIT) ? 10 : 8;
282 RK_U32 codec_hor_stride = mpp_frame_get_hor_stride(frame);
283 RK_U32 codec_ver_stride = mpp_frame_get_ver_stride(frame);
284
285 RK_U32 hal_hor_stride = (codec_hor_stride) ?
286 (impl->hal_hor_align(codec_hor_stride)) :
287 (impl->hal_hor_align(width * depth >> 3));
288 RK_U32 hal_ver_stride = (codec_ver_stride) ?
289 (impl->hal_ver_align(codec_ver_stride)) :
290 (impl->hal_ver_align(height));
291 RK_U32 hor_stride_pixel;
292
293 hal_hor_stride = (force_default_align && codec_hor_stride) ? codec_hor_stride : hal_hor_stride;
294 hal_ver_stride = (force_default_align && codec_ver_stride) ? codec_ver_stride : hal_ver_stride;
295
296 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
297 /*fbc stride default 64 align*/
298 if (*compat_ext_fbc_hdr_256_odd)
299 hal_hor_stride = (MPP_ALIGN(width, 256) | 256) * depth >> 3;
300 else
301 hal_hor_stride = MPP_ALIGN(width, 64) * depth >> 3;
302 }
303
304 switch (fmt & MPP_FRAME_FMT_MASK) {
305 case MPP_FMT_YUV420SP_10BIT: {
306 hor_stride_pixel = hal_hor_stride * 8 / 10;
307 } break;
308 case MPP_FMT_YUV422_YVYU:
309 case MPP_FMT_YUV422_YUYV:
310 case MPP_FMT_RGB565:
311 case MPP_FMT_BGR565: {
312 hor_stride_pixel = hal_hor_stride / 2;
313 } break;
314 case MPP_FMT_RGB888:
315 case MPP_FMT_BGR888: {
316 hor_stride_pixel = hal_hor_stride / 3;
317 } break;
318 default : {
319 hor_stride_pixel = hal_hor_stride;
320 } break;
321 }
322
323 RK_S32 size = hal_hor_stride * hal_ver_stride;
324
325 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
326 hor_stride_pixel = MPP_ALIGN(hor_stride_pixel, 64);
327 switch ((fmt & MPP_FRAME_FMT_MASK)) {
328 case MPP_FMT_YUV420SP_10BIT : {
329 size = get_afbc_min_size(hor_stride_pixel, hal_ver_stride, 15);
330 } break;
331 case MPP_FMT_YUV420SP : {
332 size = get_afbc_min_size(hor_stride_pixel, hal_ver_stride, 12);
333 } break;
334 case MPP_FMT_YUV422SP : {
335 size = get_afbc_min_size(hor_stride_pixel, hal_ver_stride, 16);
336 } break;
337 default : {
338 size = hal_hor_stride * hal_ver_stride * 3 / 2;
339 mpp_err("dec out fmt is no support");
340 } break;
341 }
342 mpp_frame_set_fbc_size(frame, size);
343 } else {
344 size *= impl->numerator;
345 size /= impl->denominator;
346 size = impl->hal_len_align ? impl->hal_len_align(hal_hor_stride * hal_ver_stride) : size;
347 }
348
349 mpp_frame_set_width(impl->info_set, width);
350 mpp_frame_set_height(impl->info_set, height);
351 mpp_frame_set_fmt(impl->info_set, fmt);
352 mpp_frame_set_hor_stride(impl->info_set, hal_hor_stride);
353 mpp_frame_set_ver_stride(impl->info_set, hal_ver_stride);
354 mpp_frame_set_hor_stride_pixel(impl->info_set, hor_stride_pixel);
355 mpp_frame_set_buf_size(impl->info_set, size);
356 mpp_frame_set_buf_size(frame, size);
357 mpp_frame_set_hor_stride(frame, hal_hor_stride);
358 mpp_frame_set_ver_stride(frame, hal_ver_stride);
359 mpp_frame_set_hor_stride_pixel(frame, hor_stride_pixel);
360 impl->buf_size = size;
361 if (mpp_frame_get_thumbnail_en(frame)) {
362 /*
363 * The decode hw only support 1/2 scaling in width and height,
364 * so, an extra 1/4 buffer is expanded to store scaling data.
365 */
366 impl->buf_size += size / 4;
367 mpp_frame_set_buf_size(impl->info_set, impl->buf_size);
368 mpp_frame_set_buf_size(frame, impl->buf_size);
369 }
370 MppFrameImpl *info_set_impl = (MppFrameImpl *)impl->info_set;
371 MppFrameImpl *frame_impl = (MppFrameImpl *)frame;
372 info_set_impl->color_range = frame_impl->color_range;
373 info_set_impl->color_primaries = frame_impl->color_primaries;
374 info_set_impl->color_trc = frame_impl->color_trc;
375 info_set_impl->colorspace = frame_impl->colorspace;
376 info_set_impl->chroma_location = frame_impl->chroma_location;
377 }
378
379 #define dump_slots(...) _dump_slots(__FUNCTION__, ## __VA_ARGS__)
380
buf_slot_logs_reset(MppBufSlotLogs * logs)381 static void buf_slot_logs_reset(MppBufSlotLogs *logs)
382 {
383 logs->log_count = 0;
384 logs->log_write = 0;
385 logs->log_read = 0;
386 }
387
buf_slot_logs_init(RK_U32 max_count)388 static MppBufSlotLogs *buf_slot_logs_init(RK_U32 max_count)
389 {
390 MppBufSlotLogs *logs = NULL;
391
392 if (!max_count)
393 return NULL;
394
395 logs = mpp_malloc_size(MppBufSlotLogs, sizeof(MppBufSlotLogs) +
396 max_count * sizeof(MppBufSlotLog));
397 if (!logs) {
398 mpp_err_f("failed to create %d buf slot logs\n", max_count);
399 return NULL;
400 }
401
402 logs->max_count = max_count;
403 logs->logs = (MppBufSlotLog *)(logs + 1);
404 buf_slot_logs_reset(logs);
405
406 return logs;
407 }
408
buf_slot_logs_deinit(MppBufSlotLogs * logs)409 static void buf_slot_logs_deinit(MppBufSlotLogs *logs)
410 {
411 MPP_FREE(logs);
412 }
413
buf_slot_logs_write(MppBufSlotLogs * logs,RK_S32 index,MppBufSlotOps op,SlotStatus before,SlotStatus after)414 static void buf_slot_logs_write(MppBufSlotLogs *logs, RK_S32 index, MppBufSlotOps op,
415 SlotStatus before, SlotStatus after)
416 {
417 MppBufSlotLog *log = NULL;
418
419 log = &logs->logs[logs->log_write];
420 log->index = index;
421 log->ops = op;
422 log->status_in = before;
423 log->status_out = after;
424
425 logs->log_write++;
426 if (logs->log_write >= logs->max_count)
427 logs->log_write = 0;
428
429 if (logs->log_count < logs->max_count)
430 logs->log_count++;
431 else {
432 logs->log_read++;
433 if (logs->log_read >= logs->max_count)
434 logs->log_read = 0;
435 }
436 }
437
buf_slot_logs_dump(MppBufSlotLogs * logs)438 static void buf_slot_logs_dump(MppBufSlotLogs *logs)
439 {
440 while (logs->log_count) {
441 MppBufSlotLog *log = &logs->logs[logs->log_read];
442
443 mpp_log("index %2d op: %s status in %08x out %08x",
444 log->index, op_string[log->ops], log->status_in.val, log->status_out.val);
445
446 logs->log_read++;
447 if (logs->log_read >= logs->max_count)
448 logs->log_read = 0;
449 logs->log_count--;
450 }
451 mpp_assert(logs->log_read == logs->log_write);
452 }
453
_dump_slots(const char * caller,MppBufSlotsImpl * impl)454 static void _dump_slots(const char *caller, MppBufSlotsImpl *impl)
455 {
456 RK_S32 i;
457 MppBufSlotEntry *slot = impl->slots;
458
459 mpp_log("\ncaller %s is dumping slots\n", caller, impl->slots_idx);
460 mpp_log("slots %d %p buffer count %d buffer size %d\n", impl->slots_idx,
461 impl, impl->buf_count, impl->buf_size);
462 mpp_log("decode count %d\n", impl->decode_count);
463 mpp_log("display count %d\n", impl->display_count);
464
465 for (i = 0; i < impl->buf_count; i++, slot++) {
466 SlotStatus status = slot->status;
467 mpp_log("slot %2d used %d refer %d decoding %d display %d status %08x\n",
468 i, status.on_used, status.codec_use, status.hal_use, status.queue_use, status.val);
469 }
470
471 mpp_log("\nslot operation history:\n\n");
472
473 if (impl->logs)
474 buf_slot_logs_dump(impl->logs);
475
476 mpp_assert(0);
477
478 return;
479 }
480
slot_ops_with_log(MppBufSlotsImpl * impl,MppBufSlotEntry * slot,MppBufSlotOps op,void * arg)481 static void slot_ops_with_log(MppBufSlotsImpl *impl, MppBufSlotEntry *slot, MppBufSlotOps op, void *arg)
482 {
483 RK_U32 error = 0;
484 RK_S32 index = slot->index;
485 SlotStatus status = slot->status;
486 SlotStatus before = status;
487 switch (op) {
488 case SLOT_INIT : {
489 status.val = 0;
490 } break;
491 case SLOT_SET_ON_USE : {
492 status.on_used = 1;
493 } break;
494 case SLOT_CLR_ON_USE : {
495 status.on_used = 0;
496 } break;
497 case SLOT_SET_NOT_READY : {
498 status.not_ready = 1;
499 } break;
500 case SLOT_CLR_NOT_READY : {
501 status.not_ready = 0;
502 } break;
503 case SLOT_SET_CODEC_READY : {
504 status.not_ready = 0;
505 } break;
506 case SLOT_CLR_CODEC_READY : {
507 status.not_ready = 1;
508 } break;
509 case SLOT_SET_CODEC_USE : {
510 status.codec_use = 1;
511 } break;
512 case SLOT_CLR_CODEC_USE : {
513 status.codec_use = 0;
514 } break;
515 case SLOT_SET_HAL_INPUT : {
516 status.hal_use++;
517 } break;
518 case SLOT_CLR_HAL_INPUT : {
519 if (status.hal_use)
520 status.hal_use--;
521 else {
522 mpp_err("can not clr hal_input on slot %d\n", slot->index);
523 error = 1;
524 }
525 } break;
526 case SLOT_SET_HAL_OUTPUT : {
527 status.hal_output++;
528 status.not_ready = 1;
529 } break;
530 case SLOT_CLR_HAL_OUTPUT : {
531 if (status.hal_output)
532 status.hal_output--;
533 else
534 mpp_err("can not clr hal_output on slot %d\n", slot->index);
535
536 // NOTE: set output index ready here
537 if (!status.hal_output)
538 status.not_ready = 0;
539 } break;
540 case SLOT_SET_QUEUE_USE :
541 case SLOT_ENQUEUE_OUTPUT :
542 case SLOT_ENQUEUE_DISPLAY :
543 case SLOT_ENQUEUE_DEINTER :
544 case SLOT_ENQUEUE_CONVERT : {
545 status.queue_use++;
546 } break;
547 case SLOT_CLR_QUEUE_USE :
548 case SLOT_DEQUEUE_OUTPUT :
549 case SLOT_DEQUEUE_DISPLAY :
550 case SLOT_DEQUEUE_DEINTER :
551 case SLOT_DEQUEUE_CONVERT : {
552 if (status.queue_use)
553 status.queue_use--;
554 else {
555 mpp_err("can not clr queue_use on slot %d\n", slot->index);
556 error = 1;
557 }
558 } break;
559 case SLOT_SET_EOS : {
560 status.eos = 1;
561 } break;
562 case SLOT_CLR_EOS : {
563 status.eos = 0;
564 slot->eos = 0;
565 } break;
566 case SLOT_SET_FRAME : {
567 status.has_frame = (arg) ? (1) : (0);
568 } break;
569 case SLOT_CLR_FRAME : {
570 status.has_frame = 0;
571 } break;
572 case SLOT_SET_BUFFER : {
573 status.has_buffer = (arg) ? (1) : (0);
574 } break;
575 case SLOT_CLR_BUFFER : {
576 status.has_buffer = 0;
577 } break;
578 default : {
579 mpp_err("found invalid operation code %d\n", op);
580 error = 1;
581 } break;
582 }
583 slot->status = status;
584 buf_slot_dbg(BUF_SLOT_DBG_OPS_RUNTIME, "slot %3d index %2d op: %s arg %010p status in %08x out %08x",
585 impl->slots_idx, index, op_string[op], arg, before.val, status.val);
586 if (impl->logs)
587 buf_slot_logs_write(impl->logs, index, op, before, status);
588 if (error)
589 dump_slots(impl);
590 }
591
init_slot_entry(MppBufSlotsImpl * impl,RK_S32 pos,RK_S32 count)592 static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count)
593 {
594 MppBufSlotEntry *slot = impl->slots;
595 for (RK_S32 i = 0; i < count; i++, slot++) {
596 slot->slots = impl;
597 INIT_LIST_HEAD(&slot->list);
598 slot->index = pos + i;
599 slot->frame = NULL;
600 slot_ops_with_log(impl, slot, SLOT_INIT, NULL);
601 }
602 }
603
604 /*
605 * only called on unref / displayed / decoded
606 *
607 * NOTE: MppFrame will be destroyed outside mpp
608 * but MppBuffer must dec_ref here
609 */
check_entry_unused(MppBufSlotsImpl * impl,MppBufSlotEntry * entry)610 static RK_S32 check_entry_unused(MppBufSlotsImpl *impl, MppBufSlotEntry *entry)
611 {
612 SlotStatus status = entry->status;
613
614 if (status.on_used &&
615 !status.not_ready &&
616 !status.codec_use &&
617 !status.hal_output &&
618 !status.hal_use &&
619 !status.queue_use) {
620 if (entry->frame) {
621 slot_ops_with_log(impl, entry, SLOT_CLR_FRAME, entry->frame);
622 mpp_frame_deinit(&entry->frame);
623 }
624 if (entry->buffer) {
625 mpp_buffer_put(entry->buffer);
626 slot_ops_with_log(impl, entry, SLOT_CLR_BUFFER, entry->buffer);
627 entry->buffer = NULL;
628 }
629
630 slot_ops_with_log(impl, entry, SLOT_CLR_ON_USE, NULL);
631 impl->used_count--;
632 return 1;
633 }
634
635 return 0;
636 }
637
clear_slots_impl(MppBufSlotsImpl * impl)638 static void clear_slots_impl(MppBufSlotsImpl *impl)
639 {
640 MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots;
641 RK_S32 i;
642
643 for (i = 0; i < (RK_S32)MPP_ARRAY_ELEMS(impl->queue); i++) {
644 if (!list_empty(&impl->queue[i]))
645 dump_slots(impl);
646
647 mpp_assert(list_empty(&impl->queue[i]));
648 }
649
650 for (i = 0; i < impl->buf_count; i++, slot++) {
651 mpp_assert(!slot->status.on_used);
652 if (slot->status.on_used) {
653 dump_slots(impl);
654 mpp_buf_slot_reset(impl, i);
655 }
656 }
657
658 impl->used_count = 0;
659
660 if (impl->info)
661 mpp_frame_deinit(&impl->info);
662
663 if (impl->info_set)
664 mpp_frame_deinit(&impl->info_set);
665
666 if (impl->logs) {
667 buf_slot_logs_deinit(impl->logs);
668 impl->logs = NULL;
669 }
670
671 if (impl->lock)
672 delete impl->lock;
673
674 mpp_free(impl->slots);
675 mpp_free(impl);
676 }
677
mpp_buf_slot_init(MppBufSlots * slots)678 MPP_RET mpp_buf_slot_init(MppBufSlots *slots)
679 {
680 if (NULL == slots) {
681 mpp_err_f("found NULL input\n");
682 return MPP_ERR_NULL_PTR;
683 }
684 MppBufSlotsImpl *impl = mpp_calloc(MppBufSlotsImpl, 1);
685 if (NULL == impl) {
686 *slots = NULL;
687 return MPP_NOK;
688 }
689
690 mpp_env_get_u32("buf_slot_debug", &buf_slot_debug, BUF_SLOT_DBG_OPS_HISTORY);
691
692 do {
693 impl->lock = new Mutex();
694 if (NULL == impl->lock)
695 break;
696
697 for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) {
698 INIT_LIST_HEAD(&impl->queue[i]);
699 }
700
701 if (buf_slot_debug & BUF_SLOT_DBG_OPS_HISTORY) {
702 impl->logs = buf_slot_logs_init(SLOT_OPS_MAX_COUNT);
703 if (NULL == impl->logs)
704 break;
705 }
706
707 if (mpp_frame_init(&impl->info))
708 break;
709
710 if (mpp_frame_init(&impl->info_set))
711 break;
712
713 // slots information default setup
714 impl->hal_hor_align = default_align_16;
715 impl->hal_ver_align = default_align_16;
716 impl->hal_len_align = NULL;
717 impl->numerator = 9;
718 impl->denominator = 5;
719 impl->slots_idx = buf_slot_idx++;
720
721 *slots = impl;
722 return MPP_OK;
723 } while (0);
724
725 clear_slots_impl(impl);
726
727 *slots = NULL;
728 return MPP_NOK;
729 }
730
mpp_buf_slot_deinit(MppBufSlots slots)731 MPP_RET mpp_buf_slot_deinit(MppBufSlots slots)
732 {
733 if (NULL == slots) {
734 mpp_err_f("found NULL input\n");
735 return MPP_ERR_NULL_PTR;
736 }
737
738 clear_slots_impl((MppBufSlotsImpl *)slots);
739 return MPP_OK;
740 }
741
mpp_buf_slot_setup(MppBufSlots slots,RK_S32 count)742 MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count)
743 {
744 if (NULL == slots) {
745 mpp_err_f("found NULL input\n");
746 return MPP_ERR_NULL_PTR;
747 }
748
749 buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p setup: count %d\n", slots, count);
750
751 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
752 AutoMutex auto_lock(impl->lock);
753
754 if (NULL == impl->slots) {
755 // first slot setup
756 impl->buf_count = impl->new_count = count;
757 impl->slots = mpp_calloc(MppBufSlotEntry, count);
758 init_slot_entry(impl, 0, count);
759 impl->used_count = 0;
760 } else {
761 // record the slot count for info changed ready config
762 if (count > impl->buf_count) {
763 impl->slots = mpp_realloc(impl->slots, MppBufSlotEntry, count);
764 mpp_assert(impl->slots);
765 init_slot_entry(impl, impl->buf_count, (count - impl->buf_count));
766 }
767 impl->new_count = count;
768 }
769
770 return MPP_OK;
771 }
772
mpp_buf_slot_is_changed(MppBufSlots slots)773 RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots)
774 {
775 if (NULL == slots) {
776 mpp_err_f("found NULL input\n");
777 return 0;
778 }
779
780 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
781 AutoMutex auto_lock(impl->lock);
782 return impl->info_changed;
783 }
784
mpp_buf_slot_ready(MppBufSlots slots)785 MPP_RET mpp_buf_slot_ready(MppBufSlots slots)
786 {
787 if (NULL == slots) {
788 mpp_err_f("found NULL input\n");
789 return MPP_ERR_NULL_PTR;
790 }
791
792 buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p is ready now\n", slots);
793
794 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
795 AutoMutex auto_lock(impl->lock);
796 slot_assert(impl, impl->slots);
797 if (!impl->info_changed)
798 mpp_log("found info change ready set without internal info change\n");
799
800 // ready mean the info_set will be copy to info as the new configuration
801 if (impl->buf_count != impl->new_count) {
802 impl->slots = mpp_realloc(impl->slots, MppBufSlotEntry, impl->new_count);
803 mpp_assert(impl->slots);
804 init_slot_entry(impl, 0, impl->new_count);
805 }
806 impl->buf_count = impl->new_count;
807
808 mpp_frame_copy(impl->info, impl->info_set);
809
810 if (impl->logs)
811 buf_slot_logs_reset(impl->logs);
812
813 impl->info_changed = 0;
814 return MPP_OK;
815 }
816
mpp_buf_slot_get_size(MppBufSlots slots)817 size_t mpp_buf_slot_get_size(MppBufSlots slots)
818 {
819 if (NULL == slots) {
820 mpp_err_f("found NULL input\n");
821 return 0;
822 }
823
824 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
825 AutoMutex auto_lock(impl->lock);
826 return impl->buf_size;
827 }
828
mpp_buf_slot_get_count(MppBufSlots slots)829 RK_S32 mpp_buf_slot_get_count(MppBufSlots slots)
830 {
831 if (NULL == slots) {
832 mpp_err_f("found NULL input\n");
833 return -1;
834 }
835
836 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
837 AutoMutex auto_lock(impl->lock);
838 return impl->buf_count;
839 }
840
mpp_buf_slot_set_callback(MppBufSlots slots,MppCbCtx * cb_ctx)841 MPP_RET mpp_buf_slot_set_callback(MppBufSlots slots, MppCbCtx *cb_ctx)
842 {
843 if (NULL == slots) {
844 mpp_err_f("found NULL input\n");
845 return MPP_NOK;
846 }
847
848 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
849 AutoMutex auto_lock(impl->lock);
850
851 impl->callback = *cb_ctx;
852 return MPP_OK;
853 }
854
mpp_buf_slot_get_unused(MppBufSlots slots,RK_S32 * index)855 MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index)
856 {
857 if (NULL == slots || NULL == index) {
858 mpp_err_f("found NULL input\n");
859 return MPP_ERR_NULL_PTR;
860 }
861
862 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
863 AutoMutex auto_lock(impl->lock);
864 RK_S32 i;
865 MppBufSlotEntry *slot = impl->slots;
866 for (i = 0; i < impl->buf_count; i++, slot++) {
867 if (!slot->status.on_used) {
868 *index = i;
869 slot_ops_with_log(impl, slot, SLOT_SET_ON_USE, NULL);
870 slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY, NULL);
871 impl->used_count++;
872 return MPP_OK;
873 }
874 }
875
876 *index = -1;
877 mpp_err_f("failed to get a unused slot\n");
878 dump_slots(impl);
879 slot_assert(impl, 0);
880 return MPP_NOK;
881 }
882
mpp_buf_slot_set_flag(MppBufSlots slots,RK_S32 index,SlotUsageType type)883 MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type)
884 {
885 if (NULL == slots) {
886 mpp_err_f("found NULL input\n");
887 return MPP_ERR_NULL_PTR;
888 }
889
890 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
891 AutoMutex auto_lock(impl->lock);
892 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
893 slot_ops_with_log(impl, &impl->slots[index], set_flag_op[type], NULL);
894 return MPP_OK;
895 }
896
mpp_buf_slot_clr_flag(MppBufSlots slots,RK_S32 index,SlotUsageType type)897 MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type)
898 {
899 if (NULL == slots) {
900 mpp_err_f("found NULL input\n");
901 return MPP_ERR_NULL_PTR;
902 }
903
904 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
905 RK_S32 unused = 0;
906 {
907 AutoMutex auto_lock(impl->lock);
908 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
909 MppBufSlotEntry *slot = &impl->slots[index];
910 slot_ops_with_log(impl, slot, clr_flag_op[type], NULL);
911
912 if (type == SLOT_HAL_OUTPUT)
913 impl->decode_count++;
914
915 unused = check_entry_unused(impl, slot);
916 }
917
918 if (unused)
919 mpp_callback(&impl->callback, impl);
920 return MPP_OK;
921 }
922
mpp_buf_slot_enqueue(MppBufSlots slots,RK_S32 index,SlotQueueType type)923 MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type)
924 {
925 if (NULL == slots) {
926 mpp_err_f("found NULL input\n");
927 return MPP_ERR_NULL_PTR;
928 }
929
930 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
931 AutoMutex auto_lock(impl->lock);
932 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
933 MppBufSlotEntry *slot = &impl->slots[index];
934 slot_ops_with_log(impl, slot, (MppBufSlotOps)(SLOT_ENQUEUE + type), NULL);
935
936 // add slot to display list
937 list_del_init(&slot->list);
938 list_add_tail(&slot->list, &impl->queue[type]);
939 return MPP_OK;
940 }
941
mpp_buf_slot_dequeue(MppBufSlots slots,RK_S32 * index,SlotQueueType type)942 MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type)
943 {
944 if (NULL == slots || NULL == index) {
945 mpp_err_f("found NULL input\n");
946 return MPP_ERR_NULL_PTR;
947 }
948
949 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
950 AutoMutex auto_lock(impl->lock);
951 if (list_empty(&impl->queue[type]))
952 return MPP_NOK;
953
954 MppBufSlotEntry *slot = list_entry(impl->queue[type].next, MppBufSlotEntry, list);
955 if (slot->status.not_ready)
956 return MPP_NOK;
957
958 // make sure that this slot is just the next display slot
959 list_del_init(&slot->list);
960 slot_assert(impl, slot->index < impl->buf_count);
961 slot_ops_with_log(impl, slot, (MppBufSlotOps)(SLOT_DEQUEUE + type), NULL);
962 impl->display_count++;
963 *index = slot->index;
964
965 return MPP_OK;
966 }
967
mpp_buf_slot_set_prop(MppBufSlots slots,RK_S32 index,SlotPropType type,void * val)968 MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val)
969 {
970 if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) {
971 mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
972 return MPP_ERR_UNKNOW;
973 }
974
975 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
976 AutoMutex auto_lock(impl->lock);
977 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
978 MppBufSlotEntry *slot = &impl->slots[index];
979 slot_ops_with_log(impl, slot, set_val_op[type], val);
980
981 switch (type) {
982 case SLOT_EOS: {
983 RK_U32 eos = *(RK_U32*)val;
984 slot->eos = eos;
985 if (slot->frame)
986 mpp_frame_set_eos(slot->frame, eos);
987 } break;
988 case SLOT_FRAME: {
989 MppFrame frame = val;
990
991 slot_assert(impl, slot->status.not_ready);
992 /*
993 * we need to detect infomation change here
994 * there are two types of info change:
995 * 1. buffer size change
996 * this case need to reset buffer group and commit buffer with new size
997 * 2. display info change
998 * if only width/height/fmt is change and buffer do not need to be reset
999 * only display info change is need
1000 */
1001 generate_info_set(impl, frame, 0);
1002
1003 if (NULL == slot->frame)
1004 mpp_frame_init(&slot->frame);
1005
1006 MppFrameImpl *src = (MppFrameImpl *)frame;
1007 MppFrameImpl *dst = (MppFrameImpl *)slot->frame;
1008 mpp_frame_copy(dst, src);
1009 // NOTE: stride from codec need to be change to hal stride
1010 // hor_stride and ver_stride can not be zero
1011 // they are the stride required by codec
1012 // then hal will modify it according to hardware requirement
1013 mpp_assert(src->hor_stride);
1014 mpp_assert(src->ver_stride);
1015 dst->hor_stride = src->hor_stride;
1016 dst->ver_stride = src->ver_stride;
1017 dst->eos = slot->eos;
1018
1019 if (mpp_frame_info_cmp(impl->info, impl->info_set)) {
1020 MppFrameImpl *old = (MppFrameImpl *)impl->info;
1021
1022 impl->info_changed = 1;
1023
1024 if (old->width || old->height) {
1025 mpp_dbg_info("info change found\n");
1026 mpp_dbg_info("old width %4d height %4d stride hor %4d ver %4d fmt %4d\n",
1027 old->width, old->height, old->hor_stride,
1028 old->ver_stride, old->fmt);
1029 }
1030 mpp_dbg_info("new width %4d height %4d stride hor %4d ver %4d fmt %4d\n",
1031 dst->width, dst->height, dst->hor_stride, dst->ver_stride,
1032 dst->fmt);
1033 // info change found here
1034 }
1035 } break;
1036 case SLOT_BUFFER: {
1037 MppBuffer buffer = val;
1038 if (slot->buffer) {
1039 // NOTE: reset buffer only on stream buffer slot
1040 slot_assert(impl, NULL == slot->frame);
1041 mpp_buffer_put(slot->buffer);
1042 }
1043 mpp_buffer_inc_ref(buffer);
1044 slot->buffer = buffer;
1045
1046 if (slot->frame)
1047 mpp_frame_set_buffer(slot->frame, buffer);
1048 } break;
1049 default : {
1050 } break;
1051 }
1052
1053 return MPP_OK;
1054 }
1055
mpp_buf_slot_get_prop(MppBufSlots slots,RK_S32 index,SlotPropType type,void * val)1056 MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val)
1057 {
1058 if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) {
1059 mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
1060 return MPP_ERR_UNKNOW;
1061 }
1062
1063 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1064 AutoMutex auto_lock(impl->lock);
1065 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
1066 MppBufSlotEntry *slot = &impl->slots[index];
1067
1068 switch (type) {
1069 case SLOT_EOS: {
1070 *(RK_U32*)val = slot->eos;
1071 } break;
1072 case SLOT_FRAME: {
1073 MppFrame *frame = (MppFrame *)val;
1074 //*frame = (slot->status.has_frame) ? (slot->frame) : (NULL);
1075
1076 mpp_assert(slot->status.has_frame);
1077 if (slot->status.has_frame) {
1078 if (NULL == *frame )
1079 mpp_frame_init(frame);
1080 if (*frame)
1081 mpp_frame_copy(*frame, slot->frame);
1082 } else
1083 *frame = NULL;
1084 } break;
1085 case SLOT_FRAME_PTR: {
1086 MppFrame *frame = (MppFrame *)val;
1087 mpp_assert(slot->status.has_frame);
1088 *frame = (slot->status.has_frame) ? (slot->frame) : (NULL);
1089 } break;
1090 case SLOT_BUFFER: {
1091 MppBuffer *buffer = (MppBuffer *)val;
1092 *buffer = (slot->status.has_buffer) ? (slot->buffer) : (NULL);
1093 } break;
1094 default : {
1095 } break;
1096 }
1097
1098 return MPP_OK;
1099 }
1100
mpp_buf_slot_reset(MppBufSlots slots,RK_S32 index)1101 MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index)
1102 {
1103 if (NULL == slots || index < 0) {
1104 mpp_err_f("found NULL input\n");
1105 return MPP_ERR_NULL_PTR;
1106 }
1107
1108 buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p reset index %d\n", slots, index);
1109
1110 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1111 AutoMutex auto_lock(impl->lock);
1112 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
1113 MppBufSlotEntry *slot = &impl->slots[index];
1114
1115 // make sure that this slot is just the next display slot
1116 list_del_init(&slot->list);
1117 slot_ops_with_log(impl, slot, SLOT_CLR_QUEUE_USE, NULL);
1118 slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL);
1119 slot_ops_with_log(impl, slot, SLOT_CLR_ON_USE, NULL);
1120 return MPP_OK;
1121 }
1122
mpp_buf_slot_default_info(MppBufSlots slots,RK_S32 index,void * val)1123 MPP_RET mpp_buf_slot_default_info(MppBufSlots slots, RK_S32 index, void *val)
1124 {
1125 if (NULL == slots || index < 0) {
1126 mpp_err_f("found NULL input\n");
1127 return MPP_ERR_NULL_PTR;
1128 }
1129
1130 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1131 AutoMutex auto_lock(impl->lock);
1132 slot_assert(impl, (index >= 0) && (index < impl->buf_count));
1133 MppBufSlotEntry *slot = &impl->slots[index];
1134
1135 slot_assert(impl, slot->status.not_ready);
1136 slot_assert(impl, NULL == slot->frame);
1137 slot_assert(impl, impl->info_set);
1138
1139 if (NULL == slot->frame) {
1140 mpp_frame_init(&slot->frame);
1141 mpp_frame_copy(slot->frame, impl->info_set);
1142 }
1143
1144 MppFrame *frame = (MppFrame *)val;
1145 *frame = slot->frame;
1146
1147 slot_ops_with_log(impl, slot, SLOT_CLR_NOT_READY, NULL);
1148 slot_ops_with_log(impl, slot, SLOT_SET_FRAME, slot->frame);
1149 return MPP_OK;
1150 }
1151
mpp_slots_is_empty(MppBufSlots slots,SlotQueueType type)1152 RK_U32 mpp_slots_is_empty(MppBufSlots slots, SlotQueueType type)
1153 {
1154 if (NULL == slots) {
1155 mpp_err_f("found NULL input\n");
1156 return 0;
1157 }
1158
1159 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1160 AutoMutex auto_lock(impl->lock);
1161 return list_empty(&impl->queue[type]) ? 1 : 0;
1162 }
1163
mpp_slots_get_used_count(MppBufSlots slots)1164 RK_S32 mpp_slots_get_used_count(MppBufSlots slots)
1165 {
1166 if (NULL == slots) {
1167 mpp_err_f("found NULL input\n");
1168 return 0;
1169 }
1170 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1171 AutoMutex auto_lock(impl->lock);
1172 return impl->used_count;
1173 }
1174
mpp_slots_get_unused_count(MppBufSlots slots)1175 RK_S32 mpp_slots_get_unused_count(MppBufSlots slots)
1176 {
1177 if (NULL == slots) {
1178 mpp_err_f("found NULL input\n");
1179 return MPP_ERR_NULL_PTR;
1180 }
1181
1182 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1183 AutoMutex auto_lock(impl->lock);
1184 slot_assert(impl, (impl->used_count >= 0) && (impl->used_count <= impl->buf_count));
1185 return impl->buf_count - impl->used_count;
1186 }
1187
mpp_slots_set_prop(MppBufSlots slots,SlotsPropType type,void * val)1188 MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val)
1189 {
1190 if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) {
1191 mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
1192 return MPP_ERR_UNKNOW;
1193 }
1194
1195 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1196 AutoMutex auto_lock(impl->lock);
1197 RK_U32 value = *((RK_U32*)val);
1198 switch (type) {
1199 case SLOTS_EOS: {
1200 impl->eos = value;
1201 } break;
1202 case SLOTS_NUMERATOR : {
1203 impl->numerator = value;
1204 } break;
1205 case SLOTS_DENOMINATOR : {
1206 impl->denominator = value;
1207 } break;
1208 case SLOTS_HOR_ALIGN: {
1209 impl->hal_hor_align = (AlignFunc)val;
1210 } break;
1211 case SLOTS_VER_ALIGN: {
1212 impl->hal_ver_align = (AlignFunc)val;
1213 } break;
1214 case SLOTS_LEN_ALIGN: {
1215 impl->hal_len_align = (AlignFunc)val;
1216 } break;
1217 case SLOTS_COUNT: {
1218 impl->buf_count = value;
1219 } break;
1220 case SLOTS_SIZE: {
1221 impl->buf_size = value;
1222 } break;
1223 case SLOTS_FRAME_INFO: {
1224 // do info change detection here
1225 generate_info_set(impl, (MppFrame)val, 1);
1226 mpp_frame_copy(impl->info, impl->info_set);
1227 {
1228 MppFrameImpl *p = (MppFrameImpl *)impl->info;
1229 mpp_log("set frame info: w %4d h %4d hor %4d ver %4d\n", p->width, p->height, p->hor_stride, p->ver_stride);
1230 }
1231 mpp_frame_copy((MppFrame)val, impl->info_set);
1232 } break;
1233 default : {
1234 } break;
1235 }
1236
1237 return MPP_OK;
1238 }
1239
mpp_slots_get_prop(MppBufSlots slots,SlotsPropType type,void * val)1240 MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val)
1241 {
1242 if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) {
1243 mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val);
1244 return MPP_NOK;
1245 }
1246
1247 MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots;
1248 AutoMutex auto_lock(impl->lock);
1249 MPP_RET ret = MPP_OK;
1250
1251 switch (type) {
1252 case SLOTS_EOS: {
1253 *((RK_U32 *)val) = impl->eos;
1254 } break;
1255 case SLOTS_COUNT: {
1256 *((RK_U32 *)val) = impl->buf_count;
1257 } break;
1258 case SLOTS_SIZE: {
1259 *((RK_U32 *)val) = (RK_U32)impl->buf_size;
1260 } break;
1261 case SLOTS_FRAME_INFO: {
1262 MppFrame frame = (MppFrame)val;
1263 MppFrame info = impl->info;
1264 mpp_frame_copy(frame, info);
1265 } break;
1266 default : {
1267 mpp_err("can not get slots prop type %d\n", type);
1268 ret = MPP_NOK;
1269 } break;
1270 }
1271
1272 return ret;
1273 }
1274