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