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