xref: /rockchip-linux_mpp/mpp/codec/mpp_dec.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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_dec"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka 
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka 
12*437bfbebSnyanmisaka #include "mpp_buffer_impl.h"
13*437bfbebSnyanmisaka #include "mpp_frame_impl.h"
14*437bfbebSnyanmisaka #include "mpp_dec_cfg.h"
15*437bfbebSnyanmisaka 
16*437bfbebSnyanmisaka #include "mpp_dec_debug.h"
17*437bfbebSnyanmisaka #include "mpp_dec_vproc.h"
18*437bfbebSnyanmisaka #include "mpp_dec_cb_param.h"
19*437bfbebSnyanmisaka #include "mpp_dec_normal.h"
20*437bfbebSnyanmisaka #include "mpp_dec_no_thread.h"
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka RK_U32 mpp_dec_debug = 0;
23*437bfbebSnyanmisaka 
dec_task_info_init(HalTaskInfo * task)24*437bfbebSnyanmisaka MPP_RET dec_task_info_init(HalTaskInfo *task)
25*437bfbebSnyanmisaka {
26*437bfbebSnyanmisaka     HalDecTask *p = &task->dec;
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka     p->valid  = 0;
29*437bfbebSnyanmisaka     p->flags.val = 0;
30*437bfbebSnyanmisaka     p->flags.eos = 0;
31*437bfbebSnyanmisaka     p->input_packet = NULL;
32*437bfbebSnyanmisaka     p->output = -1;
33*437bfbebSnyanmisaka     p->input = -1;
34*437bfbebSnyanmisaka     memset(&task->dec.syntax, 0, sizeof(task->dec.syntax));
35*437bfbebSnyanmisaka     memset(task->dec.refer, -1, sizeof(task->dec.refer));
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka     return MPP_OK;
38*437bfbebSnyanmisaka }
39*437bfbebSnyanmisaka 
dec_task_init(DecTask * task)40*437bfbebSnyanmisaka void dec_task_init(DecTask *task)
41*437bfbebSnyanmisaka {
42*437bfbebSnyanmisaka     task->hnd = NULL;
43*437bfbebSnyanmisaka     task->status.val = 0;
44*437bfbebSnyanmisaka     task->wait.val   = 0;
45*437bfbebSnyanmisaka     task->status.prev_task_rdy  = 1;
46*437bfbebSnyanmisaka     INIT_LIST_HEAD(&task->ts_cur.link);
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     dec_task_info_init(&task->info);
49*437bfbebSnyanmisaka }
50*437bfbebSnyanmisaka 
mpp_dec_update_cfg(MppDecImpl * p)51*437bfbebSnyanmisaka static MPP_RET mpp_dec_update_cfg(MppDecImpl *p)
52*437bfbebSnyanmisaka {
53*437bfbebSnyanmisaka     MppDecCfgSet *cfg = p->cfg;
54*437bfbebSnyanmisaka     MppDecBaseCfg *base = &cfg->base;
55*437bfbebSnyanmisaka     MppDecStatusCfg *status = &cfg->status;
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka     if (status->hal_task_count && !status->hal_support_fast_mode) {
58*437bfbebSnyanmisaka         if (!p->parser_fast_mode && base->fast_parse) {
59*437bfbebSnyanmisaka             mpp_err("can not enable fast parse while hal not support\n");
60*437bfbebSnyanmisaka             base->fast_parse = 0;
61*437bfbebSnyanmisaka         }
62*437bfbebSnyanmisaka     }
63*437bfbebSnyanmisaka 
64*437bfbebSnyanmisaka     p->parser_fast_mode     = base->fast_parse;
65*437bfbebSnyanmisaka     p->enable_deinterlace   = base->enable_vproc;
66*437bfbebSnyanmisaka     p->disable_error        = base->disable_error;
67*437bfbebSnyanmisaka     p->dis_err_clr_mark     = base->dis_err_clr_mark;
68*437bfbebSnyanmisaka 
69*437bfbebSnyanmisaka     mpp_env_get_u32("enable_deinterlace", &p->enable_deinterlace, base->enable_vproc);
70*437bfbebSnyanmisaka 
71*437bfbebSnyanmisaka     return MPP_OK;
72*437bfbebSnyanmisaka }
73*437bfbebSnyanmisaka 
mpp_dec_check_fbc_cap(MppDecImpl * p)74*437bfbebSnyanmisaka static MPP_RET mpp_dec_check_fbc_cap(MppDecImpl *p)
75*437bfbebSnyanmisaka {
76*437bfbebSnyanmisaka     MppDecBaseCfg *base = &p->cfg->base;
77*437bfbebSnyanmisaka 
78*437bfbebSnyanmisaka     if (MPP_FRAME_FMT_IS_FBC(base->out_fmt)) {
79*437bfbebSnyanmisaka         RK_U32 fbc = (RK_U32)base->out_fmt & MPP_FRAME_FBC_MASK;
80*437bfbebSnyanmisaka         RK_U32 fmt = base->out_fmt - fbc;
81*437bfbebSnyanmisaka 
82*437bfbebSnyanmisaka         if (p->hw_info && p->hw_info->cap_fbc)
83*437bfbebSnyanmisaka             fmt |= fbc;
84*437bfbebSnyanmisaka 
85*437bfbebSnyanmisaka         base->out_fmt = (MppFrameFormat)fmt;
86*437bfbebSnyanmisaka     }
87*437bfbebSnyanmisaka 
88*437bfbebSnyanmisaka     return MPP_OK;
89*437bfbebSnyanmisaka }
90*437bfbebSnyanmisaka 
mpp_dec_proc_cfg(MppDecImpl * dec,MpiCmd cmd,void * param)91*437bfbebSnyanmisaka MPP_RET mpp_dec_proc_cfg(MppDecImpl *dec, MpiCmd cmd, void *param)
92*437bfbebSnyanmisaka {
93*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     mpp_parser_control(dec->parser, cmd, param);
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     ret = mpp_hal_control(dec->hal, cmd, param);
98*437bfbebSnyanmisaka 
99*437bfbebSnyanmisaka     if (ret)
100*437bfbebSnyanmisaka         goto RET;
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka     switch (cmd) {
103*437bfbebSnyanmisaka     case MPP_DEC_SET_FRAME_INFO : {
104*437bfbebSnyanmisaka         MppFrame frame = (MppFrame)param;
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka         /* update output frame format */
107*437bfbebSnyanmisaka         dec->cfg->base.out_fmt = mpp_frame_get_fmt(frame);
108*437bfbebSnyanmisaka         mpp_log_f("found MPP_DEC_SET_FRAME_INFO fmt %x\n", dec->cfg->base.out_fmt);
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka         mpp_slots_set_prop(dec->frame_slots, SLOTS_FRAME_INFO, frame);
111*437bfbebSnyanmisaka 
112*437bfbebSnyanmisaka         mpp_log("setting default w %4d h %4d h_str %4d v_str %4d\n",
113*437bfbebSnyanmisaka                 mpp_frame_get_width(frame),
114*437bfbebSnyanmisaka                 mpp_frame_get_height(frame),
115*437bfbebSnyanmisaka                 mpp_frame_get_hor_stride(frame),
116*437bfbebSnyanmisaka                 mpp_frame_get_ver_stride(frame));
117*437bfbebSnyanmisaka 
118*437bfbebSnyanmisaka     } break;
119*437bfbebSnyanmisaka     case MPP_DEC_SET_INFO_CHANGE_READY: {
120*437bfbebSnyanmisaka         ret = mpp_buf_slot_ready(dec->frame_slots);
121*437bfbebSnyanmisaka     } break;
122*437bfbebSnyanmisaka     case MPP_DEC_GET_VPUMEM_USED_COUNT: {
123*437bfbebSnyanmisaka         RK_S32 *p = (RK_S32 *)param;
124*437bfbebSnyanmisaka         *p = mpp_slots_get_used_count(dec->frame_slots);
125*437bfbebSnyanmisaka         dec_dbg_func("used count %d\n", *p);
126*437bfbebSnyanmisaka     } break;
127*437bfbebSnyanmisaka     case MPP_DEC_SET_PRESENT_TIME_ORDER :
128*437bfbebSnyanmisaka     case MPP_DEC_SET_PARSER_SPLIT_MODE :
129*437bfbebSnyanmisaka     case MPP_DEC_SET_PARSER_FAST_MODE :
130*437bfbebSnyanmisaka     case MPP_DEC_SET_IMMEDIATE_OUT :
131*437bfbebSnyanmisaka     case MPP_DEC_SET_OUTPUT_FORMAT :
132*437bfbebSnyanmisaka     case MPP_DEC_SET_DISABLE_ERROR :
133*437bfbebSnyanmisaka     case MPP_DEC_SET_DIS_ERR_CLR_MARK :
134*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_DEINTERLACE :
135*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_FAST_PLAY :
136*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_MVC :
137*437bfbebSnyanmisaka     case MPP_DEC_SET_DISABLE_DPB_CHECK: {
138*437bfbebSnyanmisaka         ret = mpp_dec_set_cfg_by_cmd(dec->cfg_obj, cmd, param);
139*437bfbebSnyanmisaka         mpp_dec_update_cfg(dec);
140*437bfbebSnyanmisaka         mpp_dec_check_fbc_cap(dec);
141*437bfbebSnyanmisaka         dec->cfg->base.change = 0;
142*437bfbebSnyanmisaka     } break;
143*437bfbebSnyanmisaka     case MPP_DEC_QUERY: {
144*437bfbebSnyanmisaka         MppDecQueryCfg *query = (MppDecQueryCfg *)param;
145*437bfbebSnyanmisaka         RK_U32 flag = query->query_flag;
146*437bfbebSnyanmisaka 
147*437bfbebSnyanmisaka         dec_dbg_func("query %x\n", flag);
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_STATUS)
150*437bfbebSnyanmisaka             query->rt_status = dec->parser_status_flag;
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_WAIT)
153*437bfbebSnyanmisaka             query->rt_wait = dec->parser_wait_flag;
154*437bfbebSnyanmisaka 
155*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_FPS)
156*437bfbebSnyanmisaka             query->rt_fps = 0;
157*437bfbebSnyanmisaka 
158*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_BPS)
159*437bfbebSnyanmisaka             query->rt_bps = 0;
160*437bfbebSnyanmisaka 
161*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_DEC_IN_PKT)
162*437bfbebSnyanmisaka             query->dec_in_pkt_cnt = dec->dec_in_pkt_count;
163*437bfbebSnyanmisaka 
164*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_DEC_WORK)
165*437bfbebSnyanmisaka             query->dec_hw_run_cnt = dec->dec_hw_run_count;
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka         if (flag & MPP_DEC_QUERY_DEC_OUT_FRM)
168*437bfbebSnyanmisaka             query->dec_out_frm_cnt = dec->dec_out_frame_count;
169*437bfbebSnyanmisaka     } break;
170*437bfbebSnyanmisaka     case MPP_DEC_SET_CFG: {
171*437bfbebSnyanmisaka         if (param) {
172*437bfbebSnyanmisaka             kmpp_obj_update(dec->cfg_obj, (KmppObj)param);
173*437bfbebSnyanmisaka             mpp_dec_update_cfg(dec);
174*437bfbebSnyanmisaka             mpp_dec_check_fbc_cap(dec);
175*437bfbebSnyanmisaka         }
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka         dec_dbg_func("set dec cfg\n");
178*437bfbebSnyanmisaka     } break;
179*437bfbebSnyanmisaka     case MPP_DEC_GET_CFG: {
180*437bfbebSnyanmisaka         if (param)
181*437bfbebSnyanmisaka             ret = (MPP_RET)kmpp_obj_copy_entry(param, dec->cfg_obj);
182*437bfbebSnyanmisaka 
183*437bfbebSnyanmisaka         dec_dbg_func("get dec cfg\n");
184*437bfbebSnyanmisaka     } break;
185*437bfbebSnyanmisaka     default : {
186*437bfbebSnyanmisaka     } break;
187*437bfbebSnyanmisaka     }
188*437bfbebSnyanmisaka 
189*437bfbebSnyanmisaka RET:
190*437bfbebSnyanmisaka     return ret;
191*437bfbebSnyanmisaka }
192*437bfbebSnyanmisaka 
193*437bfbebSnyanmisaka /* Overall mpp_dec output frame function */
mpp_dec_put_frame(Mpp * mpp,RK_S32 index,HalDecTaskFlag flags)194*437bfbebSnyanmisaka void mpp_dec_put_frame(Mpp *mpp, RK_S32 index, HalDecTaskFlag flags)
195*437bfbebSnyanmisaka {
196*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)mpp->mDec;
197*437bfbebSnyanmisaka     MppBufSlots slots = dec->frame_slots;
198*437bfbebSnyanmisaka     MppFrame frame = NULL;
199*437bfbebSnyanmisaka     RK_U32 eos = flags.eos;
200*437bfbebSnyanmisaka     RK_U32 change = flags.info_change;
201*437bfbebSnyanmisaka     RK_U32 error = flags.parse_err || flags.ref_err;
202*437bfbebSnyanmisaka     RK_U32 refer = flags.used_for_ref;
203*437bfbebSnyanmisaka     RK_U32 fake_frame = 0;
204*437bfbebSnyanmisaka 
205*437bfbebSnyanmisaka     if (index >= 0) {
206*437bfbebSnyanmisaka         RK_U32 mode = 0;
207*437bfbebSnyanmisaka 
208*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(slots, index, SLOT_FRAME_PTR, &frame);
209*437bfbebSnyanmisaka 
210*437bfbebSnyanmisaka         mode = mpp_frame_get_mode(frame);
211*437bfbebSnyanmisaka         if (mode && dec->enable_deinterlace && NULL == dec->vproc) {
212*437bfbebSnyanmisaka             MppDecVprocCfg cfg = { mpp, NULL };
213*437bfbebSnyanmisaka             MPP_RET ret = dec_vproc_init(&dec->vproc, &cfg);
214*437bfbebSnyanmisaka             if (ret) {
215*437bfbebSnyanmisaka                 // When iep is failed to open disable deinterlace function to
216*437bfbebSnyanmisaka                 // avoid noisy log.
217*437bfbebSnyanmisaka                 dec->enable_deinterlace = 0;
218*437bfbebSnyanmisaka                 dec->vproc = NULL;
219*437bfbebSnyanmisaka             } else {
220*437bfbebSnyanmisaka                 if (dec_vproc_get_version(dec->vproc) == 1 && mode == MPP_FRAME_FLAG_DEINTERLACED) {
221*437bfbebSnyanmisaka                     mpp_frame_set_mode(frame, MPP_FRAME_FLAG_FRAME);
222*437bfbebSnyanmisaka                     /*iep 1 can't no detect DEINTERLACED, direct disable*/
223*437bfbebSnyanmisaka                     dec->cfg->base.enable_vproc &= (~MPP_VPROC_MODE_DETECTION);
224*437bfbebSnyanmisaka                     dec->enable_deinterlace = dec->cfg->base.enable_vproc;
225*437bfbebSnyanmisaka                     if (dec->vproc && !dec->enable_deinterlace) {
226*437bfbebSnyanmisaka                         dec_vproc_deinit(dec->vproc);
227*437bfbebSnyanmisaka                         dec->vproc = NULL;
228*437bfbebSnyanmisaka                     }
229*437bfbebSnyanmisaka                     dec->vproc = NULL;
230*437bfbebSnyanmisaka                 } else {
231*437bfbebSnyanmisaka                     /* store current IEP mode */
232*437bfbebSnyanmisaka                     dec_vproc_set_mode(dec->vproc, (MppVprocMode)dec->enable_deinterlace);
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka                     dec->vproc_tasks = cfg.task_group;
235*437bfbebSnyanmisaka                     dec_vproc_start(dec->vproc);
236*437bfbebSnyanmisaka                 }
237*437bfbebSnyanmisaka             }
238*437bfbebSnyanmisaka         }
239*437bfbebSnyanmisaka     } else {
240*437bfbebSnyanmisaka         // when post-process is needed and eos without slot index case
241*437bfbebSnyanmisaka         // we need to create a slot index for it
242*437bfbebSnyanmisaka         mpp_assert(eos);
243*437bfbebSnyanmisaka         mpp_assert(!change);
244*437bfbebSnyanmisaka 
245*437bfbebSnyanmisaka         if (dec->vproc) {
246*437bfbebSnyanmisaka             HalTaskGroup group = dec->vproc_tasks;
247*437bfbebSnyanmisaka             HalTaskHnd hnd = NULL;
248*437bfbebSnyanmisaka             HalTaskInfo task;
249*437bfbebSnyanmisaka             HalDecVprocTask *vproc_task = &task.dec_vproc;
250*437bfbebSnyanmisaka             MPP_RET ret = MPP_OK;
251*437bfbebSnyanmisaka 
252*437bfbebSnyanmisaka             do {
253*437bfbebSnyanmisaka                 ret = hal_task_get_hnd(group, TASK_IDLE, &hnd);
254*437bfbebSnyanmisaka                 if (ret) {
255*437bfbebSnyanmisaka                     if (dec->reset_flag) {
256*437bfbebSnyanmisaka                         return;
257*437bfbebSnyanmisaka                     } else {
258*437bfbebSnyanmisaka                         msleep(10);
259*437bfbebSnyanmisaka                     }
260*437bfbebSnyanmisaka                 }
261*437bfbebSnyanmisaka             } while (ret);
262*437bfbebSnyanmisaka             vproc_task->flags.val = 0;
263*437bfbebSnyanmisaka             vproc_task->flags.eos = eos;
264*437bfbebSnyanmisaka             vproc_task->input = index;
265*437bfbebSnyanmisaka 
266*437bfbebSnyanmisaka             hal_task_hnd_set_info(hnd, &task);
267*437bfbebSnyanmisaka             hal_task_hnd_set_status(hnd, TASK_PROCESSING);
268*437bfbebSnyanmisaka             dec_vproc_signal(dec->vproc);
269*437bfbebSnyanmisaka 
270*437bfbebSnyanmisaka             return ;
271*437bfbebSnyanmisaka         } else {
272*437bfbebSnyanmisaka             mpp_frame_init(&frame);
273*437bfbebSnyanmisaka             fake_frame = 1;
274*437bfbebSnyanmisaka             index = 0;
275*437bfbebSnyanmisaka         }
276*437bfbebSnyanmisaka 
277*437bfbebSnyanmisaka         mpp_frame_set_eos(frame, eos);
278*437bfbebSnyanmisaka     }
279*437bfbebSnyanmisaka 
280*437bfbebSnyanmisaka     mpp_assert(index >= 0);
281*437bfbebSnyanmisaka     mpp_assert(frame);
282*437bfbebSnyanmisaka 
283*437bfbebSnyanmisaka     if (dec->cfg->base.disable_error && dec->cfg->base.dis_err_clr_mark) {
284*437bfbebSnyanmisaka         mpp_frame_set_errinfo(frame, 0);
285*437bfbebSnyanmisaka         mpp_frame_set_discard(frame, 0);
286*437bfbebSnyanmisaka     }
287*437bfbebSnyanmisaka 
288*437bfbebSnyanmisaka     if (!change) {
289*437bfbebSnyanmisaka         if (dec->cfg->base.sort_pts) {
290*437bfbebSnyanmisaka             MppPktTs *pkt_ts;
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka             mpp_spinlock_lock(&dec->ts_lock);
293*437bfbebSnyanmisaka             pkt_ts = list_first_entry_or_null(&dec->ts_link, MppPktTs, link);
294*437bfbebSnyanmisaka             if (pkt_ts)
295*437bfbebSnyanmisaka                 list_del_init(&pkt_ts->link);
296*437bfbebSnyanmisaka             mpp_spinlock_unlock(&dec->ts_lock);
297*437bfbebSnyanmisaka             if (pkt_ts) {
298*437bfbebSnyanmisaka                 mpp_frame_set_dts(frame, pkt_ts->dts);
299*437bfbebSnyanmisaka                 mpp_frame_set_pts(frame, pkt_ts->pts);
300*437bfbebSnyanmisaka                 mpp_mem_pool_put_f(dec->ts_pool, pkt_ts);
301*437bfbebSnyanmisaka             }
302*437bfbebSnyanmisaka         }
303*437bfbebSnyanmisaka     }
304*437bfbebSnyanmisaka     mpp_frame_set_info_change(frame, change);
305*437bfbebSnyanmisaka 
306*437bfbebSnyanmisaka     if (eos) {
307*437bfbebSnyanmisaka         mpp_frame_set_eos(frame, 1);
308*437bfbebSnyanmisaka         if (error) {
309*437bfbebSnyanmisaka             if (refer)
310*437bfbebSnyanmisaka                 mpp_frame_set_errinfo(frame, 1);
311*437bfbebSnyanmisaka             else
312*437bfbebSnyanmisaka                 mpp_frame_set_discard(frame, 1);
313*437bfbebSnyanmisaka         }
314*437bfbebSnyanmisaka     }
315*437bfbebSnyanmisaka 
316*437bfbebSnyanmisaka     dec->dec_out_frame_count++;
317*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p put frm pts %llu fd %d\n", dec,
318*437bfbebSnyanmisaka                    mpp_frame_get_pts(frame),
319*437bfbebSnyanmisaka                    (NULL == mpp_frame_get_buffer(frame)) ? (-1) :
320*437bfbebSnyanmisaka                    mpp_buffer_get_fd(mpp_frame_get_buffer(frame)));
321*437bfbebSnyanmisaka 
322*437bfbebSnyanmisaka     if (dec->vproc) {
323*437bfbebSnyanmisaka         HalTaskGroup group = dec->vproc_tasks;
324*437bfbebSnyanmisaka         HalTaskHnd hnd = NULL;
325*437bfbebSnyanmisaka         HalTaskInfo task;
326*437bfbebSnyanmisaka         HalDecVprocTask *vproc_task = &task.dec_vproc;
327*437bfbebSnyanmisaka         MPP_RET ret = MPP_OK;
328*437bfbebSnyanmisaka 
329*437bfbebSnyanmisaka         do {
330*437bfbebSnyanmisaka             ret = hal_task_get_hnd(group, TASK_IDLE, &hnd);
331*437bfbebSnyanmisaka             if (ret) {
332*437bfbebSnyanmisaka                 if (dec->reset_flag) {
333*437bfbebSnyanmisaka                     MppBuffer buffer = NULL;
334*437bfbebSnyanmisaka                     mpp_buf_slot_get_prop(slots, index, SLOT_BUFFER, &buffer);
335*437bfbebSnyanmisaka                     if (buffer)
336*437bfbebSnyanmisaka                         mpp_buffer_put(buffer);
337*437bfbebSnyanmisaka                     return;
338*437bfbebSnyanmisaka                 } else {
339*437bfbebSnyanmisaka                     msleep(10);
340*437bfbebSnyanmisaka                 }
341*437bfbebSnyanmisaka             }
342*437bfbebSnyanmisaka         } while (ret);
343*437bfbebSnyanmisaka 
344*437bfbebSnyanmisaka         mpp_assert(ret == MPP_OK);
345*437bfbebSnyanmisaka 
346*437bfbebSnyanmisaka         vproc_task->flags.eos = eos;
347*437bfbebSnyanmisaka         vproc_task->flags.info_change = change;
348*437bfbebSnyanmisaka         vproc_task->input = index;
349*437bfbebSnyanmisaka 
350*437bfbebSnyanmisaka         if (!change) {
351*437bfbebSnyanmisaka             mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE);
352*437bfbebSnyanmisaka             mpp_buf_slot_enqueue(slots, index, QUEUE_DEINTERLACE);
353*437bfbebSnyanmisaka         }
354*437bfbebSnyanmisaka 
355*437bfbebSnyanmisaka         hal_task_hnd_set_info(hnd, &task);
356*437bfbebSnyanmisaka         hal_task_hnd_set_status(hnd, TASK_PROCESSING);
357*437bfbebSnyanmisaka 
358*437bfbebSnyanmisaka         dec_vproc_signal(dec->vproc);
359*437bfbebSnyanmisaka     } else {
360*437bfbebSnyanmisaka         // direct output -> copy a new MppFrame and output
361*437bfbebSnyanmisaka         MppList *list = mpp->mFrmOut;
362*437bfbebSnyanmisaka         MppFrame out = NULL;
363*437bfbebSnyanmisaka 
364*437bfbebSnyanmisaka         mpp_frame_init(&out);
365*437bfbebSnyanmisaka         mpp_frame_copy(out, frame);
366*437bfbebSnyanmisaka 
367*437bfbebSnyanmisaka         mpp_dbg_pts("output frame pts %lld\n", mpp_frame_get_pts(out));
368*437bfbebSnyanmisaka 
369*437bfbebSnyanmisaka         mpp_mutex_cond_lock(&list->cond_lock);
370*437bfbebSnyanmisaka         mpp_list_add_at_tail(list, &out, sizeof(out));
371*437bfbebSnyanmisaka         mpp->mFramePutCount++;
372*437bfbebSnyanmisaka         mpp_list_signal(list);
373*437bfbebSnyanmisaka         mpp_mutex_cond_unlock(&list->cond_lock);
374*437bfbebSnyanmisaka 
375*437bfbebSnyanmisaka         if (fake_frame)
376*437bfbebSnyanmisaka             mpp_frame_deinit(&frame);
377*437bfbebSnyanmisaka 
378*437bfbebSnyanmisaka         mpp_dec_callback(dec, MPP_DEC_EVENT_ON_FRM_READY, out);
379*437bfbebSnyanmisaka     }
380*437bfbebSnyanmisaka }
381*437bfbebSnyanmisaka 
mpp_dec_push_display(Mpp * mpp,HalDecTaskFlag flags)382*437bfbebSnyanmisaka RK_S32 mpp_dec_push_display(Mpp *mpp, HalDecTaskFlag flags)
383*437bfbebSnyanmisaka {
384*437bfbebSnyanmisaka     RK_S32 index = -1;
385*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)mpp->mDec;
386*437bfbebSnyanmisaka     MppBufSlots frame_slots = dec->frame_slots;
387*437bfbebSnyanmisaka     RK_U32 eos = flags.eos;
388*437bfbebSnyanmisaka     HalDecTaskFlag tmp = flags;
389*437bfbebSnyanmisaka     RK_S32 ret = 0;
390*437bfbebSnyanmisaka 
391*437bfbebSnyanmisaka     tmp.eos = 0;
392*437bfbebSnyanmisaka     /**
393*437bfbebSnyanmisaka      * After info_change is encountered by parser thread, HalDecTaskFlag will
394*437bfbebSnyanmisaka      * have this flag set. Although mpp_dec_flush is called there may be some
395*437bfbebSnyanmisaka      * frames still remaining in display queue and waiting to be output. So
396*437bfbebSnyanmisaka      * these frames shouldn't have info_change set since their resolution and
397*437bfbebSnyanmisaka      * bit depth are the same as before. What's more, the info_change flag has
398*437bfbebSnyanmisaka      * nothing to do with frames being output.
399*437bfbebSnyanmisaka      */
400*437bfbebSnyanmisaka     tmp.info_change = 0;
401*437bfbebSnyanmisaka 
402*437bfbebSnyanmisaka     if (dec->thread_hal)
403*437bfbebSnyanmisaka         mpp_thread_lock(dec->thread_hal, THREAD_OUTPUT);
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka     while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) {
406*437bfbebSnyanmisaka         /* deal with current frame */
407*437bfbebSnyanmisaka         if (eos && mpp_slots_is_empty(frame_slots, QUEUE_DISPLAY))
408*437bfbebSnyanmisaka             tmp.eos = 1;
409*437bfbebSnyanmisaka 
410*437bfbebSnyanmisaka         mpp_dec_put_frame(mpp, index, tmp);
411*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE);
412*437bfbebSnyanmisaka         ret++;
413*437bfbebSnyanmisaka     }
414*437bfbebSnyanmisaka 
415*437bfbebSnyanmisaka     if (dec->thread_hal)
416*437bfbebSnyanmisaka         mpp_thread_unlock(dec->thread_hal, THREAD_OUTPUT);
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka     return ret;
419*437bfbebSnyanmisaka }
420*437bfbebSnyanmisaka 
update_dec_hal_info(MppDecImpl * dec,MppFrame frame)421*437bfbebSnyanmisaka MPP_RET update_dec_hal_info(MppDecImpl *dec, MppFrame frame)
422*437bfbebSnyanmisaka {
423*437bfbebSnyanmisaka     HalInfo hal_info = dec->hal_info;
424*437bfbebSnyanmisaka     MppDevInfoCfg data[DEC_INFO_BUTT];
425*437bfbebSnyanmisaka     RK_S32 size = sizeof(data);
426*437bfbebSnyanmisaka     RK_U64 val = 0;
427*437bfbebSnyanmisaka     RK_S32 i;
428*437bfbebSnyanmisaka 
429*437bfbebSnyanmisaka     hal_info_set(hal_info, DEC_INFO_WIDTH, CODEC_INFO_FLAG_NUMBER,
430*437bfbebSnyanmisaka                  mpp_frame_get_width(frame));
431*437bfbebSnyanmisaka 
432*437bfbebSnyanmisaka     hal_info_set(hal_info, DEC_INFO_HEIGHT, CODEC_INFO_FLAG_NUMBER,
433*437bfbebSnyanmisaka                  mpp_frame_get_height(frame));
434*437bfbebSnyanmisaka 
435*437bfbebSnyanmisaka     val = hal_info_to_string(hal_info, DEC_INFO_FORMAT, &dec->coding);
436*437bfbebSnyanmisaka     hal_info_set(hal_info, DEC_INFO_FORMAT, CODEC_INFO_FLAG_STRING, val);
437*437bfbebSnyanmisaka 
438*437bfbebSnyanmisaka     hal_info_get(hal_info, data, &size);
439*437bfbebSnyanmisaka 
440*437bfbebSnyanmisaka     if (size) {
441*437bfbebSnyanmisaka         size /= sizeof(data[0]);
442*437bfbebSnyanmisaka         for (i = 0; i < size; i++)
443*437bfbebSnyanmisaka             mpp_dev_ioctl(dec->dev, MPP_DEV_SET_INFO, &data[i]);
444*437bfbebSnyanmisaka     }
445*437bfbebSnyanmisaka 
446*437bfbebSnyanmisaka     return MPP_OK;
447*437bfbebSnyanmisaka }
448*437bfbebSnyanmisaka 
449*437bfbebSnyanmisaka static MppDecModeApi *dec_api[] = {
450*437bfbebSnyanmisaka     &dec_api_normal,
451*437bfbebSnyanmisaka     &dec_api_no_thread,
452*437bfbebSnyanmisaka };
453*437bfbebSnyanmisaka 
454*437bfbebSnyanmisaka static const char *timing_str[DEC_TIMING_BUTT] = {
455*437bfbebSnyanmisaka     "prs thread",
456*437bfbebSnyanmisaka     "prs wait  ",
457*437bfbebSnyanmisaka     "prs proc  ",
458*437bfbebSnyanmisaka     "prepare   ",
459*437bfbebSnyanmisaka     "parse     ",
460*437bfbebSnyanmisaka     "gen reg   ",
461*437bfbebSnyanmisaka     "hw start  ",
462*437bfbebSnyanmisaka 
463*437bfbebSnyanmisaka     "hal thread",
464*437bfbebSnyanmisaka     "hal wait  ",
465*437bfbebSnyanmisaka     "hal proc  ",
466*437bfbebSnyanmisaka     "hw wait   ",
467*437bfbebSnyanmisaka };
468*437bfbebSnyanmisaka 
mpp_dec_callback_hal_to_parser(const char * caller,void * ctx,RK_S32 cmd,void * param)469*437bfbebSnyanmisaka MPP_RET mpp_dec_callback_hal_to_parser(const char *caller, void *ctx,
470*437bfbebSnyanmisaka                                        RK_S32 cmd, void *param)
471*437bfbebSnyanmisaka {
472*437bfbebSnyanmisaka     MppDecImpl *p = (MppDecImpl *)ctx;
473*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
474*437bfbebSnyanmisaka     (void) caller;
475*437bfbebSnyanmisaka 
476*437bfbebSnyanmisaka     mpp_assert(cmd == DEC_PARSER_CALLBACK);
477*437bfbebSnyanmisaka 
478*437bfbebSnyanmisaka     if (p->parser)
479*437bfbebSnyanmisaka         ret = mpp_parser_callback(p->parser, param);
480*437bfbebSnyanmisaka 
481*437bfbebSnyanmisaka     return ret;
482*437bfbebSnyanmisaka }
483*437bfbebSnyanmisaka 
mpp_dec_callback_slot(const char * caller,void * ctx,RK_S32 cmd,void * param)484*437bfbebSnyanmisaka MPP_RET mpp_dec_callback_slot(const char *caller, void *ctx, RK_S32 cmd, void *param)
485*437bfbebSnyanmisaka {
486*437bfbebSnyanmisaka     (void) caller;
487*437bfbebSnyanmisaka     (void) cmd;
488*437bfbebSnyanmisaka     (void) param;
489*437bfbebSnyanmisaka     return mpp_dec_notify((MppDec)ctx, MPP_DEC_NOTIFY_SLOT_VALID);
490*437bfbebSnyanmisaka }
491*437bfbebSnyanmisaka 
mpp_dec_init(MppDec * dec,MppDecInitCfg * cfg)492*437bfbebSnyanmisaka MPP_RET mpp_dec_init(MppDec *dec, MppDecInitCfg *cfg)
493*437bfbebSnyanmisaka {
494*437bfbebSnyanmisaka     RK_S32 i;
495*437bfbebSnyanmisaka     MPP_RET ret;
496*437bfbebSnyanmisaka     MppCodingType coding;
497*437bfbebSnyanmisaka     MppBufSlots frame_slots = NULL;
498*437bfbebSnyanmisaka     MppBufSlots packet_slots = NULL;
499*437bfbebSnyanmisaka     HalTaskGroup tasks = NULL;
500*437bfbebSnyanmisaka     Parser parser = NULL;
501*437bfbebSnyanmisaka     MppHal hal = NULL;
502*437bfbebSnyanmisaka     Mpp *mpp = (Mpp *)cfg->mpp;
503*437bfbebSnyanmisaka     MppDecImpl *p = NULL;
504*437bfbebSnyanmisaka     MppDecCfgSet *dec_cfg = NULL;
505*437bfbebSnyanmisaka     RK_U32 hal_task_count = 2;
506*437bfbebSnyanmisaka     RK_U32 support_fast_mode = 0;
507*437bfbebSnyanmisaka     SlotHalFbcAdjCfg hal_fbc_adj_cfg;
508*437bfbebSnyanmisaka 
509*437bfbebSnyanmisaka     mpp_env_get_u32("mpp_dec_debug", &mpp_dec_debug, 0);
510*437bfbebSnyanmisaka 
511*437bfbebSnyanmisaka     dec_dbg_func("in\n");
512*437bfbebSnyanmisaka 
513*437bfbebSnyanmisaka     if (NULL == dec || NULL == cfg) {
514*437bfbebSnyanmisaka         mpp_err_f("invalid input dec %p cfg %p\n", dec, cfg);
515*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
516*437bfbebSnyanmisaka     }
517*437bfbebSnyanmisaka 
518*437bfbebSnyanmisaka     *dec = NULL;
519*437bfbebSnyanmisaka 
520*437bfbebSnyanmisaka     p = mpp_calloc(MppDecImpl, 1);
521*437bfbebSnyanmisaka     if (NULL == p) {
522*437bfbebSnyanmisaka         mpp_err_f("failed to malloc context\n");
523*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
524*437bfbebSnyanmisaka     }
525*437bfbebSnyanmisaka 
526*437bfbebSnyanmisaka     p->mpp = mpp;
527*437bfbebSnyanmisaka     mpp_dec_cfg_init(&p->cfg_obj);
528*437bfbebSnyanmisaka     dec_cfg = (MppDecCfgSet *)kmpp_obj_to_entry(p->cfg_obj);
529*437bfbebSnyanmisaka     p->cfg = dec_cfg;
530*437bfbebSnyanmisaka     coding = cfg->coding;
531*437bfbebSnyanmisaka 
532*437bfbebSnyanmisaka     mpp_assert(cfg->cfg);
533*437bfbebSnyanmisaka     kmpp_obj_update(p->cfg_obj, cfg->cfg);
534*437bfbebSnyanmisaka     mpp_dec_update_cfg(p);
535*437bfbebSnyanmisaka 
536*437bfbebSnyanmisaka     p->dec_cb.callBack = mpp_dec_callback_hal_to_parser;
537*437bfbebSnyanmisaka     p->dec_cb.ctx = p;
538*437bfbebSnyanmisaka     p->dec_cb.cmd = DEC_PARSER_CALLBACK;
539*437bfbebSnyanmisaka 
540*437bfbebSnyanmisaka     do {
541*437bfbebSnyanmisaka         ret = mpp_buf_slot_init(&frame_slots);
542*437bfbebSnyanmisaka         if (ret) {
543*437bfbebSnyanmisaka             mpp_err_f("could not init frame buffer slot\n");
544*437bfbebSnyanmisaka             break;
545*437bfbebSnyanmisaka         }
546*437bfbebSnyanmisaka 
547*437bfbebSnyanmisaka         MppCbCtx cb_ctx = {
548*437bfbebSnyanmisaka             mpp_dec_callback_slot,
549*437bfbebSnyanmisaka             (void *)p,
550*437bfbebSnyanmisaka             0,
551*437bfbebSnyanmisaka         };
552*437bfbebSnyanmisaka 
553*437bfbebSnyanmisaka         mpp_buf_slot_set_callback(frame_slots, &cb_ctx);
554*437bfbebSnyanmisaka 
555*437bfbebSnyanmisaka         ret = mpp_buf_slot_init(&packet_slots);
556*437bfbebSnyanmisaka         if (ret) {
557*437bfbebSnyanmisaka             mpp_err_f("could not init packet buffer slot\n");
558*437bfbebSnyanmisaka             break;
559*437bfbebSnyanmisaka         }
560*437bfbebSnyanmisaka 
561*437bfbebSnyanmisaka         MppHalCfg hal_cfg = {
562*437bfbebSnyanmisaka             MPP_CTX_DEC,
563*437bfbebSnyanmisaka             coding,
564*437bfbebSnyanmisaka             frame_slots,
565*437bfbebSnyanmisaka             packet_slots,
566*437bfbebSnyanmisaka             dec_cfg,
567*437bfbebSnyanmisaka             &p->dec_cb,
568*437bfbebSnyanmisaka             NULL,
569*437bfbebSnyanmisaka             NULL,
570*437bfbebSnyanmisaka             0,
571*437bfbebSnyanmisaka             &hal_fbc_adj_cfg,
572*437bfbebSnyanmisaka         };
573*437bfbebSnyanmisaka 
574*437bfbebSnyanmisaka         memset(&hal_fbc_adj_cfg, 0, sizeof(hal_fbc_adj_cfg));
575*437bfbebSnyanmisaka 
576*437bfbebSnyanmisaka         ret = mpp_hal_init(&hal, &hal_cfg);
577*437bfbebSnyanmisaka         if (ret) {
578*437bfbebSnyanmisaka             mpp_err_f("could not init hal\n");
579*437bfbebSnyanmisaka             break;
580*437bfbebSnyanmisaka         }
581*437bfbebSnyanmisaka 
582*437bfbebSnyanmisaka         if (hal_fbc_adj_cfg.func)
583*437bfbebSnyanmisaka             mpp_slots_set_prop(frame_slots, SLOTS_HAL_FBC_ADJ, &hal_fbc_adj_cfg);
584*437bfbebSnyanmisaka 
585*437bfbebSnyanmisaka         support_fast_mode = hal_cfg.support_fast_mode;
586*437bfbebSnyanmisaka 
587*437bfbebSnyanmisaka         if (dec_cfg->base.fast_parse && support_fast_mode) {
588*437bfbebSnyanmisaka             hal_task_count = dec_cfg->status.hal_task_count ?
589*437bfbebSnyanmisaka                              dec_cfg->status.hal_task_count : 3;
590*437bfbebSnyanmisaka         } else {
591*437bfbebSnyanmisaka             dec_cfg->base.fast_parse = 0;
592*437bfbebSnyanmisaka             p->parser_fast_mode = 0;
593*437bfbebSnyanmisaka         }
594*437bfbebSnyanmisaka         dec_cfg->status.hal_support_fast_mode = support_fast_mode;
595*437bfbebSnyanmisaka         dec_cfg->status.hal_task_count = hal_task_count;
596*437bfbebSnyanmisaka 
597*437bfbebSnyanmisaka         ret = hal_task_group_init(&tasks, TASK_BUTT, hal_task_count, sizeof(HalDecTask));
598*437bfbebSnyanmisaka         if (ret) {
599*437bfbebSnyanmisaka             mpp_err_f("hal_task_group_init failed ret %d\n", ret);
600*437bfbebSnyanmisaka             break;
601*437bfbebSnyanmisaka         }
602*437bfbebSnyanmisaka 
603*437bfbebSnyanmisaka         mpp_buf_slot_setup(packet_slots, hal_task_count);
604*437bfbebSnyanmisaka         mpp_slots_set_prop(packet_slots, SLOTS_CODING_TYPE, &coding);
605*437bfbebSnyanmisaka         mpp_slots_set_prop(frame_slots, SLOTS_CODING_TYPE, &coding);
606*437bfbebSnyanmisaka 
607*437bfbebSnyanmisaka         p->hw_info = hal_cfg.hw_info;
608*437bfbebSnyanmisaka         p->dev = hal_cfg.dev;
609*437bfbebSnyanmisaka         /* check fbc cap after hardware info is valid */
610*437bfbebSnyanmisaka         mpp_dec_check_fbc_cap(p);
611*437bfbebSnyanmisaka 
612*437bfbebSnyanmisaka         ParserCfg parser_cfg = {
613*437bfbebSnyanmisaka             coding,
614*437bfbebSnyanmisaka             frame_slots,
615*437bfbebSnyanmisaka             packet_slots,
616*437bfbebSnyanmisaka             dec_cfg,
617*437bfbebSnyanmisaka             p->hw_info,
618*437bfbebSnyanmisaka         };
619*437bfbebSnyanmisaka 
620*437bfbebSnyanmisaka         ret = mpp_parser_init(&parser, &parser_cfg);
621*437bfbebSnyanmisaka         if (ret) {
622*437bfbebSnyanmisaka             mpp_err_f("could not init parser\n");
623*437bfbebSnyanmisaka             break;
624*437bfbebSnyanmisaka         }
625*437bfbebSnyanmisaka 
626*437bfbebSnyanmisaka         ret = hal_info_init(&p->hal_info, MPP_CTX_DEC, coding);
627*437bfbebSnyanmisaka         if (ret) {
628*437bfbebSnyanmisaka             mpp_err_f("could not init hal info\n");
629*437bfbebSnyanmisaka             break;
630*437bfbebSnyanmisaka         }
631*437bfbebSnyanmisaka 
632*437bfbebSnyanmisaka         p->coding = coding;
633*437bfbebSnyanmisaka         p->parser = parser;
634*437bfbebSnyanmisaka         p->hal    = hal;
635*437bfbebSnyanmisaka         p->tasks  = tasks;
636*437bfbebSnyanmisaka         p->frame_slots  = frame_slots;
637*437bfbebSnyanmisaka         p->packet_slots = packet_slots;
638*437bfbebSnyanmisaka 
639*437bfbebSnyanmisaka         p->statistics_en = (mpp_dec_debug & MPP_DEC_DBG_TIMING) ? 1 : 0;
640*437bfbebSnyanmisaka 
641*437bfbebSnyanmisaka         for (i = 0; i < DEC_TIMING_BUTT; i++) {
642*437bfbebSnyanmisaka             p->clocks[i] = mpp_clock_get(timing_str[i]);
643*437bfbebSnyanmisaka             mpp_assert(p->clocks[i]);
644*437bfbebSnyanmisaka             mpp_clock_enable(p->clocks[i], p->statistics_en);
645*437bfbebSnyanmisaka         }
646*437bfbebSnyanmisaka 
647*437bfbebSnyanmisaka         mpp_mutex_cond_init(&p->cmd_lock);
648*437bfbebSnyanmisaka         sem_init(&p->parser_reset, 0, 0);
649*437bfbebSnyanmisaka         sem_init(&p->hal_reset, 0, 0);
650*437bfbebSnyanmisaka         sem_init(&p->cmd_start, 0, 0);
651*437bfbebSnyanmisaka         sem_init(&p->cmd_done, 0, 0);
652*437bfbebSnyanmisaka 
653*437bfbebSnyanmisaka         if (p->cfg->base.disable_thread) {
654*437bfbebSnyanmisaka             DecTask *task = mpp_calloc(DecTask, 1);
655*437bfbebSnyanmisaka 
656*437bfbebSnyanmisaka             mpp_assert(task);
657*437bfbebSnyanmisaka 
658*437bfbebSnyanmisaka             p->task_single = task;
659*437bfbebSnyanmisaka             dec_task_info_init(&task->info);
660*437bfbebSnyanmisaka 
661*437bfbebSnyanmisaka             p->mode = MPP_DEC_MODE_NO_THREAD;
662*437bfbebSnyanmisaka         }
663*437bfbebSnyanmisaka 
664*437bfbebSnyanmisaka         p->api = dec_api[p->mode];
665*437bfbebSnyanmisaka 
666*437bfbebSnyanmisaka         // init timestamp for record and sort pts
667*437bfbebSnyanmisaka         mpp_spinlock_init(&p->ts_lock);
668*437bfbebSnyanmisaka         INIT_LIST_HEAD(&p->ts_link);
669*437bfbebSnyanmisaka         p->ts_pool = mpp_mem_pool_init_f("ts_pool", sizeof(MppPktTs));
670*437bfbebSnyanmisaka         if (!p->ts_pool) {
671*437bfbebSnyanmisaka             mpp_err_f("malloc ts pool failed!\n");
672*437bfbebSnyanmisaka             break;
673*437bfbebSnyanmisaka         }
674*437bfbebSnyanmisaka 
675*437bfbebSnyanmisaka         *dec = p;
676*437bfbebSnyanmisaka         dec_dbg_func("%p out\n", p);
677*437bfbebSnyanmisaka         return MPP_OK;
678*437bfbebSnyanmisaka     } while (0);
679*437bfbebSnyanmisaka 
680*437bfbebSnyanmisaka     mpp_dec_deinit(p);
681*437bfbebSnyanmisaka     return MPP_NOK;
682*437bfbebSnyanmisaka }
683*437bfbebSnyanmisaka 
mpp_dec_deinit(MppDec ctx)684*437bfbebSnyanmisaka MPP_RET mpp_dec_deinit(MppDec ctx)
685*437bfbebSnyanmisaka {
686*437bfbebSnyanmisaka     RK_S32 i;
687*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
688*437bfbebSnyanmisaka 
689*437bfbebSnyanmisaka     dec_dbg_func("%p in\n", dec);
690*437bfbebSnyanmisaka     if (NULL == dec) {
691*437bfbebSnyanmisaka         mpp_err_f("found NULL input\n");
692*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
693*437bfbebSnyanmisaka     }
694*437bfbebSnyanmisaka 
695*437bfbebSnyanmisaka     if (dec->statistics_en) {
696*437bfbebSnyanmisaka         mpp_log("%p work %lu wait %lu\n", dec,
697*437bfbebSnyanmisaka                 dec->parser_work_count, dec->parser_wait_count);
698*437bfbebSnyanmisaka 
699*437bfbebSnyanmisaka         for (i = 0; i < DEC_TIMING_BUTT; i++) {
700*437bfbebSnyanmisaka             MppClock timer = dec->clocks[i];
701*437bfbebSnyanmisaka             RK_S32 base = (i < DEC_HAL_TOTAL) ? (DEC_PRS_TOTAL) : (DEC_HAL_TOTAL);
702*437bfbebSnyanmisaka             RK_S64 time = mpp_clock_get_sum(timer);
703*437bfbebSnyanmisaka             RK_S64 total = mpp_clock_get_sum(dec->clocks[base]);
704*437bfbebSnyanmisaka 
705*437bfbebSnyanmisaka             if (!time || !total)
706*437bfbebSnyanmisaka                 continue;
707*437bfbebSnyanmisaka 
708*437bfbebSnyanmisaka             mpp_log("%p %s - %6.2f %-12lld avg %-12lld\n", dec,
709*437bfbebSnyanmisaka                     mpp_clock_get_name(timer), time * 100.0 / total, time,
710*437bfbebSnyanmisaka                     time / mpp_clock_get_count(timer));
711*437bfbebSnyanmisaka         }
712*437bfbebSnyanmisaka     }
713*437bfbebSnyanmisaka 
714*437bfbebSnyanmisaka     for (i = 0; i < DEC_TIMING_BUTT; i++) {
715*437bfbebSnyanmisaka         mpp_clock_put(dec->clocks[i]);
716*437bfbebSnyanmisaka         dec->clocks[i] = NULL;
717*437bfbebSnyanmisaka     }
718*437bfbebSnyanmisaka 
719*437bfbebSnyanmisaka     if (dec->hal_info) {
720*437bfbebSnyanmisaka         hal_info_deinit(dec->hal_info);
721*437bfbebSnyanmisaka         dec->hal_info = NULL;
722*437bfbebSnyanmisaka     }
723*437bfbebSnyanmisaka 
724*437bfbebSnyanmisaka     if (dec->parser) {
725*437bfbebSnyanmisaka         mpp_parser_deinit(dec->parser);
726*437bfbebSnyanmisaka         dec->parser = NULL;
727*437bfbebSnyanmisaka     }
728*437bfbebSnyanmisaka 
729*437bfbebSnyanmisaka     if (dec->tasks) {
730*437bfbebSnyanmisaka         hal_task_group_deinit(dec->tasks);
731*437bfbebSnyanmisaka         dec->tasks = NULL;
732*437bfbebSnyanmisaka     }
733*437bfbebSnyanmisaka 
734*437bfbebSnyanmisaka     if (dec->hal) {
735*437bfbebSnyanmisaka         mpp_hal_deinit(dec->hal);
736*437bfbebSnyanmisaka         dec->hal = NULL;
737*437bfbebSnyanmisaka     }
738*437bfbebSnyanmisaka 
739*437bfbebSnyanmisaka     if (dec->vproc) {
740*437bfbebSnyanmisaka         dec_vproc_deinit(dec->vproc);
741*437bfbebSnyanmisaka         dec->vproc = NULL;
742*437bfbebSnyanmisaka     }
743*437bfbebSnyanmisaka 
744*437bfbebSnyanmisaka     if (dec->frame_slots) {
745*437bfbebSnyanmisaka         mpp_buf_slot_deinit(dec->frame_slots);
746*437bfbebSnyanmisaka         dec->frame_slots = NULL;
747*437bfbebSnyanmisaka     }
748*437bfbebSnyanmisaka 
749*437bfbebSnyanmisaka     if (dec->packet_slots) {
750*437bfbebSnyanmisaka         mpp_buf_slot_deinit(dec->packet_slots);
751*437bfbebSnyanmisaka         dec->packet_slots = NULL;
752*437bfbebSnyanmisaka     }
753*437bfbebSnyanmisaka 
754*437bfbebSnyanmisaka     mpp_mutex_cond_destroy(&dec->cmd_lock);
755*437bfbebSnyanmisaka 
756*437bfbebSnyanmisaka     sem_destroy(&dec->parser_reset);
757*437bfbebSnyanmisaka     sem_destroy(&dec->hal_reset);
758*437bfbebSnyanmisaka     sem_destroy(&dec->cmd_start);
759*437bfbebSnyanmisaka     sem_destroy(&dec->cmd_done);
760*437bfbebSnyanmisaka 
761*437bfbebSnyanmisaka     if (dec->ts_pool) {
762*437bfbebSnyanmisaka         mpp_mem_pool_deinit_f(dec->ts_pool);
763*437bfbebSnyanmisaka         dec->ts_pool = NULL;
764*437bfbebSnyanmisaka     }
765*437bfbebSnyanmisaka 
766*437bfbebSnyanmisaka     if (dec->cfg_obj) {
767*437bfbebSnyanmisaka         mpp_dec_cfg_deinit(dec->cfg_obj);
768*437bfbebSnyanmisaka         dec->cfg_obj = NULL;
769*437bfbebSnyanmisaka     }
770*437bfbebSnyanmisaka     dec->cfg = NULL;
771*437bfbebSnyanmisaka 
772*437bfbebSnyanmisaka     MPP_FREE(dec->task_single);
773*437bfbebSnyanmisaka     mpp_free(dec);
774*437bfbebSnyanmisaka     dec_dbg_func("%p out\n", dec);
775*437bfbebSnyanmisaka     return MPP_OK;
776*437bfbebSnyanmisaka }
777*437bfbebSnyanmisaka 
mpp_dec_start(MppDec ctx)778*437bfbebSnyanmisaka MPP_RET mpp_dec_start(MppDec ctx)
779*437bfbebSnyanmisaka {
780*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
781*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
782*437bfbebSnyanmisaka 
783*437bfbebSnyanmisaka     dec_dbg_func("%p in\n", dec);
784*437bfbebSnyanmisaka 
785*437bfbebSnyanmisaka     if (dec->api && dec->api->start)
786*437bfbebSnyanmisaka         ret = dec->api->start(dec);
787*437bfbebSnyanmisaka 
788*437bfbebSnyanmisaka     dec_dbg_func("%p out ret %d\n", dec, ret);
789*437bfbebSnyanmisaka     return ret;
790*437bfbebSnyanmisaka }
791*437bfbebSnyanmisaka 
mpp_dec_stop(MppDec ctx)792*437bfbebSnyanmisaka MPP_RET mpp_dec_stop(MppDec ctx)
793*437bfbebSnyanmisaka {
794*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
795*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
796*437bfbebSnyanmisaka 
797*437bfbebSnyanmisaka     dec_dbg_func("%p in\n", dec);
798*437bfbebSnyanmisaka 
799*437bfbebSnyanmisaka     if (dec->thread_parser)
800*437bfbebSnyanmisaka         mpp_thread_stop(dec->thread_parser);
801*437bfbebSnyanmisaka 
802*437bfbebSnyanmisaka     if (dec->thread_hal)
803*437bfbebSnyanmisaka         mpp_thread_stop(dec->thread_hal);
804*437bfbebSnyanmisaka 
805*437bfbebSnyanmisaka     if (dec->thread_parser) {
806*437bfbebSnyanmisaka         mpp_thread_destroy(dec->thread_parser);
807*437bfbebSnyanmisaka         dec->thread_parser = NULL;
808*437bfbebSnyanmisaka     }
809*437bfbebSnyanmisaka 
810*437bfbebSnyanmisaka     if (dec->thread_hal) {
811*437bfbebSnyanmisaka         mpp_thread_destroy(dec->thread_hal);
812*437bfbebSnyanmisaka         dec->thread_hal = NULL;
813*437bfbebSnyanmisaka     }
814*437bfbebSnyanmisaka 
815*437bfbebSnyanmisaka     dec_dbg_func("%p out\n", dec);
816*437bfbebSnyanmisaka     return ret;
817*437bfbebSnyanmisaka }
818*437bfbebSnyanmisaka 
mpp_dec_reset(MppDec ctx)819*437bfbebSnyanmisaka MPP_RET mpp_dec_reset(MppDec ctx)
820*437bfbebSnyanmisaka {
821*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
822*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
823*437bfbebSnyanmisaka 
824*437bfbebSnyanmisaka     if (NULL == dec) {
825*437bfbebSnyanmisaka         mpp_err_f("found NULL input dec %p\n", dec);
826*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
827*437bfbebSnyanmisaka     }
828*437bfbebSnyanmisaka 
829*437bfbebSnyanmisaka     dec_dbg_func("%p in\n", dec);
830*437bfbebSnyanmisaka 
831*437bfbebSnyanmisaka     if (dec->api && dec->api->reset)
832*437bfbebSnyanmisaka         ret = dec->api->reset(dec);
833*437bfbebSnyanmisaka 
834*437bfbebSnyanmisaka     dec_dbg_func("%p out ret %d\n", dec, ret);
835*437bfbebSnyanmisaka 
836*437bfbebSnyanmisaka     return ret;
837*437bfbebSnyanmisaka }
838*437bfbebSnyanmisaka 
mpp_dec_flush(MppDec ctx)839*437bfbebSnyanmisaka MPP_RET mpp_dec_flush(MppDec ctx)
840*437bfbebSnyanmisaka {
841*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
842*437bfbebSnyanmisaka 
843*437bfbebSnyanmisaka     dec_dbg_func("%p in\n", dec);
844*437bfbebSnyanmisaka     if (NULL == dec) {
845*437bfbebSnyanmisaka         mpp_err_f("found NULL input dec %p\n", dec);
846*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
847*437bfbebSnyanmisaka     }
848*437bfbebSnyanmisaka 
849*437bfbebSnyanmisaka     mpp_parser_flush(dec->parser);
850*437bfbebSnyanmisaka     mpp_hal_flush(dec->hal);
851*437bfbebSnyanmisaka 
852*437bfbebSnyanmisaka     dec_dbg_func("%p out\n", dec);
853*437bfbebSnyanmisaka     return MPP_OK;
854*437bfbebSnyanmisaka }
855*437bfbebSnyanmisaka 
mpp_dec_notify(MppDec ctx,RK_U32 flag)856*437bfbebSnyanmisaka MPP_RET mpp_dec_notify(MppDec ctx, RK_U32 flag)
857*437bfbebSnyanmisaka {
858*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
859*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
860*437bfbebSnyanmisaka 
861*437bfbebSnyanmisaka     dec_dbg_func("%p in flag %08x\n", dec, flag);
862*437bfbebSnyanmisaka 
863*437bfbebSnyanmisaka     if (dec->vproc && (flag & MPP_DEC_NOTIFY_BUFFER_MATCH))
864*437bfbebSnyanmisaka         dec_vproc_signal(dec->vproc);
865*437bfbebSnyanmisaka 
866*437bfbebSnyanmisaka     if (dec->api && dec->api->notify)
867*437bfbebSnyanmisaka         ret = dec->api->notify(dec, flag);
868*437bfbebSnyanmisaka 
869*437bfbebSnyanmisaka     dec_dbg_func("%p out ret %d\n", dec, ret);
870*437bfbebSnyanmisaka 
871*437bfbebSnyanmisaka     return ret;
872*437bfbebSnyanmisaka }
873*437bfbebSnyanmisaka 
mpp_dec_callback(MppDec ctx,MppDecEvent event,void * arg)874*437bfbebSnyanmisaka MPP_RET mpp_dec_callback(MppDec ctx, MppDecEvent event, void *arg)
875*437bfbebSnyanmisaka {
876*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
877*437bfbebSnyanmisaka     MppDecCbCfg *cb = &dec->cfg->cb;
878*437bfbebSnyanmisaka     Mpp *mpp = (Mpp *)dec->mpp;
879*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
880*437bfbebSnyanmisaka 
881*437bfbebSnyanmisaka     switch (event) {
882*437bfbebSnyanmisaka     case MPP_DEC_EVENT_ON_PKT_RELEASE : {
883*437bfbebSnyanmisaka         if (cb->pkt_rdy_cb)
884*437bfbebSnyanmisaka             ret = cb->pkt_rdy_cb(cb->pkt_rdy_ctx, mpp->mCtx, cb->pkt_rdy_cmd, arg);
885*437bfbebSnyanmisaka     } break;
886*437bfbebSnyanmisaka     case MPP_DEC_EVENT_ON_FRM_READY : {
887*437bfbebSnyanmisaka         if (cb->frm_rdy_cb)
888*437bfbebSnyanmisaka             ret = cb->frm_rdy_cb(cb->frm_rdy_ctx, mpp->mCtx, cb->frm_rdy_cmd, arg);
889*437bfbebSnyanmisaka     } break;
890*437bfbebSnyanmisaka     default : {
891*437bfbebSnyanmisaka     } break;
892*437bfbebSnyanmisaka     }
893*437bfbebSnyanmisaka 
894*437bfbebSnyanmisaka     return ret;
895*437bfbebSnyanmisaka }
896*437bfbebSnyanmisaka 
mpp_dec_control(MppDec ctx,MpiCmd cmd,void * param)897*437bfbebSnyanmisaka MPP_RET mpp_dec_control(MppDec ctx, MpiCmd cmd, void *param)
898*437bfbebSnyanmisaka {
899*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
900*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
901*437bfbebSnyanmisaka 
902*437bfbebSnyanmisaka     if (NULL == dec) {
903*437bfbebSnyanmisaka         mpp_err_f("found NULL input dec %p\n", dec);
904*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
905*437bfbebSnyanmisaka     }
906*437bfbebSnyanmisaka 
907*437bfbebSnyanmisaka     dec_dbg_func("%p in %08x %p\n", dec, cmd, param);
908*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p control cmd %08x param %p start\n", dec, cmd, param);
909*437bfbebSnyanmisaka 
910*437bfbebSnyanmisaka     if (dec->api && dec->api->control)
911*437bfbebSnyanmisaka         ret = dec->api->control(dec, cmd, param);
912*437bfbebSnyanmisaka 
913*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p control cmd %08x param %p ret %d\n", dec, cmd, param, ret);
914*437bfbebSnyanmisaka     dec_dbg_func("%p out ret %d\n", dec, ret);
915*437bfbebSnyanmisaka 
916*437bfbebSnyanmisaka     return ret;
917*437bfbebSnyanmisaka }
918*437bfbebSnyanmisaka 
mpp_dec_set_cfg_by_cmd(MppDecCfg cfg,MpiCmd cmd,void * param)919*437bfbebSnyanmisaka MPP_RET mpp_dec_set_cfg_by_cmd(MppDecCfg cfg, MpiCmd cmd, void *param)
920*437bfbebSnyanmisaka {
921*437bfbebSnyanmisaka     MppDecCfgSet *dst = (MppDecCfgSet *)kmpp_obj_to_entry(cfg);
922*437bfbebSnyanmisaka     MppDecBaseCfg *base = &dst->base;
923*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
924*437bfbebSnyanmisaka 
925*437bfbebSnyanmisaka     switch (cmd) {
926*437bfbebSnyanmisaka     case MPP_DEC_SET_PRESENT_TIME_ORDER : {
927*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:sort_pts", (param) ? (*((RK_U32 *)param)) : (1));
928*437bfbebSnyanmisaka         dec_dbg_func("sort time order %d\n", base->sort_pts);
929*437bfbebSnyanmisaka     } break;
930*437bfbebSnyanmisaka     case MPP_DEC_SET_PARSER_SPLIT_MODE : {
931*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:split_parse", (param) ? (*((RK_U32 *)param)) : (0));
932*437bfbebSnyanmisaka         dec_dbg_func("split parse mode %d\n", base->split_parse);
933*437bfbebSnyanmisaka     } break;
934*437bfbebSnyanmisaka     case MPP_DEC_SET_PARSER_FAST_MODE : {
935*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:fast_parse", (param) ? (*((RK_U32 *)param)) : (0));
936*437bfbebSnyanmisaka         dec_dbg_func("fast parse mode %d\n", base->fast_parse);
937*437bfbebSnyanmisaka     } break;
938*437bfbebSnyanmisaka     case MPP_DEC_SET_OUTPUT_FORMAT : {
939*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:out_fmt", (param) ? (*((RK_U32 *)param)) : (RK_U32)(MPP_FMT_YUV420SP));
940*437bfbebSnyanmisaka         dec_dbg_func("fast out_fmt %d\n", base->out_fmt);
941*437bfbebSnyanmisaka     } break;
942*437bfbebSnyanmisaka     case MPP_DEC_SET_DISABLE_ERROR: {
943*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:disable_error", (param) ? (*((RK_U32 *)param)) : (1));
944*437bfbebSnyanmisaka         dec_dbg_func("disable error %d\n", base->disable_error);
945*437bfbebSnyanmisaka     } break;
946*437bfbebSnyanmisaka     case MPP_DEC_SET_DIS_ERR_CLR_MARK: {
947*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:dis_err_clr_mark", (param) ? (*((RK_U32 *)param)) : (1));
948*437bfbebSnyanmisaka         dec_dbg_func("disable error mark %x\n", base->dis_err_clr_mark);
949*437bfbebSnyanmisaka     } break;
950*437bfbebSnyanmisaka     case MPP_DEC_SET_IMMEDIATE_OUT : {
951*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:fast_out", (param) ? (*((RK_U32 *)param)) : (0));
952*437bfbebSnyanmisaka         dec_dbg_func("fast output mode %d\n", base->fast_out);
953*437bfbebSnyanmisaka     } break;
954*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_DEINTERLACE: {
955*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:enable_vproc", (param) ? (*((RK_U32 *)param)) : (MPP_VPROC_MODE_DEINTELACE));
956*437bfbebSnyanmisaka         dec_dbg_func("enable dec_vproc %x\n", base->enable_vproc);
957*437bfbebSnyanmisaka     } break;
958*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_FAST_PLAY : {
959*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:enable_fast_play", (param) ? (*((RK_U32 *)param)) : (0));
960*437bfbebSnyanmisaka         dec_dbg_func("disable idr immediately output %d\n", base->enable_fast_play);
961*437bfbebSnyanmisaka     } break;
962*437bfbebSnyanmisaka     case MPP_DEC_SET_ENABLE_MVC : {
963*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:enable_mvc", (param) ? (*((RK_U32 *)param)) : (0));
964*437bfbebSnyanmisaka         dec_dbg_func("enable MVC decoder %d\n", base->enable_mvc);
965*437bfbebSnyanmisaka     } break;
966*437bfbebSnyanmisaka     case MPP_DEC_SET_DISABLE_DPB_CHECK : {
967*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:disable_dpb_chk", (param) ? (*((RK_U32 *)param)) : (0));
968*437bfbebSnyanmisaka         dec_dbg_func("disable dpb discontinuous check %d\n", base->disable_dpb_chk);
969*437bfbebSnyanmisaka     } break;
970*437bfbebSnyanmisaka     case MPP_DEC_SET_CODEC_MODE : {
971*437bfbebSnyanmisaka         ret = mpp_dec_cfg_set_u32(cfg, "base:codec_mode", (param) ? (*((RK_U32 *)param)) : (0));
972*437bfbebSnyanmisaka         dec_dbg_func("force use codec device %d\n", base->codec_mode);
973*437bfbebSnyanmisaka     } break;
974*437bfbebSnyanmisaka     default : {
975*437bfbebSnyanmisaka         mpp_err_f("unsupported cfg update cmd %x\n", cmd);
976*437bfbebSnyanmisaka         ret = MPP_NOK;
977*437bfbebSnyanmisaka     } break;
978*437bfbebSnyanmisaka     }
979*437bfbebSnyanmisaka 
980*437bfbebSnyanmisaka     return ret;
981*437bfbebSnyanmisaka }
982