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