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