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