xref: /rockchip-linux_mpp/mpp/codec/dec/h264/h264d_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 
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