1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "avsd_api"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "mpp_env.h"
24 #include "mpp_mem.h"
25 #include "mpp_debug.h"
26 #include "mpp_packet_impl.h"
27
28 #include "avsd_syntax.h"
29 #include "avsd_api.h"
30 #include "avsd_parse.h"
31 #include "mpp_dec_cb_param.h"
32
33 RK_U32 avsd_parse_debug = 0;
34
35
36 /*!
37 ***********************************************************************
38 * \brief
39 * free all buffer
40 ***********************************************************************
41 */
avsd_deinit(void * decoder)42 MPP_RET avsd_deinit(void *decoder)
43 {
44 MPP_RET ret = MPP_ERR_UNKNOW;
45 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
46
47 INP_CHECK(ret, !decoder);
48 AVSD_PARSE_TRACE("In.");
49
50 mpp_packet_deinit(&p_dec->task_pkt);
51 MPP_FREE(p_dec->streambuf);
52 MPP_FREE(p_dec->mem);
53
54 __RETURN:
55 (void)decoder;
56 AVSD_PARSE_TRACE("Out.");
57 return ret = MPP_OK;
58 }
59
60 /*!
61 ***********************************************************************
62 * \brief
63 * alloc all buffer
64 ***********************************************************************
65 */
66
avsd_init(void * decoder,ParserCfg * init)67 static MPP_RET avsd_init(void *decoder, ParserCfg *init)
68 {
69 MPP_RET ret = MPP_ERR_UNKNOW;
70 RK_S32 i = 0;
71 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
72
73 AVSD_PARSE_TRACE("In.");
74 INP_CHECK(ret, !p_dec);
75
76 memset(p_dec, 0, sizeof(AvsdCtx_t));
77 mpp_env_get_u32("avsd_debug", &avsd_parse_debug, 0);
78 //!< restore init parameters
79 p_dec->init = *init;
80 p_dec->frame_slots = init->frame_slots;
81 p_dec->packet_slots = init->packet_slots;
82 //!< decoder parameters
83 mpp_buf_slot_setup(p_dec->frame_slots, 12);
84 p_dec->mem = mpp_calloc(AvsdMemory_t, 1);
85 MEM_CHECK(ret, p_dec->mem);
86
87 p_dec->syn = &p_dec->mem->syntax;
88 p_dec->stream_size = MAX_STREAM_SIZE;
89 p_dec->streambuf = mpp_malloc(RK_U8, p_dec->stream_size);
90 MEM_CHECK(ret, p_dec->streambuf);
91 mpp_packet_init(&p_dec->task_pkt, p_dec->streambuf, p_dec->stream_size);
92
93 mpp_packet_set_length(p_dec->task_pkt, 0);
94 MEM_CHECK(ret, p_dec->task_pkt);
95 for (i = 0; i < 3; i++) {
96 AvsdFrame_t *frm = &p_dec->mem->save[i];
97
98 memset(frm, 0, sizeof(*frm));
99 frm->idx = i;
100 frm->slot_idx = -1;
101 }
102 p_dec->bx = &p_dec->mem->bitctx;
103 p_dec->need_split = 1;
104
105 __RETURN:
106 AVSD_PARSE_TRACE("Out.");
107 return ret = MPP_OK;
108 __FAILED:
109 avsd_deinit(decoder);
110
111 return ret;
112 }
113
114 /*!
115 ***********************************************************************
116 * \brief
117 * reset
118 ***********************************************************************
119 */
avsd_reset(void * decoder)120 static MPP_RET avsd_reset(void *decoder)
121 {
122 MPP_RET ret = MPP_ERR_UNKNOW;
123 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
124
125 AVSD_PARSE_TRACE("In.");
126
127 avsd_reset_parameters(p_dec);
128 p_dec->got_vsh = 0;
129 p_dec->got_ph = 0;
130 p_dec->got_keyframe = 0;
131 p_dec->vec_flag = 0;
132 p_dec->got_eos = 0;
133 p_dec->left_length = 0;
134 p_dec->state = 0xFFFFFFFF;
135 p_dec->vop_header_found = 0;
136
137 mpp_packet_set_length(p_dec->task_pkt, 0);
138 mpp_packet_set_flag(p_dec->task_pkt, 0);
139
140 AVSD_PARSE_TRACE("Out.");
141
142 return ret = MPP_OK;
143 }
144
145 /*!
146 ***********************************************************************
147 * \brief
148 * flush
149 ***********************************************************************
150 */
avsd_flush(void * decoder)151 static MPP_RET avsd_flush(void *decoder)
152 {
153 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
154
155 AVSD_PARSE_TRACE("In.");
156
157 set_frame_output(p_dec, p_dec->dpb[1]);
158 set_frame_output(p_dec, p_dec->dpb[0]);
159 set_frame_output(p_dec, p_dec->cur);
160
161 p_dec->got_eos = 0;
162
163 AVSD_PARSE_TRACE("Out.");
164
165 return MPP_OK;
166 }
167
168 /*!
169 ***********************************************************************
170 * \brief
171 * control/perform
172 ***********************************************************************
173 */
avsd_control(void * decoder,MpiCmd cmd_type,void * param)174 static MPP_RET avsd_control(void *decoder, MpiCmd cmd_type, void *param)
175 {
176 MPP_RET ret = MPP_ERR_UNKNOW;
177 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
178
179 AVSD_PARSE_TRACE("In.");
180
181 switch (cmd_type) {
182 case MPP_DEC_SET_DISABLE_ERROR: {
183 p_dec->disable_error = *((RK_U32 *)param);
184 } break;
185 case MPP_DEC_SET_DIS_ERR_CLR_MARK: {
186 p_dec->dis_err_clr_mark = *((RK_U32 *)param);
187 } break;
188 default : {
189 } break;
190 }
191
192 AVSD_PARSE_TRACE("Out.");
193 return ret = MPP_OK;
194 }
195
196
197 /*!
198 ***********************************************************************
199 * \brief
200 * prepare
201 ***********************************************************************
202 */
avsd_prepare(void * decoder,MppPacket pkt,HalDecTask * task)203 static MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task)
204 {
205 MPP_RET ret = MPP_ERR_UNKNOW;
206
207 AVSD_PARSE_TRACE("In.");
208 INP_CHECK(ret, !decoder && !pkt && !task);
209
210 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
211 RK_U8 *pos = mpp_packet_get_pos(pkt);
212 size_t length = mpp_packet_get_length(pkt);
213 RK_U32 eos = mpp_packet_get_eos(pkt);
214
215 task->valid = 0;
216 if (p_dec->got_eos) {
217 AVSD_DBG(AVSD_DBG_INPUT, "got eos packet.\n");
218 mpp_packet_set_length(pkt, 0);
219 goto __RETURN;
220 }
221 AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in] pts=%lld, eos=%d, len=%d, pkt_no=%d\n",
222 mpp_packet_get_pts(pkt), eos, (RK_U32)length, (RK_U32)p_dec->pkt_no);
223 p_dec->pkt_no++;
224
225 if (mpp_packet_get_eos(pkt)) {
226 if (mpp_packet_get_length(pkt) < 4) {
227 avsd_flush(decoder);
228 }
229 p_dec->got_eos = 1;
230 task->flags.eos = p_dec->got_eos;
231 goto __RETURN;
232 }
233 if (mpp_packet_get_length(pkt) > MAX_STREAM_SIZE) {
234 AVSD_DBG(AVSD_DBG_ERROR, "[pkt_in_timeUs] input error, stream too large");
235 mpp_packet_set_length(pkt, 0);
236 ret = MPP_NOK;
237 goto __RETURN;
238 }
239
240 mpp_packet_set_length(p_dec->task_pkt, p_dec->left_length);
241
242 RK_U32 total_length = MPP_ALIGN(p_dec->left_length + length, 16) + 64;
243 if (total_length > p_dec->stream_size) {
244 do {
245 p_dec->stream_size <<= 1;
246 } while (total_length > p_dec->stream_size);
247
248 RK_U8 *dst = mpp_malloc_size(RK_U8, p_dec->stream_size);
249 mpp_assert(dst);
250
251 if (p_dec->left_length > 0) {
252 memcpy(dst, p_dec->streambuf, p_dec->left_length);
253 }
254 mpp_free(p_dec->streambuf);
255 p_dec->streambuf = dst;
256
257 mpp_packet_set_data(p_dec->task_pkt, p_dec->streambuf);
258 mpp_packet_set_size(p_dec->task_pkt, p_dec->stream_size);
259 }
260
261 if (!p_dec->need_split) {
262 p_dec->got_eos = eos;
263 // empty eos packet
264 if (eos && (length < 4)) {
265 avsd_flush(decoder);
266 goto __RETURN;
267 }
268 // copy packet direct
269 memcpy(p_dec->streambuf, pos, length);
270 mpp_packet_set_data(p_dec->task_pkt, p_dec->streambuf);
271 mpp_packet_set_length(p_dec->task_pkt, length);
272 mpp_packet_set_pts(p_dec->task_pkt, mpp_packet_get_pts(pkt));
273 mpp_packet_set_dts(p_dec->task_pkt, mpp_packet_get_dts(pkt));
274 // set input packet length to 0 here
275 mpp_packet_set_length(pkt, 0);
276 /* this step will enable the task and goto parse stage */
277 task->valid = 1;
278 } else {
279 /* Split packet mode */
280 if (MPP_OK == avsd_parser_split(p_dec, p_dec->task_pkt, pkt)) {
281 p_dec->left_length = 0;
282 task->valid = 1;
283 } else {
284 task->valid = 0;
285 p_dec->left_length = mpp_packet_get_length(p_dec->task_pkt);
286 }
287 p_dec->got_eos = mpp_packet_get_eos(p_dec->task_pkt);
288 }
289 task->input_packet = p_dec->task_pkt;
290 task->flags.eos = p_dec->got_eos;
291
292 __RETURN:
293 AVSD_PARSE_TRACE("Out.");
294 return ret = MPP_OK;
295 }
296 /*!
297 ***********************************************************************
298 * \brief
299 * parser
300 ***********************************************************************
301 */
avsd_parse(void * decoder,HalDecTask * task)302 static MPP_RET avsd_parse(void *decoder, HalDecTask *task)
303 {
304 MPP_RET ret = MPP_ERR_UNKNOW;
305 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
306 AVSD_PARSE_TRACE("In.");
307
308 task->valid = 0;
309 memset(task->refer, -1, sizeof(task->refer));
310
311 avsd_parse_stream(p_dec, task);
312 if (task->valid) {
313 avsd_fill_parameters(p_dec, p_dec->syn);
314 avsd_set_dpb(p_dec, task);
315
316 avsd_commit_syntaxs(p_dec->syn, task);
317 avsd_update_dpb(p_dec);
318 }
319 AVSD_PARSE_TRACE("Out.");
320
321 return ret = MPP_OK;
322 }
323 /*!
324 ***********************************************************************
325 * \brief
326 * callback
327 ***********************************************************************
328 */
avsd_callback(void * decoder,void * info)329 static MPP_RET avsd_callback(void *decoder, void *info)
330 {
331 MPP_RET ret = MPP_ERR_UNKNOW;
332 AvsdCtx_t *p_dec = (AvsdCtx_t *)decoder;
333 DecCbHalDone *ctx = (DecCbHalDone *)info;
334 MppFrame mframe = NULL;
335 HalDecTask *task_dec = (HalDecTask *)ctx->task;
336
337 AVSD_PARSE_TRACE("In.");
338
339 mpp_buf_slot_get_prop(p_dec->frame_slots, task_dec->output, SLOT_FRAME_PTR, &mframe);
340 if (mframe) {
341 if (ctx->hard_err || task_dec->flags.ref_err) {
342 if (task_dec->flags.used_for_ref) {
343 mpp_frame_set_errinfo(mframe, MPP_FRAME_FLAG_PAIRED_FIELD);
344 } else {
345 mpp_frame_set_discard(mframe, MPP_FRAME_FLAG_PAIRED_FIELD);
346 }
347 }
348 }
349
350 if (!ctx->hard_err && p_dec->ph.picture_coding_type == I_PICTURE)
351 p_dec->vsh.version_checked = 1;
352
353 AVSD_PARSE_TRACE("Out.");
354
355 return ret = MPP_OK;
356 }
357 /*!
358 ***********************************************************************
359 * \brief
360 * api struct interface
361 ***********************************************************************
362 */
363 const ParserApi api_avsd_parser = {
364 .name = "avsd_parse",
365 .coding = MPP_VIDEO_CodingAVS,
366 .ctx_size = sizeof(AvsdCtx_t),
367 .flag = 0,
368 .init = avsd_init,
369 .deinit = avsd_deinit,
370 .prepare = avsd_prepare,
371 .parse = avsd_parse,
372 .reset = avsd_reset,
373 .flush = avsd_flush,
374 .control = avsd_control,
375 .callback = avsd_callback,
376 };
377
378 const ParserApi api_avsd_plus_parser = {
379 .name = "avsd_parse",
380 .coding = MPP_VIDEO_CodingAVSPLUS,
381 .ctx_size = sizeof(AvsdCtx_t),
382 .flag = 0,
383 .init = avsd_init,
384 .deinit = avsd_deinit,
385 .prepare = avsd_prepare,
386 .parse = avsd_parse,
387 .reset = avsd_reset,
388 .flush = avsd_flush,
389 .control = avsd_control,
390 .callback = avsd_callback,
391 };
392