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