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