xref: /OK3568_Linux_fs/external/mpp/mpp/codec/dec/h264/h264d_parse.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright 2015 Rockchip Electronics Co. LTD
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
6*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
7*4882a593Smuzhiyun * You may obtain a copy of the License at
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun *      http://www.apache.org/licenses/LICENSE-2.0
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
12*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
13*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*4882a593Smuzhiyun * See the License for the specific language governing permissions and
15*4882a593Smuzhiyun * limitations under the License.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #define MODULE_TAG "h264d_parse"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <string.h>
21*4882a593Smuzhiyun #include <stdlib.h>
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #include "mpp_mem.h"
24*4882a593Smuzhiyun #include "mpp_packet_impl.h"
25*4882a593Smuzhiyun #include "hal_dec_task.h"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #include "h264d_global.h"
28*4882a593Smuzhiyun #include "h264d_parse.h"
29*4882a593Smuzhiyun #include "h264d_slice.h"
30*4882a593Smuzhiyun #include "h264d_sps.h"
31*4882a593Smuzhiyun #include "h264d_pps.h"
32*4882a593Smuzhiyun #include "h264d_sei.h"
33*4882a593Smuzhiyun #include "h264d_init.h"
34*4882a593Smuzhiyun #include "h264d_fill.h"
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define  HEAD_SYNTAX_MAX_SIZE        (12800)
37*4882a593Smuzhiyun #define NALU_TYPE_NORMAL_LENGTH      (1)
38*4882a593Smuzhiyun #define NALU_TYPE_EXT_LENGTH         (5)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun static const RK_U8 g_start_precode[3] = {0, 0, 1};
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun typedef struct h264d_nalu_head_t {
43*4882a593Smuzhiyun     RK_U16  is_frame_end;
44*4882a593Smuzhiyun     RK_U16  nalu_type;
45*4882a593Smuzhiyun     RK_U32  sodb_len;
46*4882a593Smuzhiyun } H264dNaluHead_t;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 
U16_AT(const RK_U8 * ptr)49*4882a593Smuzhiyun static RK_U16 U16_AT(const RK_U8 *ptr)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun     return ptr[0] << 8 | ptr[1];
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun 
U32_AT(const RK_U8 * ptr)54*4882a593Smuzhiyun static RK_U32 U32_AT(const RK_U8 *ptr)
55*4882a593Smuzhiyun {
56*4882a593Smuzhiyun     return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
parse_nal_size(RK_U8 nal_size,RK_U8 * data)59*4882a593Smuzhiyun static RK_U32 parse_nal_size(RK_U8 nal_size, RK_U8 *data)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun     switch (nal_size) {
62*4882a593Smuzhiyun     case 1:
63*4882a593Smuzhiyun         return *data;
64*4882a593Smuzhiyun     case 2:
65*4882a593Smuzhiyun         return U16_AT(data);
66*4882a593Smuzhiyun     case 3:
67*4882a593Smuzhiyun         return ((RK_U64)data[0] << 16) | U16_AT(&data[1]);
68*4882a593Smuzhiyun     case 4:
69*4882a593Smuzhiyun         return U32_AT(data);
70*4882a593Smuzhiyun     }
71*4882a593Smuzhiyun     return 0;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun 
reset_slice(H264dVideoCtx_t * p_Vid)74*4882a593Smuzhiyun static void reset_slice(H264dVideoCtx_t *p_Vid)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun     RK_U32 i = 0, j = 0;
77*4882a593Smuzhiyun     H264_SLICE_t *currSlice = &p_Vid->p_Cur->slice;
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun     memset(currSlice, 0, sizeof(H264_SLICE_t));
80*4882a593Smuzhiyun     //-- re-init parameters
81*4882a593Smuzhiyun     currSlice->view_id = -1;
82*4882a593Smuzhiyun     currSlice->p_Vid = p_Vid;
83*4882a593Smuzhiyun     currSlice->p_Dec = p_Vid->p_Dec;
84*4882a593Smuzhiyun     currSlice->p_Cur = p_Vid->p_Cur;
85*4882a593Smuzhiyun     currSlice->p_Inp = p_Vid->p_Inp;
86*4882a593Smuzhiyun     currSlice->active_sps = p_Vid->active_sps;
87*4882a593Smuzhiyun     currSlice->active_pps = p_Vid->active_pps;
88*4882a593Smuzhiyun     currSlice->active_subsps = p_Vid->active_subsps;
89*4882a593Smuzhiyun     //--- reset listP listB
90*4882a593Smuzhiyun     for (i = 0; i < MAX_NUM_DPB_LAYERS; i++) {
91*4882a593Smuzhiyun         currSlice->listP[i] = p_Vid->p_Cur->listP[i];
92*4882a593Smuzhiyun         currSlice->listB[i] = p_Vid->p_Cur->listB[i];
93*4882a593Smuzhiyun         for (j = 0; j < MAX_LIST_SIZE; j++) {
94*4882a593Smuzhiyun             currSlice->listP[i][j] = NULL;
95*4882a593Smuzhiyun             currSlice->listB[i][j] = NULL;
96*4882a593Smuzhiyun         }
97*4882a593Smuzhiyun         currSlice->listXsizeP[i] = 0;
98*4882a593Smuzhiyun         currSlice->listXsizeB[i] = 0;
99*4882a593Smuzhiyun     }
100*4882a593Smuzhiyun     reset_cur_slice(p_Vid->p_Cur, currSlice);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
realloc_buffer(RK_U8 ** buf,RK_U32 * max_size,RK_U32 add_size)103*4882a593Smuzhiyun static MPP_RET realloc_buffer(RK_U8 **buf, RK_U32 *max_size, RK_U32 add_size)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
106*4882a593Smuzhiyun     if ((*buf) == NULL) {
107*4882a593Smuzhiyun         H264D_ERR("[realloc_buffer] pointer is null, %p \n", (*buf));
108*4882a593Smuzhiyun         ret = MPP_ERR_MALLOC;
109*4882a593Smuzhiyun         goto __FAILED;
110*4882a593Smuzhiyun     }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun     add_size = MPP_ALIGN(add_size, 16);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun     (*buf) = mpp_realloc((*buf), RK_U8, ((*max_size) + add_size));
115*4882a593Smuzhiyun     if ((*buf) == NULL) {
116*4882a593Smuzhiyun         H264D_ERR("[realloc_buffer] ERROR: max_size=%d, add_size=%d \n", (*max_size), add_size);
117*4882a593Smuzhiyun         ret = MPP_ERR_MALLOC;
118*4882a593Smuzhiyun         goto __FAILED;
119*4882a593Smuzhiyun     }
120*4882a593Smuzhiyun     (*max_size) += add_size;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun     return ret = MPP_OK;
123*4882a593Smuzhiyun __FAILED:
124*4882a593Smuzhiyun     return ret;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun 
reset_nalu(H264dCurStream_t * p_strm)127*4882a593Smuzhiyun static void reset_nalu(H264dCurStream_t *p_strm)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun     if (p_strm->endcode_found) {
130*4882a593Smuzhiyun         p_strm->startcode_found = p_strm->endcode_found;
131*4882a593Smuzhiyun         p_strm->nalu_len = 0;
132*4882a593Smuzhiyun         p_strm->nalu_type = H264_NALU_TYPE_NULL;
133*4882a593Smuzhiyun         p_strm->endcode_found = 0;
134*4882a593Smuzhiyun     }
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
find_prefix_code(RK_U8 * p_data,H264dCurStream_t * p_strm)137*4882a593Smuzhiyun static void find_prefix_code(RK_U8 *p_data, H264dCurStream_t *p_strm)
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun     (void)p_data;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun     if ((p_strm->prefixdata & 0x00FFFFFF) == 0x00000001) {
142*4882a593Smuzhiyun         if (p_strm->startcode_found) {
143*4882a593Smuzhiyun             p_strm->endcode_found = 1;
144*4882a593Smuzhiyun         } else {
145*4882a593Smuzhiyun             p_strm->startcode_found = 1;
146*4882a593Smuzhiyun         }
147*4882a593Smuzhiyun     }
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
parser_nalu_header(H264_SLICE_t * currSlice)150*4882a593Smuzhiyun static MPP_RET parser_nalu_header(H264_SLICE_t *currSlice)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun     H264dCurCtx_t   *p_Cur    = currSlice->p_Cur;
155*4882a593Smuzhiyun     BitReadCtx_t    *p_bitctx = &p_Cur->bitctx;
156*4882a593Smuzhiyun     H264_Nalu_t     *cur_nal  = &p_Cur->nalu;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun     mpp_set_bitread_ctx(p_bitctx, cur_nal->sodb_buf, cur_nal->sodb_len);
159*4882a593Smuzhiyun     mpp_set_bitread_pseudo_code_type(p_bitctx, PSEUDO_CODE_H264_H265);
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun     READ_BITS(p_bitctx, 1, &cur_nal->forbidden_bit);
162*4882a593Smuzhiyun     ASSERT(cur_nal->forbidden_bit == 0);
163*4882a593Smuzhiyun     {
164*4882a593Smuzhiyun         RK_S32  *ptmp = NULL;
165*4882a593Smuzhiyun         ptmp = (RK_S32 *)&cur_nal->nal_reference_idc;
166*4882a593Smuzhiyun         READ_BITS(p_bitctx, 2, ptmp); //!<  nal_ref_idc
167*4882a593Smuzhiyun         ptmp = (RK_S32 *)&cur_nal->nalu_type;
168*4882a593Smuzhiyun         READ_BITS(p_bitctx, 5, ptmp); //!< nalu_type
169*4882a593Smuzhiyun     }
170*4882a593Smuzhiyun     cur_nal->ualu_header_bytes = 1;
171*4882a593Smuzhiyun     currSlice->svc_extension_flag = -1; //!< initialize to -1
172*4882a593Smuzhiyun     if (cur_nal->nalu_type == H264_NALU_TYPE_PREFIX
173*4882a593Smuzhiyun         || cur_nal->nalu_type == H264_NALU_TYPE_SLC_EXT) {
174*4882a593Smuzhiyun         READ_ONEBIT(p_bitctx, &currSlice->svc_extension_flag);
175*4882a593Smuzhiyun         if (currSlice->svc_extension_flag) {
176*4882a593Smuzhiyun             currSlice->svcExt.valid = 1;
177*4882a593Smuzhiyun             p_Cur->p_Dec->svc_valid = 1;
178*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->svcExt.idr_flag);
179*4882a593Smuzhiyun             READ_BITS(p_bitctx,    6, &currSlice->svcExt.priority_id);
180*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->svcExt.no_inter_layer_pred_flag);
181*4882a593Smuzhiyun             READ_BITS(p_bitctx,    3, &currSlice->svcExt.dependency_id);
182*4882a593Smuzhiyun             READ_BITS(p_bitctx,    4, &currSlice->svcExt.quality_id);
183*4882a593Smuzhiyun             READ_BITS(p_bitctx,    3, &currSlice->svcExt.temporal_id);
184*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->svcExt.use_ref_base_pic_flag);
185*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->svcExt.discardable_flag);
186*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->svcExt.output_flag);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun             ASSERT(currSlice->svcExt.no_inter_layer_pred_flag == 1);
189*4882a593Smuzhiyun             ASSERT(currSlice->svcExt.dependency_id == 0);
190*4882a593Smuzhiyun             ASSERT(currSlice->svcExt.quality_id == 0);
191*4882a593Smuzhiyun             ASSERT(currSlice->svcExt.use_ref_base_pic_flag == 0);
192*4882a593Smuzhiyun         } else { //!< MVC
193*4882a593Smuzhiyun             currSlice->mvcExt.valid = 1;
194*4882a593Smuzhiyun             p_Cur->p_Dec->mvc_valid = 1;
195*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->mvcExt.non_idr_flag);
196*4882a593Smuzhiyun             READ_BITS(p_bitctx,    6, &currSlice->mvcExt.priority_id);
197*4882a593Smuzhiyun             READ_BITS(p_bitctx,   10, &currSlice->mvcExt.view_id);
198*4882a593Smuzhiyun             READ_BITS(p_bitctx,    3, &currSlice->mvcExt.temporal_id);
199*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->mvcExt.anchor_pic_flag);
200*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->mvcExt.inter_view_flag);
201*4882a593Smuzhiyun             READ_ONEBIT(p_bitctx,     &currSlice->mvcExt.reserved_one_bit);
202*4882a593Smuzhiyun             ASSERT(currSlice->mvcExt.reserved_one_bit == 1);
203*4882a593Smuzhiyun             currSlice->mvcExt.iPrefixNALU = (cur_nal->nalu_type == H264_NALU_TYPE_PREFIX) ? 1 : 0;
204*4882a593Smuzhiyun             //!< combine H264_NALU_TYPE_SLC_EXT into H264_NALU_TYPE_SLICE
205*4882a593Smuzhiyun             if (cur_nal->nalu_type == H264_NALU_TYPE_SLC_EXT) {
206*4882a593Smuzhiyun                 cur_nal->nalu_type = H264_NALU_TYPE_SLICE;
207*4882a593Smuzhiyun             }
208*4882a593Smuzhiyun         }
209*4882a593Smuzhiyun         cur_nal->ualu_header_bytes += 3;
210*4882a593Smuzhiyun     }
211*4882a593Smuzhiyun     /* Move forward the bitread offset */
212*4882a593Smuzhiyun     mpp_set_bitread_ctx(p_bitctx,
213*4882a593Smuzhiyun                         cur_nal->sodb_buf + cur_nal->ualu_header_bytes,
214*4882a593Smuzhiyun                         cur_nal->sodb_len - cur_nal->ualu_header_bytes);
215*4882a593Smuzhiyun     mpp_set_bitread_pseudo_code_type(p_bitctx, PSEUDO_CODE_H264_H265);
216*4882a593Smuzhiyun     p_Cur->p_Dec->nalu_ret = StartofNalu;
217*4882a593Smuzhiyun 
218*4882a593Smuzhiyun     return ret = MPP_OK;
219*4882a593Smuzhiyun __BITREAD_ERR:
220*4882a593Smuzhiyun     p_Cur->p_Dec->nalu_ret = ReadNaluError;
221*4882a593Smuzhiyun     return ret = p_bitctx->ret;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
parser_one_nalu(H264_SLICE_t * currSlice)224*4882a593Smuzhiyun static MPP_RET parser_one_nalu(H264_SLICE_t *currSlice)
225*4882a593Smuzhiyun {
226*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun     FUN_CHECK(ret = parser_nalu_header(currSlice));
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun     if (currSlice->p_Vid->deny_flag &&
231*4882a593Smuzhiyun         currSlice->p_Cur->nalu.nalu_type != H264_NALU_TYPE_SPS) {
232*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NaluNotSupport;
233*4882a593Smuzhiyun         return MPP_OK;
234*4882a593Smuzhiyun     }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun     //!< nalu_parse
237*4882a593Smuzhiyun     switch (currSlice->p_Cur->nalu.nalu_type) {
238*4882a593Smuzhiyun     case H264_NALU_TYPE_SLICE:
239*4882a593Smuzhiyun     case H264_NALU_TYPE_IDR:
240*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SLICE.");
241*4882a593Smuzhiyun         FUN_CHECK(ret = process_slice(currSlice));
242*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = StartOfPicture;
243*4882a593Smuzhiyun         if (currSlice->layer_id && !currSlice->p_Dec->cfg->base.enable_mvc)
244*4882a593Smuzhiyun             currSlice->p_Dec->nalu_ret = MvcDisAble;
245*4882a593Smuzhiyun         break;
246*4882a593Smuzhiyun     case H264_NALU_TYPE_SPS:
247*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SPS");
248*4882a593Smuzhiyun         FUN_CHECK(ret = process_sps(currSlice));
249*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NALU_SPS;
250*4882a593Smuzhiyun         currSlice->p_Vid->deny_flag = 0;
251*4882a593Smuzhiyun         break;
252*4882a593Smuzhiyun     case H264_NALU_TYPE_PPS:
253*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=PPS");
254*4882a593Smuzhiyun         if (process_pps(currSlice) < 0)
255*4882a593Smuzhiyun             H264D_WARNNING("Function error(%d).\n", __LINE__);
256*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NALU_PPS;
257*4882a593Smuzhiyun         break;
258*4882a593Smuzhiyun     case H264_NALU_TYPE_SUB_SPS:
259*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SUB_SPS");
260*4882a593Smuzhiyun         if (process_subsps(currSlice) < 0)
261*4882a593Smuzhiyun             H264D_WARNNING("Function error(%d).\n", __LINE__);
262*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NALU_SubSPS;
263*4882a593Smuzhiyun         break;
264*4882a593Smuzhiyun     case H264_NALU_TYPE_SEI:
265*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "nalu_type=SEI");
266*4882a593Smuzhiyun         ret = process_sei(currSlice);
267*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NALU_SEI;
268*4882a593Smuzhiyun         break;
269*4882a593Smuzhiyun     case H264_NALU_TYPE_SLC_EXT:
270*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_SLC_EXT.");
271*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
272*4882a593Smuzhiyun         break;
273*4882a593Smuzhiyun     case H264_NALU_TYPE_PREFIX:
274*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_PREFIX.");
275*4882a593Smuzhiyun         process_prefix(currSlice);
276*4882a593Smuzhiyun         break;
277*4882a593Smuzhiyun     case H264_NALU_TYPE_AUD:
278*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_AUD.");
279*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
280*4882a593Smuzhiyun         break;
281*4882a593Smuzhiyun     case H264_NALU_TYPE_EOSEQ:
282*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_EOSEQ.");
283*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
284*4882a593Smuzhiyun         break;
285*4882a593Smuzhiyun     case H264_NALU_TYPE_EOSTREAM:
286*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_EOSTREAM.");
287*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
288*4882a593Smuzhiyun         break;
289*4882a593Smuzhiyun     case H264_NALU_TYPE_FILL:
290*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_FILL.");
291*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
292*4882a593Smuzhiyun         break;
293*4882a593Smuzhiyun     case H264_NALU_TYPE_VDRD:
294*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU, "Found H264_NALU_TYPE_VDRD.");
295*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
296*4882a593Smuzhiyun         break;
297*4882a593Smuzhiyun     case H264_NALU_TYPE_DPA:
298*4882a593Smuzhiyun     case H264_NALU_TYPE_DPB:
299*4882a593Smuzhiyun     case H264_NALU_TYPE_DPC:
300*4882a593Smuzhiyun         H264D_DBG(H264D_DBG_PARSE_NALU,
301*4882a593Smuzhiyun                   "Found H264_NALU_TYPE_DPA DPB DPC, and not supported.");
302*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = NaluNotSupport;
303*4882a593Smuzhiyun         break;
304*4882a593Smuzhiyun     default:
305*4882a593Smuzhiyun         currSlice->p_Dec->nalu_ret = SkipNALU;
306*4882a593Smuzhiyun         break;
307*4882a593Smuzhiyun     }
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun     return ret = MPP_OK;
310*4882a593Smuzhiyun __FAILED:
311*4882a593Smuzhiyun     H264D_DBG(H264D_DBG_PARSE_NALU, "parser_one_nalu error.");
312*4882a593Smuzhiyun     currSlice->p_Dec->nalu_ret = ReadNaluError;
313*4882a593Smuzhiyun     return ret;
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun 
add_empty_nalu(H264dCurStream_t * p_strm)316*4882a593Smuzhiyun static MPP_RET add_empty_nalu(H264dCurStream_t *p_strm)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
319*4882a593Smuzhiyun     RK_U8  *p_des = NULL;
320*4882a593Smuzhiyun     RK_U32 add_size = sizeof(H264dNaluHead_t);
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun     if ((p_strm->head_offset + add_size) >= p_strm->head_max_size) {
323*4882a593Smuzhiyun         FUN_CHECK(ret = realloc_buffer(&p_strm->head_buf, &p_strm->head_max_size, HEAD_BUF_ADD_SIZE));
324*4882a593Smuzhiyun     }
325*4882a593Smuzhiyun     p_des = &p_strm->head_buf[p_strm->head_offset];
326*4882a593Smuzhiyun     ((H264dNaluHead_t *)p_des)->is_frame_end  = 1;
327*4882a593Smuzhiyun     ((H264dNaluHead_t *)p_des)->nalu_type = 0;
328*4882a593Smuzhiyun     ((H264dNaluHead_t *)p_des)->sodb_len = 0;
329*4882a593Smuzhiyun     p_strm->head_offset += add_size;
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun     return ret = MPP_OK;
332*4882a593Smuzhiyun __FAILED:
333*4882a593Smuzhiyun     return ret;
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun 
store_cur_nalu(H264dCurCtx_t * p_Cur,H264dCurStream_t * p_strm,H264dDxvaCtx_t * dxva_ctx)336*4882a593Smuzhiyun static MPP_RET store_cur_nalu(H264dCurCtx_t *p_Cur, H264dCurStream_t *p_strm, H264dDxvaCtx_t *dxva_ctx)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
339*4882a593Smuzhiyun     RK_U8 *p_des = NULL;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun     //!< fill head buffer
342*4882a593Smuzhiyun     if (   (p_strm->nalu_type == H264_NALU_TYPE_SLICE)
343*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_IDR)
344*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_SPS)
345*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_PPS)
346*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_SUB_SPS)
347*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_SEI)
348*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_PREFIX)
349*4882a593Smuzhiyun            || (p_strm->nalu_type == H264_NALU_TYPE_SLC_EXT)) {
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun         RK_U32 head_size = MPP_MIN(HEAD_SYNTAX_MAX_SIZE, p_strm->nalu_len);
352*4882a593Smuzhiyun         RK_U32 add_size = head_size + sizeof(H264dNaluHead_t);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun         if ((p_strm->head_offset + add_size) >= p_strm->head_max_size) {
355*4882a593Smuzhiyun             FUN_CHECK(ret = realloc_buffer(&p_strm->head_buf, &p_strm->head_max_size, add_size));
356*4882a593Smuzhiyun         }
357*4882a593Smuzhiyun         p_des = &p_strm->head_buf[p_strm->head_offset];
358*4882a593Smuzhiyun         ((H264dNaluHead_t *)p_des)->is_frame_end  = 0;
359*4882a593Smuzhiyun         ((H264dNaluHead_t *)p_des)->nalu_type = p_strm->nalu_type;
360*4882a593Smuzhiyun         ((H264dNaluHead_t *)p_des)->sodb_len = head_size;
361*4882a593Smuzhiyun         memcpy(p_des + sizeof(H264dNaluHead_t), p_strm->nalu_buf, head_size);
362*4882a593Smuzhiyun         p_strm->head_offset += add_size;
363*4882a593Smuzhiyun     }    //!< fill sodb buffer
364*4882a593Smuzhiyun     if ((p_strm->nalu_type == H264_NALU_TYPE_SLICE)
365*4882a593Smuzhiyun         || (p_strm->nalu_type == H264_NALU_TYPE_IDR)) {
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun         RK_U32 add_size = p_strm->nalu_len + sizeof(g_start_precode);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun         if ((dxva_ctx->strm_offset + add_size) >= dxva_ctx->max_strm_size) {
370*4882a593Smuzhiyun             FUN_CHECK(ret = realloc_buffer(&dxva_ctx->bitstream, &dxva_ctx->max_strm_size, add_size));
371*4882a593Smuzhiyun         }
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun         p_des = &dxva_ctx->bitstream[dxva_ctx->strm_offset];
374*4882a593Smuzhiyun         memcpy(p_des, g_start_precode, sizeof(g_start_precode));
375*4882a593Smuzhiyun         memcpy(p_des + sizeof(g_start_precode), p_strm->nalu_buf, p_strm->nalu_len);
376*4882a593Smuzhiyun         dxva_ctx->strm_offset += add_size;
377*4882a593Smuzhiyun     }
378*4882a593Smuzhiyun     if (h264d_debug & H264D_DBG_WRITE_ES_EN) {
379*4882a593Smuzhiyun         H264dInputCtx_t *p_Inp = p_Cur->p_Inp;
380*4882a593Smuzhiyun         if ((p_strm->nalu_type == H264_NALU_TYPE_SPS)
381*4882a593Smuzhiyun             || (p_strm->nalu_type == H264_NALU_TYPE_PPS)) {
382*4882a593Smuzhiyun             if (p_Inp->spspps_update_flag) {
383*4882a593Smuzhiyun                 p_des = &p_Inp->spspps_buf[p_Inp->spspps_offset];
384*4882a593Smuzhiyun                 memcpy(p_des, g_start_precode, sizeof(g_start_precode));
385*4882a593Smuzhiyun                 memcpy(p_des + sizeof(g_start_precode), p_strm->nalu_buf, p_strm->nalu_len);
386*4882a593Smuzhiyun                 p_Inp->spspps_offset += p_strm->nalu_len + sizeof(g_start_precode);
387*4882a593Smuzhiyun                 p_Inp->spspps_len = p_Inp->spspps_offset;
388*4882a593Smuzhiyun             }
389*4882a593Smuzhiyun         } else if ((p_strm->nalu_type == H264_NALU_TYPE_SLICE)
390*4882a593Smuzhiyun                    || (p_strm->nalu_type == H264_NALU_TYPE_IDR)) {
391*4882a593Smuzhiyun             p_Cur->p_Inp->spspps_update_flag = 1;
392*4882a593Smuzhiyun             p_Inp->spspps_offset = 0;
393*4882a593Smuzhiyun         }
394*4882a593Smuzhiyun     }
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun     return ret = MPP_OK;
397*4882a593Smuzhiyun __FAILED:
398*4882a593Smuzhiyun     return ret;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun 
judge_is_new_frame(H264dCurCtx_t * p_Cur,H264dCurStream_t * p_strm)401*4882a593Smuzhiyun static MPP_RET judge_is_new_frame(H264dCurCtx_t *p_Cur, H264dCurStream_t *p_strm)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
404*4882a593Smuzhiyun     RK_U32 nalu_header_bytes  = 0;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun     BitReadCtx_t    *p_bitctx = &p_Cur->bitctx;
407*4882a593Smuzhiyun     memset(p_bitctx, 0, sizeof(BitReadCtx_t));
408*4882a593Smuzhiyun     {
409*4882a593Smuzhiyun         RK_U32      forbidden_bit = -1;
410*4882a593Smuzhiyun         RK_U32  nal_reference_idc = -1;
411*4882a593Smuzhiyun         mpp_set_bitread_ctx(p_bitctx, p_strm->nalu_buf, 4);
412*4882a593Smuzhiyun         mpp_set_bitread_pseudo_code_type(p_bitctx, PSEUDO_CODE_H264_H265);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun         READ_BITS(p_bitctx, 1, &forbidden_bit);
415*4882a593Smuzhiyun         ASSERT(forbidden_bit == 0);
416*4882a593Smuzhiyun         READ_BITS(p_bitctx, 2, &nal_reference_idc);
417*4882a593Smuzhiyun         READ_BITS(p_bitctx, 5, &p_strm->nalu_type);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun         nalu_header_bytes = 1;
420*4882a593Smuzhiyun         if ((p_strm->nalu_type == H264_NALU_TYPE_PREFIX)
421*4882a593Smuzhiyun             || (p_strm->nalu_type == H264_NALU_TYPE_SLC_EXT)) {
422*4882a593Smuzhiyun             if (p_strm->nalu_type == H264_NALU_TYPE_SLC_EXT) {
423*4882a593Smuzhiyun                 p_strm->nalu_type = H264_NALU_TYPE_SLICE;
424*4882a593Smuzhiyun             }
425*4882a593Smuzhiyun             nalu_header_bytes += 3;
426*4882a593Smuzhiyun         }
427*4882a593Smuzhiyun     }
428*4882a593Smuzhiyun     if ((p_strm->nalu_len == 1)
429*4882a593Smuzhiyun         && (p_strm->nalu_type == H264_NALU_TYPE_SEI
430*4882a593Smuzhiyun             || p_strm->nalu_type == H264_NALU_TYPE_SPS
431*4882a593Smuzhiyun             || p_strm->nalu_type == H264_NALU_TYPE_PPS
432*4882a593Smuzhiyun             || p_strm->nalu_type == H264_NALU_TYPE_SUB_SPS
433*4882a593Smuzhiyun             || p_strm->nalu_type == H264_NALU_TYPE_AUD
434*4882a593Smuzhiyun             /*|| p_strm->nalu_type == H264_NALU_TYPE_PREFIX*/)) { // prefix may insert in slices of one frame
435*4882a593Smuzhiyun         if (p_Cur->p_Dec->have_slice_data) {
436*4882a593Smuzhiyun             p_Cur->p_Dec->is_new_frame = 1;
437*4882a593Smuzhiyun         }
438*4882a593Smuzhiyun         p_Cur->p_Dec->have_slice_data = 0;
439*4882a593Smuzhiyun     } else if ((p_strm->nalu_len > 1)
440*4882a593Smuzhiyun                && (p_strm->nalu_type == H264_NALU_TYPE_SLICE
441*4882a593Smuzhiyun                    || p_strm->nalu_type == H264_NALU_TYPE_IDR)) {
442*4882a593Smuzhiyun         RK_U32 first_mb_in_slice  = 0;
443*4882a593Smuzhiyun         mpp_set_bitread_ctx(p_bitctx, (p_strm->nalu_buf + nalu_header_bytes), 4); // reset
444*4882a593Smuzhiyun         mpp_set_bitread_pseudo_code_type(p_bitctx, PSEUDO_CODE_H264_H265);
445*4882a593Smuzhiyun         READ_UE(p_bitctx, &first_mb_in_slice);
446*4882a593Smuzhiyun         if (first_mb_in_slice == 0) {
447*4882a593Smuzhiyun             p_Cur->last_dts = p_Cur->curr_dts;
448*4882a593Smuzhiyun             p_Cur->last_pts = p_Cur->curr_pts;
449*4882a593Smuzhiyun             p_Cur->curr_dts = p_Cur->p_Inp->in_dts;
450*4882a593Smuzhiyun             p_Cur->curr_pts = p_Cur->p_Inp->in_pts;
451*4882a593Smuzhiyun             if (p_Cur->p_Dec->have_slice_data) {
452*4882a593Smuzhiyun                 p_Cur->p_Dec->is_new_frame = 1;
453*4882a593Smuzhiyun             }
454*4882a593Smuzhiyun             p_Cur->p_Dec->have_slice_data = 1;
455*4882a593Smuzhiyun         }
456*4882a593Smuzhiyun     }
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun     return ret = MPP_OK;
459*4882a593Smuzhiyun __BITREAD_ERR:
460*4882a593Smuzhiyun     return ret = p_bitctx->ret;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun #define  MAX_ES_FILE_SIZE  (100*1024*1024)
464*4882a593Smuzhiyun static RK_U32 global_file_fid = 0;
465*4882a593Smuzhiyun static RK_U64 global_flie_size = 0;
466*4882a593Smuzhiyun /*!
467*4882a593Smuzhiyun ***********************************************************************
468*4882a593Smuzhiyun * \brief
469*4882a593Smuzhiyun *    open stream file to store packet
470*4882a593Smuzhiyun ***********************************************************************
471*4882a593Smuzhiyun */
open_stream_file(H264dInputCtx_t * p_Inp,char * path)472*4882a593Smuzhiyun MPP_RET open_stream_file(H264dInputCtx_t *p_Inp, char *path)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun     if (h264d_debug & H264D_DBG_WRITE_ES_EN) {
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun         sprintf(p_Inp->fname[0], "%s/rkv_h264d_file_00.h264", path);
477*4882a593Smuzhiyun         sprintf(p_Inp->fname[1], "%s/rkv_h264d_file_01.h264", path);
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun         p_Inp->fp = fopen(p_Inp->fname[global_file_fid], "ab"); {
480*4882a593Smuzhiyun             if (p_Inp->fp == NULL) {
481*4882a593Smuzhiyun                 H264D_WARNNING("[open_stream_file] can not open stream file, %s.", p_Inp->fname[global_file_fid]);
482*4882a593Smuzhiyun             }
483*4882a593Smuzhiyun         }
484*4882a593Smuzhiyun     }
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun     return MPP_OK;
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun /*!
489*4882a593Smuzhiyun ***********************************************************************
490*4882a593Smuzhiyun * \brief
491*4882a593Smuzhiyun *    write stream file
492*4882a593Smuzhiyun ***********************************************************************
493*4882a593Smuzhiyun */
fwrite_stream_to_file(H264dInputCtx_t * p_Inp,RK_U8 * pdata,RK_U32 len)494*4882a593Smuzhiyun MPP_RET fwrite_stream_to_file(H264dInputCtx_t *p_Inp, RK_U8 *pdata, RK_U32 len)
495*4882a593Smuzhiyun {
496*4882a593Smuzhiyun     if (p_Inp->fp && (h264d_debug & H264D_DBG_WRITE_ES_EN)) {
497*4882a593Smuzhiyun         if (p_Inp->fp) {
498*4882a593Smuzhiyun             fwrite(pdata, sizeof(RK_U8), len, p_Inp->fp);
499*4882a593Smuzhiyun             fflush(p_Inp->fp);
500*4882a593Smuzhiyun         }
501*4882a593Smuzhiyun         global_flie_size += len;
502*4882a593Smuzhiyun         if (global_flie_size > MAX_ES_FILE_SIZE) {
503*4882a593Smuzhiyun             MPP_FCLOSE(p_Inp->fp);
504*4882a593Smuzhiyun             global_file_fid = 1 - global_file_fid;
505*4882a593Smuzhiyun             global_flie_size = 0;
506*4882a593Smuzhiyun             p_Inp->fp = fopen(p_Inp->fname[global_file_fid], "wb");
507*4882a593Smuzhiyun             if (p_Inp->fp == NULL) {
508*4882a593Smuzhiyun                 H264D_WARNNING("[open_stream_file] can not open stream file, %s", p_Inp->fname[global_file_fid]);
509*4882a593Smuzhiyun             } else {
510*4882a593Smuzhiyun                 fwrite(p_Inp->spspps_buf, sizeof(RK_U8), p_Inp->spspps_len, p_Inp->fp);
511*4882a593Smuzhiyun                 fflush(p_Inp->fp);
512*4882a593Smuzhiyun             }
513*4882a593Smuzhiyun         }
514*4882a593Smuzhiyun     }
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun     return MPP_OK;
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun /*!
519*4882a593Smuzhiyun ***********************************************************************
520*4882a593Smuzhiyun * \brief
521*4882a593Smuzhiyun *    close stream file
522*4882a593Smuzhiyun ***********************************************************************
523*4882a593Smuzhiyun */
close_stream_file(H264dInputCtx_t * p_Inp)524*4882a593Smuzhiyun MPP_RET close_stream_file(H264dInputCtx_t *p_Inp)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun     if (h264d_debug & H264D_DBG_WRITE_ES_EN) {
527*4882a593Smuzhiyun         if (p_Inp->fp) {
528*4882a593Smuzhiyun             fflush(p_Inp->fp);
529*4882a593Smuzhiyun             MPP_FCLOSE(p_Inp->fp);
530*4882a593Smuzhiyun         }
531*4882a593Smuzhiyun     }
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun     return MPP_OK;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun /*!
536*4882a593Smuzhiyun ***********************************************************************
537*4882a593Smuzhiyun * \brief
538*4882a593Smuzhiyun *    prepare function for parser
539*4882a593Smuzhiyun ***********************************************************************
540*4882a593Smuzhiyun */
parse_prepare(H264dInputCtx_t * p_Inp,H264dCurCtx_t * p_Cur)541*4882a593Smuzhiyun MPP_RET parse_prepare(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur)
542*4882a593Smuzhiyun {
543*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun     H264_DecCtx_t   *p_Dec   = p_Inp->p_Dec;
546*4882a593Smuzhiyun     H264dCurStream_t *p_strm = &p_Cur->strm;
547*4882a593Smuzhiyun     MppPacketImpl *pkt_impl  = (MppPacketImpl *)p_Inp->in_pkt;
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun     p_Dec->nalu_ret = NALU_NULL;
550*4882a593Smuzhiyun     p_Inp->task_valid = 0;
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun     //!< check eos
553*4882a593Smuzhiyun     if (p_Inp->pkt_eos && !p_Inp->in_length) {
554*4882a593Smuzhiyun         FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
555*4882a593Smuzhiyun         FUN_CHECK(ret = add_empty_nalu(p_strm));
556*4882a593Smuzhiyun         p_Dec->p_Inp->task_valid = 1;
557*4882a593Smuzhiyun         p_Dec->p_Inp->task_eos = 1;
558*4882a593Smuzhiyun         H264D_LOG("----- end of stream ----");
559*4882a593Smuzhiyun         goto __RETURN;
560*4882a593Smuzhiyun     }
561*4882a593Smuzhiyun     //!< check input
562*4882a593Smuzhiyun     if (!p_Inp->in_length) {
563*4882a593Smuzhiyun         p_Dec->nalu_ret = HaveNoStream;
564*4882a593Smuzhiyun         goto __RETURN;
565*4882a593Smuzhiyun     }
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun     while (pkt_impl->length > 0) {
568*4882a593Smuzhiyun         p_strm->curdata = &p_Inp->in_buf[p_strm->nalu_offset++];
569*4882a593Smuzhiyun         pkt_impl->length--;
570*4882a593Smuzhiyun         p_strm->prefixdata = (p_strm->prefixdata << 8) | (*p_strm->curdata);
571*4882a593Smuzhiyun         if (p_strm->startcode_found) {
572*4882a593Smuzhiyun             if (p_strm->nalu_len >= p_strm->nalu_max_size) {
573*4882a593Smuzhiyun                 FUN_CHECK(ret = realloc_buffer(&p_strm->nalu_buf, &p_strm->nalu_max_size, NALU_BUF_ADD_SIZE));
574*4882a593Smuzhiyun             }
575*4882a593Smuzhiyun             p_strm->nalu_buf[p_strm->nalu_len++] = *p_strm->curdata;
576*4882a593Smuzhiyun             if ((p_strm->nalu_len == NALU_TYPE_NORMAL_LENGTH)
577*4882a593Smuzhiyun                 || (p_strm->nalu_len == NALU_TYPE_EXT_LENGTH)) {
578*4882a593Smuzhiyun                 FUN_CHECK(ret = judge_is_new_frame(p_Cur, p_strm));
579*4882a593Smuzhiyun                 if (p_Cur->p_Dec->is_new_frame) {
580*4882a593Smuzhiyun                     FUN_CHECK(ret = add_empty_nalu(p_strm));
581*4882a593Smuzhiyun                     p_strm->head_offset = 0;
582*4882a593Smuzhiyun                     p_Cur->p_Inp->task_valid = 1;
583*4882a593Smuzhiyun                     p_Cur->p_Dec->is_new_frame = 0;
584*4882a593Smuzhiyun                     break;
585*4882a593Smuzhiyun                 }
586*4882a593Smuzhiyun             }
587*4882a593Smuzhiyun         }
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun         find_prefix_code(p_strm->curdata, p_strm);
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun         if (p_strm->endcode_found) {
592*4882a593Smuzhiyun             p_strm->nalu_len -= START_PREFIX_3BYTE;
593*4882a593Smuzhiyun             if (p_strm->nalu_len > START_PREFIX_3BYTE) {
594*4882a593Smuzhiyun                 while ((p_strm->nalu_len > 0) &&
595*4882a593Smuzhiyun                        (p_strm->nalu_buf[p_strm->nalu_len - 1] == 0x00)) {
596*4882a593Smuzhiyun                     p_strm->nalu_len--;
597*4882a593Smuzhiyun                 }
598*4882a593Smuzhiyun             }
599*4882a593Smuzhiyun             p_Dec->nalu_ret = EndOfNalu;
600*4882a593Smuzhiyun             FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
601*4882a593Smuzhiyun             reset_nalu(p_strm);
602*4882a593Smuzhiyun             break;
603*4882a593Smuzhiyun         }
604*4882a593Smuzhiyun     }
605*4882a593Smuzhiyun     p_Inp->in_length = pkt_impl->length;
606*4882a593Smuzhiyun     //!< check input
607*4882a593Smuzhiyun     if (!p_Inp->in_length) {
608*4882a593Smuzhiyun         p_strm->nalu_offset = 0;
609*4882a593Smuzhiyun         p_Dec->nalu_ret = HaveNoStream;
610*4882a593Smuzhiyun     }
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun     if (p_Inp->pkt_eos && p_Inp->in_length < 4) {
613*4882a593Smuzhiyun         FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
614*4882a593Smuzhiyun         FUN_CHECK(ret = add_empty_nalu(p_strm));
615*4882a593Smuzhiyun         p_Dec->p_Inp->task_valid = 1;
616*4882a593Smuzhiyun         p_Dec->p_Inp->task_eos = 1;
617*4882a593Smuzhiyun     }
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun __RETURN:
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun     return ret = MPP_OK;
622*4882a593Smuzhiyun __FAILED:
623*4882a593Smuzhiyun     return ret;
624*4882a593Smuzhiyun }
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun /*!
627*4882a593Smuzhiyun ***********************************************************************
628*4882a593Smuzhiyun * \brief
629*4882a593Smuzhiyun *    prepare function for parser
630*4882a593Smuzhiyun ***********************************************************************
631*4882a593Smuzhiyun */
parse_prepare_fast(H264dInputCtx_t * p_Inp,H264dCurCtx_t * p_Cur)632*4882a593Smuzhiyun MPP_RET parse_prepare_fast(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur)
633*4882a593Smuzhiyun {
634*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun     H264_DecCtx_t   *p_Dec   = p_Inp->p_Dec;
637*4882a593Smuzhiyun     H264dCurStream_t *p_strm = &p_Cur->strm;
638*4882a593Smuzhiyun     MppPacketImpl *pkt_impl  = (MppPacketImpl *)p_Inp->in_pkt;
639*4882a593Smuzhiyun 
640*4882a593Smuzhiyun     p_Dec->nalu_ret = NALU_NULL;
641*4882a593Smuzhiyun     p_Inp->task_valid = 0;
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun     while (pkt_impl->length > 0) {
644*4882a593Smuzhiyun         p_strm->curdata = &p_Inp->in_buf[p_strm->nalu_offset++];
645*4882a593Smuzhiyun         pkt_impl->length--;
646*4882a593Smuzhiyun         p_strm->prefixdata = (p_strm->prefixdata << 8) | (*p_strm->curdata);
647*4882a593Smuzhiyun         if (p_strm->startcode_found) {
648*4882a593Smuzhiyun             if (p_strm->nalu_len >= p_strm->nalu_max_size) {
649*4882a593Smuzhiyun                 FUN_CHECK(ret = realloc_buffer(&p_strm->nalu_buf, &p_strm->nalu_max_size, NALU_BUF_ADD_SIZE));
650*4882a593Smuzhiyun             }
651*4882a593Smuzhiyun             p_strm->nalu_buf[p_strm->nalu_len++] = *p_strm->curdata;
652*4882a593Smuzhiyun             if (p_strm->nalu_len == 1) {
653*4882a593Smuzhiyun                 p_strm->nalu_type = p_strm->nalu_buf[0] & 0x1F;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun                 if (p_strm->nalu_type == H264_NALU_TYPE_SLICE
656*4882a593Smuzhiyun                     || p_strm->nalu_type == H264_NALU_TYPE_IDR || p_strm->nalu_type == H264_NALU_TYPE_SLC_EXT) {
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun                     if (p_strm->nalu_type == H264_NALU_TYPE_SLC_EXT)
659*4882a593Smuzhiyun                         p_strm->nalu_type = H264_NALU_TYPE_SLICE;
660*4882a593Smuzhiyun 
661*4882a593Smuzhiyun                     p_strm->nalu_len += (RK_U32)pkt_impl->length;
662*4882a593Smuzhiyun                     if (p_strm->nalu_len >= p_strm->nalu_max_size) {
663*4882a593Smuzhiyun                         RK_U32 add_size =  pkt_impl->length + 1 - p_strm->nalu_max_size;
664*4882a593Smuzhiyun                         FUN_CHECK(ret = realloc_buffer(&p_strm->nalu_buf, &p_strm->nalu_max_size, MPP_MAX(NALU_BUF_ADD_SIZE, add_size)));
665*4882a593Smuzhiyun                     }
666*4882a593Smuzhiyun                     memcpy(&p_strm->nalu_buf[0], p_strm->curdata, pkt_impl->length + 1);
667*4882a593Smuzhiyun                     pkt_impl->length = 0;
668*4882a593Smuzhiyun                     p_Cur->p_Inp->task_valid = 1;
669*4882a593Smuzhiyun                     break;
670*4882a593Smuzhiyun                 }
671*4882a593Smuzhiyun             }
672*4882a593Smuzhiyun         }
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun         find_prefix_code(p_strm->curdata, p_strm);
675*4882a593Smuzhiyun 
676*4882a593Smuzhiyun         if (p_strm->endcode_found) {
677*4882a593Smuzhiyun             p_strm->nalu_len -= START_PREFIX_3BYTE;
678*4882a593Smuzhiyun             while (p_strm->nalu_len > 0 && p_strm->nalu_buf[p_strm->nalu_len - 1] == 0x00) {
679*4882a593Smuzhiyun                 p_strm->nalu_len--;
680*4882a593Smuzhiyun             }
681*4882a593Smuzhiyun             p_Dec->nalu_ret = EndOfNalu;
682*4882a593Smuzhiyun             FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
683*4882a593Smuzhiyun             reset_nalu(p_strm);
684*4882a593Smuzhiyun             break;
685*4882a593Smuzhiyun         }
686*4882a593Smuzhiyun     }
687*4882a593Smuzhiyun     if (p_Cur->p_Inp->task_valid) {
688*4882a593Smuzhiyun         FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
689*4882a593Smuzhiyun         FUN_CHECK(ret = add_empty_nalu(p_strm));
690*4882a593Smuzhiyun         p_strm->head_offset = 0;
691*4882a593Smuzhiyun         p_Cur->last_dts = p_Cur->p_Inp->in_dts;
692*4882a593Smuzhiyun         p_Cur->last_pts = p_Cur->p_Inp->in_pts;
693*4882a593Smuzhiyun     }
694*4882a593Smuzhiyun     p_Inp->in_length = pkt_impl->length;
695*4882a593Smuzhiyun     //!< check input
696*4882a593Smuzhiyun     if (!p_Inp->in_length) {
697*4882a593Smuzhiyun         if (!p_Cur->p_Inp->task_valid) {
698*4882a593Smuzhiyun             p_Dec->nalu_ret = EndOfNalu;
699*4882a593Smuzhiyun             FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Dec->dxva_ctx));
700*4882a593Smuzhiyun         } else {
701*4882a593Smuzhiyun             p_Dec->nalu_ret = HaveNoStream;
702*4882a593Smuzhiyun         }
703*4882a593Smuzhiyun         p_strm->nalu_offset = 0;
704*4882a593Smuzhiyun         p_strm->endcode_found = 1;
705*4882a593Smuzhiyun 
706*4882a593Smuzhiyun         reset_nalu(p_strm);
707*4882a593Smuzhiyun         p_strm->startcode_found = 0;
708*4882a593Smuzhiyun     }
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun     return ret = MPP_OK;
711*4882a593Smuzhiyun __FAILED:
712*4882a593Smuzhiyun     return ret;
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun /*!
715*4882a593Smuzhiyun ***********************************************************************
716*4882a593Smuzhiyun * \brief
717*4882a593Smuzhiyun *    main function for parser avcC header
718*4882a593Smuzhiyun ***********************************************************************
719*4882a593Smuzhiyun */
parse_prepare_avcC_header(H264dInputCtx_t * p_Inp,H264dCurCtx_t * p_Cur)720*4882a593Smuzhiyun MPP_RET parse_prepare_avcC_header(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur)
721*4882a593Smuzhiyun {
722*4882a593Smuzhiyun     RK_S32 i = 0;
723*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun     H264dCurStream_t *p_strm = &p_Cur->strm;
726*4882a593Smuzhiyun     RK_U8 *pdata = p_Inp->in_buf;
727*4882a593Smuzhiyun     RK_U64 extrasize = p_Inp->in_length;
728*4882a593Smuzhiyun     MppPacketImpl *pkt_impl  = (MppPacketImpl *)p_Inp->in_pkt;
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun     //!< free nalu_buffer
731*4882a593Smuzhiyun     MPP_FREE(p_strm->nalu_buf);
732*4882a593Smuzhiyun     if (p_Inp->in_length < 7) {
733*4882a593Smuzhiyun         H264D_ERR("avcC too short, len=%d \n", p_Inp->in_length);
734*4882a593Smuzhiyun         goto __FAILED;
735*4882a593Smuzhiyun     }
736*4882a593Smuzhiyun     if (pdata[0] != 1) {
737*4882a593Smuzhiyun         goto __FAILED;
738*4882a593Smuzhiyun     }
739*4882a593Smuzhiyun     p_Inp->profile = pdata[1];
740*4882a593Smuzhiyun     p_Inp->level = pdata[3];
741*4882a593Smuzhiyun     p_Inp->nal_size = 1 + (pdata[4] & 3);
742*4882a593Smuzhiyun     p_Inp->sps_num = pdata[5] & 31;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun     pdata += 6;
745*4882a593Smuzhiyun     extrasize -= 6;
746*4882a593Smuzhiyun     for (i = 0; i < p_Inp->sps_num; ++i) {
747*4882a593Smuzhiyun         p_strm->nalu_len = U16_AT(pdata);
748*4882a593Smuzhiyun         pdata += 2;
749*4882a593Smuzhiyun         extrasize -= 2;
750*4882a593Smuzhiyun         p_strm->nalu_type = H264_NALU_TYPE_SPS;
751*4882a593Smuzhiyun         p_strm->nalu_buf = pdata;
752*4882a593Smuzhiyun         FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Cur->p_Dec->dxva_ctx));
753*4882a593Smuzhiyun         pdata += p_strm->nalu_len;
754*4882a593Smuzhiyun         extrasize -= p_strm->nalu_len;
755*4882a593Smuzhiyun     }
756*4882a593Smuzhiyun     p_strm->nalu_buf = NULL;
757*4882a593Smuzhiyun     p_Inp->pps_num = *pdata;
758*4882a593Smuzhiyun     ++pdata;
759*4882a593Smuzhiyun     --extrasize;
760*4882a593Smuzhiyun     for (i = 0; i < p_Inp->pps_num; ++i) {
761*4882a593Smuzhiyun         p_strm->nalu_len = U16_AT(pdata);
762*4882a593Smuzhiyun         pdata += 2;
763*4882a593Smuzhiyun         extrasize -= 2;
764*4882a593Smuzhiyun         p_strm->nalu_type = H264_NALU_TYPE_PPS;
765*4882a593Smuzhiyun         p_strm->nalu_buf = pdata;
766*4882a593Smuzhiyun         FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Cur->p_Dec->dxva_ctx));
767*4882a593Smuzhiyun         pdata += p_strm->nalu_len;
768*4882a593Smuzhiyun         extrasize -= p_strm->nalu_len;
769*4882a593Smuzhiyun     }
770*4882a593Smuzhiyun     pkt_impl->length = 0;
771*4882a593Smuzhiyun     p_strm->nalu_buf = NULL;
772*4882a593Smuzhiyun     p_strm->startcode_found = 1;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun     ret = MPP_OK;
775*4882a593Smuzhiyun __FAILED:
776*4882a593Smuzhiyun     return ret;
777*4882a593Smuzhiyun }
778*4882a593Smuzhiyun /*!
779*4882a593Smuzhiyun ***********************************************************************
780*4882a593Smuzhiyun * \brief
781*4882a593Smuzhiyun *    main function for parser avcC data
782*4882a593Smuzhiyun ***********************************************************************
783*4882a593Smuzhiyun */
parse_prepare_avcC_data(H264dInputCtx_t * p_Inp,H264dCurCtx_t * p_Cur)784*4882a593Smuzhiyun MPP_RET parse_prepare_avcC_data(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur)
785*4882a593Smuzhiyun {
786*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
787*4882a593Smuzhiyun 
788*4882a593Smuzhiyun     H264dCurStream_t *p_strm = &p_Cur->strm;
789*4882a593Smuzhiyun     MppPacketImpl *pkt_impl  = (MppPacketImpl *)p_Inp->in_pkt;
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun     p_strm->nalu_buf = NULL;
792*4882a593Smuzhiyun     p_Inp->task_valid = 0;
793*4882a593Smuzhiyun     if (p_Inp->pkt_eos) {
794*4882a593Smuzhiyun         p_Inp->task_eos = 1;
795*4882a593Smuzhiyun         if (p_Inp->in_length)
796*4882a593Smuzhiyun             p_Inp->task_valid = 1;
797*4882a593Smuzhiyun         return MPP_OK;
798*4882a593Smuzhiyun     }
799*4882a593Smuzhiyun     VAL_CHECK(ret, (p_Inp->nal_size > 0));
800*4882a593Smuzhiyun     p_strm->curdata = &p_Inp->in_buf[p_strm->nalu_offset];
801*4882a593Smuzhiyun     while (p_Inp->in_length > 0) {
802*4882a593Smuzhiyun         if (p_strm->startcode_found) {
803*4882a593Smuzhiyun             p_strm->nalu_len = parse_nal_size(p_Inp->nal_size, p_strm->curdata);
804*4882a593Smuzhiyun             if (p_strm->nalu_len <= 0 ||  p_strm->nalu_len >= p_Inp->in_length) {
805*4882a593Smuzhiyun                 p_Cur->p_Dec->is_new_frame = 1;
806*4882a593Smuzhiyun                 p_Cur->p_Dec->have_slice_data = 0;
807*4882a593Smuzhiyun                 pkt_impl->length = 0;
808*4882a593Smuzhiyun                 p_Inp->in_length = 0;
809*4882a593Smuzhiyun                 p_strm->nalu_len = 0;
810*4882a593Smuzhiyun                 p_strm->nalu_offset = 0;
811*4882a593Smuzhiyun                 p_strm->startcode_found = 1;
812*4882a593Smuzhiyun                 p_strm->endcode_found = 0;
813*4882a593Smuzhiyun                 p_strm->nalu_buf  = NULL;
814*4882a593Smuzhiyun                 goto __FAILED;
815*4882a593Smuzhiyun             }
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun             p_strm->nalu_buf = p_strm->curdata + p_Inp->nal_size;
818*4882a593Smuzhiyun             judge_is_new_frame(p_Cur, p_strm);
819*4882a593Smuzhiyun             if (p_Cur->p_Dec->is_new_frame) {
820*4882a593Smuzhiyun                 p_Cur->p_Dec->have_slice_data = 0;
821*4882a593Smuzhiyun                 p_strm->startcode_found = 1;
822*4882a593Smuzhiyun                 p_strm->endcode_found = 0;
823*4882a593Smuzhiyun                 break;
824*4882a593Smuzhiyun             }
825*4882a593Smuzhiyun 
826*4882a593Smuzhiyun             p_strm->curdata += p_Inp->nal_size;
827*4882a593Smuzhiyun             p_strm->nalu_offset += p_Inp->nal_size;
828*4882a593Smuzhiyun             pkt_impl->length -= p_Inp->nal_size;
829*4882a593Smuzhiyun             p_Inp->in_length -= p_Inp->nal_size;
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun             p_strm->nalu_buf = p_strm->curdata;
832*4882a593Smuzhiyun             p_strm->nalu_type = p_strm->nalu_buf[0] & 0x1F;
833*4882a593Smuzhiyun             p_strm->startcode_found = 0;
834*4882a593Smuzhiyun             p_strm->endcode_found = 1;
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun             FUN_CHECK(ret = store_cur_nalu(p_Cur, p_strm, p_Cur->p_Dec->dxva_ctx));
837*4882a593Smuzhiyun             p_strm->curdata += p_strm->nalu_len;
838*4882a593Smuzhiyun             p_strm->nalu_offset += p_strm->nalu_len;
839*4882a593Smuzhiyun             pkt_impl->length -= p_strm->nalu_len;
840*4882a593Smuzhiyun             p_Inp->in_length -= p_strm->nalu_len;
841*4882a593Smuzhiyun             p_strm->startcode_found = 1;
842*4882a593Smuzhiyun             p_strm->endcode_found = 0;
843*4882a593Smuzhiyun             p_strm->nalu_len = 0;
844*4882a593Smuzhiyun         }
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun         if (p_Inp->in_length < p_Inp->nal_size) {
847*4882a593Smuzhiyun             p_Cur->p_Dec->is_new_frame = 1;
848*4882a593Smuzhiyun             p_Cur->p_Dec->have_slice_data = 0;
849*4882a593Smuzhiyun             pkt_impl->length = 0;
850*4882a593Smuzhiyun             p_Inp->in_length = 0;
851*4882a593Smuzhiyun             p_strm->nalu_len = 0;
852*4882a593Smuzhiyun             p_strm->nalu_offset = 0;
853*4882a593Smuzhiyun             p_strm->startcode_found = 1;
854*4882a593Smuzhiyun             p_strm->endcode_found = 0;
855*4882a593Smuzhiyun             p_strm->nalu_buf  = NULL;
856*4882a593Smuzhiyun             break;
857*4882a593Smuzhiyun         }
858*4882a593Smuzhiyun     }
859*4882a593Smuzhiyun     //!< one frame end
860*4882a593Smuzhiyun     if (p_Cur->p_Dec->is_new_frame) {
861*4882a593Smuzhiyun         //!< add an empty nalu to tell frame end
862*4882a593Smuzhiyun         FUN_CHECK(ret = add_empty_nalu(p_strm));
863*4882a593Smuzhiyun         //!< reset curstream parameters
864*4882a593Smuzhiyun         p_strm->head_offset = 0;
865*4882a593Smuzhiyun         p_Cur->p_Inp->task_valid = 1;
866*4882a593Smuzhiyun         p_Cur->p_Dec->is_new_frame = 0;
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun         p_Cur->last_dts = p_Inp->in_dts;
869*4882a593Smuzhiyun         p_Cur->last_pts = p_Inp->in_pts;
870*4882a593Smuzhiyun     }
871*4882a593Smuzhiyun     p_strm->nalu_buf = NULL;
872*4882a593Smuzhiyun     ret = MPP_OK;
873*4882a593Smuzhiyun __FAILED:
874*4882a593Smuzhiyun     //p_strm->nalu_len = 0;
875*4882a593Smuzhiyun     p_Cur->last_dts  = p_Inp->in_dts;
876*4882a593Smuzhiyun     p_Cur->last_pts  = p_Inp->in_pts;
877*4882a593Smuzhiyun     p_Inp->p_Dec->nalu_ret = HaveNoStream;
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun     return ret;
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun 
882*4882a593Smuzhiyun 
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun /*!
885*4882a593Smuzhiyun ***********************************************************************
886*4882a593Smuzhiyun * \brief
887*4882a593Smuzhiyun *    main function for parser
888*4882a593Smuzhiyun ***********************************************************************
889*4882a593Smuzhiyun */
parse_loop(H264_DecCtx_t * p_Dec)890*4882a593Smuzhiyun MPP_RET parse_loop(H264_DecCtx_t *p_Dec)
891*4882a593Smuzhiyun {
892*4882a593Smuzhiyun     MPP_RET ret = MPP_ERR_UNKNOW;
893*4882a593Smuzhiyun     RK_U8 *p_curdata = NULL;
894*4882a593Smuzhiyun     RK_U8 while_loop_flag = 1;
895*4882a593Smuzhiyun     H264dNaluHead_t *p_head = NULL;
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun     INP_CHECK(ret, !p_Dec);
898*4882a593Smuzhiyun     //!< ==== loop ====
899*4882a593Smuzhiyun     p_Dec->next_state = SliceSTATE_ResetSlice;
900*4882a593Smuzhiyun     p_curdata = p_Dec->p_Cur->strm.head_buf;
901*4882a593Smuzhiyun 
902*4882a593Smuzhiyun     while (while_loop_flag) {
903*4882a593Smuzhiyun         switch (p_Dec->next_state) {
904*4882a593Smuzhiyun         case SliceSTATE_ResetSlice:
905*4882a593Smuzhiyun             reset_slice(p_Dec->p_Vid);
906*4882a593Smuzhiyun             p_Dec->next_state = SliceSTATE_ReadNalu;
907*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_ResetSlice");
908*4882a593Smuzhiyun             break;
909*4882a593Smuzhiyun         case SliceSTATE_ReadNalu:
910*4882a593Smuzhiyun             p_head = (H264dNaluHead_t *)p_curdata;
911*4882a593Smuzhiyun             if (p_head->is_frame_end) {
912*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_RegisterOneFrame;
913*4882a593Smuzhiyun                 p_Dec->nalu_ret = HaveNoStream;
914*4882a593Smuzhiyun             } else {
915*4882a593Smuzhiyun                 p_curdata += sizeof(H264dNaluHead_t);
916*4882a593Smuzhiyun                 memset(&p_Dec->p_Cur->nalu, 0, sizeof(H264_Nalu_t));
917*4882a593Smuzhiyun                 p_Dec->p_Cur->nalu.sodb_buf = p_curdata;
918*4882a593Smuzhiyun                 p_Dec->p_Cur->nalu.sodb_len = p_head->sodb_len;
919*4882a593Smuzhiyun                 p_curdata += p_head->sodb_len;
920*4882a593Smuzhiyun                 p_Dec->nalu_ret = EndOfNalu;
921*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_ParseNalu;
922*4882a593Smuzhiyun             }
923*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_ReadNalu");
924*4882a593Smuzhiyun             break;
925*4882a593Smuzhiyun         case SliceSTATE_ParseNalu:
926*4882a593Smuzhiyun             FUN_CHECK(ret = parser_one_nalu(&p_Dec->p_Cur->slice));
927*4882a593Smuzhiyun             if (p_Dec->nalu_ret == StartOfSlice) {
928*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_GetSliceData;
929*4882a593Smuzhiyun             } else if (p_Dec->nalu_ret == StartOfPicture) {
930*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_InitPicture;
931*4882a593Smuzhiyun             }  else if (p_Dec->nalu_ret == MvcDisAble) {
932*4882a593Smuzhiyun                 H264D_LOG("xxxxxxxx MVC disable");
933*4882a593Smuzhiyun                 goto __FAILED;
934*4882a593Smuzhiyun             } else if (p_Dec->nalu_ret == NaluNotSupport) {
935*4882a593Smuzhiyun                 H264D_LOG("NALU not support, abort decoding");
936*4882a593Smuzhiyun                 goto __FAILED;
937*4882a593Smuzhiyun             } else {
938*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_ReadNalu;
939*4882a593Smuzhiyun             }
940*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_ParseNalu");
941*4882a593Smuzhiyun             break;
942*4882a593Smuzhiyun         case SliceSTATE_InitPicture:
943*4882a593Smuzhiyun             if (!p_Dec->p_Vid->iNumOfSlicesDecoded) {
944*4882a593Smuzhiyun                 FUN_CHECK(ret = init_picture(&p_Dec->p_Cur->slice));
945*4882a593Smuzhiyun                 p_Dec->is_parser_end = 1;
946*4882a593Smuzhiyun             }
947*4882a593Smuzhiyun             p_Dec->next_state = SliceSTATE_GetSliceData;
948*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_InitPicture");
949*4882a593Smuzhiyun             break;
950*4882a593Smuzhiyun         case SliceSTATE_GetSliceData:
951*4882a593Smuzhiyun             FUN_CHECK(ret = fill_slice_syntax(&p_Dec->p_Cur->slice, p_Dec->dxva_ctx));
952*4882a593Smuzhiyun             p_Dec->p_Vid->iNumOfSlicesDecoded++;
953*4882a593Smuzhiyun             if (p_Dec->is_parser_end) {
954*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_RegisterOneFrame;
955*4882a593Smuzhiyun             } else {
956*4882a593Smuzhiyun                 p_Dec->next_state = SliceSTATE_ResetSlice;
957*4882a593Smuzhiyun             }
958*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_GetSliceData");
959*4882a593Smuzhiyun             break;
960*4882a593Smuzhiyun         case SliceSTATE_RegisterOneFrame:
961*4882a593Smuzhiyun             if (!p_Dec->is_parser_end) {
962*4882a593Smuzhiyun                 ret = MPP_NOK;
963*4882a593Smuzhiyun                 goto __FAILED;
964*4882a593Smuzhiyun             }
965*4882a593Smuzhiyun             commit_buffer(p_Dec->dxva_ctx);
966*4882a593Smuzhiyun             while_loop_flag = 0;
967*4882a593Smuzhiyun             p_Dec->next_state = SliceSTATE_ReadNalu;
968*4882a593Smuzhiyun             H264D_DBG(H264D_DBG_LOOP_STATE, "SliceSTATE_RegisterOneFrame");
969*4882a593Smuzhiyun             break;
970*4882a593Smuzhiyun         default:
971*4882a593Smuzhiyun             ret = MPP_NOK;
972*4882a593Smuzhiyun             break;
973*4882a593Smuzhiyun         }
974*4882a593Smuzhiyun     }
975*4882a593Smuzhiyun 
976*4882a593Smuzhiyun __RETURN:
977*4882a593Smuzhiyun     return ret = MPP_OK;
978*4882a593Smuzhiyun __FAILED:
979*4882a593Smuzhiyun     p_Dec->nalu_ret = NALU_NULL;
980*4882a593Smuzhiyun     p_Dec->dxva_ctx->slice_count = 0;
981*4882a593Smuzhiyun     p_Dec->dxva_ctx->strm_offset = 0;
982*4882a593Smuzhiyun     p_Dec->p_Vid->iNumOfSlicesDecoded = 0;
983*4882a593Smuzhiyun     p_Dec->p_Vid->exit_picture_flag   = 0;
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun     return ret;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 
989