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