xref: /OK3568_Linux_fs/external/mpp/mpp/base/mpp_buf_slot.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_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