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