1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19 *******************************************************************************
20 * @file
21 * ihevcd_decode.c
22 *
23 * @brief
24 * Contains codecs main decode function
25 *
26 * @author
27 * Harish
28 *
29 * @par List of Functions:
30 * - fill_outargs()
31 * - ihevcd_decode
32 * @remarks
33 * None
34 *
35 *******************************************************************************
36 */
37 /*****************************************************************************/
38 /* File Includes */
39 /*****************************************************************************/
40 #include <stdio.h>
41 #include <stddef.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45
46 #include "ihevc_typedefs.h"
47 #include "iv.h"
48 #include "ivd.h"
49 #include "ihevcd_cxa.h"
50 #include "ithread.h"
51
52 #include "ihevc_defs.h"
53 #include "ihevc_debug.h"
54 #include "ihevc_structs.h"
55 #include "ihevc_macros.h"
56 #include "ihevc_platform_macros.h"
57 #include "ihevc_cabac_tables.h"
58 #include "ihevc_disp_mgr.h"
59 #include "ihevc_buf_mgr.h"
60 #include "ihevc_dpb_mgr.h"
61 #include "ihevc_error.h"
62
63 #include "ihevcd_defs.h"
64 #include "ihevcd_function_selector.h"
65 #include "ihevcd_structs.h"
66 #include "ihevcd_error.h"
67 #include "ihevcd_nal.h"
68 #include "ihevcd_bitstream.h"
69 #include "ihevcd_fmt_conv.h"
70 #include "ihevcd_job_queue.h"
71 #include "ihevcd_debug.h"
72 #include "ihevcd_process_slice.h"
73 #include "ihevcd_ittiam_logo.h"
74 #include "ihevcd_profile.h"
75
76 #define NUM_FRAMES_LIMIT_ENABLED 0
77
78 #if NUM_FRAMES_LIMIT_ENABLED
79 #define NUM_FRAMES_LIMIT 10000
80 #else
81 #define NUM_FRAMES_LIMIT 0x7FFFFFFF
82 #endif
83
84 IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
85 process_ctxt_t *ps_proc,
86 UWORD8 *pu1_y_dst,
87 UWORD8 *pu1_u_dst,
88 UWORD8 *pu1_v_dst,
89 WORD32 cur_row,
90 WORD32 num_rows);
91 WORD32 ihevcd_init(codec_t *ps_codec);
92
93 WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
94 WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
95 /*****************************************************************************/
96 /* Function Prototypes */
97 /*****************************************************************************/
98
99
100 /**
101 *******************************************************************************
102 *
103 * @brief Fills output arguments for decode process
104 *
105 * @par Description
106 * Fills elements in the output structure based on the current state
107 *
108 * @param[in] ps_codec
109 * Codec context
110 *
111 * @param[in] ps_dec_ip
112 * Pointer to input structure
113 *
114 * @param[in] ps_dec_op
115 * Pointer to output structure
116 *
117 * @returns none
118 *
119 * @remarks
120 *
121 *******************************************************************************
122 */
ihevcd_map_error(IHEVCD_ERROR_T e_error)123 static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error)
124 {
125 UWORD32 error_code = 0;
126 error_code = e_error;
127 switch(error_code)
128 {
129 case IHEVCD_SUCCESS :
130 break;
131 case IHEVCD_INIT_NOT_DONE:
132 case IHEVCD_LEVEL_UNSUPPORTED:
133 case IHEVCD_NUM_REF_UNSUPPORTED:
134 case IHEVCD_NUM_REORDER_UNSUPPORTED:
135 case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED:
136 case IHEVCD_INSUFFICIENT_MEM_MVBANK:
137 case IHEVCD_INSUFFICIENT_MEM_PICBUF:
138 error_code |= 1 << IVD_FATALERROR;
139 break;
140 case IHEVCD_INVALID_DISP_STRD:
141 case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
142 case IHEVCD_UNSUPPORTED_VPS_ID:
143 case IHEVCD_UNSUPPORTED_SPS_ID:
144 case IHEVCD_UNSUPPORTED_PPS_ID:
145 case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
146 case IHEVCD_UNSUPPORTED_BIT_DEPTH:
147 case IHEVCD_BUF_MGR_ERROR:
148 case IHEVCD_NO_FREE_MVBANK:
149 case IHEVCD_NO_FREE_PICBUF:
150 case IHEVCD_SLICE_IN_HEADER_MODE:
151 case IHEVCD_END_OF_SEQUENCE:
152 break;
153 default:
154 break;
155 }
156 return error_code;
157 }
158 /**
159 *******************************************************************************
160 *
161 * @brief Fills output arguments for decode process
162 *
163 * @par Description
164 * Fills elements in the output structure based on the current state
165 *
166 * @param[in] ps_codec
167 * Codec context
168 *
169 * @param[in] ps_dec_ip
170 * Pointer to input structure
171 *
172 * @param[in] ps_dec_op
173 * Pointer to output structure
174 *
175 * @returns none
176 *
177 * @remarks
178 *
179 *******************************************************************************
180 */
ihevcd_fill_outargs(codec_t * ps_codec,ivd_video_decode_ip_t * ps_dec_ip,ivd_video_decode_op_t * ps_dec_op)181 static void ihevcd_fill_outargs(codec_t *ps_codec,
182 ivd_video_decode_ip_t *ps_dec_ip,
183 ivd_video_decode_op_t *ps_dec_op)
184 {
185
186 ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
187 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
188 - ps_codec->i4_bytes_remaining;
189 if(ps_codec->i4_sps_done)
190 {
191 ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
192 ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
193 }
194 else
195 {
196 ps_dec_op->u4_pic_wd = 0;
197 ps_dec_op->u4_pic_ht = 0;
198 }
199
200 ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
201 ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
202 ps_dec_op->u4_new_seq = 0;
203
204 ps_dec_op->u4_output_present = 0;
205 ps_dec_op->u4_progressive_frame_flag = 1;
206 ps_dec_op->u4_is_ref_flag = 1;
207 ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
208 ps_dec_op->u4_is_ref_flag = 1;
209
210 ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
211
212 ps_dec_op->u4_ts = (UWORD32)(-1);
213 ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
214 if(ps_codec->i4_flush_mode)
215 {
216 ps_dec_op->u4_num_bytes_consumed = 0;
217 /*In the case of flush ,since no frame is decoded set pic type as invalid*/
218 ps_dec_op->u4_is_ref_flag = 0;
219 ps_dec_op->e_pic_type = IV_NA_FRAME;
220 ps_dec_op->u4_frame_decoded_flag = 0;
221
222 }
223 /* If there is a display buffer */
224 if(ps_codec->ps_disp_buf)
225 {
226 pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
227
228 ps_dec_op->u4_output_present = 1;
229 ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
230 if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
231 ps_dec_op->u4_output_present = 0;
232 ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
233 ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
234
235 if(ps_codec->i4_share_disp_buf)
236 {
237 ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
238 if(ps_codec->e_chroma_fmt != IV_YUV_420P)
239 {
240 ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
241 ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
242 }
243 else
244 {
245 WORD32 i;
246 UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
247 for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
248 {
249 WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
250 if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
251 {
252 pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
253 pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
254
255 pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
256 pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
257 break;
258 }
259 }
260 ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
261 ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
262 }
263 ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
264 }
265 else
266 {
267 ps_dec_op->s_disp_frm_buf.pv_y_buf =
268 ps_dec_ip->s_out_buffer.pu1_bufs[0];
269 ps_dec_op->s_disp_frm_buf.pv_u_buf =
270 ps_dec_ip->s_out_buffer.pu1_bufs[1];
271 ps_dec_op->s_disp_frm_buf.pv_v_buf =
272 ps_dec_ip->s_out_buffer.pu1_bufs[2];
273 ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
274 }
275
276 if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
277 || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
278 {
279 ps_dec_op->s_disp_frm_buf.u4_u_strd =
280 ps_dec_op->s_disp_frm_buf.u4_y_strd;
281 ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
282 ps_dec_op->s_disp_frm_buf.u4_u_wd =
283 ps_dec_op->s_disp_frm_buf.u4_y_wd;
284 ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
285 ps_dec_op->s_disp_frm_buf.u4_u_ht =
286 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
287 ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
288 }
289 else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
290 {
291 ps_dec_op->s_disp_frm_buf.u4_u_strd =
292 ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
293 ps_dec_op->s_disp_frm_buf.u4_v_strd =
294 ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
295 ps_dec_op->s_disp_frm_buf.u4_u_wd =
296 ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
297 ps_dec_op->s_disp_frm_buf.u4_v_wd =
298 ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
299 ps_dec_op->s_disp_frm_buf.u4_u_ht =
300 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
301 ps_dec_op->s_disp_frm_buf.u4_v_ht =
302 ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
303 }
304
305 }
306 else if(ps_codec->i4_flush_mode)
307 {
308 ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
309 /* Come out of flush mode */
310 ps_codec->i4_flush_mode = 0;
311 }
312
313 }
314
315 /**
316 *******************************************************************************
317 *
318 * @brief
319 * Codec process call
320 *
321 * @par Description:
322 * Codec process call Tests for few error checks Handle flush and decode
323 * header related code Parse bitstream for start codes For each NAL unit
324 * call decode NAL function Once a complete frame is decoded (in frame
325 * decode mode) Fill output arguments and return
326 *
327 * @param[in] ps_codec_obj
328 * Pointer to codec object at API level
329 *
330 * @param[in] pv_api_ip
331 * Pointer to input argument structure
332 *
333 * @param[in] pv_api_op
334 * Pointer to output argument structure
335 *
336 * @returns Status
337 *
338 * @remarks
339 *
340 *
341 *******************************************************************************
342 */
ihevcd_decode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)343 WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
344 {
345 WORD32 ret = IV_SUCCESS;
346 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
347 ivd_video_decode_ip_t *ps_dec_ip;
348 ivd_video_decode_op_t *ps_dec_op;
349
350 WORD32 proc_idx = 0;
351 WORD32 prev_proc_idx = 0;
352
353 /* Initialize error code */
354 ps_codec->i4_error_code = 0;
355
356 ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
357 ps_dec_op = (ivd_video_decode_op_t *)pv_api_op;
358
359 {
360 UWORD32 u4_size = ps_dec_op->u4_size;
361 memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t));
362 ps_dec_op->u4_size = u4_size; //Restore size field
363 }
364 if(ps_codec->i4_init_done != 1)
365 {
366 ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
367 ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
368 return IV_FAIL;
369 }
370
371 if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
372 {
373 ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
374 ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
375 return IV_FAIL;
376 }
377
378 /* If reset flag is set, flush the existing buffers */
379 if(ps_codec->i4_reset_flag)
380 {
381 ps_codec->i4_flush_mode = 1;
382 }
383
384 /*Data memory barries instruction,so that bitstream write by the application is complete*/
385 //arm_dsb();
386 /* In case the decoder is not in flush mode check for input buffer validity */
387 if(0 == ps_codec->i4_flush_mode)
388 {
389 if(ps_dec_ip->pv_stream_buffer == NULL)
390 {
391 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
392 ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
393 return IV_FAIL;
394 }
395 if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
396 {
397 if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
398 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
399 else
400 ps_dec_op->u4_num_bytes_consumed = 0;
401
402 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
403 ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
404 return IV_FAIL;
405
406 }
407 }
408
409 #ifdef APPLY_CONCEALMENT
410 {
411 WORD32 num_mbs;
412
413 num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
414 /* Reset MB Count at the beginning of every process call */
415 ps_codec->mb_count = 0;
416 memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
417 }
418 #endif
419
420 if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
421 {
422 UWORD32 i;
423 if(ps_dec_ip->s_out_buffer.u4_num_bufs == 0)
424 {
425 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
426 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
427 return IV_FAIL;
428 }
429
430 for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
431 {
432 if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
433 {
434 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
435 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
436 return IV_FAIL;
437 }
438
439 if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
440 {
441 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
442 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
443 return IV_FAIL;
444 }
445 }
446 }
447
448 ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
449 ps_codec->u4_ts = ps_dec_ip->u4_ts;
450 if(ps_codec->i4_flush_mode)
451 {
452
453 ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
454 ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
455
456 ps_dec_op->u4_new_seq = 0;
457
458 ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
459 (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
460 /* In case of non-shared mode, then convert/copy the frame to output buffer */
461 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
462 if((ps_codec->ps_disp_buf)
463 && ((0 == ps_codec->i4_share_disp_buf)
464 || (IV_YUV_420P
465 == ps_codec->e_chroma_fmt)))
466 {
467
468 process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
469 if(0 == ps_proc->i4_init_done)
470 {
471 ihevcd_init_proc_ctxt(ps_proc, 0);
472 }
473
474 /* Set remaining number of rows to be processed */
475 ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
476 ps_dec_ip->s_out_buffer.pu1_bufs[0],
477 ps_dec_ip->s_out_buffer.pu1_bufs[1],
478 ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
479 ps_codec->i4_disp_ht);
480
481 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
482 ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
483 }
484
485 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
486
487 if(1 == ps_dec_op->u4_output_present)
488 {
489 WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
490 WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
491
492 if(ypos < 0)
493 ypos = 0;
494
495 if(xpos < 0)
496 xpos = 0;
497
498 INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
499 ps_dec_ip->s_out_buffer.pu1_bufs[1],
500 ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
501 xpos,
502 ypos,
503 ps_codec->e_chroma_fmt,
504 ps_codec->i4_disp_wd,
505 ps_codec->i4_disp_ht);
506 }
507
508
509 if(NULL == ps_codec->ps_disp_buf)
510 {
511 /* If in flush mode and there are no more buffers to flush,
512 * check for the reset flag and reset the decoder */
513 if(ps_codec->i4_reset_flag)
514 {
515 ihevcd_init(ps_codec);
516 }
517 return (IV_FAIL);
518 }
519
520 return (IV_SUCCESS);
521
522 }
523 /* In case of shared mode, check if there is a free buffer for reconstruction */
524 if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
525 {
526 WORD32 buf_status;
527 buf_status = 1;
528 if(ps_codec->pv_pic_buf_mgr)
529 buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
530
531 /* If there is no free buffer, then return with an error code */
532 if(0 == buf_status)
533 {
534 ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
535 ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
536 return IV_FAIL;
537 }
538 }
539 ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
540 ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
541 ps_codec->s_parse.i4_end_of_frame = 0;
542
543 ps_codec->i4_pic_present = 0;
544 ps_codec->i4_slice_error = 0;
545 ps_codec->ps_disp_buf = NULL;
546
547 if(ps_codec->i4_num_cores > 1)
548 {
549 ithread_set_affinity(0);
550 }
551 while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
552 {
553 WORD32 nal_len;
554 WORD32 nal_ofst;
555 WORD32 bits_len;
556
557 if(ps_codec->i4_slice_error)
558 {
559 slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
560 WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
561 ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
562 if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
563 ps_codec->i4_slice_error = 0;
564 }
565
566 if(ps_codec->pu1_bitsbuf_dynamic)
567 {
568 ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
569 ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
570 }
571 else
572 {
573 ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
574 ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
575 }
576
577 nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
578 ps_codec->i4_bytes_remaining);
579
580 ps_codec->i4_nal_ofst = nal_ofst;
581 {
582 WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
583
584 bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
585 ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
586 ps_codec->pu1_bitsbuf,
587 bytes_remaining,
588 &nal_len, &bits_len);
589
590 /* Decoder may read upto 8 extra bytes at the end of frame */
591 /* These are not used, but still set them to zero to avoid uninitialized reads */
592 if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
593 {
594 memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
595 }
596 }
597 /* This may be used to update the offsets for tiles and entropy sync row offsets */
598 ps_codec->i4_num_emln_bytes = nal_len - bits_len;
599 ps_codec->i4_nal_len = nal_len;
600
601 ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
602 bits_len);
603
604 ret = ihevcd_nal_unit(ps_codec);
605
606 /* If the frame is incomplete and
607 * the bytes remaining is zero or a header is received,
608 * complete the frame treating it to be in error */
609 if(ps_codec->i4_pic_present &&
610 (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
611 {
612 if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
613 (ps_codec->i4_header_in_slice_mode))
614 {
615 slice_header_t *ps_slice_hdr_next;
616
617 ps_codec->s_parse.i4_cur_slice_idx--;
618 if(ps_codec->s_parse.i4_cur_slice_idx < 0)
619 ps_codec->s_parse.i4_cur_slice_idx = 0;
620
621 ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
622 ps_slice_hdr_next->i2_ctb_x = 0;
623 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
624 ps_codec->i4_slice_error = 1;
625 continue;
626 }
627 }
628
629 if(IHEVCD_IGNORE_SLICE == ret)
630 {
631 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
632 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
633
634 continue;
635 }
636
637 if((IVD_RES_CHANGED == ret) ||
638 (IHEVCD_UNSUPPORTED_DIMENSIONS == ret))
639 {
640 break;
641 }
642
643 /* Update bytes remaining and bytes consumed and input bitstream pointer */
644 /* Do not consume the NAL in the following cases */
645 /* Slice header reached during header decode mode */
646 /* TODO: Next picture's slice reached */
647 if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
648 {
649 if((0 == ps_codec->i4_slice_error) ||
650 (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
651 {
652 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
653 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
654 }
655 if(ret != IHEVCD_SUCCESS)
656 break;
657
658 if(ps_codec->s_parse.i4_end_of_frame)
659 break;
660 }
661 else
662 {
663 ret = IHEVCD_SUCCESS;
664 break;
665 }
666
667 /* Allocate dynamic bitstream buffer once SPS is decoded */
668 if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
669 {
670 WORD32 ret;
671 ret = ihevcd_allocate_dynamic_bufs(ps_codec);
672 if(ret != IV_SUCCESS)
673 {
674 /* Free any dynamic buffers that are allocated */
675 ihevcd_free_dynamic_bufs(ps_codec);
676 ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
677 ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
678 ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
679
680 return IV_FAIL;
681 }
682 }
683
684 BREAK_AFTER_SLICE_NAL();
685 }
686
687 if((ps_codec->u4_pic_cnt == 0) && (ret != IHEVCD_SUCCESS))
688 {
689 ps_codec->i4_error_code = ret;
690
691 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
692 return IV_FAIL;
693 }
694
695 if(1 == ps_codec->i4_pic_present)
696 {
697 WORD32 i;
698 sps_t *ps_sps = ps_codec->s_parse.ps_sps;
699 ps_codec->i4_first_pic_done = 1;
700
701 /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue */
702 if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
703 {
704
705 /* Add job queue for format conversion / frame copy for each ctb row */
706 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
707 process_ctxt_t *ps_proc;
708
709 /* i4_num_cores - 1 contexts are currently being used by other threads */
710 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
711
712 if((ps_codec->ps_disp_buf) &&
713 ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
714 {
715 /* If format conversion jobs were not issued in pic_init() add them here */
716 if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
717 (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
718 for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
719 {
720 proc_job_t s_job;
721 IHEVCD_ERROR_T ret;
722 s_job.i4_cmd = CMD_FMTCONV;
723 s_job.i2_ctb_cnt = 0;
724 s_job.i2_ctb_x = 0;
725 s_job.i2_ctb_y = i;
726 s_job.i2_slice_idx = 0;
727 s_job.i4_tu_coeff_data_ofst = 0;
728 ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
729 &s_job, sizeof(proc_job_t), 1);
730 if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
731 return (WORD32)ret;
732 }
733 }
734 /* Reached end of frame : Signal terminate */
735 /* The terminate flag is checked only after all the jobs are dequeued */
736 ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
737
738 while(1)
739 {
740 IHEVCD_ERROR_T ret;
741 proc_job_t s_job;
742 process_ctxt_t *ps_proc;
743
744 /* i4_num_cores - 1 contexts are currently being used by other threads */
745 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
746
747 ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
748 sizeof(proc_job_t), 1);
749 if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
750 break;
751
752 ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
753 ps_proc->i4_ctb_x = s_job.i2_ctb_x;
754 ps_proc->i4_ctb_y = s_job.i2_ctb_y;
755 ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
756
757 if(CMD_PROCESS == s_job.i4_cmd)
758 {
759 ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
760
761 ihevcd_process(ps_proc);
762 }
763 else if(CMD_FMTCONV == s_job.i4_cmd)
764 {
765 sps_t *ps_sps = ps_codec->s_parse.ps_sps;
766 WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
767 if(0 == ps_proc->i4_init_done)
768 {
769 ihevcd_init_proc_ctxt(ps_proc, 0);
770 }
771
772 num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
773 if(num_rows < 0)
774 num_rows = 0;
775
776 ihevcd_fmt_conv(ps_codec, ps_proc,
777 ps_dec_ip->s_out_buffer.pu1_bufs[0],
778 ps_dec_ip->s_out_buffer.pu1_bufs[1],
779 ps_dec_ip->s_out_buffer.pu1_bufs[2],
780 s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
781 num_rows);
782 }
783 }
784 }
785 /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
786 /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
787 else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
788 (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
789 (ps_codec->s_parse.i4_end_of_frame))
790 {
791 process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
792 /* Set remaining number of rows to be processed */
793 ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
794 - ps_codec->s_fmt_conv.i4_cur_row;
795 if(0 == ps_proc->i4_init_done)
796 {
797 ihevcd_init_proc_ctxt(ps_proc, 0);
798 }
799
800 if(ps_codec->s_fmt_conv.i4_num_rows < 0)
801 ps_codec->s_fmt_conv.i4_num_rows = 0;
802
803 ret = ihevcd_fmt_conv(ps_codec, ps_proc,
804 ps_dec_ip->s_out_buffer.pu1_bufs[0],
805 ps_dec_ip->s_out_buffer.pu1_bufs[1],
806 ps_dec_ip->s_out_buffer.pu1_bufs[2],
807 ps_codec->s_fmt_conv.i4_cur_row,
808 ps_codec->s_fmt_conv.i4_num_rows);
809 ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
810
811 }
812
813
814 DEBUG_DUMP_MV_MAP(ps_codec);
815
816 /* Mark MV Buf as needed for reference */
817 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
818 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
819 BUF_MGR_REF);
820
821 /* Mark pic buf as needed for reference */
822 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
823 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
824 BUF_MGR_REF);
825
826 /* Mark pic buf as needed for display */
827 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
828 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
829 BUF_MGR_DISP);
830
831 /* Insert the current picture as short term reference */
832 ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
833 ps_codec->as_process[proc_idx].ps_cur_pic,
834 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
835
836 /* If a frame was displayed (in non-shared mode), then release it from display manager */
837 if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
838 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
839 ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
840
841 /* Wait for threads */
842 for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
843 {
844 if(ps_codec->ai4_process_thread_created[i])
845 {
846 ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
847 ps_codec->ai4_process_thread_created[i] = 0;
848 }
849 }
850
851 DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
852 if(ps_codec->u4_pic_cnt > 0)
853 {
854 DEBUG_DUMP_PIC_PU(ps_codec);
855 }
856 DEBUG_DUMP_PIC_BUFFERS(ps_codec);
857
858 /* Increment the number of pictures decoded */
859 ps_codec->u4_pic_cnt++;
860 }
861 ihevcd_fill_outargs(ps_codec, ps_dec_ip, ps_dec_op);
862
863 if(1 == ps_dec_op->u4_output_present)
864 {
865 WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
866 WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
867
868 if(ypos < 0)
869 ypos = 0;
870
871 if(xpos < 0)
872 xpos = 0;
873
874 INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
875 ps_dec_ip->s_out_buffer.pu1_bufs[1],
876 ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
877 xpos,
878 ypos,
879 ps_codec->e_chroma_fmt,
880 ps_codec->i4_disp_wd,
881 ps_codec->i4_disp_ht);
882 }
883
884
885 return ret;
886 }
887
888