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