xref: /rockchip-linux_mpp/mpp/codec/mpp_dec_no_thread.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define  MODULE_TAG "mpp_dec_nt"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka 
10*437bfbebSnyanmisaka #include "mpp_buffer_impl.h"
11*437bfbebSnyanmisaka 
12*437bfbebSnyanmisaka #include "mpp_dec_debug.h"
13*437bfbebSnyanmisaka #include "mpp_dec_vproc.h"
14*437bfbebSnyanmisaka #include "mpp_dec_no_thread.h"
15*437bfbebSnyanmisaka #include "rk_hdr_meta_com.h"
16*437bfbebSnyanmisaka 
mpp_dec_decode(MppDec ctx,MppPacket packet)17*437bfbebSnyanmisaka MPP_RET mpp_dec_decode(MppDec ctx, MppPacket packet)
18*437bfbebSnyanmisaka {
19*437bfbebSnyanmisaka     MppDecImpl *dec = (MppDecImpl *)ctx;
20*437bfbebSnyanmisaka     Mpp *mpp = (Mpp *)dec->mpp;
21*437bfbebSnyanmisaka     DecTask *task = (DecTask *)dec->task_single;
22*437bfbebSnyanmisaka     DecTaskStatus *status = &task->status;
23*437bfbebSnyanmisaka     MppBufSlots frame_slots = dec->frame_slots;
24*437bfbebSnyanmisaka     MppBufSlots packet_slots = dec->packet_slots;
25*437bfbebSnyanmisaka     HalDecTask  *task_dec = &task->info.dec;
26*437bfbebSnyanmisaka     MppMutexCond *cmd_lock = &dec->cmd_lock;
27*437bfbebSnyanmisaka     MppPacket input = dec->mpp_pkt_in;
28*437bfbebSnyanmisaka     size_t stream_size = 0;
29*437bfbebSnyanmisaka     RK_S32 output = 0;
30*437bfbebSnyanmisaka     RK_U32 i;
31*437bfbebSnyanmisaka 
32*437bfbebSnyanmisaka     mpp_mutex_cond_lock(cmd_lock);
33*437bfbebSnyanmisaka 
34*437bfbebSnyanmisaka     /*
35*437bfbebSnyanmisaka      * 1. task no ready and last packet is done try process new input packet
36*437bfbebSnyanmisaka      */
37*437bfbebSnyanmisaka     if (input == NULL && !status->curr_task_rdy) {
38*437bfbebSnyanmisaka         input = packet;
39*437bfbebSnyanmisaka 
40*437bfbebSnyanmisaka         if (input == NULL) {
41*437bfbebSnyanmisaka             mpp_mutex_cond_unlock(cmd_lock);
42*437bfbebSnyanmisaka             return MPP_OK;
43*437bfbebSnyanmisaka         }
44*437bfbebSnyanmisaka     }
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     if (input)
47*437bfbebSnyanmisaka         dec_dbg_detail("detail: %p input pkt %p len %d task ready %d\n", dec,
48*437bfbebSnyanmisaka                        input, mpp_packet_get_length(input), status->curr_task_rdy);
49*437bfbebSnyanmisaka     else
50*437bfbebSnyanmisaka         dec_dbg_detail("detail: %p input pkt NULL task ready %d\n", dec,
51*437bfbebSnyanmisaka                        input, status->curr_task_rdy);
52*437bfbebSnyanmisaka 
53*437bfbebSnyanmisaka     /*
54*437bfbebSnyanmisaka      * 2. prepare stream to generate task
55*437bfbebSnyanmisaka      */
56*437bfbebSnyanmisaka     if (!status->curr_task_rdy) {
57*437bfbebSnyanmisaka         mpp_parser_prepare(dec->parser, input, task_dec);
58*437bfbebSnyanmisaka 
59*437bfbebSnyanmisaka         dec_dbg_detail("detail: %p prepare pkt %p get task %d\n", dec,
60*437bfbebSnyanmisaka                        input, task_dec->valid);
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka         /* record remaining packet */
63*437bfbebSnyanmisaka         if (task_dec->valid) {
64*437bfbebSnyanmisaka             status->curr_task_rdy = 1;
65*437bfbebSnyanmisaka             dec->mpp_pkt_in = input;
66*437bfbebSnyanmisaka         }
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka         if (input && !mpp_packet_get_length(input))
69*437bfbebSnyanmisaka             dec->mpp_pkt_in = NULL;
70*437bfbebSnyanmisaka     }
71*437bfbebSnyanmisaka 
72*437bfbebSnyanmisaka     /*
73*437bfbebSnyanmisaka      * 3. when task not ready check eos empty task
74*437bfbebSnyanmisaka      */
75*437bfbebSnyanmisaka     if (!status->curr_task_rdy) {
76*437bfbebSnyanmisaka         if (task_dec->flags.eos) {
77*437bfbebSnyanmisaka             mpp_dec_flush(dec);
78*437bfbebSnyanmisaka             output += mpp_dec_push_display(mpp, task_dec->flags);
79*437bfbebSnyanmisaka             /*
80*437bfbebSnyanmisaka             * Use -1 as invalid buffer slot index.
81*437bfbebSnyanmisaka             * Reason: the last task maybe is a empty task with eos flag
82*437bfbebSnyanmisaka             * only but this task may go through vproc process also. We need
83*437bfbebSnyanmisaka             * create a buffer slot index for it.
84*437bfbebSnyanmisaka             */
85*437bfbebSnyanmisaka             mpp_dec_put_frame(mpp, -1, task_dec->flags);
86*437bfbebSnyanmisaka             output++;
87*437bfbebSnyanmisaka         }
88*437bfbebSnyanmisaka         mpp_mutex_cond_unlock(cmd_lock);
89*437bfbebSnyanmisaka         return (MPP_RET)output;
90*437bfbebSnyanmisaka     }
91*437bfbebSnyanmisaka 
92*437bfbebSnyanmisaka     // NOTE: packet in task should be ready now
93*437bfbebSnyanmisaka     mpp_assert(task_dec->input_packet);
94*437bfbebSnyanmisaka 
95*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p hw pkt %p process start\n", dec, task_dec->input_packet);
96*437bfbebSnyanmisaka 
97*437bfbebSnyanmisaka     /*
98*437bfbebSnyanmisaka      * 4. look for a unused packet slot index
99*437bfbebSnyanmisaka      * 5. malloc hardware buffer for the packet slot index
100*437bfbebSnyanmisaka      */
101*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p hal_pkt_buf_in %p\n", dec, task->hal_pkt_buf_in);
102*437bfbebSnyanmisaka     if (!task->hal_pkt_buf_in) {
103*437bfbebSnyanmisaka         MppBuffer hal_buf_in = mpp_packet_get_buffer(task_dec->input_packet);
104*437bfbebSnyanmisaka         RK_S32 slot_pkt = -1;
105*437bfbebSnyanmisaka 
106*437bfbebSnyanmisaka         mpp_buf_slot_get_unused(packet_slots, &slot_pkt);
107*437bfbebSnyanmisaka         mpp_assert(slot_pkt >= 0);
108*437bfbebSnyanmisaka         stream_size = mpp_packet_get_size(task_dec->input_packet);
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka         if (NULL == hal_buf_in) {
111*437bfbebSnyanmisaka             mpp_buf_slot_get_prop(packet_slots, slot_pkt, SLOT_BUFFER, &hal_buf_in);
112*437bfbebSnyanmisaka         } else {
113*437bfbebSnyanmisaka             /* use external buffer and set to slot */
114*437bfbebSnyanmisaka             task_dec->input_no_copy = 1;
115*437bfbebSnyanmisaka 
116*437bfbebSnyanmisaka             mpp_buf_slot_set_prop(packet_slots, slot_pkt, SLOT_BUFFER, hal_buf_in);
117*437bfbebSnyanmisaka             mpp_buffer_attach_dev(hal_buf_in, dec->dev);
118*437bfbebSnyanmisaka         }
119*437bfbebSnyanmisaka 
120*437bfbebSnyanmisaka         if (NULL == hal_buf_in) {
121*437bfbebSnyanmisaka             mpp_buffer_get(mpp->mPacketGroup, &hal_buf_in, stream_size);
122*437bfbebSnyanmisaka             if (hal_buf_in) {
123*437bfbebSnyanmisaka                 mpp_buf_slot_set_prop(packet_slots, slot_pkt, SLOT_BUFFER, hal_buf_in);
124*437bfbebSnyanmisaka                 mpp_buffer_attach_dev(hal_buf_in, dec->dev);
125*437bfbebSnyanmisaka                 mpp_buffer_put(hal_buf_in);
126*437bfbebSnyanmisaka             }
127*437bfbebSnyanmisaka         } else {
128*437bfbebSnyanmisaka             MppBufferImpl *buf = (MppBufferImpl *)hal_buf_in;
129*437bfbebSnyanmisaka             mpp_assert(buf->info.size >= stream_size);
130*437bfbebSnyanmisaka         }
131*437bfbebSnyanmisaka 
132*437bfbebSnyanmisaka         dec_dbg_detail("detail: %p hw pkt %p get buf %p slot %d\n", dec,
133*437bfbebSnyanmisaka                        task_dec->input_packet, hal_buf_in, slot_pkt);
134*437bfbebSnyanmisaka 
135*437bfbebSnyanmisaka         task_dec->input = slot_pkt;
136*437bfbebSnyanmisaka         task->hal_pkt_buf_in = hal_buf_in;
137*437bfbebSnyanmisaka     }
138*437bfbebSnyanmisaka 
139*437bfbebSnyanmisaka     /*
140*437bfbebSnyanmisaka      * 6. copy data to hardware buffer
141*437bfbebSnyanmisaka      */
142*437bfbebSnyanmisaka     if (!status->dec_pkt_copy_rdy) {
143*437bfbebSnyanmisaka         if (!task_dec->input_no_copy) {
144*437bfbebSnyanmisaka             void *src = mpp_packet_get_data(task_dec->input_packet);
145*437bfbebSnyanmisaka             size_t length = mpp_packet_get_length(task_dec->input_packet);
146*437bfbebSnyanmisaka 
147*437bfbebSnyanmisaka             mpp_assert(task->hal_pkt_buf_in);
148*437bfbebSnyanmisaka             mpp_assert(task_dec->input_packet);
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka             dec_dbg_detail("detail: %p copy to hw length %d\n", dec, length);
151*437bfbebSnyanmisaka             mpp_buffer_write(task->hal_pkt_buf_in, 0, src, length);
152*437bfbebSnyanmisaka             mpp_buffer_sync_partial_end(task->hal_pkt_buf_in, 0, length);
153*437bfbebSnyanmisaka 
154*437bfbebSnyanmisaka         }
155*437bfbebSnyanmisaka 
156*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY);
157*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT);
158*437bfbebSnyanmisaka 
159*437bfbebSnyanmisaka         status->dec_pkt_copy_rdy = 1;
160*437bfbebSnyanmisaka     }
161*437bfbebSnyanmisaka 
162*437bfbebSnyanmisaka     /*
163*437bfbebSnyanmisaka      * 7. parse the stream in input buffer and generate task
164*437bfbebSnyanmisaka      */
165*437bfbebSnyanmisaka     if (!status->task_parsed_rdy) {
166*437bfbebSnyanmisaka         mpp_clock_start(dec->clocks[DEC_PRS_PARSE]);
167*437bfbebSnyanmisaka         mpp_parser_parse(dec->parser, task_dec);
168*437bfbebSnyanmisaka         mpp_clock_pause(dec->clocks[DEC_PRS_PARSE]);
169*437bfbebSnyanmisaka         status->task_parsed_rdy = 1;
170*437bfbebSnyanmisaka 
171*437bfbebSnyanmisaka         /* add extra output slot operaton for jpeg decoding */
172*437bfbebSnyanmisaka         if (task_dec->input_no_copy && task_dec->output >= 0) {
173*437bfbebSnyanmisaka             mpp_buf_slot_set_flag(frame_slots, task_dec->output, SLOT_QUEUE_USE);
174*437bfbebSnyanmisaka             mpp_buf_slot_enqueue(frame_slots, task_dec->output, QUEUE_DISPLAY);
175*437bfbebSnyanmisaka         }
176*437bfbebSnyanmisaka     }
177*437bfbebSnyanmisaka 
178*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p parse output slot %d valid %d\n", dec,
179*437bfbebSnyanmisaka                    task_dec->output, task_dec->valid);
180*437bfbebSnyanmisaka     /*
181*437bfbebSnyanmisaka      * 8. check task generate failure
182*437bfbebSnyanmisaka      */
183*437bfbebSnyanmisaka     if (task_dec->output < 0 || !task_dec->valid) {
184*437bfbebSnyanmisaka         /*
185*437bfbebSnyanmisaka          * We may meet an eos in parser step and there will be no anymore vaild
186*437bfbebSnyanmisaka          * task generated. So here we try push eos task to hal, hal will push
187*437bfbebSnyanmisaka          * all frame(s) to display, a frame of them with a eos flag will be
188*437bfbebSnyanmisaka          * used to inform that all frame have decoded
189*437bfbebSnyanmisaka          */
190*437bfbebSnyanmisaka         if (task_dec->flags.eos) {
191*437bfbebSnyanmisaka             mpp_dec_flush(dec);
192*437bfbebSnyanmisaka             output += mpp_dec_push_display(mpp, task_dec->flags);
193*437bfbebSnyanmisaka         }
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka         if (status->dec_pkt_copy_rdy) {
196*437bfbebSnyanmisaka             mpp_buf_slot_clr_flag(packet_slots, task_dec->input,  SLOT_HAL_INPUT);
197*437bfbebSnyanmisaka             status->dec_pkt_copy_rdy = 0;
198*437bfbebSnyanmisaka         }
199*437bfbebSnyanmisaka         status->curr_task_rdy  = 0;
200*437bfbebSnyanmisaka         status->task_parsed_rdy = 0;
201*437bfbebSnyanmisaka         dec_task_info_init(&task->info);
202*437bfbebSnyanmisaka         task->hal_pkt_buf_in  = NULL;
203*437bfbebSnyanmisaka 
204*437bfbebSnyanmisaka         dec_dbg_detail("detail: %p parse return no task with output %d\n", dec, output);
205*437bfbebSnyanmisaka         mpp_mutex_cond_unlock(cmd_lock);
206*437bfbebSnyanmisaka         return (MPP_RET)output;
207*437bfbebSnyanmisaka     }
208*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p check output index pass\n", dec);
209*437bfbebSnyanmisaka 
210*437bfbebSnyanmisaka     /*
211*437bfbebSnyanmisaka      * 9. parse local task and slot to check whether new buffer or info change is needed.
212*437bfbebSnyanmisaka      *
213*437bfbebSnyanmisaka      * detect info change from frame slot
214*437bfbebSnyanmisaka      */
215*437bfbebSnyanmisaka     if (mpp_buf_slot_is_changed(frame_slots)) {
216*437bfbebSnyanmisaka         if (!status->info_task_gen_rdy) {
217*437bfbebSnyanmisaka             RK_U32 eos = task_dec->flags.eos;
218*437bfbebSnyanmisaka             // NOTE: info change should not go with eos flag
219*437bfbebSnyanmisaka             task_dec->flags.info_change = 1;
220*437bfbebSnyanmisaka             task_dec->flags.eos = 0;
221*437bfbebSnyanmisaka             mpp_dec_flush(dec);
222*437bfbebSnyanmisaka             output += mpp_dec_push_display(mpp, task_dec->flags);
223*437bfbebSnyanmisaka             mpp_dec_put_frame(mpp, task_dec->output, task_dec->flags);
224*437bfbebSnyanmisaka             output++;
225*437bfbebSnyanmisaka             task_dec->flags.eos = eos;
226*437bfbebSnyanmisaka             status->info_task_gen_rdy = 1;
227*437bfbebSnyanmisaka             dec_dbg_detail("detail: %p info change found return frame %d\n",
228*437bfbebSnyanmisaka                            dec, output);
229*437bfbebSnyanmisaka             mpp_mutex_cond_unlock(cmd_lock);
230*437bfbebSnyanmisaka             return (MPP_RET)output;
231*437bfbebSnyanmisaka         }
232*437bfbebSnyanmisaka         dec->info_updated = 0;
233*437bfbebSnyanmisaka     }
234*437bfbebSnyanmisaka 
235*437bfbebSnyanmisaka     task->wait.info_change = mpp_buf_slot_is_changed(frame_slots);
236*437bfbebSnyanmisaka     if (task->wait.info_change) {
237*437bfbebSnyanmisaka         mpp_mutex_cond_unlock(cmd_lock);
238*437bfbebSnyanmisaka         return MPP_OK;
239*437bfbebSnyanmisaka     } else {
240*437bfbebSnyanmisaka         status->info_task_gen_rdy = 0;
241*437bfbebSnyanmisaka         task_dec->flags.info_change = 0;
242*437bfbebSnyanmisaka     }
243*437bfbebSnyanmisaka 
244*437bfbebSnyanmisaka     /* 10. whether the frame buffer group is internal or external */
245*437bfbebSnyanmisaka     if (NULL == mpp->mFrameGroup) {
246*437bfbebSnyanmisaka         mpp_log("mpp_dec use internal frame buffer group\n");
247*437bfbebSnyanmisaka         mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION);
248*437bfbebSnyanmisaka     }
249*437bfbebSnyanmisaka 
250*437bfbebSnyanmisaka     /* 10.1 look for a unused hardware buffer for output */
251*437bfbebSnyanmisaka     if (mpp->mFrameGroup) {
252*437bfbebSnyanmisaka         RK_S32 unused = mpp_buffer_group_unused(mpp->mFrameGroup);
253*437bfbebSnyanmisaka 
254*437bfbebSnyanmisaka         // NOTE: When dec post-process is enabled reserve 2 buffer for it.
255*437bfbebSnyanmisaka         task->wait.dec_pic_unusd = (dec->vproc) ? (unused < 3) : (unused < 1);
256*437bfbebSnyanmisaka         if (task->wait.dec_pic_unusd) {
257*437bfbebSnyanmisaka             mpp_mutex_cond_wait(cmd_lock);
258*437bfbebSnyanmisaka             /* return here and process all the flow again */
259*437bfbebSnyanmisaka             mpp_mutex_cond_unlock(cmd_lock);
260*437bfbebSnyanmisaka             return MPP_OK;
261*437bfbebSnyanmisaka         }
262*437bfbebSnyanmisaka     }
263*437bfbebSnyanmisaka     dec_dbg_detail("detail: %p check frame group count pass\n", dec);
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka     /* if dec_task is reset quit decoding and mark current packet is done */
266*437bfbebSnyanmisaka     if (task_dec->output < 0 || !task_dec->valid)
267*437bfbebSnyanmisaka         return MPP_OK;
268*437bfbebSnyanmisaka 
269*437bfbebSnyanmisaka     if (!task->hal_frm_buf_out) {
270*437bfbebSnyanmisaka         MppBuffer hal_buf_out = NULL;
271*437bfbebSnyanmisaka 
272*437bfbebSnyanmisaka         output = task_dec->output;
273*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &hal_buf_out);
274*437bfbebSnyanmisaka         if (NULL == hal_buf_out) {
275*437bfbebSnyanmisaka             size_t size = mpp_buf_slot_get_size(frame_slots);
276*437bfbebSnyanmisaka             mpp_buffer_get(mpp->mFrameGroup, &hal_buf_out, size);
277*437bfbebSnyanmisaka             if (hal_buf_out)
278*437bfbebSnyanmisaka                 mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER,
279*437bfbebSnyanmisaka                                       hal_buf_out);
280*437bfbebSnyanmisaka         }
281*437bfbebSnyanmisaka         if (!dec->info_updated && dec->dev) {
282*437bfbebSnyanmisaka             MppFrame slot_frm = NULL;
283*437bfbebSnyanmisaka 
284*437bfbebSnyanmisaka             mpp_buf_slot_get_prop(frame_slots, output, SLOT_FRAME_PTR, &slot_frm);
285*437bfbebSnyanmisaka             update_dec_hal_info(dec, slot_frm);
286*437bfbebSnyanmisaka             dec->info_updated = 1;
287*437bfbebSnyanmisaka         }
288*437bfbebSnyanmisaka 
289*437bfbebSnyanmisaka         task->hal_frm_buf_out = hal_buf_out;
290*437bfbebSnyanmisaka     }
291*437bfbebSnyanmisaka 
292*437bfbebSnyanmisaka     {
293*437bfbebSnyanmisaka         MppFrame mframe = NULL;
294*437bfbebSnyanmisaka 
295*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe);
296*437bfbebSnyanmisaka 
297*437bfbebSnyanmisaka         if (MPP_FRAME_FMT_IS_HDR(mpp_frame_get_fmt(mframe)) &&
298*437bfbebSnyanmisaka             dec->cfg->base.enable_hdr_meta) {
299*437bfbebSnyanmisaka             fill_hdr_meta_to_frame(mframe, dec->coding);
300*437bfbebSnyanmisaka         }
301*437bfbebSnyanmisaka     }
302*437bfbebSnyanmisaka 
303*437bfbebSnyanmisaka     task->wait.dec_pic_match = (NULL == task->hal_frm_buf_out);
304*437bfbebSnyanmisaka     if (task->wait.dec_pic_match) {
305*437bfbebSnyanmisaka         mpp_mutex_cond_unlock(cmd_lock);
306*437bfbebSnyanmisaka         return MPP_NOK;
307*437bfbebSnyanmisaka     }
308*437bfbebSnyanmisaka 
309*437bfbebSnyanmisaka     mpp_hal_reg_gen(dec->hal, &task->info);
310*437bfbebSnyanmisaka     mpp_hal_hw_start(dec->hal, &task->info);
311*437bfbebSnyanmisaka     mpp_hal_hw_wait(dec->hal, &task->info);
312*437bfbebSnyanmisaka     dec->dec_hw_run_count++;
313*437bfbebSnyanmisaka 
314*437bfbebSnyanmisaka     /*
315*437bfbebSnyanmisaka      * when hardware decoding is done:
316*437bfbebSnyanmisaka      * 1. clear decoding flag (mark buffer is ready)
317*437bfbebSnyanmisaka      * 2. use get_display to get a new frame with buffer
318*437bfbebSnyanmisaka      * 3. add frame to output list
319*437bfbebSnyanmisaka      * repeat 2 and 3 until not frame can be output
320*437bfbebSnyanmisaka      */
321*437bfbebSnyanmisaka     mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT);
322*437bfbebSnyanmisaka 
323*437bfbebSnyanmisaka     if (task_dec->output >= 0)
324*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT);
325*437bfbebSnyanmisaka 
326*437bfbebSnyanmisaka     for (i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) {
327*437bfbebSnyanmisaka         RK_S32 index = task_dec->refer[i];
328*437bfbebSnyanmisaka         if (index >= 0)
329*437bfbebSnyanmisaka             mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT);
330*437bfbebSnyanmisaka     }
331*437bfbebSnyanmisaka     if (task_dec->flags.eos)
332*437bfbebSnyanmisaka         mpp_dec_flush(dec);
333*437bfbebSnyanmisaka 
334*437bfbebSnyanmisaka     output += mpp_dec_push_display(mpp, task_dec->flags);
335*437bfbebSnyanmisaka 
336*437bfbebSnyanmisaka     status->dec_pkt_copy_rdy = 0;
337*437bfbebSnyanmisaka     status->curr_task_rdy   = 0;
338*437bfbebSnyanmisaka     status->task_parsed_rdy = 0;
339*437bfbebSnyanmisaka     status->prev_task_rdy   = 0;
340*437bfbebSnyanmisaka     dec_task_info_init(&task->info);
341*437bfbebSnyanmisaka     task->hal_pkt_buf_in  = NULL;
342*437bfbebSnyanmisaka     task->hal_frm_buf_out = NULL;
343*437bfbebSnyanmisaka     mpp_mutex_cond_unlock(cmd_lock);
344*437bfbebSnyanmisaka 
345*437bfbebSnyanmisaka     return (MPP_RET)output;
346*437bfbebSnyanmisaka }
347*437bfbebSnyanmisaka 
mpp_dec_reset_no_thread(MppDecImpl * dec)348*437bfbebSnyanmisaka MPP_RET mpp_dec_reset_no_thread(MppDecImpl *dec)
349*437bfbebSnyanmisaka {
350*437bfbebSnyanmisaka     DecTask *task = (DecTask *)dec->task_single;
351*437bfbebSnyanmisaka     MppBufSlots frame_slots  = dec->frame_slots;
352*437bfbebSnyanmisaka     MppMutexCond *cmd_lock = &dec->cmd_lock;
353*437bfbebSnyanmisaka     HalDecTask *task_dec = &task->info.dec;
354*437bfbebSnyanmisaka     RK_S32 index;
355*437bfbebSnyanmisaka     RK_U32 i;
356*437bfbebSnyanmisaka 
357*437bfbebSnyanmisaka     mpp_mutex_cond_lock(cmd_lock);
358*437bfbebSnyanmisaka 
359*437bfbebSnyanmisaka     task->status.curr_task_rdy = 0;
360*437bfbebSnyanmisaka     task->status.prev_task_rdy = 1;
361*437bfbebSnyanmisaka     task_dec->valid = 0;
362*437bfbebSnyanmisaka     mpp_parser_reset(dec->parser);
363*437bfbebSnyanmisaka     mpp_hal_reset(dec->hal);
364*437bfbebSnyanmisaka     if (dec->vproc) {
365*437bfbebSnyanmisaka         dec_dbg_reset("reset: vproc reset start\n");
366*437bfbebSnyanmisaka         dec_vproc_reset(dec->vproc);
367*437bfbebSnyanmisaka         dec_dbg_reset("reset: vproc reset done\n");
368*437bfbebSnyanmisaka     }
369*437bfbebSnyanmisaka 
370*437bfbebSnyanmisaka     // wait hal thread reset ready
371*437bfbebSnyanmisaka     if (task->wait.info_change) {
372*437bfbebSnyanmisaka         mpp_log("reset at info change status\n");
373*437bfbebSnyanmisaka         mpp_buf_slot_reset(frame_slots, task_dec->output);
374*437bfbebSnyanmisaka     }
375*437bfbebSnyanmisaka 
376*437bfbebSnyanmisaka     if (task->status.task_parsed_rdy) {
377*437bfbebSnyanmisaka         mpp_log("task no send to hal que must clr current frame hal status\n");
378*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT);
379*437bfbebSnyanmisaka         for (i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) {
380*437bfbebSnyanmisaka             index = task_dec->refer[i];
381*437bfbebSnyanmisaka             if (index >= 0)
382*437bfbebSnyanmisaka                 mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT);
383*437bfbebSnyanmisaka         }
384*437bfbebSnyanmisaka         task->status.task_parsed_rdy = 0;
385*437bfbebSnyanmisaka     }
386*437bfbebSnyanmisaka 
387*437bfbebSnyanmisaka     while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) {
388*437bfbebSnyanmisaka         /* release extra ref in slot's MppBuffer */
389*437bfbebSnyanmisaka         MppBuffer buffer = NULL;
390*437bfbebSnyanmisaka 
391*437bfbebSnyanmisaka         mpp_buf_slot_get_prop(frame_slots, index, SLOT_BUFFER, &buffer);
392*437bfbebSnyanmisaka         if (buffer)
393*437bfbebSnyanmisaka             mpp_buffer_put(buffer);
394*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE);
395*437bfbebSnyanmisaka     }
396*437bfbebSnyanmisaka 
397*437bfbebSnyanmisaka     if (task->status.dec_pkt_copy_rdy) {
398*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(dec->packet_slots, task_dec->input,  SLOT_HAL_INPUT);
399*437bfbebSnyanmisaka         mpp_buf_slot_clr_flag(dec->packet_slots, task_dec->input,  SLOT_CODEC_READY);
400*437bfbebSnyanmisaka         task->status.dec_pkt_copy_rdy = 0;
401*437bfbebSnyanmisaka         task->hal_pkt_buf_in = NULL;
402*437bfbebSnyanmisaka         task_dec->input = -1;
403*437bfbebSnyanmisaka     }
404*437bfbebSnyanmisaka 
405*437bfbebSnyanmisaka     // external packet release by user
406*437bfbebSnyanmisaka     dec->mpp_pkt_in = NULL;
407*437bfbebSnyanmisaka 
408*437bfbebSnyanmisaka     task->status.task_parsed_rdy = 0;
409*437bfbebSnyanmisaka     dec_task_init(task);
410*437bfbebSnyanmisaka 
411*437bfbebSnyanmisaka     dec_dbg_reset("reset: parser reset all done\n");
412*437bfbebSnyanmisaka 
413*437bfbebSnyanmisaka     dec->dec_in_pkt_count = 0;
414*437bfbebSnyanmisaka     dec->dec_hw_run_count = 0;
415*437bfbebSnyanmisaka     dec->dec_out_frame_count = 0;
416*437bfbebSnyanmisaka     dec->info_updated = 0;
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka     mpp_mutex_cond_signal(cmd_lock);
419*437bfbebSnyanmisaka     mpp_mutex_cond_unlock(cmd_lock);
420*437bfbebSnyanmisaka 
421*437bfbebSnyanmisaka     return MPP_OK;
422*437bfbebSnyanmisaka }
423*437bfbebSnyanmisaka 
mpp_dec_notify_no_thread(MppDecImpl * dec,RK_U32 flag)424*437bfbebSnyanmisaka MPP_RET mpp_dec_notify_no_thread(MppDecImpl *dec, RK_U32 flag)
425*437bfbebSnyanmisaka {
426*437bfbebSnyanmisaka     // Only notify buffer group control
427*437bfbebSnyanmisaka     if (flag == (MPP_DEC_NOTIFY_BUFFER_VALID | MPP_DEC_NOTIFY_BUFFER_MATCH)) {
428*437bfbebSnyanmisaka         mpp_mutex_cond_signal(&dec->cmd_lock);
429*437bfbebSnyanmisaka         return MPP_OK;
430*437bfbebSnyanmisaka     }
431*437bfbebSnyanmisaka 
432*437bfbebSnyanmisaka     return MPP_OK;
433*437bfbebSnyanmisaka }
434*437bfbebSnyanmisaka 
mpp_dec_control_no_thread(MppDecImpl * dec,MpiCmd cmd,void * param)435*437bfbebSnyanmisaka MPP_RET mpp_dec_control_no_thread(MppDecImpl *dec, MpiCmd cmd, void *param)
436*437bfbebSnyanmisaka {
437*437bfbebSnyanmisaka     // cmd_lock is used to sync all async operations
438*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
439*437bfbebSnyanmisaka 
440*437bfbebSnyanmisaka     mpp_mutex_cond_lock(&dec->cmd_lock);
441*437bfbebSnyanmisaka     dec->cmd_send++;
442*437bfbebSnyanmisaka     ret = mpp_dec_proc_cfg(dec, cmd, param);
443*437bfbebSnyanmisaka     mpp_mutex_cond_unlock(&dec->cmd_lock);
444*437bfbebSnyanmisaka 
445*437bfbebSnyanmisaka     return ret;
446*437bfbebSnyanmisaka }
447*437bfbebSnyanmisaka 
448*437bfbebSnyanmisaka MppDecModeApi dec_api_no_thread = {
449*437bfbebSnyanmisaka     NULL,
450*437bfbebSnyanmisaka     NULL,
451*437bfbebSnyanmisaka     mpp_dec_reset_no_thread,
452*437bfbebSnyanmisaka     mpp_dec_notify_no_thread,
453*437bfbebSnyanmisaka     mpp_dec_control_no_thread,
454*437bfbebSnyanmisaka };
455