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