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