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