xref: /rockchip-linux_mpp/mpp/codec/dec/dummy/dummy_dec_api.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka *
3*437bfbebSnyanmisaka * Copyright 2015 Rockchip Electronics Co. LTD
4*437bfbebSnyanmisaka *
5*437bfbebSnyanmisaka * Licensed under the Apache License, Version 2.0 (the "License");
6*437bfbebSnyanmisaka * you may not use this file except in compliance with the License.
7*437bfbebSnyanmisaka * You may obtain a copy of the License at
8*437bfbebSnyanmisaka *
9*437bfbebSnyanmisaka *      http://www.apache.org/licenses/LICENSE-2.0
10*437bfbebSnyanmisaka *
11*437bfbebSnyanmisaka * Unless required by applicable law or agreed to in writing, software
12*437bfbebSnyanmisaka * distributed under the License is distributed on an "AS IS" BASIS,
13*437bfbebSnyanmisaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*437bfbebSnyanmisaka * See the License for the specific language governing permissions and
15*437bfbebSnyanmisaka * limitations under the License.
16*437bfbebSnyanmisaka */
17*437bfbebSnyanmisaka #define MODULE_TAG "dummy_dec_api"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_mem.h"
22*437bfbebSnyanmisaka #include "mpp_debug.h"
23*437bfbebSnyanmisaka #include "mpp_common.h"
24*437bfbebSnyanmisaka 
25*437bfbebSnyanmisaka #include "dummy_dec_api.h"
26*437bfbebSnyanmisaka 
27*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_WIDTH       1280
28*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_HEIGHT      720
29*437bfbebSnyanmisaka 
30*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_NEW_WIDTH   1920
31*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_NEW_HEIGHT  1088
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_SIZE        SZ_1M
34*437bfbebSnyanmisaka #define DUMMY_DEC_FRAME_COUNT       16
35*437bfbebSnyanmisaka #define DUMMY_DEC_REF_COUNT         2
36*437bfbebSnyanmisaka 
37*437bfbebSnyanmisaka typedef struct DummyDec_t {
38*437bfbebSnyanmisaka     MppBufSlots     frame_slots;
39*437bfbebSnyanmisaka     MppBufSlots     packet_slots;
40*437bfbebSnyanmisaka     RK_S32          task_count;
41*437bfbebSnyanmisaka     void            *stream;
42*437bfbebSnyanmisaka     size_t          stream_size;
43*437bfbebSnyanmisaka     MppPacket       task_pkt;
44*437bfbebSnyanmisaka 
45*437bfbebSnyanmisaka     RK_S64          task_pts;
46*437bfbebSnyanmisaka     RK_U32          task_eos;
47*437bfbebSnyanmisaka 
48*437bfbebSnyanmisaka     RK_U32          slots_inited;
49*437bfbebSnyanmisaka     RK_U32          frame_count;
50*437bfbebSnyanmisaka     RK_S32          prev_index;
51*437bfbebSnyanmisaka     RK_S32          slot_index[DUMMY_DEC_REF_COUNT];
52*437bfbebSnyanmisaka } DummyDec;
53*437bfbebSnyanmisaka 
dummy_dec_init(void * dec,ParserCfg * cfg)54*437bfbebSnyanmisaka MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg)
55*437bfbebSnyanmisaka {
56*437bfbebSnyanmisaka     DummyDec *p;
57*437bfbebSnyanmisaka     RK_S32 i;
58*437bfbebSnyanmisaka     void *stream;
59*437bfbebSnyanmisaka     size_t stream_size = SZ_512K;
60*437bfbebSnyanmisaka     MppPacket task_pkt;
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka     if (NULL == dec) {
63*437bfbebSnyanmisaka         mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg);
64*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
65*437bfbebSnyanmisaka     }
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka     stream = mpp_malloc_size(void, stream_size);
68*437bfbebSnyanmisaka     if (NULL == stream) {
69*437bfbebSnyanmisaka         mpp_err_f("failed to malloc stream buffer size %d\n", stream_size);
70*437bfbebSnyanmisaka         return MPP_ERR_MALLOC;
71*437bfbebSnyanmisaka     }
72*437bfbebSnyanmisaka 
73*437bfbebSnyanmisaka     mpp_packet_init(&task_pkt, stream, stream_size);
74*437bfbebSnyanmisaka     if (NULL == task_pkt) {
75*437bfbebSnyanmisaka         mpp_err_f("failed to create mpp_packet for task\n");
76*437bfbebSnyanmisaka         return MPP_ERR_UNKNOW;
77*437bfbebSnyanmisaka     }
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka     p = (DummyDec *)dec;
80*437bfbebSnyanmisaka     p->frame_slots  = cfg->frame_slots;
81*437bfbebSnyanmisaka     p->packet_slots = cfg->packet_slots;
82*437bfbebSnyanmisaka     p->task_count   = 2;
83*437bfbebSnyanmisaka     p->stream       = stream;
84*437bfbebSnyanmisaka     p->stream_size  = stream_size;
85*437bfbebSnyanmisaka     p->task_pkt     = task_pkt;
86*437bfbebSnyanmisaka     for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) {
87*437bfbebSnyanmisaka         p->slot_index[i] = -1;
88*437bfbebSnyanmisaka     }
89*437bfbebSnyanmisaka     return MPP_OK;
90*437bfbebSnyanmisaka }
91*437bfbebSnyanmisaka 
dummy_dec_deinit(void * dec)92*437bfbebSnyanmisaka MPP_RET dummy_dec_deinit(void *dec)
93*437bfbebSnyanmisaka {
94*437bfbebSnyanmisaka     DummyDec *p;
95*437bfbebSnyanmisaka     if (NULL == dec) {
96*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
97*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
98*437bfbebSnyanmisaka     }
99*437bfbebSnyanmisaka 
100*437bfbebSnyanmisaka     p = (DummyDec *)dec;
101*437bfbebSnyanmisaka     if (p->task_pkt)
102*437bfbebSnyanmisaka         mpp_packet_deinit(&p->task_pkt);
103*437bfbebSnyanmisaka     if (p->stream)
104*437bfbebSnyanmisaka         mpp_free(p->stream);
105*437bfbebSnyanmisaka     return MPP_OK;
106*437bfbebSnyanmisaka }
107*437bfbebSnyanmisaka 
dummy_dec_reset(void * dec)108*437bfbebSnyanmisaka MPP_RET dummy_dec_reset(void *dec)
109*437bfbebSnyanmisaka {
110*437bfbebSnyanmisaka     if (NULL == dec) {
111*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
112*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
113*437bfbebSnyanmisaka     }
114*437bfbebSnyanmisaka     return MPP_OK;
115*437bfbebSnyanmisaka }
116*437bfbebSnyanmisaka 
117*437bfbebSnyanmisaka 
dummy_dec_flush(void * dec)118*437bfbebSnyanmisaka MPP_RET dummy_dec_flush(void *dec)
119*437bfbebSnyanmisaka {
120*437bfbebSnyanmisaka     if (NULL == dec) {
121*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
122*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
123*437bfbebSnyanmisaka     }
124*437bfbebSnyanmisaka     return MPP_OK;
125*437bfbebSnyanmisaka }
126*437bfbebSnyanmisaka 
127*437bfbebSnyanmisaka 
dummy_dec_control(void * dec,MpiCmd cmd_type,void * param)128*437bfbebSnyanmisaka MPP_RET dummy_dec_control(void *dec, MpiCmd cmd_type, void *param)
129*437bfbebSnyanmisaka {
130*437bfbebSnyanmisaka     if (NULL == dec) {
131*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
132*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
133*437bfbebSnyanmisaka     }
134*437bfbebSnyanmisaka     (void)cmd_type;
135*437bfbebSnyanmisaka     (void)param;
136*437bfbebSnyanmisaka     return MPP_OK;
137*437bfbebSnyanmisaka }
138*437bfbebSnyanmisaka 
dummy_dec_prepare(void * dec,MppPacket pkt,HalDecTask * task)139*437bfbebSnyanmisaka MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task)
140*437bfbebSnyanmisaka {
141*437bfbebSnyanmisaka     DummyDec *p;
142*437bfbebSnyanmisaka     RK_U8 *data;
143*437bfbebSnyanmisaka     size_t length;
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka     if (NULL == dec) {
146*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
147*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
148*437bfbebSnyanmisaka     }
149*437bfbebSnyanmisaka 
150*437bfbebSnyanmisaka     p = (DummyDec *)dec;
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka     /*********************************************************************
153*437bfbebSnyanmisaka      * do packet prepare here
154*437bfbebSnyanmisaka      * including connet nals into a big buffer, setup packet for task copy
155*437bfbebSnyanmisaka      * pts/eos record
156*437bfbebSnyanmisaka      *********************************************************************/
157*437bfbebSnyanmisaka     p->task_pts = mpp_packet_get_pts(pkt);
158*437bfbebSnyanmisaka     p->task_eos = mpp_packet_get_eos(pkt);
159*437bfbebSnyanmisaka 
160*437bfbebSnyanmisaka     // set pos to indicate that buffer is done
161*437bfbebSnyanmisaka     data    = mpp_packet_get_data(pkt);
162*437bfbebSnyanmisaka     length  = mpp_packet_get_length(pkt);
163*437bfbebSnyanmisaka     if (length > p->stream_size) {
164*437bfbebSnyanmisaka         p->stream = mpp_realloc(p->stream, RK_U8, length);
165*437bfbebSnyanmisaka         mpp_packet_set_data(p->task_pkt, p->stream);
166*437bfbebSnyanmisaka         p->stream_size = length;
167*437bfbebSnyanmisaka     }
168*437bfbebSnyanmisaka     if (p->stream) {
169*437bfbebSnyanmisaka         memcpy(p->stream, data, length);
170*437bfbebSnyanmisaka         mpp_packet_set_length(p->task_pkt, length);
171*437bfbebSnyanmisaka     } else {
172*437bfbebSnyanmisaka         mpp_err("failed to found task buffer for hardware\n");
173*437bfbebSnyanmisaka         return MPP_ERR_UNKNOW;
174*437bfbebSnyanmisaka     }
175*437bfbebSnyanmisaka     mpp_packet_set_pos(pkt, data + length);
176*437bfbebSnyanmisaka 
177*437bfbebSnyanmisaka     /*
178*437bfbebSnyanmisaka      * this step will enable the task and goto parse stage
179*437bfbebSnyanmisaka      */
180*437bfbebSnyanmisaka     task->input_packet = p->task_pkt;
181*437bfbebSnyanmisaka     task->flags.eos = p->task_eos;
182*437bfbebSnyanmisaka     task->valid = 1;
183*437bfbebSnyanmisaka     return MPP_OK;
184*437bfbebSnyanmisaka }
dummy_dec_parse(void * dec,HalDecTask * task)185*437bfbebSnyanmisaka MPP_RET dummy_dec_parse(void *dec, HalDecTask *task)
186*437bfbebSnyanmisaka {
187*437bfbebSnyanmisaka     DummyDec *p;
188*437bfbebSnyanmisaka     RK_S32 output;
189*437bfbebSnyanmisaka     MppFrame frame = NULL;
190*437bfbebSnyanmisaka     RK_U32 frame_count;
191*437bfbebSnyanmisaka     MppBufSlots slots;
192*437bfbebSnyanmisaka     RK_S32 i;
193*437bfbebSnyanmisaka     RK_U32 width, height;
194*437bfbebSnyanmisaka 
195*437bfbebSnyanmisaka     if (NULL == dec) {
196*437bfbebSnyanmisaka         mpp_err_f("found NULL intput\n");
197*437bfbebSnyanmisaka         return MPP_ERR_NULL_PTR;
198*437bfbebSnyanmisaka     }
199*437bfbebSnyanmisaka     p = (DummyDec *)dec;
200*437bfbebSnyanmisaka 
201*437bfbebSnyanmisaka     slots = p->frame_slots;
202*437bfbebSnyanmisaka     frame_count = p->frame_count;
203*437bfbebSnyanmisaka 
204*437bfbebSnyanmisaka     width = DUMMY_DEC_FRAME_WIDTH;
205*437bfbebSnyanmisaka     height = DUMMY_DEC_FRAME_HEIGHT;
206*437bfbebSnyanmisaka 
207*437bfbebSnyanmisaka     mpp_frame_init(&frame);
208*437bfbebSnyanmisaka 
209*437bfbebSnyanmisaka     if (!p->slots_inited) {
210*437bfbebSnyanmisaka         mpp_buf_slot_setup(slots, DUMMY_DEC_FRAME_COUNT);
211*437bfbebSnyanmisaka         p->slots_inited = 1;
212*437bfbebSnyanmisaka     } else if (frame_count >= 2) {
213*437bfbebSnyanmisaka         // do info change test
214*437bfbebSnyanmisaka         width = DUMMY_DEC_FRAME_NEW_WIDTH;
215*437bfbebSnyanmisaka         height = DUMMY_DEC_FRAME_NEW_HEIGHT;
216*437bfbebSnyanmisaka     }
217*437bfbebSnyanmisaka 
218*437bfbebSnyanmisaka     mpp_frame_set_width(frame, width);
219*437bfbebSnyanmisaka     mpp_frame_set_height(frame, height);
220*437bfbebSnyanmisaka     mpp_frame_set_hor_stride(frame, MPP_ALIGN(width, 16));
221*437bfbebSnyanmisaka     mpp_frame_set_ver_stride(frame, MPP_ALIGN(height, 16));
222*437bfbebSnyanmisaka 
223*437bfbebSnyanmisaka     /*
224*437bfbebSnyanmisaka      * set slots information
225*437bfbebSnyanmisaka      * 1. output index MUST be set
226*437bfbebSnyanmisaka      * 2. get unused index for output if needed
227*437bfbebSnyanmisaka      * 3. set output index as hal_input
228*437bfbebSnyanmisaka      * 4. set frame information to output index
229*437bfbebSnyanmisaka      * 5. if one frame can be display, it SHOULD be enqueued to display queue
230*437bfbebSnyanmisaka      */
231*437bfbebSnyanmisaka     mpp_buf_slot_get_unused(slots, &output);
232*437bfbebSnyanmisaka     mpp_buf_slot_set_flag(slots, output, SLOT_HAL_OUTPUT);
233*437bfbebSnyanmisaka     task->output = output;
234*437bfbebSnyanmisaka 
235*437bfbebSnyanmisaka     mpp_frame_set_pts(frame, p->task_pts);
236*437bfbebSnyanmisaka     mpp_buf_slot_set_prop(slots, output, SLOT_FRAME, frame);
237*437bfbebSnyanmisaka     mpp_frame_deinit(&frame);
238*437bfbebSnyanmisaka     mpp_assert(NULL == frame);
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka     /*
241*437bfbebSnyanmisaka      * setup output task
242*437bfbebSnyanmisaka      * 1. valid flag MUST be set if need hardware to run once
243*437bfbebSnyanmisaka      * 2. set output slot index
244*437bfbebSnyanmisaka      * 3. set reference slot index
245*437bfbebSnyanmisaka      */
246*437bfbebSnyanmisaka     memset(&task->refer, -1, sizeof(task->refer));
247*437bfbebSnyanmisaka     for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) {
248*437bfbebSnyanmisaka         RK_S32 index = p->slot_index[i];
249*437bfbebSnyanmisaka         if (index >= 0) {
250*437bfbebSnyanmisaka             task->refer[i] = index;
251*437bfbebSnyanmisaka             mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT);
252*437bfbebSnyanmisaka             mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE);
253*437bfbebSnyanmisaka         }
254*437bfbebSnyanmisaka     }
255*437bfbebSnyanmisaka 
256*437bfbebSnyanmisaka     /*
257*437bfbebSnyanmisaka      * update dpb status assuming that hw has decoded the frame
258*437bfbebSnyanmisaka      */
259*437bfbebSnyanmisaka     mpp_buf_slot_set_flag(slots, output, SLOT_QUEUE_USE);
260*437bfbebSnyanmisaka     mpp_buf_slot_enqueue(slots, output, QUEUE_DISPLAY);
261*437bfbebSnyanmisaka 
262*437bfbebSnyanmisaka     // add new reference buffer
263*437bfbebSnyanmisaka     if (p->task_eos) {
264*437bfbebSnyanmisaka         for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) {
265*437bfbebSnyanmisaka             mpp_buf_slot_clr_flag(slots, p->slot_index[i], SLOT_CODEC_USE);
266*437bfbebSnyanmisaka             p->slot_index[i] = -1;
267*437bfbebSnyanmisaka         }
268*437bfbebSnyanmisaka     } else {
269*437bfbebSnyanmisaka         // clear unreference buffer
270*437bfbebSnyanmisaka         RK_U32 replace_index = frame_count & 1;
271*437bfbebSnyanmisaka         if (p->slot_index[replace_index] >= 0)
272*437bfbebSnyanmisaka             mpp_buf_slot_clr_flag(slots, p->slot_index[replace_index], SLOT_CODEC_USE);
273*437bfbebSnyanmisaka 
274*437bfbebSnyanmisaka         p->slot_index[replace_index] = output;
275*437bfbebSnyanmisaka         mpp_buf_slot_set_flag(slots, output, SLOT_CODEC_USE);
276*437bfbebSnyanmisaka     }
277*437bfbebSnyanmisaka 
278*437bfbebSnyanmisaka     p->frame_count = ++frame_count;
279*437bfbebSnyanmisaka 
280*437bfbebSnyanmisaka     return MPP_OK;
281*437bfbebSnyanmisaka }
282*437bfbebSnyanmisaka 
dummy_dec_callback(void * dec,void * err_info)283*437bfbebSnyanmisaka MPP_RET dummy_dec_callback(void *dec, void *err_info)
284*437bfbebSnyanmisaka {
285*437bfbebSnyanmisaka     (void)dec;
286*437bfbebSnyanmisaka     (void)err_info;
287*437bfbebSnyanmisaka     return MPP_OK;
288*437bfbebSnyanmisaka }
289*437bfbebSnyanmisaka const ParserApi dummy_dec_parser = {
290*437bfbebSnyanmisaka     .name = "dummy_dec_parser",
291*437bfbebSnyanmisaka     .coding = MPP_VIDEO_CodingUnused,
292*437bfbebSnyanmisaka     .ctx_size = sizeof(DummyDec),
293*437bfbebSnyanmisaka     .flag = 0,
294*437bfbebSnyanmisaka     .init = dummy_dec_init,
295*437bfbebSnyanmisaka     .deinit = dummy_dec_deinit,
296*437bfbebSnyanmisaka     .prepare = dummy_dec_prepare,
297*437bfbebSnyanmisaka     .parse = dummy_dec_parse,
298*437bfbebSnyanmisaka     .reset = dummy_dec_reset,
299*437bfbebSnyanmisaka     .flush = dummy_dec_flush,
300*437bfbebSnyanmisaka     .control = dummy_dec_control,
301*437bfbebSnyanmisaka     .callback = dummy_dec_callback,
302*437bfbebSnyanmisaka };
303*437bfbebSnyanmisaka 
304