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