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
18 #define MODULE_TAG "h264d_api"
19
20 #include <string.h>
21
22 #include "mpp_env.h"
23 #include "mpp_platform.h"
24 #include "mpp_packet_impl.h"
25 #include "mpp_frame_impl.h"
26
27 #include "h264d_api.h"
28 #include "h264d_global.h"
29 #include "h264d_parse.h"
30 #include "h264d_sps.h"
31 #include "h264d_slice.h"
32 #include "h264d_dpb.h"
33 #include "h264d_init.h"
34 #include "h2645d_sei.h"
35 #include "mpp_dec_cb_param.h"
36
37 RK_U32 h264d_debug = 0;
38
39 // for mblock 16 coded width align
rkv_mblock_width_align(RK_U32 val)40 static RK_U32 rkv_mblock_width_align(RK_U32 val)
41 {
42 return MPP_ALIGN(val, 16);
43 }
44
free_input_ctx(H264dInputCtx_t * p_Inp)45 static MPP_RET free_input_ctx(H264dInputCtx_t *p_Inp)
46 {
47 MPP_RET ret = MPP_ERR_UNKNOW;
48
49 INP_CHECK(ret, !p_Inp);
50 close_stream_file(p_Inp);
51 MPP_FREE(p_Inp->spspps_buf);
52
53 __RETURN:
54 return ret = MPP_OK;
55 }
init_input_ctx(H264dInputCtx_t * p_Inp,ParserCfg * init)56 static MPP_RET init_input_ctx(H264dInputCtx_t *p_Inp, ParserCfg *init)
57 {
58 MPP_RET ret = MPP_ERR_UNKNOW;
59
60 INP_CHECK(ret, !p_Inp && !init);
61
62 open_stream_file(p_Inp, "/sdcard");
63 if (h264d_debug & H264D_DBG_WRITE_ES_EN) {
64 p_Inp->spspps_size = HEAD_BUF_MAX_SIZE;
65 p_Inp->spspps_buf = mpp_malloc_size(RK_U8, p_Inp->spspps_size);
66 MEM_CHECK(ret, p_Inp->spspps_buf);
67 }
68
69 __RETURN:
70 return ret = MPP_OK;
71 __FAILED:
72 free_input_ctx(p_Inp);
73 return ret;
74 }
75
76
free_cur_ctx(H264dCurCtx_t * p_Cur)77 static MPP_RET free_cur_ctx(H264dCurCtx_t *p_Cur)
78 {
79 RK_U32 i = 0;
80 MPP_RET ret = MPP_ERR_UNKNOW;
81
82 INP_CHECK(ret, !p_Cur);
83
84 if (p_Cur) {
85 for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
86 MPP_FREE(p_Cur->listP[i]);
87 MPP_FREE(p_Cur->listB[i]);
88 }
89 MPP_FREE(p_Cur->strm.nalu_buf);
90 MPP_FREE(p_Cur->strm.head_buf);
91 MPP_FREE(p_Cur->strm.tmp_buf);
92
93 for (i = 0; i < MAX_MARKING_TIMES; i++)
94 MPP_FREE(p_Cur->dec_ref_pic_marking_buffer[i]);
95
96 MPP_FREE(p_Cur->subsps);
97 MPP_FREE(p_Cur->sei);
98 MPP_FREE(p_Cur->hdr_dynamic_meta);
99 }
100
101 __RETURN:
102 return ret = MPP_OK;
103 }
init_cur_ctx(H264dCurCtx_t * p_Cur)104 static MPP_RET init_cur_ctx(H264dCurCtx_t *p_Cur)
105 {
106 RK_U32 i = 0;
107 MPP_RET ret = MPP_ERR_UNKNOW;
108 H264dCurStream_t *p_strm = NULL;
109
110 INP_CHECK(ret, !p_Cur);
111
112 p_strm = &p_Cur->strm;
113 p_strm->nalu_max_size = NALU_BUF_MAX_SIZE;
114 p_strm->nalu_buf = mpp_malloc_size(RK_U8, p_strm->nalu_max_size);
115 p_strm->head_max_size = HEAD_BUF_MAX_SIZE;
116 p_strm->head_buf = mpp_malloc_size(RK_U8, p_strm->head_max_size);
117 p_strm->tmp_max_size = HEAD_BUF_MAX_SIZE;
118 p_strm->tmp_buf = mpp_malloc_size(RK_U8, p_strm->head_max_size);
119 MEM_CHECK(ret, p_strm->nalu_buf && p_strm->head_buf);
120 p_strm->prefixdata = 0xffffffff;
121 for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
122 p_Cur->listP[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*));
123 p_Cur->listB[i] = mpp_malloc_size(H264_StorePic_t*, MAX_LIST_SIZE * sizeof(H264_StorePic_t*));
124 MEM_CHECK(ret, p_Cur->listP[i] && p_Cur->listB[i]); // +1 for reordering
125 }
126 reset_cur_slice(p_Cur, &p_Cur->slice);
127
128 __RETURN:
129 return ret = MPP_OK;
130 __FAILED:
131 free_cur_ctx(p_Cur);
132
133 return ret;
134 }
135
136
free_vid_ctx(H264dVideoCtx_t * p_Vid)137 static MPP_RET free_vid_ctx(H264dVideoCtx_t *p_Vid)
138 {
139 RK_U32 i = 0;
140 MPP_RET ret = MPP_ERR_UNKNOW;
141
142 INP_CHECK(ret, !p_Vid);
143
144 for (i = 0; i < MAXSPS; i++) {
145 MPP_FREE(p_Vid->spsSet[i]);
146 if (p_Vid->subspsSet[i])
147 recycle_subsps(p_Vid->subspsSet[i]);
148 MPP_FREE(p_Vid->subspsSet[i]);
149 }
150
151 for (i = 0; i < MAXPPS; i++)
152 MPP_FREE(p_Vid->ppsSet[i]);
153
154 for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
155 free_dpb(p_Vid->p_Dpb_layer[i]);
156 MPP_FREE(p_Vid->p_Dpb_layer[i]);
157 }
158
159 free_storable_picture(p_Vid->p_Dec, p_Vid->dec_pic);
160
161 if (p_Vid->pic_st) {
162 mpp_mem_pool_deinit_f(p_Vid->pic_st);
163 p_Vid->pic_st = NULL;
164 }
165
166 __RETURN:
167 return ret = MPP_OK;
168 }
init_vid_ctx(H264dVideoCtx_t * p_Vid)169 static MPP_RET init_vid_ctx(H264dVideoCtx_t *p_Vid)
170 {
171 RK_U32 i = 0;
172 MPP_RET ret = MPP_ERR_UNKNOW;
173
174 INP_CHECK(ret, !p_Vid);
175
176 for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
177 p_Vid->p_Dpb_layer[i] = mpp_calloc(H264_DpbBuf_t, 1);
178 MEM_CHECK(ret, p_Vid->p_Dpb_layer[i]);
179 p_Vid->p_Dpb_layer[i]->layer_id = i;
180 p_Vid->p_Dpb_layer[i]->p_Vid = p_Vid;
181 p_Vid->p_Dpb_layer[i]->init_done = 0;
182 p_Vid->p_Dpb_layer[i]->poc_interval = 2;
183 }
184
185 //!< init active_sps
186 p_Vid->active_sps = NULL;
187 p_Vid->active_subsps = NULL;
188 p_Vid->active_sps_id[0] = -1;
189 p_Vid->active_sps_id[1] = -1;
190 p_Vid->pic_st = mpp_mem_pool_init_f("h264d_pic_st", sizeof(H264_StorePic_t));
191 __RETURN:
192 return ret = MPP_OK;
193 __FAILED:
194 free_vid_ctx(p_Vid);
195
196 return ret;
197 }
198
free_dxva_ctx(H264dDxvaCtx_t * p_dxva)199 static MPP_RET free_dxva_ctx(H264dDxvaCtx_t *p_dxva)
200 {
201 MPP_RET ret = MPP_ERR_UNKNOW;
202
203 INP_CHECK(ret, NULL == p_dxva);
204
205 MPP_FREE(p_dxva->slice_long);
206 MPP_FREE(p_dxva->bitstream);
207 MPP_FREE(p_dxva->syn.buf);
208
209 __RETURN:
210 return ret = MPP_OK;
211 }
212
init_dxva_ctx(H264dDxvaCtx_t * p_dxva)213 static MPP_RET init_dxva_ctx(H264dDxvaCtx_t *p_dxva)
214 {
215 MPP_RET ret = MPP_ERR_UNKNOW;
216
217 INP_CHECK(ret, !p_dxva);
218
219 p_dxva->slice_count = 0;
220 p_dxva->max_slice_size = MAX_SLICE_NUM;
221 p_dxva->max_strm_size = BITSTREAM_MAX_SIZE;
222 p_dxva->slice_long = mpp_calloc(DXVA_Slice_H264_Long, p_dxva->max_slice_size);
223 MEM_CHECK(ret, p_dxva->slice_long);
224 p_dxva->bitstream = mpp_malloc(RK_U8, p_dxva->max_strm_size);
225 p_dxva->syn.buf = mpp_calloc(DXVA2_DecodeBufferDesc, SYNTAX_BUF_SIZE);
226 MEM_CHECK(ret, p_dxva->bitstream && p_dxva->syn.buf);
227
228 __RETURN:
229 return ret = MPP_OK;
230
231 __FAILED:
232 return ret;
233 }
234
free_dec_ctx(H264_DecCtx_t * p_Dec)235 static MPP_RET free_dec_ctx(H264_DecCtx_t *p_Dec)
236 {
237 MPP_RET ret = MPP_ERR_UNKNOW;
238
239 INP_CHECK(ret, NULL == p_Dec);
240
241 if (p_Dec->mem) {
242 free_dxva_ctx(&p_Dec->mem->dxva_ctx);
243 MPP_FREE(p_Dec->mem);
244 }
245 //!< free mpp packet
246 mpp_packet_deinit(&p_Dec->task_pkt);
247
248 __RETURN:
249 return ret = MPP_OK;
250 }
init_dec_ctx(H264_DecCtx_t * p_Dec)251 static MPP_RET init_dec_ctx(H264_DecCtx_t *p_Dec)
252 {
253 RK_U32 i = 0;
254 MPP_RET ret = MPP_ERR_UNKNOW;
255
256 INP_CHECK(ret, !p_Dec);
257
258 p_Dec->mem = mpp_calloc(H264_DecMem_t, 1);
259 MEM_CHECK(ret, p_Dec->mem);
260 p_Dec->dpb_mark = p_Dec->mem->dpb_mark; //!< for write out, MAX_DPB_SIZE
261 p_Dec->dpb_info = p_Dec->mem->dpb_info; //!< 16
262 p_Dec->refpic_info_p = p_Dec->mem->refpic_info_p; //!< 32
263 p_Dec->refpic_info_b[0] = p_Dec->mem->refpic_info_b[0]; //!< [2][32]
264 p_Dec->refpic_info_b[1] = p_Dec->mem->refpic_info_b[1]; //!< [2][32]
265 //!< init dxva memory
266 p_Dec->mem->dxva_ctx.p_Dec = p_Dec;
267 FUN_CHECK(ret = init_dxva_ctx(&p_Dec->mem->dxva_ctx));
268 p_Dec->dxva_ctx = &p_Dec->mem->dxva_ctx;
269 //!< init Dpb_memory Mark
270 for (i = 0; i < MAX_MARK_SIZE; i++) {
271 reset_dpb_mark(&p_Dec->dpb_mark[i]);
272 p_Dec->dpb_mark[i].mark_idx = i;
273 }
274 mpp_buf_slot_setup(p_Dec->frame_slots, MAX_MARK_SIZE);
275 //!< malloc mpp packet
276 mpp_packet_init(&p_Dec->task_pkt, p_Dec->dxva_ctx->bitstream, p_Dec->dxva_ctx->max_strm_size);
277 MEM_CHECK(ret, p_Dec->task_pkt);
278 //!< set Dec support decoder method
279 p_Dec->spt_decode_mtds = MPP_DEC_BY_FRAME;
280 p_Dec->next_state = SliceSTATE_ResetSlice;
281 p_Dec->nalu_ret = NALU_NULL;
282 p_Dec->have_slice_data = 0;
283 p_Dec->last_frame_slot_idx = -1;
284 memset(&p_Dec->errctx, 0, sizeof(H264dErrCtx_t));
285 __RETURN:
286 return ret = MPP_OK;
287
288 __FAILED:
289 free_dec_ctx(p_Dec);
290
291 return ret;
292 }
293
h264d_flush_dpb_eos(H264_DecCtx_t * p_Dec)294 static MPP_RET h264d_flush_dpb_eos(H264_DecCtx_t *p_Dec)
295 {
296 MPP_RET ret = MPP_ERR_UNKNOW;
297 INP_CHECK(ret, !p_Dec->p_Vid);
298
299 FUN_CHECK(ret = flush_dpb(p_Dec->p_Vid->p_Dpb_layer[0], 1));
300 FUN_CHECK(ret = init_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[0], 1));
301 if (p_Dec->mvc_valid) {
302 // layer_id == 1
303 FUN_CHECK(ret = flush_dpb(p_Dec->p_Vid->p_Dpb_layer[1], 1));
304 FUN_CHECK(ret = init_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[1], 2));
305 FUN_CHECK(ret = check_mvc_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[0], p_Dec->p_Vid->p_Dpb_layer[1]));
306 }
307
308 flush_dpb_buf_slot(p_Dec);
309
310 __RETURN:
311 return ret = MPP_OK;
312 __FAILED:
313 return ret = MPP_NOK;
314 }
315 /*!
316 ***********************************************************************
317 * \brief
318 * alloc all buffer
319 ***********************************************************************
320 */
321
h264d_init(void * decoder,ParserCfg * init)322 MPP_RET h264d_init(void *decoder, ParserCfg *init)
323 {
324 MPP_RET ret = MPP_ERR_UNKNOW;
325 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
326 INP_CHECK(ret, !p_Dec);
327 memset(p_Dec, 0, sizeof(H264_DecCtx_t));
328
329 mpp_env_get_u32("h264d_debug", &h264d_debug, H264D_DBG_ERROR);
330
331 //!< get init frame_slots and packet_slots
332 p_Dec->frame_slots = init->frame_slots;
333 p_Dec->packet_slots = init->packet_slots;
334 p_Dec->cfg = init->cfg;
335 mpp_frame_init(&p_Dec->curframe);
336 //!< malloc decoder buffer
337 p_Dec->p_Inp = mpp_calloc(H264dInputCtx_t, 1);
338 p_Dec->p_Cur = mpp_calloc(H264dCurCtx_t, 1);
339 p_Dec->p_Vid = mpp_calloc(H264dVideoCtx_t, 1);
340 MEM_CHECK(ret, p_Dec->p_Inp && p_Dec->p_Cur && p_Dec->p_Vid);
341 p_Dec->p_Inp->p_Dec = p_Dec;
342 p_Dec->p_Inp->p_Cur = p_Dec->p_Cur;
343 p_Dec->p_Inp->p_Vid = p_Dec->p_Vid;
344
345 p_Dec->p_Cur->p_Dec = p_Dec;
346 p_Dec->p_Cur->p_Inp = p_Dec->p_Inp;
347 p_Dec->p_Cur->p_Vid = p_Dec->p_Vid;
348
349 p_Dec->p_Vid->p_Dec = p_Dec;
350 p_Dec->p_Vid->p_Inp = p_Dec->p_Inp;
351 p_Dec->p_Vid->p_Cur = p_Dec->p_Cur;
352 p_Dec->hw_info = init->hw_info;
353 FUN_CHECK(ret = init_input_ctx(p_Dec->p_Inp, init));
354 FUN_CHECK(ret = init_cur_ctx(p_Dec->p_Cur));
355 FUN_CHECK(ret = init_vid_ctx(p_Dec->p_Vid));
356 FUN_CHECK(ret = init_dec_ctx(p_Dec));
357 p_Dec->immediate_out = p_Dec->cfg->base.fast_out;
358 mpp_env_get_u32("force_fast_play_mode", &p_Dec->cfg->base.enable_fast_play,
359 p_Dec->cfg->base.enable_fast_play);
360 p_Dec->p_Vid->dpb_fast_out = p_Dec->cfg->base.enable_fast_play;
361 H264D_LOG("fast play mode: %d", p_Dec->cfg->base.enable_fast_play);
362 p_Dec->p_Vid->dpb_first_fast_played = 0;
363 mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_WIDTH_ALIGN, rkv_mblock_width_align);
364 __RETURN:
365 return ret = MPP_OK;
366 __FAILED:
367 h264d_deinit(decoder);
368
369 return ret;
370 }
371 /*!
372 ***********************************************************************
373 * \brief
374 * free all buffer
375 ***********************************************************************
376 */
h264d_deinit(void * decoder)377 MPP_RET h264d_deinit(void *decoder)
378 {
379 MPP_RET ret = MPP_ERR_UNKNOW;
380 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
381
382 INP_CHECK(ret, !decoder);
383
384 mpp_frame_deinit(&p_Dec->curframe);
385 free_input_ctx(p_Dec->p_Inp);
386 MPP_FREE(p_Dec->p_Inp);
387 free_cur_ctx(p_Dec->p_Cur);
388 MPP_FREE(p_Dec->p_Cur);
389 free_vid_ctx(p_Dec->p_Vid);
390 MPP_FREE(p_Dec->p_Vid);
391 free_dec_ctx(p_Dec);
392
393 __RETURN:
394 return ret = MPP_OK;
395 }
396 /*!
397 ***********************************************************************
398 * \brief
399 * reset
400 ***********************************************************************
401 */
h264d_reset(void * decoder)402 MPP_RET h264d_reset(void *decoder)
403 {
404 MPP_RET ret = MPP_ERR_UNKNOW;
405 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
406 H264dCurStream_t *p_strm = NULL;
407
408 INP_CHECK(ret, !decoder);
409
410 flush_dpb(p_Dec->p_Vid->p_Dpb_layer[0], 1);
411 init_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[0], 1);
412 if (p_Dec->mvc_valid) {
413 // layer_id == 1
414 flush_dpb(p_Dec->p_Vid->p_Dpb_layer[1], 1);
415 init_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[1], 2);
416 check_mvc_dpb(p_Dec->p_Vid, p_Dec->p_Vid->p_Dpb_layer[0], p_Dec->p_Vid->p_Dpb_layer[1]);
417 }
418 flush_dpb_buf_slot(p_Dec);
419 //!< reset input parameter
420 p_Dec->p_Inp->in_buf = NULL;
421 p_Dec->p_Inp->pkt_eos = 0;
422 p_Dec->p_Inp->task_eos = 0;
423 p_Dec->p_Inp->in_pts = 0;
424 p_Dec->p_Inp->in_dts = 0;
425 p_Dec->p_Inp->has_get_eos = 0;
426 //!< reset video parameter
427 p_Dec->p_Vid->have_outpicture_flag = 0;
428 p_Dec->p_Vid->exit_picture_flag = 0;
429 p_Dec->p_Vid->active_mvc_sps_flag = 0;
430 p_Dec->p_Vid->g_framecnt = 0;
431 p_Dec->p_Vid->dec_pic = NULL;
432 p_Dec->p_Vid->last_pic = NULL;
433 memset(&p_Dec->p_Vid->recovery, 0, sizeof(RecoveryPoint));
434 memset(&p_Dec->p_Vid->old_pic, 0, sizeof(H264_StorePic_t));
435 memset(&p_Dec->errctx, 0, sizeof(H264dErrCtx_t));
436 //!< reset current time stamp
437 p_Dec->p_Cur->last_dts = 0;
438 p_Dec->p_Cur->last_pts = 0;
439 p_Dec->p_Cur->curr_dts = 0;
440 p_Dec->p_Cur->curr_pts = 0;
441 //!< reset current stream
442 p_strm = &p_Dec->p_Cur->strm;
443 p_strm->prefixdata = 0xffffffff;
444 p_strm->nalu_offset = 0;
445 p_strm->nalu_len = 0;
446 if (p_strm->nalu_type != H264_NALU_TYPE_PPS && p_strm->nalu_type != H264_NALU_TYPE_SPS)
447 p_strm->head_offset = 0;
448 p_strm->tmp_offset = 0;
449 p_strm->first_mb_in_slice = 0;
450 p_strm->endcode_found = 0;
451 p_strm->startcode_found = p_Dec->p_Inp->is_nalff;
452 //!< reset decoder parameter
453 p_Dec->next_state = SliceSTATE_ResetSlice;
454 p_Dec->nalu_ret = NALU_NULL;
455 p_Dec->have_slice_data = 0;
456 p_Dec->is_new_frame = 0;
457 p_Dec->is_parser_end = 0;
458 p_Dec->dxva_ctx->strm_offset = 0;
459 p_Dec->dxva_ctx->slice_count = 0;
460 p_Dec->last_frame_slot_idx = -1;
461 mpp_env_get_u32("force_fast_play_mode", &p_Dec->cfg->base.enable_fast_play,
462 p_Dec->cfg->base.enable_fast_play);
463 p_Dec->p_Vid->dpb_fast_out = p_Dec->cfg->base.enable_fast_play;
464 H264D_LOG("fast play mode: %d", p_Dec->cfg->base.enable_fast_play);
465 p_Dec->p_Vid->dpb_first_fast_played = 0;
466
467 __RETURN:
468 return ret = MPP_OK;
469 }
470
471 /*!
472 ***********************************************************************
473 * \brief
474 * flush
475 ***********************************************************************
476 */
h264d_flush(void * decoder)477 MPP_RET h264d_flush(void *decoder)
478 {
479 MPP_RET ret = MPP_ERR_UNKNOW;
480 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
481
482 INP_CHECK(ret, !decoder);
483 INP_CHECK(ret, !p_Dec->p_Inp);
484 INP_CHECK(ret, !p_Dec->p_Vid);
485
486 FUN_CHECK(ret = output_dpb(p_Dec, p_Dec->p_Vid->p_Dpb_layer[0]));
487 if (p_Dec->mvc_valid) {
488 FUN_CHECK(ret = output_dpb(p_Dec, p_Dec->p_Vid->p_Dpb_layer[1]));
489 }
490
491 __RETURN:
492 return ret = MPP_OK;
493 __FAILED:
494 return ret = MPP_NOK;
495 }
496
497 /*!
498 ***********************************************************************
499 * \brief
500 * control/perform
501 ***********************************************************************
502 */
h264d_control(void * decoder,MpiCmd cmd_type,void * param)503 MPP_RET h264d_control(void *decoder, MpiCmd cmd_type, void *param)
504 {
505 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
506
507 switch (cmd_type) {
508 case MPP_DEC_SET_ENABLE_FAST_PLAY:
509 p_Dec->cfg->base.enable_fast_play = (param) ? (*((RK_U32 *)param)) : (1);
510 mpp_env_get_u32("force_fast_play_mode", &p_Dec->cfg->base.enable_fast_play,
511 p_Dec->cfg->base.enable_fast_play);
512 p_Dec->p_Vid->dpb_fast_out = p_Dec->cfg->base.enable_fast_play;
513 H264D_LOG("fast play mode: %d", p_Dec->cfg->base.enable_fast_play);
514 break;
515 case MPP_DEC_SET_MAX_USE_BUFFER_SIZE :
516 p_Dec->p_Inp->max_buf_size = (param) ? (*((RK_U32 *)param)) : (0);
517 break;
518 default:
519 break;
520 }
521
522 return MPP_OK;
523 }
524
525
526 /*!
527 ***********************************************************************
528 * \brief
529 * prepare
530 ***********************************************************************
531 */
532 #define MAX_STREM_IN_SIZE (10*1024*1024)
h264d_prepare(void * decoder,MppPacket pkt,HalDecTask * task)533 MPP_RET h264d_prepare(void *decoder, MppPacket pkt, HalDecTask *task)
534 {
535 MPP_RET ret = MPP_ERR_UNKNOW;
536 H264dInputCtx_t *p_Inp = NULL;
537 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
538
539 INP_CHECK(ret, !decoder && !pkt && !task);
540
541 p_Inp = p_Dec->p_Inp;
542 if (p_Inp->has_get_eos) {
543 mpp_packet_set_length(pkt, 0);
544 task->flags.eos = mpp_packet_get_eos(pkt);
545 goto __RETURN;
546 }
547 p_Inp->in_pkt = pkt;
548 p_Inp->in_pts = mpp_packet_get_pts(pkt);
549 p_Inp->in_dts = mpp_packet_get_dts(pkt);
550 p_Inp->in_length = mpp_packet_get_length(pkt);
551 p_Inp->pkt_eos = mpp_packet_get_eos(pkt);
552 p_Inp->in_buf = (RK_U8 *)mpp_packet_get_pos(pkt);
553
554 if (p_Inp->pkt_eos && p_Inp->in_length < 4) {
555 p_Inp->has_get_eos = 1;
556 p_Inp->in_buf = NULL;
557 p_Inp->in_length = 0;
558 mpp_packet_set_length(p_Inp->in_pkt, 0);
559 task->flags.eos = p_Inp->pkt_eos;
560 }
561
562 if (p_Inp->in_length > MAX_STREM_IN_SIZE) {
563 H264D_ERR("[pkt_in_timeUs] input error, stream too large, pts=%lld, eos=%d, len=%d, pkt_no=%d",
564 p_Inp->in_pts, p_Inp->pkt_eos, p_Inp->in_length, p_Dec->p_Vid->g_framecnt);
565 mpp_packet_set_length(pkt, 0);
566 ret = MPP_NOK;
567 goto __FAILED;
568 }
569 //!< avcC stream
570 if (mpp_packet_get_flag(pkt) & MPP_PACKET_FLAG_EXTRA_DATA) {
571 RK_U8 *pdata = p_Inp->in_buf;
572
573 p_Inp->is_nalff = (p_Inp->in_length > 3) && (pdata[0] == 1);
574 mpp_log("is_avcC=%d\n", p_Inp->is_nalff);
575 if (p_Inp->is_nalff) {
576 (ret = parse_prepare_avcC_header(p_Inp, p_Dec->p_Cur));
577 goto __RETURN;
578 }
579 }
580 H264D_DBG(H264D_DBG_INPUT, "[pkt_in_timeUs] is_avcC=%d, in_pts=%lld, pkt_eos=%d, len=%d, pkt_no=%d",
581 p_Inp->is_nalff, p_Inp->in_pts, p_Inp->pkt_eos, p_Inp->in_length, p_Dec->p_Vid->g_framecnt);
582 if (p_Inp->is_nalff) {
583 (ret = parse_prepare_avcC_data(p_Inp, p_Dec->p_Cur));
584 task->valid = p_Inp->task_valid; //!< prepare valid flag
585 } else {
586 fwrite_stream_to_file(p_Inp, p_Inp->in_buf, (RK_U32)p_Inp->in_length);
587 do {
588 if (p_Dec->cfg->base.split_parse) {
589 ret = parse_prepare(p_Inp, p_Dec->p_Cur);
590 } else {
591 ret = parse_prepare_fast(p_Inp, p_Dec->p_Cur);
592 }
593 task->valid = p_Inp->task_valid; //!< prepare valid flag
594 } while (mpp_packet_get_length(pkt) && !task->valid);
595 }
596 if (p_Inp->in_length < 4)
597 task->flags.eos = p_Inp->pkt_eos;
598 if (task->valid) {
599 memset(p_Dec->dxva_ctx->bitstream + p_Dec->dxva_ctx->strm_offset, 0,
600 MPP_ALIGN(p_Dec->dxva_ctx->strm_offset, 16) - p_Dec->dxva_ctx->strm_offset);
601 mpp_packet_set_data(p_Dec->task_pkt, p_Dec->dxva_ctx->bitstream);
602 mpp_packet_set_length(p_Dec->task_pkt, MPP_ALIGN(p_Dec->dxva_ctx->strm_offset, 16));
603 mpp_packet_set_size(p_Dec->task_pkt, p_Dec->dxva_ctx->max_strm_size);
604 task->input_packet = p_Dec->task_pkt;
605 } else {
606 task->input_packet = NULL;
607 /*
608 * During split_parse, the empty EOS will endcode and decode the
609 * last complete packet.
610 * When sending EOS in split mode, dpb can not be flushed
611 * before split process.
612 */
613 if (p_Inp->pkt_eos && p_Inp->in_length < 4)
614 h264d_flush_dpb_eos(p_Dec);
615 }
616 __RETURN:
617
618 return ret = MPP_OK;
619 __FAILED:
620 return ret;
621 }
622
623
624 /*!
625 ***********************************************************************
626 * \brief
627 * parser
628 ***********************************************************************
629 */
h264d_parse(void * decoder,HalDecTask * in_task)630 MPP_RET h264d_parse(void *decoder, HalDecTask *in_task)
631 {
632 MPP_RET ret = MPP_ERR_UNKNOW;
633 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
634 H264dErrCtx_t *p_err = &p_Dec->errctx;
635
636 in_task->valid = 0;
637 p_Dec->in_task = in_task;
638 p_err->cur_err_flag = 0;
639 p_err->used_ref_flag = 0;
640 p_Dec->is_parser_end = 0;
641 if (p_Dec->p_Cur->sei)
642 memset(p_Dec->p_Cur->sei, 0, sizeof(*p_Dec->p_Cur->sei));
643
644 ret = parse_loop(p_Dec);
645 if (ret) {
646 in_task->flags.parse_err = 1;
647 }
648
649 if (p_Dec->is_parser_end) {
650 p_Dec->is_parser_end = 0;
651 p_Dec->p_Vid->g_framecnt++;
652 ret = update_dpb(p_Dec);
653 if (ret) {
654 in_task->flags.ref_err = 1;
655 }
656 if (in_task->flags.eos) {
657 h264d_flush_dpb_eos(p_Dec);
658 }
659 }
660 in_task->valid = 1;
661 if (!in_task->flags.parse_err) {
662 in_task->syntax.number = p_Dec->dxva_ctx->syn.num;
663 in_task->syntax.data = (void *)p_Dec->dxva_ctx->syn.buf;
664 in_task->flags.used_for_ref = p_err->used_ref_flag;
665 in_task->flags.ref_err |= (p_err->dpb_err_flag | p_err->cur_err_flag) ? 1 : 0;
666 }
667
668 return ret;
669 }
670
671 /*!
672 ***********************************************************************
673 * \brief
674 * callback
675 ***********************************************************************
676 */
h264d_callback(void * decoder,void * errinfo)677 MPP_RET h264d_callback(void *decoder, void *errinfo)
678 {
679 MPP_RET ret = MPP_ERR_UNKNOW;
680 H264_DecCtx_t *p_Dec = (H264_DecCtx_t *)decoder;
681 DecCbHalDone *ctx = (DecCbHalDone *)errinfo;
682 HalDecTask *task_dec = (HalDecTask *)ctx->task;
683 RK_U32 task_err = task_dec->flags.parse_err || task_dec->flags.ref_err;
684 RK_U32 ref_used = task_dec->flags.ref_info_valid ? task_dec->flags.ref_used : 0;
685 RK_U32 hw_dec_err = ctx->hard_err;
686 RK_S32 output = task_dec->output;
687 RK_U32 err_mark = 0;
688 MppFrame frame = NULL;
689
690 INP_CHECK(ret, !decoder);
691
692 if (output >= 0)
693 mpp_buf_slot_get_prop(p_Dec->frame_slots, output, SLOT_FRAME_PTR, &frame);
694
695 if (!frame)
696 goto __RETURN;
697
698 /* check and mark current frame */
699 if (task_err) {
700 err_mark |= MPP_FRAME_ERR_DEC_INVALID;
701 goto DONE;
702 }
703
704 if (hw_dec_err) {
705 err_mark |= MPP_FRAME_ERR_DEC_HW_ERR;
706 goto DONE;
707 }
708
709 if (ref_used) {
710 RK_S32 *refer = task_dec->refer;
711 RK_U32 i;
712
713 for (i = 0; i < 16; i++) {
714 RK_U32 mask = 1 << i;
715 RK_U32 error = 0;
716 MppFrameImpl *tmp = NULL;
717
718 /* not used frame or non-refer frame skip */
719 if (!(ref_used & mask) || (refer[i] < 0))
720 continue;
721
722 /* check and mark error for error reference frame */
723 mpp_buf_slot_get_prop(p_Dec->frame_slots, refer[i],
724 SLOT_FRAME_PTR, &tmp);
725
726 error = tmp->errinfo;
727 H264D_DBG(H264D_DBG_DPB_REF_ERR,
728 "cur_poc %d frm slot %d refer %d slot %d poc %d errinfo %x\n",
729 mpp_frame_get_poc(frame), output, i, refer[i], tmp->poc, error);
730
731 if (error) {
732 mpp_log_f("cur_poc %d mark error ref slot %d:%d poc %d err %x\n",
733 mpp_frame_get_poc(frame), i, refer[i], tmp->poc, error);
734 err_mark |= MPP_FRAME_ERR_UNKNOW;
735 break;
736 }
737 }
738 }
739
740 DONE:
741 if (err_mark) {
742 if (task_dec->flags.used_for_ref) {
743 mpp_frame_set_errinfo(frame, err_mark);
744 } else {
745 mpp_frame_set_discard(frame, err_mark);
746 }
747 }
748
749 H264D_DBG(H264D_DBG_CALLBACK,
750 "[CALLBACK] g_no %d, out_idx %d, dpberr %d, harderr %d, ref_flag %d, "
751 "errinfo %x, discard %x poc %d view_id %d\n",
752 p_Dec->p_Vid->g_framecnt, output, task_err, ctx->hard_err,
753 task_dec->flags.used_for_ref, mpp_frame_get_errinfo(frame),
754 mpp_frame_get_discard(frame), mpp_frame_get_poc(frame),
755 mpp_frame_get_viewid(frame));
756
757 __RETURN:
758 return ret = MPP_OK;
759 }
760 /*!
761 ***********************************************************************
762 * \brief
763 * api struct interface
764 ***********************************************************************
765 */
766
767 const ParserApi api_h264d_parser = {
768 .name = "h264d_parse",
769 .coding = MPP_VIDEO_CodingAVC,
770 .ctx_size = sizeof(H264_DecCtx_t),
771 .flag = 0,
772 .init = h264d_init,
773 .deinit = h264d_deinit,
774 .prepare = h264d_prepare,
775 .parse = h264d_parse,
776 .reset = h264d_reset,
777 .flush = h264d_flush,
778 .control = h264d_control,
779 .callback = h264d_callback,
780 };
781
782