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