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