1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka */
5*437bfbebSnyanmisaka
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_dec_vproc"
7*437bfbebSnyanmisaka
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka #include "mpp_mem.h"
12*437bfbebSnyanmisaka #include "mpp_common.h"
13*437bfbebSnyanmisaka
14*437bfbebSnyanmisaka #include "mpp_dec_impl.h"
15*437bfbebSnyanmisaka
16*437bfbebSnyanmisaka #include "mpp_meta_impl.h"
17*437bfbebSnyanmisaka #include "mpp_frame_impl.h"
18*437bfbebSnyanmisaka #include "mpp_dec_vproc.h"
19*437bfbebSnyanmisaka #include "iep_api.h"
20*437bfbebSnyanmisaka #include "iep2_api.h"
21*437bfbebSnyanmisaka
22*437bfbebSnyanmisaka #define DUMP_FILE 1
23*437bfbebSnyanmisaka
24*437bfbebSnyanmisaka #define dec_vproc_dbg(flag, fmt, ...) \
25*437bfbebSnyanmisaka do { \
26*437bfbebSnyanmisaka _mpp_dbg(vproc_debug, flag, fmt, ## __VA_ARGS__); \
27*437bfbebSnyanmisaka } while (0)
28*437bfbebSnyanmisaka
29*437bfbebSnyanmisaka #define vproc_dbg_f(flag, fmt, ...) \
30*437bfbebSnyanmisaka do { \
31*437bfbebSnyanmisaka _mpp_dbg_f(vproc_debug, flag, fmt, ## __VA_ARGS__); \
32*437bfbebSnyanmisaka } while (0)
33*437bfbebSnyanmisaka
34*437bfbebSnyanmisaka #define VPROC_DBG_FUNCTION (0x00000001)
35*437bfbebSnyanmisaka #define VPROC_DBG_STATUS (0x00000002)
36*437bfbebSnyanmisaka #define VPROC_DBG_RESET (0x00000004)
37*437bfbebSnyanmisaka #define VPROC_DBG_DUMP_IN (0x00000010)
38*437bfbebSnyanmisaka #define VPROC_DBG_DUMP_OUT (0x00000020)
39*437bfbebSnyanmisaka #define VPROC_DBG_IN (0x00000040)
40*437bfbebSnyanmisaka #define VPROC_DBG_OUT (0x00000080)
41*437bfbebSnyanmisaka
42*437bfbebSnyanmisaka #define vproc_dbg_func(fmt, ...) \
43*437bfbebSnyanmisaka vproc_dbg_f(VPROC_DBG_FUNCTION, fmt, ## __VA_ARGS__);
44*437bfbebSnyanmisaka #define vproc_dbg_status(fmt, ...) \
45*437bfbebSnyanmisaka vproc_dbg_f(VPROC_DBG_STATUS, fmt, ## __VA_ARGS__);
46*437bfbebSnyanmisaka #define vproc_dbg_reset(fmt, ...) \
47*437bfbebSnyanmisaka vproc_dbg_f(VPROC_DBG_RESET, fmt, ## __VA_ARGS__);
48*437bfbebSnyanmisaka #define vproc_dbg_in(fmt, ...) \
49*437bfbebSnyanmisaka vproc_dbg_f(VPROC_DBG_IN, fmt, ## __VA_ARGS__);
50*437bfbebSnyanmisaka #define vproc_dbg_out(fmt, ...) \
51*437bfbebSnyanmisaka vproc_dbg_f(VPROC_DBG_OUT, fmt, ## __VA_ARGS__);
52*437bfbebSnyanmisaka
53*437bfbebSnyanmisaka RK_U32 vproc_debug = 0;
54*437bfbebSnyanmisaka
55*437bfbebSnyanmisaka typedef union VprocTaskStatus_u {
56*437bfbebSnyanmisaka RK_U32 val;
57*437bfbebSnyanmisaka struct {
58*437bfbebSnyanmisaka RK_U32 task_rdy : 1;
59*437bfbebSnyanmisaka RK_U32 buf_rdy : 1;
60*437bfbebSnyanmisaka };
61*437bfbebSnyanmisaka } VprocTaskStatus;
62*437bfbebSnyanmisaka
63*437bfbebSnyanmisaka typedef union VprocTaskWait_u {
64*437bfbebSnyanmisaka RK_U32 val;
65*437bfbebSnyanmisaka struct {
66*437bfbebSnyanmisaka RK_U32 task_in : 1;
67*437bfbebSnyanmisaka RK_U32 task_buf_in : 1;
68*437bfbebSnyanmisaka };
69*437bfbebSnyanmisaka } VprocTaskWait;
70*437bfbebSnyanmisaka
71*437bfbebSnyanmisaka typedef struct MppDecVprocCtxImpl_t {
72*437bfbebSnyanmisaka Mpp *mpp;
73*437bfbebSnyanmisaka HalTaskGroup task_group;
74*437bfbebSnyanmisaka MppBufSlots slots;
75*437bfbebSnyanmisaka
76*437bfbebSnyanmisaka MppThread *thd;
77*437bfbebSnyanmisaka RK_U32 reset;
78*437bfbebSnyanmisaka sem_t reset_sem;
79*437bfbebSnyanmisaka
80*437bfbebSnyanmisaka IepCtx iep_ctx;
81*437bfbebSnyanmisaka iep_com_ctx *com_ctx;
82*437bfbebSnyanmisaka IepCmdParamDeiCfg dei_cfg;
83*437bfbebSnyanmisaka struct iep2_api_info dei_info;
84*437bfbebSnyanmisaka
85*437bfbebSnyanmisaka VprocTaskStatus task_status;
86*437bfbebSnyanmisaka VprocTaskWait task_wait;
87*437bfbebSnyanmisaka
88*437bfbebSnyanmisaka // slot index for previous frame and current frame
89*437bfbebSnyanmisaka RK_S32 prev_idx0;
90*437bfbebSnyanmisaka MppFrame prev_frm0;
91*437bfbebSnyanmisaka RK_S32 prev_idx1;
92*437bfbebSnyanmisaka MppFrame prev_frm1;
93*437bfbebSnyanmisaka enum IEP2_FF_MODE pre_ff_mode;
94*437bfbebSnyanmisaka RK_U32 pd_mode;
95*437bfbebSnyanmisaka MppBuffer out_buf0;
96*437bfbebSnyanmisaka MppBuffer out_buf1;
97*437bfbebSnyanmisaka MppVprocMode vproc_mode;
98*437bfbebSnyanmisaka
99*437bfbebSnyanmisaka MPP_RET (*set_dei)(MppDecVprocCtx *vproc_ctx, MppFrame frm);
100*437bfbebSnyanmisaka MPP_RET (*start_dei)(MppDecVprocCtx *vproc_ctx, RK_U32 mode);
101*437bfbebSnyanmisaka MPP_RET (*update_ref)(MppDecVprocCtx *vproc_ctx, MppFrame frm, RK_U32 index);
102*437bfbebSnyanmisaka } MppDecVprocCtxImpl;
103*437bfbebSnyanmisaka
dec_vproc_put_frame(Mpp * mpp,MppFrame frame,MppBuffer buf,RK_S64 pts,RK_U32 err)104*437bfbebSnyanmisaka static void dec_vproc_put_frame(Mpp *mpp, MppFrame frame, MppBuffer buf, RK_S64 pts, RK_U32 err)
105*437bfbebSnyanmisaka {
106*437bfbebSnyanmisaka MppList *list = mpp->mFrmOut;
107*437bfbebSnyanmisaka MppFrame out = mpp_frame_dup(frame);
108*437bfbebSnyanmisaka MppFrameImpl *impl = (MppFrameImpl *)out;
109*437bfbebSnyanmisaka MppBuffer src_buf = mpp_frame_get_buffer(frame);
110*437bfbebSnyanmisaka
111*437bfbebSnyanmisaka if (pts >= 0)
112*437bfbebSnyanmisaka impl->pts = pts;
113*437bfbebSnyanmisaka
114*437bfbebSnyanmisaka if (buf)
115*437bfbebSnyanmisaka impl->buffer = buf;
116*437bfbebSnyanmisaka
117*437bfbebSnyanmisaka /* check and copy hdr info */
118*437bfbebSnyanmisaka if (impl->meta && src_buf != buf) {
119*437bfbebSnyanmisaka RK_S32 hdr_offset = 0;
120*437bfbebSnyanmisaka RK_S32 hdr_size = 0;
121*437bfbebSnyanmisaka
122*437bfbebSnyanmisaka mpp_meta_s32_read(impl->meta, meta_hdr_offset_index, &hdr_offset);
123*437bfbebSnyanmisaka mpp_meta_s32_read(impl->meta, meta_hdr_size_index, &hdr_size);
124*437bfbebSnyanmisaka
125*437bfbebSnyanmisaka if (hdr_offset && hdr_size) {
126*437bfbebSnyanmisaka RK_U8 *src = (RK_U8 *)mpp_buffer_get_ptr(src_buf) + hdr_offset;
127*437bfbebSnyanmisaka RK_U8 *dst = (RK_U8 *)mpp_buffer_get_ptr(buf) + hdr_offset;
128*437bfbebSnyanmisaka
129*437bfbebSnyanmisaka mpp_buffer_sync_ro_partial_begin(src_buf, hdr_offset, hdr_size);
130*437bfbebSnyanmisaka memcpy(dst, src, hdr_size);
131*437bfbebSnyanmisaka mpp_buffer_sync_partial_end(buf, hdr_offset, hdr_size);
132*437bfbebSnyanmisaka }
133*437bfbebSnyanmisaka }
134*437bfbebSnyanmisaka
135*437bfbebSnyanmisaka impl->errinfo |= err;
136*437bfbebSnyanmisaka
137*437bfbebSnyanmisaka mpp_mutex_cond_lock(&list->cond_lock);
138*437bfbebSnyanmisaka mpp_list_add_at_tail(list, &out, sizeof(out));
139*437bfbebSnyanmisaka
140*437bfbebSnyanmisaka mpp->mFramePutCount++;
141*437bfbebSnyanmisaka vproc_dbg_out("Output frame[%d]:poc %d, pts %lld, err 0x%x, dis %x, buf ptr %p\n",
142*437bfbebSnyanmisaka mpp->mFramePutCount, mpp_frame_get_poc(out), mpp_frame_get_pts(out),
143*437bfbebSnyanmisaka mpp_frame_get_errinfo(frame), mpp_frame_get_discard(frame),
144*437bfbebSnyanmisaka mpp_buffer_get_ptr(impl->buffer));
145*437bfbebSnyanmisaka mpp_mutex_cond_signal(&list->cond_lock);
146*437bfbebSnyanmisaka mpp_mutex_cond_unlock(&list->cond_lock);
147*437bfbebSnyanmisaka
148*437bfbebSnyanmisaka if (mpp->mDec)
149*437bfbebSnyanmisaka mpp_dec_callback(mpp->mDec, MPP_DEC_EVENT_ON_FRM_READY, out);
150*437bfbebSnyanmisaka }
151*437bfbebSnyanmisaka
dec_vproc_clr_prev0(MppDecVprocCtxImpl * ctx)152*437bfbebSnyanmisaka static void dec_vproc_clr_prev0(MppDecVprocCtxImpl *ctx)
153*437bfbebSnyanmisaka {
154*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_STATUS) {
155*437bfbebSnyanmisaka if (ctx->prev_frm0) {
156*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(ctx->prev_frm0);
157*437bfbebSnyanmisaka RK_S32 fd = (buf) ? (mpp_buffer_get_fd(buf)) : (-1);
158*437bfbebSnyanmisaka mpp_log("clearing prev index %d frm %p fd %d, poc%d\n", ctx->prev_idx0,
159*437bfbebSnyanmisaka ctx->prev_frm0, fd, mpp_frame_get_poc(ctx->prev_frm0));
160*437bfbebSnyanmisaka } else
161*437bfbebSnyanmisaka mpp_log("clearing nothing\n");
162*437bfbebSnyanmisaka }
163*437bfbebSnyanmisaka
164*437bfbebSnyanmisaka if (ctx->prev_frm0) {
165*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(ctx->prev_frm0);
166*437bfbebSnyanmisaka if (buf)
167*437bfbebSnyanmisaka mpp_buffer_put(buf);
168*437bfbebSnyanmisaka }
169*437bfbebSnyanmisaka if (ctx->prev_idx0 >= 0)
170*437bfbebSnyanmisaka mpp_buf_slot_clr_flag(ctx->slots, ctx->prev_idx0, SLOT_QUEUE_USE);
171*437bfbebSnyanmisaka
172*437bfbebSnyanmisaka ctx->prev_idx0 = -1;
173*437bfbebSnyanmisaka ctx->prev_frm0 = NULL;
174*437bfbebSnyanmisaka }
175*437bfbebSnyanmisaka
dec_vproc_clr_prev1(MppDecVprocCtxImpl * ctx)176*437bfbebSnyanmisaka static void dec_vproc_clr_prev1(MppDecVprocCtxImpl *ctx)
177*437bfbebSnyanmisaka {
178*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_STATUS) {
179*437bfbebSnyanmisaka if (ctx->prev_frm1) {
180*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(ctx->prev_frm1);
181*437bfbebSnyanmisaka RK_S32 fd = (buf) ? (mpp_buffer_get_fd(buf)) : (-1);
182*437bfbebSnyanmisaka mpp_log("clearing prev index %d frm %p fd %d, poc %d\n", ctx->prev_idx1,
183*437bfbebSnyanmisaka ctx->prev_frm1, fd, mpp_frame_get_poc(ctx->prev_frm1));
184*437bfbebSnyanmisaka } else
185*437bfbebSnyanmisaka mpp_log("clearing nothing\n");
186*437bfbebSnyanmisaka }
187*437bfbebSnyanmisaka if (ctx->prev_frm1) {
188*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(ctx->prev_frm1);
189*437bfbebSnyanmisaka if (buf)
190*437bfbebSnyanmisaka mpp_buffer_put(buf);
191*437bfbebSnyanmisaka }
192*437bfbebSnyanmisaka if (ctx->prev_idx1 >= 0)
193*437bfbebSnyanmisaka mpp_buf_slot_clr_flag(ctx->slots, ctx->prev_idx1, SLOT_QUEUE_USE);
194*437bfbebSnyanmisaka
195*437bfbebSnyanmisaka ctx->prev_idx1 = -1;
196*437bfbebSnyanmisaka ctx->prev_frm1 = NULL;
197*437bfbebSnyanmisaka }
198*437bfbebSnyanmisaka
dec_vproc_clr_prev(MppDecVprocCtxImpl * ctx)199*437bfbebSnyanmisaka static void dec_vproc_clr_prev(MppDecVprocCtxImpl *ctx)
200*437bfbebSnyanmisaka {
201*437bfbebSnyanmisaka dec_vproc_clr_prev0(ctx);
202*437bfbebSnyanmisaka dec_vproc_clr_prev1(ctx);
203*437bfbebSnyanmisaka if (ctx->out_buf0) {
204*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf0);
205*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
206*437bfbebSnyanmisaka }
207*437bfbebSnyanmisaka if (ctx->out_buf1) {
208*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf1);
209*437bfbebSnyanmisaka ctx->out_buf1 = NULL;
210*437bfbebSnyanmisaka }
211*437bfbebSnyanmisaka }
212*437bfbebSnyanmisaka
dec_vproc_set_img_fmt(IepImg * img,MppFrame frm)213*437bfbebSnyanmisaka static void dec_vproc_set_img_fmt(IepImg *img, MppFrame frm)
214*437bfbebSnyanmisaka {
215*437bfbebSnyanmisaka memset(img, 0, sizeof(*img));
216*437bfbebSnyanmisaka img->act_w = mpp_frame_get_width(frm);
217*437bfbebSnyanmisaka img->act_h = mpp_frame_get_height(frm);
218*437bfbebSnyanmisaka img->vir_w = mpp_frame_get_hor_stride(frm);
219*437bfbebSnyanmisaka img->vir_h = mpp_frame_get_ver_stride(frm);
220*437bfbebSnyanmisaka img->format = IEP_FORMAT_YCbCr_420_SP;
221*437bfbebSnyanmisaka }
222*437bfbebSnyanmisaka
dec_vproc_set_img(MppDecVprocCtxImpl * ctx,IepImg * img,RK_S32 fd,IepCmd cmd)223*437bfbebSnyanmisaka static void dec_vproc_set_img(MppDecVprocCtxImpl *ctx, IepImg *img, RK_S32 fd, IepCmd cmd)
224*437bfbebSnyanmisaka {
225*437bfbebSnyanmisaka RK_S32 y_size = img->vir_w * img->vir_h;
226*437bfbebSnyanmisaka img->mem_addr = fd;
227*437bfbebSnyanmisaka img->uv_addr = fd + (y_size << 10);
228*437bfbebSnyanmisaka img->v_addr = fd + ((y_size + y_size / 4) << 10);
229*437bfbebSnyanmisaka
230*437bfbebSnyanmisaka MPP_RET ret = ctx->com_ctx->ops->control(ctx->iep_ctx, cmd, img);
231*437bfbebSnyanmisaka if (ret)
232*437bfbebSnyanmisaka mpp_log_f("control %08x failed %d\n", cmd, ret);
233*437bfbebSnyanmisaka }
234*437bfbebSnyanmisaka
dec_vproc_start_dei_v1(MppDecVprocCtx * vproc_ctx,RK_U32 mode)235*437bfbebSnyanmisaka static MPP_RET dec_vproc_start_dei_v1(MppDecVprocCtx *vproc_ctx, RK_U32 mode)
236*437bfbebSnyanmisaka {
237*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
238*437bfbebSnyanmisaka MppDecVprocCtxImpl *impl = (MppDecVprocCtxImpl *) vproc_ctx;
239*437bfbebSnyanmisaka impl->dei_cfg.dei_field_order = (mode & MPP_FRAME_FLAG_TOP_FIRST) ?
240*437bfbebSnyanmisaka (IEP_DEI_FLD_ORDER_TOP_FIRST) :
241*437bfbebSnyanmisaka (IEP_DEI_FLD_ORDER_BOT_FIRST);
242*437bfbebSnyanmisaka ret = impl->com_ctx->ops->control(impl->iep_ctx,
243*437bfbebSnyanmisaka IEP_CMD_SET_DEI_CFG, &impl->dei_cfg);
244*437bfbebSnyanmisaka if (ret)
245*437bfbebSnyanmisaka mpp_err_f("IEP_CMD_SET_DEI_CFG failed %d\n", ret);
246*437bfbebSnyanmisaka
247*437bfbebSnyanmisaka ret = impl->com_ctx->ops->control(impl->iep_ctx, IEP_CMD_RUN_SYNC, &impl->dei_info);
248*437bfbebSnyanmisaka if (ret)
249*437bfbebSnyanmisaka mpp_err_f("IEP_CMD_RUN_SYNC failed %d\n", ret);
250*437bfbebSnyanmisaka
251*437bfbebSnyanmisaka return ret;
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka
dec_vproc_start_dei_v2(MppDecVprocCtx * vproc_ctx,RK_U32 mode)254*437bfbebSnyanmisaka static MPP_RET dec_vproc_start_dei_v2(MppDecVprocCtx *vproc_ctx, RK_U32 mode)
255*437bfbebSnyanmisaka {
256*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
257*437bfbebSnyanmisaka MppDecVprocCtxImpl *impl = (MppDecVprocCtxImpl *) vproc_ctx;
258*437bfbebSnyanmisaka (void)mode;
259*437bfbebSnyanmisaka
260*437bfbebSnyanmisaka ret = impl->com_ctx->ops->control(impl->iep_ctx, IEP_CMD_RUN_SYNC, &impl->dei_info);
261*437bfbebSnyanmisaka if (ret)
262*437bfbebSnyanmisaka mpp_log_f("IEP_CMD_RUN_SYNC failed %d\n", ret);
263*437bfbebSnyanmisaka
264*437bfbebSnyanmisaka return ret;
265*437bfbebSnyanmisaka }
266*437bfbebSnyanmisaka
dec_vproc_set_dei_v1(MppDecVprocCtx * vproc_ctx,MppFrame frm)267*437bfbebSnyanmisaka static MPP_RET dec_vproc_set_dei_v1(MppDecVprocCtx *vproc_ctx, MppFrame frm)
268*437bfbebSnyanmisaka {
269*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
270*437bfbebSnyanmisaka IepImg img;
271*437bfbebSnyanmisaka MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)vproc_ctx;
272*437bfbebSnyanmisaka
273*437bfbebSnyanmisaka Mpp *mpp = ctx->mpp;
274*437bfbebSnyanmisaka RK_U32 mode = mpp_frame_get_mode(frm);
275*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(frm);
276*437bfbebSnyanmisaka MppBuffer dst0 = ctx->out_buf0;
277*437bfbebSnyanmisaka MppBuffer dst1 = ctx->out_buf1;
278*437bfbebSnyanmisaka int fd = -1;
279*437bfbebSnyanmisaka RK_U32 frame_err = 0;
280*437bfbebSnyanmisaka
281*437bfbebSnyanmisaka // setup source IepImg
282*437bfbebSnyanmisaka dec_vproc_set_img_fmt(&img, frm);
283*437bfbebSnyanmisaka
284*437bfbebSnyanmisaka ret = ctx->com_ctx->ops->control(ctx->iep_ctx, IEP_CMD_INIT, NULL);
285*437bfbebSnyanmisaka if (ret)
286*437bfbebSnyanmisaka mpp_log_f("IEP_CMD_INIT failed %d\n", ret);
287*437bfbebSnyanmisaka
288*437bfbebSnyanmisaka struct IepCap_t *cap = NULL;
289*437bfbebSnyanmisaka ret = ctx->com_ctx->ops->control(ctx->iep_ctx, IEP_CMD_QUERY_CAP, &cap);
290*437bfbebSnyanmisaka if (ret)
291*437bfbebSnyanmisaka mpp_log_f("IEP_CMD_QUERY_CAP failed %d\n", ret);
292*437bfbebSnyanmisaka
293*437bfbebSnyanmisaka // setup destination IepImg with new buffer
294*437bfbebSnyanmisaka // NOTE: when deinterlace is enabled parser thread will reserve
295*437bfbebSnyanmisaka // more buffer than normal case
296*437bfbebSnyanmisaka if (ctx->prev_frm0 && cap && cap->i4_deinterlace_supported) {
297*437bfbebSnyanmisaka // 4 in 2 out case
298*437bfbebSnyanmisaka vproc_dbg_status("4 field in and 2 frame out\n");
299*437bfbebSnyanmisaka RK_S64 prev_pts = mpp_frame_get_pts(ctx->prev_frm0);
300*437bfbebSnyanmisaka RK_S64 curr_pts = mpp_frame_get_pts(frm);
301*437bfbebSnyanmisaka RK_S64 first_pts = (prev_pts + curr_pts) / 2;
302*437bfbebSnyanmisaka
303*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(ctx->prev_frm0);
304*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
305*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_SRC);
306*437bfbebSnyanmisaka frame_err = mpp_frame_get_errinfo(ctx->prev_frm0) ||
307*437bfbebSnyanmisaka mpp_frame_get_discard(ctx->prev_frm0);
308*437bfbebSnyanmisaka // setup dst 0
309*437bfbebSnyanmisaka mpp_assert(dst0);
310*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(dst0);
311*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DST);
312*437bfbebSnyanmisaka
313*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(frm);
314*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
315*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC1);
316*437bfbebSnyanmisaka frame_err |= mpp_frame_get_errinfo(frm) ||
317*437bfbebSnyanmisaka mpp_frame_get_discard(frm);
318*437bfbebSnyanmisaka // setup dst 1
319*437bfbebSnyanmisaka mpp_assert(dst1);
320*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(dst1);
321*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_DST1);
322*437bfbebSnyanmisaka
323*437bfbebSnyanmisaka ctx->dei_cfg.dei_mode = IEP_DEI_MODE_I4O2;
324*437bfbebSnyanmisaka
325*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I4O2;
326*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
327*437bfbebSnyanmisaka
328*437bfbebSnyanmisaka // start hardware
329*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
330*437bfbebSnyanmisaka
331*437bfbebSnyanmisaka // NOTE: we need to process pts here
332*437bfbebSnyanmisaka if (mode & MPP_FRAME_FLAG_TOP_FIRST) {
333*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, first_pts, frame_err);
334*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst1, curr_pts, frame_err);
335*437bfbebSnyanmisaka } else {
336*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst1, first_pts, frame_err);
337*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, curr_pts, frame_err);
338*437bfbebSnyanmisaka }
339*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
340*437bfbebSnyanmisaka ctx->out_buf1 = NULL;
341*437bfbebSnyanmisaka } else {
342*437bfbebSnyanmisaka // 2 in 1 out case
343*437bfbebSnyanmisaka vproc_dbg_status("2 field in and 1 frame out\n");
344*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(frm);
345*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
346*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_SRC);
347*437bfbebSnyanmisaka frame_err = mpp_frame_get_errinfo(frm) ||
348*437bfbebSnyanmisaka mpp_frame_get_discard(frm);
349*437bfbebSnyanmisaka
350*437bfbebSnyanmisaka // setup dst 0
351*437bfbebSnyanmisaka mpp_assert(dst0);
352*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(dst0);
353*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DST);
354*437bfbebSnyanmisaka
355*437bfbebSnyanmisaka ctx->dei_cfg.dei_mode = IEP_DEI_MODE_I2O1;
356*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I2O1;
357*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
358*437bfbebSnyanmisaka
359*437bfbebSnyanmisaka // start hardware
360*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
361*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, -1, frame_err);
362*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
363*437bfbebSnyanmisaka }
364*437bfbebSnyanmisaka
365*437bfbebSnyanmisaka return ret;
366*437bfbebSnyanmisaka }
367*437bfbebSnyanmisaka
368*437bfbebSnyanmisaka #if DUMP_FILE
dump_mppbuffer(MppBuffer buf,const char * fname,int stride,int height)369*437bfbebSnyanmisaka static void dump_mppbuffer(MppBuffer buf, const char *fname, int stride, int height)
370*437bfbebSnyanmisaka {
371*437bfbebSnyanmisaka char title[256];
372*437bfbebSnyanmisaka void *ptr = mpp_buffer_get_ptr(buf);
373*437bfbebSnyanmisaka sprintf(title, "%s.%dx%d.yuv", fname, stride, height);
374*437bfbebSnyanmisaka FILE *dump = fopen(title, "ab+");
375*437bfbebSnyanmisaka
376*437bfbebSnyanmisaka if (dump) {
377*437bfbebSnyanmisaka fwrite(ptr, 1, stride * height * 3 / 2, dump);
378*437bfbebSnyanmisaka fclose(dump);
379*437bfbebSnyanmisaka }
380*437bfbebSnyanmisaka }
381*437bfbebSnyanmisaka #else
382*437bfbebSnyanmisaka #define dump_mppbuffer(...)
383*437bfbebSnyanmisaka #endif
384*437bfbebSnyanmisaka
dec_vproc_config_dei_v2(MppDecVprocCtxImpl * ctx,MppFrame frm,enum IEP2_DIL_MODE dil_mode)385*437bfbebSnyanmisaka static MPP_RET dec_vproc_config_dei_v2(MppDecVprocCtxImpl *ctx, MppFrame frm,
386*437bfbebSnyanmisaka enum IEP2_DIL_MODE dil_mode)
387*437bfbebSnyanmisaka {
388*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
389*437bfbebSnyanmisaka MppBuffer buf = NULL;
390*437bfbebSnyanmisaka RK_S32 fd = -1;
391*437bfbebSnyanmisaka IepImg img;
392*437bfbebSnyanmisaka struct iep2_api_params params;
393*437bfbebSnyanmisaka iep_com_ops *ops = ctx->com_ctx->ops;
394*437bfbebSnyanmisaka
395*437bfbebSnyanmisaka if (!frm) {
396*437bfbebSnyanmisaka mpp_err("found NULL pointer frm\n");
397*437bfbebSnyanmisaka ret = MPP_ERR_NULL_PTR;
398*437bfbebSnyanmisaka return ret;
399*437bfbebSnyanmisaka }
400*437bfbebSnyanmisaka
401*437bfbebSnyanmisaka /* default alloc 2 out buffer for IEP */
402*437bfbebSnyanmisaka if (!ctx->out_buf0 || !ctx->out_buf1) {
403*437bfbebSnyanmisaka mpp_err("found NULL pointer out_buf0 %p out_buf1 %p\n", ctx->out_buf0, ctx->out_buf1);
404*437bfbebSnyanmisaka ret = MPP_ERR_NULL_PTR;
405*437bfbebSnyanmisaka return ret;
406*437bfbebSnyanmisaka }
407*437bfbebSnyanmisaka
408*437bfbebSnyanmisaka // setup source IepImg
409*437bfbebSnyanmisaka dec_vproc_set_img_fmt(&img, frm);
410*437bfbebSnyanmisaka
411*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_IN)
412*437bfbebSnyanmisaka dump_mppbuffer(buf, "/data/dump/dump_in.yuv", img.vir_w, img.vir_h);
413*437bfbebSnyanmisaka
414*437bfbebSnyanmisaka vproc_dbg_status("set dil_mode %d\n", dil_mode);
415*437bfbebSnyanmisaka // TODO: check the input frame
416*437bfbebSnyanmisaka switch (dil_mode) {
417*437bfbebSnyanmisaka case IEP2_DIL_MODE_I5O2:
418*437bfbebSnyanmisaka case IEP2_DIL_MODE_I5O1T:
419*437bfbebSnyanmisaka case IEP2_DIL_MODE_I5O1B:
420*437bfbebSnyanmisaka case IEP2_DIL_MODE_DECT: {
421*437bfbebSnyanmisaka // require 3 frames
422*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(ctx->prev_frm0);
423*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
424*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_SRC);
425*437bfbebSnyanmisaka
426*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(frm);
427*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
428*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC1);
429*437bfbebSnyanmisaka
430*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(ctx->prev_frm1);
431*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
432*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC2);
433*437bfbebSnyanmisaka } break;
434*437bfbebSnyanmisaka case IEP2_DIL_MODE_PD: {
435*437bfbebSnyanmisaka // require 2 frame
436*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(frm);
437*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
438*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC1);
439*437bfbebSnyanmisaka
440*437bfbebSnyanmisaka if (ctx->prev_frm0) {
441*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(ctx->prev_frm0);
442*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
443*437bfbebSnyanmisaka } else if (ctx->prev_frm1) {
444*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(ctx->prev_frm1);
445*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
446*437bfbebSnyanmisaka }
447*437bfbebSnyanmisaka
448*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_SRC);
449*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC2);
450*437bfbebSnyanmisaka } break;
451*437bfbebSnyanmisaka case IEP2_DIL_MODE_I2O2:
452*437bfbebSnyanmisaka case IEP2_DIL_MODE_I1O1T:
453*437bfbebSnyanmisaka case IEP2_DIL_MODE_I1O1B:
454*437bfbebSnyanmisaka case IEP2_DIL_MODE_BYPASS:
455*437bfbebSnyanmisaka default: {
456*437bfbebSnyanmisaka buf = mpp_frame_get_buffer(frm);
457*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(buf);
458*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_SRC);
459*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC1);
460*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_SRC2);
461*437bfbebSnyanmisaka } break;
462*437bfbebSnyanmisaka }
463*437bfbebSnyanmisaka
464*437bfbebSnyanmisaka // setup output
465*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(ctx->out_buf0);
466*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DST);
467*437bfbebSnyanmisaka fd = mpp_buffer_get_fd(ctx->out_buf1);
468*437bfbebSnyanmisaka dec_vproc_set_img(ctx, &img, fd, IEP_CMD_SET_DEI_DST1);
469*437bfbebSnyanmisaka
470*437bfbebSnyanmisaka memset(¶ms, 0, sizeof(params));
471*437bfbebSnyanmisaka params.ptype = IEP2_PARAM_TYPE_MODE;
472*437bfbebSnyanmisaka params.param.mode.dil_mode = dil_mode;
473*437bfbebSnyanmisaka params.param.mode.out_mode = IEP2_OUT_MODE_LINE;
474*437bfbebSnyanmisaka {
475*437bfbebSnyanmisaka RK_U32 mode = mpp_frame_get_mode(frm);
476*437bfbebSnyanmisaka RK_U32 fo_from_syntax = (mode & MPP_FRAME_FLAG_TOP_FIRST) ? 1 : 0;
477*437bfbebSnyanmisaka
478*437bfbebSnyanmisaka /* refer to syntax */
479*437bfbebSnyanmisaka if ((mode & MPP_FRAME_FLAG_TOP_FIRST) && (mode & MPP_FRAME_FLAG_BOT_FIRST))
480*437bfbebSnyanmisaka params.param.mode.dil_order = IEP2_FIELD_ORDER_UND;
481*437bfbebSnyanmisaka else if (fo_from_syntax)
482*437bfbebSnyanmisaka params.param.mode.dil_order = IEP2_FIELD_ORDER_TFF;
483*437bfbebSnyanmisaka else
484*437bfbebSnyanmisaka params.param.mode.dil_order = IEP2_FIELD_ORDER_BFF;
485*437bfbebSnyanmisaka
486*437bfbebSnyanmisaka /* refer to IEP */
487*437bfbebSnyanmisaka if (ctx->pre_ff_mode == IEP2_FF_MODE_FIELD) {
488*437bfbebSnyanmisaka RK_U32 fo_from_iep = (ctx->dei_info.dil_order == IEP2_FIELD_ORDER_UND) ?
489*437bfbebSnyanmisaka fo_from_syntax : (ctx->dei_info.dil_order == IEP2_FIELD_ORDER_TFF);
490*437bfbebSnyanmisaka RK_U32 is_tff = 0;
491*437bfbebSnyanmisaka
492*437bfbebSnyanmisaka if (fo_from_iep != fo_from_syntax) {
493*437bfbebSnyanmisaka if (ctx->dei_info.dil_order_confidence_ratio > 30)
494*437bfbebSnyanmisaka is_tff = fo_from_iep;
495*437bfbebSnyanmisaka else
496*437bfbebSnyanmisaka is_tff = fo_from_syntax;
497*437bfbebSnyanmisaka } else {
498*437bfbebSnyanmisaka is_tff = fo_from_syntax;
499*437bfbebSnyanmisaka }
500*437bfbebSnyanmisaka
501*437bfbebSnyanmisaka if (is_tff)
502*437bfbebSnyanmisaka params.param.mode.dil_order = IEP2_FIELD_ORDER_TFF;
503*437bfbebSnyanmisaka else
504*437bfbebSnyanmisaka params.param.mode.dil_order = IEP2_FIELD_ORDER_BFF;
505*437bfbebSnyanmisaka
506*437bfbebSnyanmisaka vproc_dbg_status("Config field order: is TFF %d, syn %d vs iep %d\n",
507*437bfbebSnyanmisaka is_tff, fo_from_syntax, fo_from_iep);
508*437bfbebSnyanmisaka }
509*437bfbebSnyanmisaka }
510*437bfbebSnyanmisaka ops->control(ctx->iep_ctx, IEP_CMD_SET_DEI_CFG, ¶ms);
511*437bfbebSnyanmisaka
512*437bfbebSnyanmisaka memset(¶ms, 0, sizeof(params));
513*437bfbebSnyanmisaka params.ptype = IEP2_PARAM_TYPE_COM;
514*437bfbebSnyanmisaka params.param.com.sfmt = IEP2_FMT_YUV420;
515*437bfbebSnyanmisaka params.param.com.dfmt = IEP2_FMT_YUV420;
516*437bfbebSnyanmisaka params.param.com.sswap = IEP2_YUV_SWAP_SP_UV;
517*437bfbebSnyanmisaka params.param.com.dswap = IEP2_YUV_SWAP_SP_UV;
518*437bfbebSnyanmisaka params.param.com.width = img.act_w;
519*437bfbebSnyanmisaka params.param.com.height = img.act_h;
520*437bfbebSnyanmisaka params.param.com.hor_stride = img.vir_w;//img.act_w;
521*437bfbebSnyanmisaka ops->control(ctx->iep_ctx, IEP_CMD_SET_DEI_CFG, ¶ms);
522*437bfbebSnyanmisaka
523*437bfbebSnyanmisaka return MPP_OK;
524*437bfbebSnyanmisaka }
525*437bfbebSnyanmisaka
dec_vproc_output_dei_v2(MppDecVprocCtxImpl * ctx,MppFrame frm,RK_U32 is_frm)526*437bfbebSnyanmisaka MPP_RET dec_vproc_output_dei_v2(MppDecVprocCtxImpl *ctx, MppFrame frm, RK_U32 is_frm)
527*437bfbebSnyanmisaka {
528*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
529*437bfbebSnyanmisaka Mpp *mpp = ctx->mpp;
530*437bfbebSnyanmisaka RK_U32 hor_stride = mpp_frame_get_hor_stride(frm);
531*437bfbebSnyanmisaka RK_U32 ver_stride = mpp_frame_get_ver_stride(frm);
532*437bfbebSnyanmisaka RK_U32 mode = mpp_frame_get_mode(frm);
533*437bfbebSnyanmisaka RK_U32 dei_mode = mode & MPP_FRAME_FLAG_IEP_DEI_MASK;
534*437bfbebSnyanmisaka MppBuffer dst0 = ctx->out_buf0;
535*437bfbebSnyanmisaka MppBuffer dst1 = ctx->out_buf1;
536*437bfbebSnyanmisaka RK_U32 frame_err = 0;
537*437bfbebSnyanmisaka
538*437bfbebSnyanmisaka vproc_dbg_status("is_frm %d frm %p, dei_mode %d field0 %p field1 %p",
539*437bfbebSnyanmisaka is_frm, ctx->prev_frm1, dei_mode, dst0, dst1);
540*437bfbebSnyanmisaka if (is_frm) {
541*437bfbebSnyanmisaka if (ctx->prev_frm1) {
542*437bfbebSnyanmisaka vproc_dbg_out("output frame prev1 poc %d\n", mpp_frame_get_poc(ctx->prev_frm1));
543*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, ctx->prev_frm1, NULL, -1, 0);
544*437bfbebSnyanmisaka if (ctx->prev_idx1 >= 0)
545*437bfbebSnyanmisaka mpp_buf_slot_clr_flag(ctx->slots, ctx->prev_idx1, SLOT_QUEUE_USE);
546*437bfbebSnyanmisaka ctx->prev_idx1 = -1;
547*437bfbebSnyanmisaka ctx->prev_frm1 = NULL;
548*437bfbebSnyanmisaka }
549*437bfbebSnyanmisaka return ret;
550*437bfbebSnyanmisaka }
551*437bfbebSnyanmisaka
552*437bfbebSnyanmisaka switch (dei_mode) {
553*437bfbebSnyanmisaka case MPP_FRAME_FLAG_IEP_DEI_I4O2: {
554*437bfbebSnyanmisaka RK_S64 prev_pts = mpp_frame_get_pts(ctx->prev_frm1);
555*437bfbebSnyanmisaka RK_S64 curr_pts = mpp_frame_get_pts(ctx->prev_frm0);
556*437bfbebSnyanmisaka RK_S64 first_pts = (prev_pts + curr_pts) / 2;
557*437bfbebSnyanmisaka
558*437bfbebSnyanmisaka frame_err |= mpp_frame_get_errinfo(ctx->prev_frm0) + mpp_frame_get_discard(ctx->prev_frm0);
559*437bfbebSnyanmisaka frame_err |= mpp_frame_get_errinfo(ctx->prev_frm1) + mpp_frame_get_discard(ctx->prev_frm1);
560*437bfbebSnyanmisaka
561*437bfbebSnyanmisaka if (ctx->pd_mode) {
562*437bfbebSnyanmisaka // NOTE: we need to process pts here if PD mode
563*437bfbebSnyanmisaka if (ctx->dei_info.pd_flag != PD_COMP_FLAG_NON &&
564*437bfbebSnyanmisaka ctx->dei_info.pd_types != PD_TYPES_UNKNOWN) {
565*437bfbebSnyanmisaka vproc_dbg_out("output at pd mode, frame poc %d\n", mpp_frame_get_poc(frm));
566*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, first_pts, frame_err);
567*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
568*437bfbebSnyanmisaka dump_mppbuffer(dst0, "/data/dump/dump_output.yuv", hor_stride, ver_stride);
569*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
570*437bfbebSnyanmisaka }
571*437bfbebSnyanmisaka } else {
572*437bfbebSnyanmisaka RK_U32 fo_from_syntax = (mode & MPP_FRAME_FLAG_TOP_FIRST) ? 1 : 0;
573*437bfbebSnyanmisaka RK_U32 fo_from_iep = (ctx->dei_info.dil_order == IEP2_FIELD_ORDER_UND) ?
574*437bfbebSnyanmisaka fo_from_syntax : (ctx->dei_info.dil_order == IEP2_FIELD_ORDER_TFF);
575*437bfbebSnyanmisaka RK_U32 is_tff = 0;
576*437bfbebSnyanmisaka
577*437bfbebSnyanmisaka if (fo_from_iep != fo_from_syntax) {
578*437bfbebSnyanmisaka if (ctx->dei_info.dil_order_confidence_ratio > 30)
579*437bfbebSnyanmisaka is_tff = fo_from_iep;
580*437bfbebSnyanmisaka else
581*437bfbebSnyanmisaka is_tff = fo_from_syntax;
582*437bfbebSnyanmisaka } else {
583*437bfbebSnyanmisaka is_tff = fo_from_syntax;
584*437bfbebSnyanmisaka }
585*437bfbebSnyanmisaka
586*437bfbebSnyanmisaka vproc_dbg_status("Output field order: is TFF %d, syn %d vs iep %d\n",
587*437bfbebSnyanmisaka is_tff, fo_from_syntax, fo_from_iep);
588*437bfbebSnyanmisaka
589*437bfbebSnyanmisaka if (is_tff) {
590*437bfbebSnyanmisaka vproc_dbg_out("output at I4O2 for tff, frame poc %d\n", mpp_frame_get_poc(frm));
591*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, first_pts, frame_err);
592*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
593*437bfbebSnyanmisaka dump_mppbuffer(dst0, "/data/dump/dump_output.yuv", hor_stride, ver_stride);
594*437bfbebSnyanmisaka vproc_dbg_out("output at I4O2 for bff, frame poc %d\n", mpp_frame_get_poc(frm));
595*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst1, curr_pts, frame_err);
596*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
597*437bfbebSnyanmisaka dump_mppbuffer(dst1, "/data/dump/dump_output.yuv", hor_stride, ver_stride);
598*437bfbebSnyanmisaka } else {
599*437bfbebSnyanmisaka vproc_dbg_out("output at I4O2 for bff, frame poc %d\n", mpp_frame_get_poc(frm));
600*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst1, first_pts, frame_err);
601*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
602*437bfbebSnyanmisaka dump_mppbuffer(dst1, "/data/dump/dump_output.yuv", hor_stride, mpp_frame_get_height(frm));
603*437bfbebSnyanmisaka vproc_dbg_out("output at I4O2 for tff, frame poc %d\n", mpp_frame_get_poc(frm));
604*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, curr_pts, frame_err);
605*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
606*437bfbebSnyanmisaka dump_mppbuffer(dst0, "/data/dump/dump_output.yuv", hor_stride, mpp_frame_get_height(frm));
607*437bfbebSnyanmisaka }
608*437bfbebSnyanmisaka
609*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
610*437bfbebSnyanmisaka ctx->out_buf1 = NULL;
611*437bfbebSnyanmisaka }
612*437bfbebSnyanmisaka } break;
613*437bfbebSnyanmisaka case MPP_FRAME_FLAG_IEP_DEI_I2O1:
614*437bfbebSnyanmisaka case MPP_FRAME_FLAG_IEP_DEI_I4O1: {
615*437bfbebSnyanmisaka vproc_dbg_out("output at I2O1, frame poc %d\n", mpp_frame_get_poc(frm));
616*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, dst0, -1, frame_err);
617*437bfbebSnyanmisaka if (vproc_debug & VPROC_DBG_DUMP_OUT)
618*437bfbebSnyanmisaka dump_mppbuffer(dst0, "/data/dump/dump_output.yuv", hor_stride, mpp_frame_get_height(frm));
619*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
620*437bfbebSnyanmisaka }
621*437bfbebSnyanmisaka default:
622*437bfbebSnyanmisaka break;
623*437bfbebSnyanmisaka }
624*437bfbebSnyanmisaka
625*437bfbebSnyanmisaka return ret;
626*437bfbebSnyanmisaka }
627*437bfbebSnyanmisaka
dec_vproc_dei_v2_deinterlace(MppDecVprocCtxImpl * ctx,MppFrame frm)628*437bfbebSnyanmisaka static MPP_RET dec_vproc_dei_v2_deinterlace(MppDecVprocCtxImpl *ctx, MppFrame frm)
629*437bfbebSnyanmisaka {
630*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
631*437bfbebSnyanmisaka RK_U32 mode = mpp_frame_get_mode(frm);
632*437bfbebSnyanmisaka enum IEP2_DIL_MODE dil_mode = IEP2_DIL_MODE_DISABLE;
633*437bfbebSnyanmisaka
634*437bfbebSnyanmisaka /* refer to syntax */
635*437bfbebSnyanmisaka if (((mode & MPP_FRAME_FLAG_PAIRED_FIELD) == MPP_FRAME_FLAG_FRAME) &&
636*437bfbebSnyanmisaka !(mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK))
637*437bfbebSnyanmisaka return dec_vproc_output_dei_v2(ctx, frm, 1);
638*437bfbebSnyanmisaka
639*437bfbebSnyanmisaka if (ctx->prev_frm1 && ctx->prev_frm0) {
640*437bfbebSnyanmisaka // 5 in 2 out case
641*437bfbebSnyanmisaka vproc_dbg_status("5 field in and 2 frame out\n");
642*437bfbebSnyanmisaka
643*437bfbebSnyanmisaka if (!ctx->pd_mode)
644*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_I5O2;
645*437bfbebSnyanmisaka else
646*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_PD;
647*437bfbebSnyanmisaka
648*437bfbebSnyanmisaka dec_vproc_config_dei_v2(ctx, frm, dil_mode);
649*437bfbebSnyanmisaka
650*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I4O2;
651*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
652*437bfbebSnyanmisaka // start hardware
653*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
654*437bfbebSnyanmisaka
655*437bfbebSnyanmisaka dec_vproc_output_dei_v2(ctx, frm, 0);
656*437bfbebSnyanmisaka
657*437bfbebSnyanmisaka if (ctx->dei_info.pd_types == PD_TYPES_UNKNOWN)
658*437bfbebSnyanmisaka ctx->pd_mode = 0;
659*437bfbebSnyanmisaka else
660*437bfbebSnyanmisaka ctx->pd_mode = 1;
661*437bfbebSnyanmisaka
662*437bfbebSnyanmisaka } else if (ctx->prev_frm0 && ! ctx->prev_frm1) {
663*437bfbebSnyanmisaka vproc_dbg_status("Wait for next frame to turn into I5O2");
664*437bfbebSnyanmisaka
665*437bfbebSnyanmisaka if (ctx->out_buf0) {
666*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf0);
667*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
668*437bfbebSnyanmisaka }
669*437bfbebSnyanmisaka
670*437bfbebSnyanmisaka if (ctx->out_buf1) {
671*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf1);
672*437bfbebSnyanmisaka ctx->out_buf1 = NULL;
673*437bfbebSnyanmisaka }
674*437bfbebSnyanmisaka } else {
675*437bfbebSnyanmisaka // 2 in 1 out case
676*437bfbebSnyanmisaka vproc_dbg_status("2 field in and 1 frame out\n");
677*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_I1O1T;
678*437bfbebSnyanmisaka
679*437bfbebSnyanmisaka dec_vproc_config_dei_v2(ctx, frm, dil_mode);
680*437bfbebSnyanmisaka
681*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I2O1;
682*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
683*437bfbebSnyanmisaka // start hardware
684*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
685*437bfbebSnyanmisaka
686*437bfbebSnyanmisaka dec_vproc_output_dei_v2(ctx, frm, 0);
687*437bfbebSnyanmisaka }
688*437bfbebSnyanmisaka
689*437bfbebSnyanmisaka return ret;
690*437bfbebSnyanmisaka }
691*437bfbebSnyanmisaka
dec_vproc_dei_v2_detection(MppDecVprocCtxImpl * ctx,MppFrame frm)692*437bfbebSnyanmisaka static MPP_RET dec_vproc_dei_v2_detection(MppDecVprocCtxImpl *ctx, MppFrame frm)
693*437bfbebSnyanmisaka {
694*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
695*437bfbebSnyanmisaka RK_U32 mode = mpp_frame_get_mode(frm);
696*437bfbebSnyanmisaka enum IEP2_DIL_MODE dil_mode = IEP2_DIL_MODE_DISABLE;
697*437bfbebSnyanmisaka RK_U32 is_frame = 0;
698*437bfbebSnyanmisaka
699*437bfbebSnyanmisaka if (ctx->pre_ff_mode == IEP2_FF_MODE_UND) {
700*437bfbebSnyanmisaka if (((mode & MPP_FRAME_FLAG_PAIRED_FIELD) == MPP_FRAME_FLAG_FRAME) &&
701*437bfbebSnyanmisaka !(mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK))
702*437bfbebSnyanmisaka is_frame = 1;
703*437bfbebSnyanmisaka else
704*437bfbebSnyanmisaka is_frame = 0;
705*437bfbebSnyanmisaka } else {
706*437bfbebSnyanmisaka is_frame = ctx->pre_ff_mode == IEP2_FF_MODE_FRAME ? 1 : 0;
707*437bfbebSnyanmisaka }
708*437bfbebSnyanmisaka
709*437bfbebSnyanmisaka /* TODO: diff detection strategy */
710*437bfbebSnyanmisaka if (ctx->prev_frm1 && ctx->prev_frm0) {
711*437bfbebSnyanmisaka // 5 in 2 out case
712*437bfbebSnyanmisaka vproc_dbg_status("5 field in and 2 frame out\n");
713*437bfbebSnyanmisaka
714*437bfbebSnyanmisaka if (!ctx->pd_mode)
715*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_I5O2;
716*437bfbebSnyanmisaka else
717*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_PD;
718*437bfbebSnyanmisaka
719*437bfbebSnyanmisaka dec_vproc_config_dei_v2(ctx, frm, dil_mode);
720*437bfbebSnyanmisaka
721*437bfbebSnyanmisaka // start hardware
722*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
723*437bfbebSnyanmisaka
724*437bfbebSnyanmisaka if (ctx->dei_info.frm_mode == IEP2_FF_MODE_FRAME) {
725*437bfbebSnyanmisaka is_frame = 1;
726*437bfbebSnyanmisaka } else if (ctx->dei_info.pd_types == PD_TYPES_UNKNOWN) {
727*437bfbebSnyanmisaka ctx->pd_mode = 0;
728*437bfbebSnyanmisaka is_frame = 0;
729*437bfbebSnyanmisaka } else {
730*437bfbebSnyanmisaka ctx->pd_mode = 1;
731*437bfbebSnyanmisaka is_frame = 0;
732*437bfbebSnyanmisaka }
733*437bfbebSnyanmisaka
734*437bfbebSnyanmisaka if (!is_frame) {
735*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I4O2;
736*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
737*437bfbebSnyanmisaka }
738*437bfbebSnyanmisaka } else if (ctx->prev_frm0 && ! ctx->prev_frm1) {
739*437bfbebSnyanmisaka vproc_dbg_status("Wait for next frame to turn into I5O2");
740*437bfbebSnyanmisaka
741*437bfbebSnyanmisaka if (ctx->out_buf0) {
742*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf0);
743*437bfbebSnyanmisaka ctx->out_buf0 = NULL;
744*437bfbebSnyanmisaka }
745*437bfbebSnyanmisaka
746*437bfbebSnyanmisaka if (ctx->out_buf1) {
747*437bfbebSnyanmisaka mpp_buffer_put(ctx->out_buf1);
748*437bfbebSnyanmisaka ctx->out_buf1 = NULL;
749*437bfbebSnyanmisaka }
750*437bfbebSnyanmisaka } else {
751*437bfbebSnyanmisaka // 2 in 1 out case
752*437bfbebSnyanmisaka vproc_dbg_status("2 field in and 1 frame out\n");
753*437bfbebSnyanmisaka dil_mode = IEP2_DIL_MODE_I1O1T;
754*437bfbebSnyanmisaka
755*437bfbebSnyanmisaka dec_vproc_config_dei_v2(ctx, frm, dil_mode);
756*437bfbebSnyanmisaka
757*437bfbebSnyanmisaka mode = mode | MPP_FRAME_FLAG_IEP_DEI_I2O1;
758*437bfbebSnyanmisaka mpp_frame_set_mode(frm, mode);
759*437bfbebSnyanmisaka // start hardware
760*437bfbebSnyanmisaka ctx->start_dei((MppDecVprocCtx *)ctx, mode);
761*437bfbebSnyanmisaka }
762*437bfbebSnyanmisaka
763*437bfbebSnyanmisaka ret = dec_vproc_output_dei_v2(ctx, frm, is_frame);
764*437bfbebSnyanmisaka ctx->pre_ff_mode = ctx->dei_info.frm_mode;
765*437bfbebSnyanmisaka
766*437bfbebSnyanmisaka return ret;
767*437bfbebSnyanmisaka }
768*437bfbebSnyanmisaka
dec_vproc_set_dei_v2(MppDecVprocCtx * vproc_ctx,MppFrame frm)769*437bfbebSnyanmisaka static MPP_RET dec_vproc_set_dei_v2(MppDecVprocCtx *vproc_ctx, MppFrame frm)
770*437bfbebSnyanmisaka {
771*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
772*437bfbebSnyanmisaka MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)vproc_ctx;
773*437bfbebSnyanmisaka /* RK_U32 mode = mpp_frame_get_mode(frm);
774*437bfbebSnyanmisaka enum IEP2_DIL_MODE dil_mode = IEP2_DIL_MODE_DISABLE; */
775*437bfbebSnyanmisaka MppVprocMode vproc_mode = ctx->vproc_mode;
776*437bfbebSnyanmisaka
777*437bfbebSnyanmisaka switch (vproc_mode) {
778*437bfbebSnyanmisaka case MPP_VPROC_MODE_DETECTION: {
779*437bfbebSnyanmisaka dec_vproc_dei_v2_detection(ctx, frm);
780*437bfbebSnyanmisaka } break;
781*437bfbebSnyanmisaka case MPP_VPROC_MODE_DEINTELACE: {
782*437bfbebSnyanmisaka dec_vproc_dei_v2_deinterlace(ctx, frm);
783*437bfbebSnyanmisaka } break;
784*437bfbebSnyanmisaka default: {
785*437bfbebSnyanmisaka mpp_err("warning: vproc mode unknown!\n");
786*437bfbebSnyanmisaka ret = MPP_NOK;
787*437bfbebSnyanmisaka } break;
788*437bfbebSnyanmisaka }
789*437bfbebSnyanmisaka
790*437bfbebSnyanmisaka return ret;
791*437bfbebSnyanmisaka }
792*437bfbebSnyanmisaka
dec_vproc_update_ref_v1(MppDecVprocCtx * vproc_ctx,MppFrame frm,RK_U32 index)793*437bfbebSnyanmisaka MPP_RET dec_vproc_update_ref_v1(MppDecVprocCtx *vproc_ctx, MppFrame frm, RK_U32 index)
794*437bfbebSnyanmisaka {
795*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
796*437bfbebSnyanmisaka MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)vproc_ctx;
797*437bfbebSnyanmisaka dec_vproc_clr_prev0(ctx);
798*437bfbebSnyanmisaka ctx->prev_idx0 = index;
799*437bfbebSnyanmisaka ctx->prev_frm0 = frm;
800*437bfbebSnyanmisaka
801*437bfbebSnyanmisaka return ret;
802*437bfbebSnyanmisaka }
803*437bfbebSnyanmisaka
dec_vproc_update_ref_v2(MppDecVprocCtx * vproc_ctx,MppFrame frm,RK_U32 index)804*437bfbebSnyanmisaka MPP_RET dec_vproc_update_ref_v2(MppDecVprocCtx *vproc_ctx, MppFrame frm, RK_U32 index)
805*437bfbebSnyanmisaka {
806*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
807*437bfbebSnyanmisaka MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)vproc_ctx;
808*437bfbebSnyanmisaka
809*437bfbebSnyanmisaka dec_vproc_clr_prev1(ctx);
810*437bfbebSnyanmisaka
811*437bfbebSnyanmisaka ctx->prev_idx1 = ctx->prev_idx0;
812*437bfbebSnyanmisaka ctx->prev_idx0 = index;
813*437bfbebSnyanmisaka ctx->prev_frm1 = ctx->prev_frm0;
814*437bfbebSnyanmisaka ctx->prev_frm0 = frm;
815*437bfbebSnyanmisaka return ret;
816*437bfbebSnyanmisaka }
817*437bfbebSnyanmisaka
dec_vproc_update_ref(MppDecVprocCtxImpl * ctx,MppFrame frm,RK_U32 index,RK_U32 eos)818*437bfbebSnyanmisaka static MPP_RET dec_vproc_update_ref(MppDecVprocCtxImpl *ctx, MppFrame frm, RK_U32 index, RK_U32 eos)
819*437bfbebSnyanmisaka {
820*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
821*437bfbebSnyanmisaka Mpp *mpp = ctx->mpp;
822*437bfbebSnyanmisaka
823*437bfbebSnyanmisaka ret = ctx->update_ref((MppDecVprocCtx *)ctx, frm, index);
824*437bfbebSnyanmisaka
825*437bfbebSnyanmisaka if (eos) {
826*437bfbebSnyanmisaka mpp_frame_init(&frm);
827*437bfbebSnyanmisaka mpp_frame_set_eos(frm, eos);
828*437bfbebSnyanmisaka vproc_dbg_out("output at update ref, frame poc %d\n", mpp_frame_get_poc(frm));
829*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, NULL, -1, 0);
830*437bfbebSnyanmisaka dec_vproc_clr_prev(ctx);
831*437bfbebSnyanmisaka mpp_frame_deinit(&frm);
832*437bfbebSnyanmisaka }
833*437bfbebSnyanmisaka return ret;
834*437bfbebSnyanmisaka }
835*437bfbebSnyanmisaka
dec_vproc_thread(void * data)836*437bfbebSnyanmisaka static void *dec_vproc_thread(void *data)
837*437bfbebSnyanmisaka {
838*437bfbebSnyanmisaka MppDecVprocCtxImpl *ctx = (MppDecVprocCtxImpl *)data;
839*437bfbebSnyanmisaka HalTaskGroup tasks = ctx->task_group;
840*437bfbebSnyanmisaka MppThread *thd = ctx->thd;
841*437bfbebSnyanmisaka Mpp *mpp = ctx->mpp;
842*437bfbebSnyanmisaka MppDecImpl *dec = (MppDecImpl *)mpp->mDec;
843*437bfbebSnyanmisaka MppBufSlots slots = dec->frame_slots;
844*437bfbebSnyanmisaka
845*437bfbebSnyanmisaka HalTaskHnd task = NULL;
846*437bfbebSnyanmisaka HalTaskInfo task_info;
847*437bfbebSnyanmisaka HalDecVprocTask *task_vproc = &task_info.dec_vproc;
848*437bfbebSnyanmisaka
849*437bfbebSnyanmisaka mpp_dbg_info("mpp_dec_post_proc_thread started\n");
850*437bfbebSnyanmisaka
851*437bfbebSnyanmisaka while (1) {
852*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
853*437bfbebSnyanmisaka
854*437bfbebSnyanmisaka mpp_thread_lock(thd, THREAD_WORK);
855*437bfbebSnyanmisaka if (MPP_THREAD_RUNNING != mpp_thread_get_status(thd, THREAD_WORK)) {
856*437bfbebSnyanmisaka mpp_thread_unlock(thd, THREAD_WORK);
857*437bfbebSnyanmisaka break;
858*437bfbebSnyanmisaka }
859*437bfbebSnyanmisaka
860*437bfbebSnyanmisaka if (ctx->task_wait.val && !ctx->reset) {
861*437bfbebSnyanmisaka vproc_dbg_status("vproc thread wait %d", ctx->task_wait.val);
862*437bfbebSnyanmisaka mpp_thread_wait(thd, THREAD_WORK);
863*437bfbebSnyanmisaka }
864*437bfbebSnyanmisaka mpp_thread_unlock(thd, THREAD_WORK);
865*437bfbebSnyanmisaka
866*437bfbebSnyanmisaka if (!ctx->task_status.task_rdy) {
867*437bfbebSnyanmisaka if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) {
868*437bfbebSnyanmisaka if (ctx->reset) {
869*437bfbebSnyanmisaka /* reset only on all task finished */
870*437bfbebSnyanmisaka vproc_dbg_reset("reset start\n");
871*437bfbebSnyanmisaka
872*437bfbebSnyanmisaka dec_vproc_clr_prev(ctx);
873*437bfbebSnyanmisaka
874*437bfbebSnyanmisaka mpp_thread_lock(thd, THREAD_CONTROL);
875*437bfbebSnyanmisaka ctx->reset = 0;
876*437bfbebSnyanmisaka mpp_thread_unlock(thd, THREAD_CONTROL);
877*437bfbebSnyanmisaka sem_post(&ctx->reset_sem);
878*437bfbebSnyanmisaka ctx->task_wait.val = 0;
879*437bfbebSnyanmisaka
880*437bfbebSnyanmisaka vproc_dbg_reset("reset done\n");
881*437bfbebSnyanmisaka continue;
882*437bfbebSnyanmisaka }
883*437bfbebSnyanmisaka
884*437bfbebSnyanmisaka ctx->task_wait.task_in = 1;
885*437bfbebSnyanmisaka continue;
886*437bfbebSnyanmisaka }
887*437bfbebSnyanmisaka ctx->task_status.task_rdy = 1;
888*437bfbebSnyanmisaka ctx->task_wait.task_in = 0;
889*437bfbebSnyanmisaka }
890*437bfbebSnyanmisaka
891*437bfbebSnyanmisaka if (task) {
892*437bfbebSnyanmisaka ret = hal_task_hnd_get_info(task, &task_info);
893*437bfbebSnyanmisaka
894*437bfbebSnyanmisaka mpp_assert(ret == MPP_OK);
895*437bfbebSnyanmisaka
896*437bfbebSnyanmisaka RK_S32 index = task_vproc->input;
897*437bfbebSnyanmisaka RK_U32 eos = task_vproc->flags.eos;
898*437bfbebSnyanmisaka RK_U32 change = task_vproc->flags.info_change;
899*437bfbebSnyanmisaka MppFrame frm = NULL;
900*437bfbebSnyanmisaka
901*437bfbebSnyanmisaka if (eos && index < 0) {
902*437bfbebSnyanmisaka vproc_dbg_status("eos signal\n");
903*437bfbebSnyanmisaka
904*437bfbebSnyanmisaka mpp_frame_init(&frm);
905*437bfbebSnyanmisaka mpp_frame_set_eos(frm, eos);
906*437bfbebSnyanmisaka vproc_dbg_out("output at eos, frame poc %d\n", mpp_frame_get_poc(frm));
907*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, NULL, -1, 0);
908*437bfbebSnyanmisaka dec_vproc_clr_prev(ctx);
909*437bfbebSnyanmisaka mpp_frame_deinit(&frm);
910*437bfbebSnyanmisaka
911*437bfbebSnyanmisaka hal_task_hnd_set_status(task, TASK_IDLE);
912*437bfbebSnyanmisaka ctx->task_status.task_rdy = 0;
913*437bfbebSnyanmisaka continue;
914*437bfbebSnyanmisaka }
915*437bfbebSnyanmisaka
916*437bfbebSnyanmisaka mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frm);
917*437bfbebSnyanmisaka
918*437bfbebSnyanmisaka if (change) {
919*437bfbebSnyanmisaka vproc_dbg_status("info change\n");
920*437bfbebSnyanmisaka vproc_dbg_out("output at info change, frame poc %d\n", mpp_frame_get_poc(frm));
921*437bfbebSnyanmisaka dec_vproc_put_frame(mpp, frm, NULL, -1, 0);
922*437bfbebSnyanmisaka dec_vproc_clr_prev(ctx);
923*437bfbebSnyanmisaka
924*437bfbebSnyanmisaka if (ctx->com_ctx->ops->reset)
925*437bfbebSnyanmisaka ctx->com_ctx->ops->reset(ctx->iep_ctx);
926*437bfbebSnyanmisaka
927*437bfbebSnyanmisaka hal_task_hnd_set_status(task, TASK_IDLE);
928*437bfbebSnyanmisaka ctx->task_status.task_rdy = 0;
929*437bfbebSnyanmisaka continue;
930*437bfbebSnyanmisaka }
931*437bfbebSnyanmisaka vproc_dbg_status("vproc get buf in");
932*437bfbebSnyanmisaka if (!ctx->task_status.buf_rdy && !ctx->reset) {
933*437bfbebSnyanmisaka MppBuffer buf = mpp_frame_get_buffer(frm);
934*437bfbebSnyanmisaka size_t buf_size = mpp_buffer_get_size(buf);
935*437bfbebSnyanmisaka
936*437bfbebSnyanmisaka if (!ctx->out_buf0) {
937*437bfbebSnyanmisaka mpp_buffer_get(mpp->mFrameGroup, &ctx->out_buf0, buf_size);
938*437bfbebSnyanmisaka vproc_dbg_out("get out buf0 ptr %p\n", mpp_buffer_get_ptr(ctx->out_buf0));
939*437bfbebSnyanmisaka if (NULL == ctx->out_buf0) {
940*437bfbebSnyanmisaka ctx->task_wait.task_buf_in = 1;
941*437bfbebSnyanmisaka continue;
942*437bfbebSnyanmisaka }
943*437bfbebSnyanmisaka }
944*437bfbebSnyanmisaka if (!ctx->out_buf1) {
945*437bfbebSnyanmisaka mpp_buffer_get(mpp->mFrameGroup, &ctx->out_buf1, buf_size);
946*437bfbebSnyanmisaka vproc_dbg_out("get out buf1 ptr %p\n", mpp_buffer_get_ptr(ctx->out_buf1));
947*437bfbebSnyanmisaka if (NULL == ctx->out_buf1) {
948*437bfbebSnyanmisaka ctx->task_wait.task_buf_in = 1;
949*437bfbebSnyanmisaka continue;
950*437bfbebSnyanmisaka }
951*437bfbebSnyanmisaka }
952*437bfbebSnyanmisaka ctx->task_status.buf_rdy = 1;
953*437bfbebSnyanmisaka }
954*437bfbebSnyanmisaka
955*437bfbebSnyanmisaka RK_S32 tmp = -1;
956*437bfbebSnyanmisaka mpp_buf_slot_dequeue(slots, &tmp, QUEUE_DEINTERLACE);
957*437bfbebSnyanmisaka mpp_assert(tmp == index);
958*437bfbebSnyanmisaka
959*437bfbebSnyanmisaka vproc_dbg_status("vproc get buf ready & start process ");
960*437bfbebSnyanmisaka if (!ctx->reset && ctx->iep_ctx) {
961*437bfbebSnyanmisaka vproc_dbg_in("processing frame poc %d, mode 0x%x, err %x vs %x, buf slot %x, ptr %p\n",
962*437bfbebSnyanmisaka mpp_frame_get_poc(frm), mpp_frame_get_mode(frm), mpp_frame_get_errinfo(frm),
963*437bfbebSnyanmisaka mpp_frame_get_discard(frm), index, mpp_buffer_get_ptr(mpp_frame_get_buffer(frm)));
964*437bfbebSnyanmisaka ctx->set_dei((MppDecVprocCtx *)ctx, frm);
965*437bfbebSnyanmisaka }
966*437bfbebSnyanmisaka
967*437bfbebSnyanmisaka dec_vproc_update_ref(ctx, frm, index, eos);
968*437bfbebSnyanmisaka hal_task_hnd_set_status(task, TASK_IDLE);
969*437bfbebSnyanmisaka ctx->task_status.val = 0;
970*437bfbebSnyanmisaka ctx->task_wait.val = 0;
971*437bfbebSnyanmisaka
972*437bfbebSnyanmisaka vproc_dbg_status("vproc task done");
973*437bfbebSnyanmisaka }
974*437bfbebSnyanmisaka }
975*437bfbebSnyanmisaka mpp_dbg_info("mpp_dec_post_proc_thread exited\n");
976*437bfbebSnyanmisaka
977*437bfbebSnyanmisaka return NULL;
978*437bfbebSnyanmisaka }
979*437bfbebSnyanmisaka
dec_vproc_init(MppDecVprocCtx * ctx,MppDecVprocCfg * cfg)980*437bfbebSnyanmisaka MPP_RET dec_vproc_init(MppDecVprocCtx *ctx, MppDecVprocCfg *cfg)
981*437bfbebSnyanmisaka {
982*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
983*437bfbebSnyanmisaka if (NULL == ctx || NULL == cfg || NULL == cfg->mpp) {
984*437bfbebSnyanmisaka mpp_err_f("found NULL input ctx %p mpp %p\n", ctx, cfg->mpp);
985*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
986*437bfbebSnyanmisaka }
987*437bfbebSnyanmisaka
988*437bfbebSnyanmisaka vproc_dbg_func("in\n");
989*437bfbebSnyanmisaka mpp_env_get_u32("vproc_debug", &vproc_debug, 0);
990*437bfbebSnyanmisaka
991*437bfbebSnyanmisaka *ctx = NULL;
992*437bfbebSnyanmisaka
993*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = mpp_calloc(MppDecVprocCtxImpl, 1);
994*437bfbebSnyanmisaka if (NULL == p) {
995*437bfbebSnyanmisaka mpp_err_f("malloc failed\n");
996*437bfbebSnyanmisaka return MPP_ERR_MALLOC;
997*437bfbebSnyanmisaka }
998*437bfbebSnyanmisaka
999*437bfbebSnyanmisaka p->pre_ff_mode = IEP2_FF_MODE_UND;
1000*437bfbebSnyanmisaka p->mpp = (Mpp *)cfg->mpp;
1001*437bfbebSnyanmisaka p->slots = ((MppDecImpl *)p->mpp->mDec)->frame_slots;
1002*437bfbebSnyanmisaka p->thd = mpp_thread_create(dec_vproc_thread, p, "mpp_dec_vproc");
1003*437bfbebSnyanmisaka sem_init(&p->reset_sem, 0, 0);
1004*437bfbebSnyanmisaka ret = hal_task_group_init(&p->task_group, TASK_BUTT, 4, sizeof(HalDecVprocTask));
1005*437bfbebSnyanmisaka if (ret) {
1006*437bfbebSnyanmisaka mpp_err_f("create task group failed\n");
1007*437bfbebSnyanmisaka mpp_thread_destroy(p->thd);
1008*437bfbebSnyanmisaka MPP_FREE(p);
1009*437bfbebSnyanmisaka return MPP_ERR_MALLOC;
1010*437bfbebSnyanmisaka }
1011*437bfbebSnyanmisaka cfg->task_group = p->task_group;
1012*437bfbebSnyanmisaka
1013*437bfbebSnyanmisaka p->com_ctx = get_iep_ctx();
1014*437bfbebSnyanmisaka if (!p->com_ctx) {
1015*437bfbebSnyanmisaka mpp_err("failed to require context\n");
1016*437bfbebSnyanmisaka mpp_thread_destroy(p->thd);
1017*437bfbebSnyanmisaka
1018*437bfbebSnyanmisaka if (p->task_group) {
1019*437bfbebSnyanmisaka hal_task_group_deinit(p->task_group);
1020*437bfbebSnyanmisaka p->task_group = NULL;
1021*437bfbebSnyanmisaka }
1022*437bfbebSnyanmisaka
1023*437bfbebSnyanmisaka MPP_FREE(p);
1024*437bfbebSnyanmisaka
1025*437bfbebSnyanmisaka return MPP_ERR_MALLOC;
1026*437bfbebSnyanmisaka }
1027*437bfbebSnyanmisaka
1028*437bfbebSnyanmisaka if (p->com_ctx->ver == 1) {
1029*437bfbebSnyanmisaka p->start_dei = dec_vproc_start_dei_v1;
1030*437bfbebSnyanmisaka p->set_dei = dec_vproc_set_dei_v1;
1031*437bfbebSnyanmisaka p->update_ref = dec_vproc_update_ref_v1;
1032*437bfbebSnyanmisaka } else {
1033*437bfbebSnyanmisaka p->start_dei = dec_vproc_start_dei_v2;
1034*437bfbebSnyanmisaka p->set_dei = dec_vproc_set_dei_v2;
1035*437bfbebSnyanmisaka p->update_ref = dec_vproc_update_ref_v2;
1036*437bfbebSnyanmisaka }
1037*437bfbebSnyanmisaka
1038*437bfbebSnyanmisaka ret = p->com_ctx->ops->init(&p->com_ctx->priv);
1039*437bfbebSnyanmisaka p->iep_ctx = p->com_ctx->priv;
1040*437bfbebSnyanmisaka if (!p->thd || ret) {
1041*437bfbebSnyanmisaka mpp_err("failed to create context\n");
1042*437bfbebSnyanmisaka if (p->thd) {
1043*437bfbebSnyanmisaka mpp_thread_destroy(p->thd);
1044*437bfbebSnyanmisaka p->thd = NULL;
1045*437bfbebSnyanmisaka }
1046*437bfbebSnyanmisaka
1047*437bfbebSnyanmisaka if (p->iep_ctx)
1048*437bfbebSnyanmisaka p->com_ctx->ops->deinit(p->iep_ctx);
1049*437bfbebSnyanmisaka
1050*437bfbebSnyanmisaka if (p->task_group) {
1051*437bfbebSnyanmisaka hal_task_group_deinit(p->task_group);
1052*437bfbebSnyanmisaka p->task_group = NULL;
1053*437bfbebSnyanmisaka }
1054*437bfbebSnyanmisaka
1055*437bfbebSnyanmisaka put_iep_ctx(p->com_ctx);
1056*437bfbebSnyanmisaka
1057*437bfbebSnyanmisaka MPP_FREE(p);
1058*437bfbebSnyanmisaka } else {
1059*437bfbebSnyanmisaka p->dei_cfg.dei_mode = IEP_DEI_MODE_I2O1;
1060*437bfbebSnyanmisaka p->dei_cfg.dei_field_order = IEP_DEI_FLD_ORDER_BOT_FIRST;
1061*437bfbebSnyanmisaka /*
1062*437bfbebSnyanmisaka * We need to turn off this switch to prevent some areas
1063*437bfbebSnyanmisaka * of the video from flickering.
1064*437bfbebSnyanmisaka */
1065*437bfbebSnyanmisaka p->dei_cfg.dei_high_freq_en = 0;
1066*437bfbebSnyanmisaka p->dei_cfg.dei_high_freq_fct = 64;
1067*437bfbebSnyanmisaka p->dei_cfg.dei_ei_mode = 0;
1068*437bfbebSnyanmisaka p->dei_cfg.dei_ei_smooth = 1;
1069*437bfbebSnyanmisaka p->dei_cfg.dei_ei_sel = 0;
1070*437bfbebSnyanmisaka p->dei_cfg.dei_ei_radius = 2;
1071*437bfbebSnyanmisaka
1072*437bfbebSnyanmisaka p->prev_idx0 = -1;
1073*437bfbebSnyanmisaka p->prev_frm0 = NULL;
1074*437bfbebSnyanmisaka p->prev_idx1 = -1;
1075*437bfbebSnyanmisaka p->prev_frm1 = NULL;
1076*437bfbebSnyanmisaka }
1077*437bfbebSnyanmisaka
1078*437bfbebSnyanmisaka *ctx = p;
1079*437bfbebSnyanmisaka
1080*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1081*437bfbebSnyanmisaka return ret;
1082*437bfbebSnyanmisaka }
1083*437bfbebSnyanmisaka
dec_vproc_get_version(MppDecVprocCtx ctx)1084*437bfbebSnyanmisaka RK_U32 dec_vproc_get_version(MppDecVprocCtx ctx)
1085*437bfbebSnyanmisaka {
1086*437bfbebSnyanmisaka if (NULL == ctx) {
1087*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1088*437bfbebSnyanmisaka return 0;
1089*437bfbebSnyanmisaka }
1090*437bfbebSnyanmisaka
1091*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1092*437bfbebSnyanmisaka return p->com_ctx->ver;
1093*437bfbebSnyanmisaka }
1094*437bfbebSnyanmisaka
dec_vproc_set_mode(MppDecVprocCtx ctx,MppVprocMode mode)1095*437bfbebSnyanmisaka MPP_RET dec_vproc_set_mode(MppDecVprocCtx ctx, MppVprocMode mode)
1096*437bfbebSnyanmisaka {
1097*437bfbebSnyanmisaka if (NULL == ctx) {
1098*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1099*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1100*437bfbebSnyanmisaka }
1101*437bfbebSnyanmisaka
1102*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1103*437bfbebSnyanmisaka p->vproc_mode = mode;
1104*437bfbebSnyanmisaka return MPP_OK;
1105*437bfbebSnyanmisaka }
1106*437bfbebSnyanmisaka
dec_vproc_deinit(MppDecVprocCtx ctx)1107*437bfbebSnyanmisaka MPP_RET dec_vproc_deinit(MppDecVprocCtx ctx)
1108*437bfbebSnyanmisaka {
1109*437bfbebSnyanmisaka if (NULL == ctx) {
1110*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1111*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1112*437bfbebSnyanmisaka }
1113*437bfbebSnyanmisaka vproc_dbg_func("in\n");
1114*437bfbebSnyanmisaka
1115*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1116*437bfbebSnyanmisaka if (p->thd) {
1117*437bfbebSnyanmisaka mpp_thread_destroy(p->thd);
1118*437bfbebSnyanmisaka p->thd = NULL;
1119*437bfbebSnyanmisaka }
1120*437bfbebSnyanmisaka
1121*437bfbebSnyanmisaka if (p->iep_ctx)
1122*437bfbebSnyanmisaka p->com_ctx->ops->deinit(p->iep_ctx);
1123*437bfbebSnyanmisaka
1124*437bfbebSnyanmisaka if (p->task_group) {
1125*437bfbebSnyanmisaka hal_task_group_deinit(p->task_group);
1126*437bfbebSnyanmisaka p->task_group = NULL;
1127*437bfbebSnyanmisaka }
1128*437bfbebSnyanmisaka
1129*437bfbebSnyanmisaka if (p->com_ctx) {
1130*437bfbebSnyanmisaka put_iep_ctx(p->com_ctx);
1131*437bfbebSnyanmisaka p->com_ctx = NULL;
1132*437bfbebSnyanmisaka }
1133*437bfbebSnyanmisaka
1134*437bfbebSnyanmisaka sem_destroy(&p->reset_sem);
1135*437bfbebSnyanmisaka mpp_free(p);
1136*437bfbebSnyanmisaka
1137*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1138*437bfbebSnyanmisaka return MPP_OK;
1139*437bfbebSnyanmisaka }
1140*437bfbebSnyanmisaka
dec_vproc_start(MppDecVprocCtx ctx)1141*437bfbebSnyanmisaka MPP_RET dec_vproc_start(MppDecVprocCtx ctx)
1142*437bfbebSnyanmisaka {
1143*437bfbebSnyanmisaka if (NULL == ctx) {
1144*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1145*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1146*437bfbebSnyanmisaka }
1147*437bfbebSnyanmisaka vproc_dbg_func("in\n");
1148*437bfbebSnyanmisaka
1149*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1150*437bfbebSnyanmisaka
1151*437bfbebSnyanmisaka if (p->thd)
1152*437bfbebSnyanmisaka mpp_thread_start(p->thd);
1153*437bfbebSnyanmisaka else
1154*437bfbebSnyanmisaka mpp_err("failed to start dec vproc thread\n");
1155*437bfbebSnyanmisaka
1156*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1157*437bfbebSnyanmisaka return MPP_OK;
1158*437bfbebSnyanmisaka }
1159*437bfbebSnyanmisaka
dec_vproc_stop(MppDecVprocCtx ctx)1160*437bfbebSnyanmisaka MPP_RET dec_vproc_stop(MppDecVprocCtx ctx)
1161*437bfbebSnyanmisaka {
1162*437bfbebSnyanmisaka if (NULL == ctx) {
1163*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1164*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1165*437bfbebSnyanmisaka }
1166*437bfbebSnyanmisaka vproc_dbg_func("in\n");
1167*437bfbebSnyanmisaka
1168*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1169*437bfbebSnyanmisaka
1170*437bfbebSnyanmisaka if (p->thd)
1171*437bfbebSnyanmisaka mpp_thread_stop(p->thd);
1172*437bfbebSnyanmisaka else
1173*437bfbebSnyanmisaka mpp_err("failed to stop dec vproc thread\n");
1174*437bfbebSnyanmisaka
1175*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1176*437bfbebSnyanmisaka return MPP_OK;
1177*437bfbebSnyanmisaka }
1178*437bfbebSnyanmisaka
dec_vproc_signal(MppDecVprocCtx ctx)1179*437bfbebSnyanmisaka MPP_RET dec_vproc_signal(MppDecVprocCtx ctx)
1180*437bfbebSnyanmisaka {
1181*437bfbebSnyanmisaka if (NULL == ctx) {
1182*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1183*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1184*437bfbebSnyanmisaka }
1185*437bfbebSnyanmisaka vproc_dbg_func("in\n");
1186*437bfbebSnyanmisaka
1187*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1188*437bfbebSnyanmisaka if (p->thd) {
1189*437bfbebSnyanmisaka mpp_thread_lock(p->thd, THREAD_WORK);
1190*437bfbebSnyanmisaka mpp_thread_signal(p->thd, THREAD_WORK);
1191*437bfbebSnyanmisaka mpp_thread_unlock(p->thd, THREAD_WORK);
1192*437bfbebSnyanmisaka }
1193*437bfbebSnyanmisaka
1194*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1195*437bfbebSnyanmisaka return MPP_OK;
1196*437bfbebSnyanmisaka }
1197*437bfbebSnyanmisaka
dec_vproc_reset(MppDecVprocCtx ctx)1198*437bfbebSnyanmisaka MPP_RET dec_vproc_reset(MppDecVprocCtx ctx)
1199*437bfbebSnyanmisaka {
1200*437bfbebSnyanmisaka if (NULL == ctx) {
1201*437bfbebSnyanmisaka mpp_err_f("found NULL input\n");
1202*437bfbebSnyanmisaka return MPP_ERR_NULL_PTR;
1203*437bfbebSnyanmisaka }
1204*437bfbebSnyanmisaka vproc_dbg_func("in\n");
1205*437bfbebSnyanmisaka
1206*437bfbebSnyanmisaka MppDecVprocCtxImpl *p = (MppDecVprocCtxImpl *)ctx;
1207*437bfbebSnyanmisaka if (p->thd) {
1208*437bfbebSnyanmisaka MppThread *thd = p->thd;
1209*437bfbebSnyanmisaka
1210*437bfbebSnyanmisaka vproc_dbg_reset("reset contorl start\n");
1211*437bfbebSnyanmisaka // wait reset finished
1212*437bfbebSnyanmisaka mpp_thread_lock(thd, THREAD_WORK);
1213*437bfbebSnyanmisaka mpp_thread_lock(thd, THREAD_CONTROL);
1214*437bfbebSnyanmisaka p->reset = 1;
1215*437bfbebSnyanmisaka mpp_thread_signal(thd, THREAD_WORK);
1216*437bfbebSnyanmisaka mpp_thread_unlock(thd, THREAD_CONTROL);
1217*437bfbebSnyanmisaka mpp_thread_unlock(thd, THREAD_WORK);
1218*437bfbebSnyanmisaka
1219*437bfbebSnyanmisaka vproc_dbg_reset("reset contorl wait\n");
1220*437bfbebSnyanmisaka sem_wait(&p->reset_sem);
1221*437bfbebSnyanmisaka vproc_dbg_reset("reset contorl done\n");
1222*437bfbebSnyanmisaka
1223*437bfbebSnyanmisaka mpp_assert(p->reset == 0);
1224*437bfbebSnyanmisaka }
1225*437bfbebSnyanmisaka
1226*437bfbebSnyanmisaka vproc_dbg_func("out\n");
1227*437bfbebSnyanmisaka return MPP_OK;
1228*437bfbebSnyanmisaka }
1229