/****************************************************************************** * * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ***************************************************************************** * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore */ /*****************************************************************************/ /* */ /* File Name : imvcd_slice_functions.c */ /* */ /* Description : Functions for MVC Slice parsing, etc. */ /* */ /*****************************************************************************/ #include "ih264_typedefs.h" #include "ih264_error.h" #include "ih264_buf_mgr.h" #include "ih264d_bitstrm.h" #include "ih264d_deblocking.h" #include "ih264d_debug.h" #include "ih264d_defs.h" #include "ih264d_error_handler.h" #include "ih264d_inter_pred.h" #include "ih264d_mb_utils.h" #include "ih264d_mvpred.h" #include "ih264d_parse_slice.h" #include "ih264d_parse_islice.h" #include "ih264d_process_bslice.h" #include "ih264d_process_pslice.h" #include "ih264d_quant_scaling.h" #include "ih264d_tables.h" #include "ih264d_thread_compute_bs.h" #include "ih264d_thread_parse_decode.h" #include "ih264d_structs.h" #include "ih264d_utils.h" #include "ih264d_api_utils.h" #include "ithread.h" #include "imvc_defs.h" #include "imvcd_dpb_manager.h" #include "imvcd_error_handler.h" #include "imvcd_structs.h" #include "imvcd_utils.h" static WORD32 imvcd_set_first_mb_in_slice(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u2_first_mb_in_slice = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(ps_cur_slice->u2_first_mb_in_slice >= (ps_view_ctxt->u2_frm_ht_in_mbs * ps_view_ctxt->u2_frm_wd_in_mbs)) { return ERROR_CORRUPTED_SLICE; } if(((ps_cur_slice->u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) <= ps_view_ctxt->u2_cur_mb_addr) && (ps_view_ctxt->u4_first_slice_in_pic == 0)) { return ERROR_CORRUPTED_SLICE; } COPYTHECONTEXT("SH: first_mb_in_slice", ps_cur_slice->u2_first_mb_in_slice); return OK; } static WORD32 imvcd_set_slice_type(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u1_slice_type = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(ps_cur_slice->u1_slice_type > 9) { return ERROR_INV_SLC_TYPE_T; } if(ps_cur_slice->u1_slice_type > 4) { ps_cur_slice->u1_slice_type -= 5; } COPYTHECONTEXT("SH: slice_type", ps_cur_slice->u1_slice_type); return OK; } static WORD32 imvcd_set_cur_pps(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_pps_id) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pu1_pps_id[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); ps_view_ctxt->ps_cur_pps = &ps_view_ctxt->ps_pps[pu1_pps_id[0]]; ps_view_ctxt->ps_cur_sps = ps_view_ctxt->ps_pps[pu1_pps_id[0]].ps_sps; if(!ps_view_ctxt->ps_cur_pps->u1_is_valid || !ps_view_ctxt->ps_cur_pps->ps_sps->u1_is_valid) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: pps_id", pu1_pps_id[0]); return OK; } static WORD32 imvcd_set_frame_num(dec_struct_t *ps_view_ctxt, UWORD8 u1_bits_in_frm_num) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, u1_bits_in_frm_num); COPYTHECONTEXT("SH: frame_num", ps_cur_slice->u2_frame_num); return OK; } static WORD32 imvcd_set_idr_pic_id(dec_struct_t *ps_view_ctxt, UWORD32 *pu4_idr_pic_id) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pu4_idr_pic_id[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(pu4_idr_pic_id[0] > 65535) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: idr_pic_id", pu4_idr_pic_id[0]); return OK; } static WORD32 imvcd_set_poc_lsb(dec_struct_t *ps_view_ctxt, WORD32 *pi4_pic_order_cnt_lsb, WORD32 i4_max_poc_lsb, UWORD8 u1_log2_max_poc_lsb) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pi4_pic_order_cnt_lsb[0] = ih264d_get_bits_h264(ps_bitstrm, u1_log2_max_poc_lsb); if((pi4_pic_order_cnt_lsb[0] < 0) || (pi4_pic_order_cnt_lsb[0] > i4_max_poc_lsb)) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: pic_order_cnt_lsb", pi4_pic_order_cnt_lsb[0]); return OK; } static WORD32 imvcd_set_delta_poc(dec_struct_t *ps_view_ctxt, WORD32 *pi4_delta_poc) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pi4_delta_poc[0] = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); COPYTHECONTEXT("SH: delta_pic_order_cnt", pi4_delta_poc[0]); return OK; } static WORD32 imvcd_set_redundant_pic_cnt(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_redundant_pic_cnt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pu1_redundant_pic_cnt[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(pu1_redundant_pic_cnt[0] > MAX_REDUNDANT_PIC_CNT) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: redundant_pic_cnt", pu1_redundant_pic_cnt[0]); return OK; } static WORD32 imvcd_set_direct_spatial_mv_pred_flag(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm); COPYTHECONTEXT("SH: direct_spatial_mv_pred_flag", ps_cur_slice->u1_direct_spatial_mv_pred_flag); return OK; } static WORD32 imvcd_set_ref_idx_override_flag(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264(ps_bitstrm); COPYTHECONTEXT("SH: num_ref_idx_override_flag", ps_cur_slice->u1_num_ref_idx_active_override_flag); return OK; } static WORD32 imvcd_set_num_ref_idx_active(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_num_ref_idx) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; UWORD32 u4_num_ref_idx_m1 = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(u4_num_ref_idx_m1 >= H264_MAX_REF_PICS) { return ERROR_NUM_REF; } pu1_num_ref_idx[0] = 1 + u4_num_ref_idx_m1; COPYTHECONTEXT("SH: num_ref_idx_lx_active_minus1", u4_num_ref_idx_m1); return OK; } static WORD32 imvcd_set_ref_pic_list_reordering_flag(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_ref_idx_reorder_flag) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pu1_ref_idx_reorder_flag[0] = ih264d_get_bit_h264(ps_bitstrm); COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_lx", pu1_ref_idx_reorder_flag[0]); return OK; } static WORD32 imvcd_set_modification_of_pic_nums_idc(dec_struct_t *ps_view_ctxt, UWORD8 *pu1_modification_of_pic_nums_idc) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pu1_modification_of_pic_nums_idc[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); COPYTHECONTEXT("SH: modification_of_pic_nums_idc", pu1_modification_of_pic_nums_idc[0]); return OK; } static WORD32 imvcd_set_abs_diff_pic_num_minus1(dec_struct_t *ps_view_ctxt, WORD32 *pi4_abs_diff_pic_num_minus1) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pi4_abs_diff_pic_num_minus1[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); COPYTHECONTEXT("SH: abs_diff_pic_num_minus1", pi4_abs_diff_pic_num_minus1[0]); return OK; } static WORD32 imvcd_set_abs_diff_view_idx_minus1(dec_struct_t *ps_view_ctxt, WORD32 *pi4_abs_diff_view_idx_minus1) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pi4_abs_diff_view_idx_minus1[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); COPYTHECONTEXT("SH: abs_diff_view_idx_minus1", pi4_abs_diff_view_idx_minus1[0]); return OK; } static WORD32 imvcd_set_long_term_pic_num(dec_struct_t *ps_view_ctxt, WORD32 *pi4_long_term_pic_num) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pi4_long_term_pic_num[0] = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); COPYTHECONTEXT("SH: long_term_pic_num", pi4_long_term_pic_num[0]); return OK; } static WORD32 imvcd_set_cabac_init_idc(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ps_cur_slice->u1_cabac_init_idc = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(ps_cur_slice->u1_cabac_init_idc > MAX_CABAC_INIT_IDC) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: cabac_init_idc", ps_cur_slice->u1_cabac_init_idc); return OK; } static WORD32 imvcd_set_slice_qp(dec_struct_t *ps_view_ctxt) { WORD8 i1_slice_qp_delta; dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; dec_pic_params_t *ps_cur_pps = ps_view_ctxt->ps_cur_pps; i1_slice_qp_delta = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); ps_cur_slice->u1_slice_qp = i1_slice_qp_delta + ps_cur_pps->u1_pic_init_qp; if(ps_cur_slice->u1_slice_qp > MAX_H264_QP) { return ERROR_INV_RANGE_QP_T; } COPYTHECONTEXT("SH: slice_qp_delta", i1_slice_qp_delta); return OK; } static WORD32 imvcd_set_slice_deblk_params(dec_struct_t *ps_view_ctxt) { dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; dec_pic_params_t *ps_cur_pps = ps_view_ctxt->ps_cur_pps; if(ps_cur_pps->u1_deblocking_filter_parameters_present_flag) { ps_cur_slice->u1_disable_dblk_filter_idc = ih264d_uev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); if(ps_cur_slice->u1_disable_dblk_filter_idc > SLICE_BOUNDARY_DBLK_DISABLED) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: disable_deblocking_filter_idc", ps_cur_slice->u1_disable_dblk_filter_idc); if(ps_cur_slice->u1_disable_dblk_filter_idc != 1) { ps_cur_slice->i1_slice_alpha_c0_offset = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer) << 1; if((MIN_DBLK_FIL_OFF > ps_cur_slice->i1_slice_alpha_c0_offset) || (ps_cur_slice->i1_slice_alpha_c0_offset > MAX_DBLK_FIL_OFF)) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2", ps_cur_slice->i1_slice_alpha_c0_offset >> 1); ps_cur_slice->i1_slice_beta_offset = ih264d_sev(&ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer) << 1; if((MIN_DBLK_FIL_OFF > ps_cur_slice->i1_slice_beta_offset) || (ps_cur_slice->i1_slice_beta_offset > MAX_DBLK_FIL_OFF)) { return ERROR_INV_SLICE_HDR_T; } COPYTHECONTEXT("SH: slice_beta_offset_div2", ps_cur_slice->i1_slice_beta_offset >> 1); } else { ps_cur_slice->i1_slice_alpha_c0_offset = 0; ps_cur_slice->i1_slice_beta_offset = 0; } } else { ps_cur_slice->u1_disable_dblk_filter_idc = 0; ps_cur_slice->i1_slice_alpha_c0_offset = 0; ps_cur_slice->i1_slice_beta_offset = 0; } return OK; } static WORD32 imvcd_set_ref_pic_list_mod_data(mvc_dec_ctxt_t *ps_mvcd_ctxt) { WORD32 i4_error_code; WORD32 i; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; ref_pic_list_mod_data_t *ps_ref_pic_list_mod_data = imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt); bool b_is_b_pic = ps_cur_slice->u1_slice_type == BSLICE; for(i = 0; i < 1 + ((WORD32) b_is_b_pic); i++) { ps_ref_pic_list_mod_data->au1_num_active_refs[i] = ps_cur_slice->u1_num_ref_idx_lx_active[i]; i4_error_code = imvcd_set_ref_pic_list_reordering_flag( ps_view_ctxt, &ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i]); if(OK != i4_error_code) { return i4_error_code; } if(ps_ref_pic_list_mod_data->au1_ref_pic_list_modification_flag_lx[i]) { UWORD8 *pu1_modification_of_pic_nums_idc = ps_ref_pic_list_mod_data->au1_modification_of_pic_nums_idc[i]; WORD32 *pi4_abs_diff_pic_num_minus1 = ps_ref_pic_list_mod_data->ai4_abs_diff_pic_num_minus1[i]; WORD32 *pi4_long_term_pic_num = ps_ref_pic_list_mod_data->ai4_long_term_pic_num[i]; WORD32 *pi4_abs_diff_view_idx_minus1 = ps_ref_pic_list_mod_data->ai4_abs_diff_view_idx_minus1[i]; UWORD32 u4_pic_num_mod_count = 0; do { i4_error_code = imvcd_set_modification_of_pic_nums_idc( ps_view_ctxt, pu1_modification_of_pic_nums_idc); if(OK != i4_error_code) { return i4_error_code; } if((0 == pu1_modification_of_pic_nums_idc[0]) || (1 == pu1_modification_of_pic_nums_idc[0])) { i4_error_code = imvcd_set_abs_diff_pic_num_minus1(ps_view_ctxt, pi4_abs_diff_pic_num_minus1); if(OK != i4_error_code) { return i4_error_code; } } else if(2 == pu1_modification_of_pic_nums_idc[0]) { i4_error_code = imvcd_set_long_term_pic_num(ps_view_ctxt, pi4_long_term_pic_num); if(OK != i4_error_code) { return i4_error_code; } } else if((4 == pu1_modification_of_pic_nums_idc[0]) || (5 == pu1_modification_of_pic_nums_idc[0])) { i4_error_code = imvcd_set_abs_diff_view_idx_minus1( ps_view_ctxt, pi4_abs_diff_view_idx_minus1); if(OK != i4_error_code) { return i4_error_code; } } else if(3 != pu1_modification_of_pic_nums_idc[0]) { return ERROR_REFIDX_ORDER_T; } else { break; } pu1_modification_of_pic_nums_idc++; pi4_abs_diff_pic_num_minus1++; pi4_long_term_pic_num++; pi4_abs_diff_view_idx_minus1++; u4_pic_num_mod_count++; if(u4_pic_num_mod_count > ps_ref_pic_list_mod_data->au1_num_active_refs[i]) { return ERROR_INV_SLICE_HDR_T; } } while(true); } } return OK; } static WORD32 imvcd_decode_gaps_in_frame_num(mvc_dec_ctxt_t *ps_mvcd_ctxt) { pocstruct_t s_tmp_poc; UWORD32 u4_start_frm_num; WORD32 i4_poc; WORD8 i1_gap_idx; WORD8 *pi1_gaps_per_seq; WORD32 i4_error_code; WORD64 i8_display_poc; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps; mvc_dpb_manager_t *ps_dpb_mgr = ps_mvcd_ctxt->ps_dpb_mgr; UWORD16 u2_frame_num = ps_cur_slice->u2_frame_num; UWORD32 u4_next_frm_num = ps_view_ctxt->u2_prev_ref_frame_num + 1; UWORD32 u4_max_frm_num = ps_view_ctxt->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; WORD32 *pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt); if(ps_cur_slice->u1_field_pic_flag) { if(ps_view_ctxt->u2_prev_ref_frame_num == u2_frame_num) { return OK; } } if(u4_next_frm_num >= u4_max_frm_num) { u4_next_frm_num -= u4_max_frm_num; } if(u4_next_frm_num == u2_frame_num) { return OK; } if(b_is_idr_slice && (u4_next_frm_num >= u2_frame_num)) { return OK; } u4_start_frm_num = u4_next_frm_num; s_tmp_poc.i4_pic_order_cnt_lsb = 0; s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0; s_tmp_poc.i4_pic_order_cnt_lsb = 0; s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0; s_tmp_poc.i4_delta_pic_order_cnt[0] = 0; s_tmp_poc.i4_delta_pic_order_cnt[1] = 0; for(i1_gap_idx = 0; i1_gap_idx < MAX_FRAMES; i1_gap_idx++) { if(INVALID_FRAME_NUM == pi4_gaps_start_frm_num[i1_gap_idx]) { break; } } if(MAX_FRAMES == i1_gap_idx) { return ERROR_DBP_MANAGER_T; } i4_poc = 0; pi4_gaps_start_frm_num[i1_gap_idx] = u4_start_frm_num; ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = u2_frame_num - 1; pi1_gaps_per_seq = ps_dpb_mgr->ai1_gaps_per_seq; pi1_gaps_per_seq[i1_gap_idx] = 0; while(u4_next_frm_num != u2_frame_num) { imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr); if(ps_pps->ps_sps->u1_pic_order_cnt_type) { /* allocate a picture buffer and insert it as ST node */ i4_error_code = ih264d_decode_pic_order_cnt(0, u4_next_frm_num, &ps_view_ctxt->s_prev_pic_poc, &s_tmp_poc, ps_cur_slice, ps_pps, 1, 0, 0, &i4_poc); if(i4_error_code != OK) { return i4_error_code; } /* Display seq no calculations */ if(i4_poc >= ps_view_ctxt->i4_max_poc) { ps_view_ctxt->i4_max_poc = i4_poc; } /* IDR Picture or POC wrap around */ if(i4_poc == 0) { imvcd_modulate_max_disp_seq(ps_view_ctxt); } ps_cur_slice->u1_mmco_equalto5 = 0; ps_cur_slice->u2_frame_num = u4_next_frm_num; } if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_view_ctxt->u1_max_dec_frame_buffering) { i4_error_code = imvcd_dpb_assign_display_seq(ps_mvcd_ctxt->ps_dpb_mgr); if(i4_error_code != OK) { return i4_error_code; } } i8_display_poc = ((WORD64) ps_view_ctxt->i4_prev_max_display_seq) + ((WORD64) i4_poc); if(IS_OUT_OF_RANGE_S32(i8_display_poc)) { ps_view_ctxt->i4_prev_max_display_seq = 0; i8_display_poc = i4_poc; } i4_error_code = imvcd_dpb_insert_pic_in_display_list(ps_dpb_mgr, (WORD32) i8_display_poc, u4_next_frm_num, DO_NOT_DISP); if(i4_error_code != OK) { return i4_error_code; } pi1_gaps_per_seq[i1_gap_idx]++; i4_error_code = imvcd_dpb_do_mmco_for_gaps(ps_dpb_mgr, ps_view_ctxt->ps_cur_sps->u1_num_ref_frames); if(i4_error_code != OK) { return i4_error_code; } imvcd_dpb_delete_nonref_nondisplay_pics(ps_dpb_mgr); u4_next_frm_num++; if(u4_next_frm_num >= u4_max_frm_num) { u4_next_frm_num -= u4_max_frm_num; } } return OK; } static void imvcd_pocstruct_init(dec_struct_t *ps_view_ctxt) { pocstruct_t *ps_prev_poc = &ps_view_ctxt->s_prev_pic_poc; pocstruct_t *ps_cur_poc = &ps_view_ctxt->s_cur_pic_poc; ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst; ps_prev_poc->u2_frame_num = ps_cur_poc->u2_frame_num; ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5; if(ps_view_ctxt->ps_cur_slice->u1_nal_ref_idc) { ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb; ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb; ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom; ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0]; ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1]; ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field; } } static WORD32 imvcd_pic_init(mvc_dec_ctxt_t *ps_mvcd_ctxt, pocstruct_t *ps_cur_poc, WORD32 i4_poc, bool b_is_idr_slice) { WORD32 i4_error_code; WORD32 i; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; pocstruct_t *ps_prev_poc = &ps_view_ctxt->s_cur_pic_poc; dec_slice_params_t *ps_cur_slice = ps_view_ctxt->ps_cur_slice; dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps; dec_seq_params_t *ps_sps = ps_pps->ps_sps; subset_sps_t *ps_subset_sps = imvcd_get_valid_subset_sps(ps_mvcd_ctxt); nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt); dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status; prev_seq_params_t *ps_prev_seq_params = &ps_view_ctxt->s_prev_seq_params; UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views; UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded; UWORD16 u2_view_id = ps_nalu_mvc_ext->u2_view_id; UWORD16 u2_frame_num = ps_cur_slice->u2_frame_num; ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb; ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb; ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom; ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0]; ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1]; ps_prev_poc->u1_bot_field = ps_view_ctxt->ps_cur_slice->u1_bottom_field_flag; ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst; ps_prev_poc->u2_frame_num = u2_frame_num; ps_view_ctxt->i1_prev_mb_qp_delta = 0; ps_view_ctxt->i1_next_ctxt_idx = 0; ps_view_ctxt->u4_use_intrapred_line_copy = 1; if(ps_view_ctxt->u4_num_cores == 1) { ps_view_ctxt->u4_nmb_deblk = 1; } else { ps_view_ctxt->u4_nmb_deblk = 0; } ps_view_ctxt->u4_app_disable_deblk_frm = 0; if(ps_view_ctxt->i4_degrade_type && ps_view_ctxt->i4_degrade_pics) { WORD32 i4_degrade_pic = 0; ps_view_ctxt->i4_degrade_pic_cnt++; /* If degrade is to be done in all frames, then do not check further */ switch(ps_view_ctxt->i4_degrade_pics) { case 4: { i4_degrade_pic = 1; break; } case 3: { if(ps_cur_slice->u1_slice_type != I_SLICE) { i4_degrade_pic = 1; } break; } case 2: { if((ps_cur_slice->u1_slice_type != I_SLICE) && (ps_view_ctxt->i4_degrade_pic_cnt != ps_view_ctxt->i4_nondegrade_interval)) { i4_degrade_pic = 1; } break; } case 1: { if(0 == ps_cur_slice->u1_nal_ref_idc) { i4_degrade_pic = 1; } break; } } if(i4_degrade_pic) { if(ps_view_ctxt->i4_degrade_type & 0x2) { ps_view_ctxt->u4_app_disable_deblk_frm = 1; } if(0 == ps_cur_slice->u1_nal_ref_idc) { if(ps_view_ctxt->i4_degrade_type & 0x4) { ps_view_ctxt->i4_mv_frac_mask = 0; } if(ps_view_ctxt->i4_degrade_type & 0x8) { ps_view_ctxt->i4_mv_frac_mask = 0; } } } else { ps_view_ctxt->i4_degrade_pic_cnt = 0; } } if((ps_cur_slice->u1_slice_type == I_SLICE) || (ps_cur_slice->u1_slice_type == SI_SLICE)) { ps_err->u1_cur_pic_type = PIC_TYPE_I; } else { ps_err->u1_cur_pic_type = PIC_TYPE_UNKNOWN; } if(ps_err->u1_pic_aud_i == PIC_TYPE_I) { ps_err->u1_cur_pic_type = PIC_TYPE_I; ps_err->u1_pic_aud_i = PIC_TYPE_UNKNOWN; } if(b_is_idr_slice) { if(ps_err->u1_err_flag) { imvcd_reset_dpb(ps_mvcd_ctxt->ps_dpb_mgr); } ps_err->u1_err_flag = ACCEPT_ALL_PICS; } if(ps_view_ctxt->u1_init_dec_flag && ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending && (u2_view_order_id == (u2_num_views - 1))) { imvcd_release_all_ref_and_io_bufs(ps_mvcd_ctxt, MAX_DISP_BUFS_NEW); ps_view_ctxt->u1_second_field = 0; ps_view_ctxt->i4_cur_display_seq = 0; ps_view_ctxt->s_prev_seq_params.u1_eoseq_pending = 0; imvcd_dpb_set_display_num(ps_mvcd_ctxt->ps_dpb_mgr, 0); } if(0 == u2_view_order_id) { imvcd_dpb_set_max_pic_num(ps_mvcd_ctxt->ps_dpb_mgr, ps_sps->u2_u4_max_pic_num_minus1 + 1); imvcd_dpb_set_num_views(ps_mvcd_ctxt->ps_dpb_mgr, u2_num_views); } ps_view_ctxt->i4_pic_type = NA_SLICE; ps_view_ctxt->i4_frametype = IV_NA_FRAME; ps_view_ctxt->i4_content_type = IV_CONTENTTYPE_NA; ps_sps->u2_max_mb_addr = ps_sps->u2_frm_wd_in_mbs * ps_sps->u2_frm_ht_in_mbs - 1; ps_view_ctxt->u2_frm_ht_in_mbs = ps_sps->u2_frm_ht_in_mbs; if(!ps_view_ctxt->u1_init_dec_flag) { ps_view_ctxt->u1_max_dec_frame_buffering = ih264d_get_dpb_size(ps_sps); ps_view_ctxt->i4_display_delay = ps_view_ctxt->u1_max_dec_frame_buffering; if(ps_sps->u1_vui_parameters_present_flag && ps_sps->s_vui.u1_bitstream_restriction_flag) { if(ps_sps->u1_frame_mbs_only_flag) { ps_view_ctxt->i4_display_delay = ps_sps->s_vui.u4_num_reorder_frames + 1; } else { ps_view_ctxt->i4_display_delay = ps_sps->s_vui.u4_num_reorder_frames * 2 + 2; } } if(IVD_DECODE_FRAME_OUT == ps_view_ctxt->e_frm_out_mode) { ps_view_ctxt->i4_display_delay = 0; } imvcd_dpb_set_display_delay(ps_mvcd_ctxt->ps_dpb_mgr, ps_view_ctxt->i4_display_delay); ps_view_ctxt->u1_pic_bufs = ps_view_ctxt->i4_display_delay + ps_sps->u1_num_ref_frames + 1; ps_view_ctxt->u1_pic_bufs += imvcd_get_max_num_ivp_refs(ps_mvcd_ctxt); ps_view_ctxt->u1_pic_bufs = CLIP3(2, MVC_MAX_REF_PICS, ps_view_ctxt->u1_pic_bufs); ps_view_ctxt->u1_max_dec_frame_buffering = MIN(ps_view_ctxt->u1_max_dec_frame_buffering, ps_view_ctxt->u1_pic_bufs); /*********************************************************************/ /* Configuring decoder parameters based on level and then */ /* fresh pointer initialisation in decoder scratch and state buffers */ /*********************************************************************/ i4_error_code = ih264d_init_dec_mb_grp(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } i4_error_code = imvcd_allocate_dynamic_bufs(ps_mvcd_ctxt); if(i4_error_code != OK) { imvcd_free_dynamic_bufs(ps_mvcd_ctxt); return IVD_MEM_ALLOC_FAILED; } i4_error_code = imvcd_init_au_buffers(ps_mvcd_ctxt); if(i4_error_code != OK) { return i4_error_code; } i4_error_code = imvcd_init_au_mv_pred_bufs(ps_mvcd_ctxt); if(i4_error_code != OK) { return i4_error_code; } ps_view_ctxt->u1_init_dec_flag = 1; ps_prev_seq_params->u2_frm_wd_in_mbs = ps_sps->u2_frm_wd_in_mbs; ps_prev_seq_params->u1_level_idc = ps_sps->u1_level_idc; ps_prev_seq_params->u1_profile_idc = ps_sps->u1_profile_idc; ps_prev_seq_params->u2_frm_ht_in_mbs = ps_sps->u2_frm_ht_in_mbs; ps_prev_seq_params->u1_frame_mbs_only_flag = ps_sps->u1_frame_mbs_only_flag; ps_prev_seq_params->u1_direct_8x8_inference_flag = ps_sps->u1_direct_8x8_inference_flag; ps_view_ctxt->i4_cur_display_seq = 0; ps_view_ctxt->i4_prev_max_display_seq = 0; ps_view_ctxt->i4_max_poc = 0; imvcd_dpb_set_display_num(ps_mvcd_ctxt->ps_dpb_mgr, 0); { /* 0th entry of CtxtIncMbMap will be always be containing default values for CABAC context representing MB not available */ ctxt_inc_mb_info_t *p_DefCtxt = ps_view_ctxt->p_ctxt_inc_mb_map - 1; UWORD8 *pu1_temp; p_DefCtxt->u1_mb_type = CAB_SKIP; p_DefCtxt->u1_cbp = 0x0f; p_DefCtxt->u1_intra_chroma_pred_mode = 0; p_DefCtxt->u1_yuv_dc_csbp = 0x7; p_DefCtxt->u1_transform8x8_ctxt = 0; pu1_temp = (UWORD8 *) p_DefCtxt->i1_ref_idx; for(i = 0; i < 4; i++, pu1_temp++) { (*pu1_temp) = 0; } pu1_temp = (UWORD8 *) p_DefCtxt->u1_mv; for(i = 0; i < 16; i++, pu1_temp++) { (*pu1_temp) = 0; } ps_view_ctxt->ps_def_ctxt_mb_info = p_DefCtxt; } } /* reset DBP commands read u4_flag */ ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read = 0; ps_view_ctxt->pv_parse_tu_coeff_data = ps_view_ctxt->pv_pic_tu_coeff_data; ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_pic_tu_coeff_data; ps_view_ctxt->ps_nmb_info = ps_view_ctxt->ps_frm_mb_info; if(ps_view_ctxt->u1_separate_parse) { UWORD32 num_mbs; num_mbs = ps_view_ctxt->ps_cur_sps->u2_total_num_of_mbs; if(ps_view_ctxt->pu1_dec_mb_map) { memset((void *) ps_view_ctxt->pu1_dec_mb_map, 0, num_mbs); } if(ps_view_ctxt->pu1_recon_mb_map) { memset((void *) ps_view_ctxt->pu1_recon_mb_map, 0, num_mbs); } if(ps_view_ctxt->pu2_slice_num_map) { memset((void *) ps_view_ctxt->pu2_slice_num_map, 0, (num_mbs * sizeof(UWORD16))); } } ps_view_ctxt->ps_parse_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]); ps_view_ctxt->ps_decode_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]); ps_view_ctxt->ps_computebs_cur_slice = &(ps_view_ctxt->ps_dec_slice_buf[0]); ps_view_ctxt->u2_cur_slice_num = 0; ps_view_ctxt->s_high_profile.u1_scaling_present = 0; ps_view_ctxt->s_high_profile.u1_transform8x8_present = 0; if(0 == u2_view_order_id) { mvc_au_buffer_t *ps_cur_au; mvc_au_mv_pred_t *ps_au_mv_data; WORD32 i4_pic_buf_id, i4_mv_buf_id; ps_cur_au = (mvc_au_buffer_t *) ih264_buf_mgr_get_next_free( ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, &i4_pic_buf_id); if(NULL == ps_cur_au) { return ERROR_UNAVAIL_PICBUF_T; } else { /* Buf will alwys be marked as REF here to ensure IVP works */ /* If AU nalRefIdc=0, REF status will be removed during endOfAU processing */ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_buf_mgr.ps_buf_mgr_ctxt, i4_pic_buf_id, BUF_MGR_IO | BUF_MGR_REF); } ps_au_mv_data = (mvc_au_mv_pred_t *) ih264_buf_mgr_get_next_free( ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt, &i4_mv_buf_id); if(ps_au_mv_data == NULL) { return ERROR_UNAVAIL_MVBUF_T; } else { /* Buf will alwys be marked as REF here to ensure IVP works */ /* If AU nalRefIdc=0, REF status will be removed during endOfAU processing */ ih264_buf_mgr_set_status(ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.ps_buf_mgr_ctxt, i4_mv_buf_id, BUF_MGR_REF); } ps_mvcd_ctxt->ps_cur_au = ps_cur_au; ps_cur_au->s_sei_pic = ps_view_ctxt->ps_sei[0]; ps_cur_au->i4_mv_buf_id = i4_mv_buf_id; ps_cur_au->ps_au_mv_data = ps_au_mv_data; ps_cur_au->i4_poc = i4_poc; ps_cur_au->i4_avg_poc = i4_poc; ps_cur_au->i4_frame_num = u2_frame_num; ps_cur_au->i4_pic_num = u2_frame_num; ps_cur_au->u4_time_stamp = ps_view_ctxt->u4_ts; ps_cur_au->u1_picturetype = FRM_PIC; ps_cur_au->u2_disp_width = ps_view_ctxt->u2_disp_width; ps_cur_au->u2_disp_height = ps_view_ctxt->u2_disp_height; memset(ps_cur_au->au4_pack_slc_typ, 0, sizeof(ps_cur_au->au4_pack_slc_typ)); ps_mvcd_ctxt->s_mvc_au_buf_mgr.au1_au_buf_id_to_mv_buf_id_map[i4_pic_buf_id] = i4_mv_buf_id; ps_mvcd_ctxt->s_mvc_au_buf_mgr.aps_buf_id_to_au_buf_map[i4_pic_buf_id] = ps_cur_au; ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr.aps_buf_id_to_mv_pred_buf_map[i4_mv_buf_id] = ps_au_mv_data; ps_view_ctxt->au1_pic_buf_ref_flag[i4_pic_buf_id] = 0; ps_cur_au->s_ivp_data.b_is_ivp_ref = false; imvcd_dpb_init_au_bufs(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_au); } if(u2_view_order_id > 0) { ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id] = ps_mvcd_ctxt->aps_pps_id_to_subset_sps_map[ps_pps->u1_pic_parameter_set_id] ->s_disp_offsets; } else { /* Accounting for lihbavc's idiocy */ ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_left_offset = ps_view_ctxt->u2_crop_offset_y; ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_right_offset = 0; ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_top_offset = 0; ps_mvcd_ctxt->ps_cur_au->as_disp_offsets[u2_view_id].u2_bottom_offset = 0; } for(i = 0; i < 2; i++) { ps_view_ctxt->ps_ref_pic_buf_lx[i] = imvcd_dpb_get_view_ref_pic_list( ps_mvcd_ctxt->ps_dpb_mgr, u2_view_order_id, u2_view_id, i); imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt); } if(ps_mvcd_ctxt->u2_num_views > 1) { imvcd_dpb_init_view_bufs(ps_mvcd_ctxt->ps_dpb_mgr, u2_view_order_id, u2_view_id); imvcd_dpb_init_ivp_ctxt(ps_mvcd_ctxt->ps_dpb_mgr, &ps_subset_sps->s_sps_mvc_ext, ps_mvcd_ctxt->as_nalu_mvc_ext); } ps_view_ctxt->u4_pic_buf_got = 1; ps_cur_slice->u1_mbaff_frame_flag = 0; ps_view_ctxt->ps_cur_mb_row = ps_view_ctxt->ps_nbr_mb_row; // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be // valid ps_view_ctxt->ps_cur_mb_row += 2; ps_view_ctxt->ps_top_mb_row = ps_view_ctxt->ps_nbr_mb_row; ps_view_ctxt->ps_top_mb_row += ps_view_ctxt->u2_frm_wd_in_mbs + 2; // Increment by 2 ,so that left mb (mbaff decrements by 2) will always be // valid ps_view_ctxt->ps_top_mb_row += 2; ps_view_ctxt->u1_mb_idx = 0; ps_view_ctxt->u2_total_mbs_coded = 0; ps_view_ctxt->i4_submb_ofst = -(SUB_BLK_SIZE); ps_view_ctxt->i2_prev_slice_mbx = -1; ps_view_ctxt->i2_prev_slice_mby = 0; ps_view_ctxt->u4_pred_info_idx = 0; ps_view_ctxt->u4_pred_info_pkd_idx = 0; ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params; ps_view_ctxt->u4_dma_buf_idx = 0; ps_view_ctxt->ps_mv_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id]; ps_view_ctxt->ps_mv_top = ps_view_ctxt->ps_mv_top_p[0]; ps_view_ctxt->u1_mv_top_p = 0; ps_view_ctxt->ps_mv_left = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id]; ps_view_ctxt->ps_mv = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id]; ps_view_ctxt->ps_mv_bank_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id]; ps_view_ctxt->pu1_col_zero_flag = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->apu1_mode_descriptors[u2_view_id]; ps_view_ctxt->u2_mv_2mb[0] = 0; ps_view_ctxt->u2_mv_2mb[1] = 0; ps_view_ctxt->u1_last_pic_not_decoded = 0; ps_view_ctxt->u2_cur_slice_num_dec_thread = 0; ps_view_ctxt->u2_cur_slice_num_bs = 0; ps_view_ctxt->u4_intra_pred_line_ofst = 0; ps_view_ctxt->pu1_cur_y_intra_pred_line = ps_view_ctxt->pu1_y_intra_pred_line; ps_view_ctxt->pu1_cur_u_intra_pred_line = ps_view_ctxt->pu1_u_intra_pred_line; ps_view_ctxt->pu1_cur_v_intra_pred_line = ps_view_ctxt->pu1_v_intra_pred_line; ps_view_ctxt->pu1_cur_y_intra_pred_line_base = ps_view_ctxt->pu1_y_intra_pred_line; ps_view_ctxt->pu1_cur_u_intra_pred_line_base = ps_view_ctxt->pu1_u_intra_pred_line; ps_view_ctxt->pu1_cur_v_intra_pred_line_base = ps_view_ctxt->pu1_v_intra_pred_line; ps_view_ctxt->pu1_prev_y_intra_pred_line = ps_view_ctxt->pu1_y_intra_pred_line + (ps_view_ctxt->u2_frm_wd_in_mbs * MB_SIZE); ps_view_ctxt->pu1_prev_u_intra_pred_line = ps_view_ctxt->pu1_u_intra_pred_line + ps_view_ctxt->u2_frm_wd_in_mbs * BLK8x8SIZE * YUV420SP_FACTOR; ps_view_ctxt->pu1_prev_v_intra_pred_line = ps_view_ctxt->pu1_v_intra_pred_line + ps_view_ctxt->u2_frm_wd_in_mbs * BLK8x8SIZE; ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_deblk_pic; ps_view_ctxt->pf_compute_bs = ih264d_compute_bs_non_mbaff; ps_view_ctxt->u1_cur_mb_fld_dec_flag = ps_cur_slice->u1_field_pic_flag; if(0 == u2_view_order_id) { imvcd_assign_pic_num(ps_mvcd_ctxt->ps_dpb_mgr, ps_sps->u2_u4_max_pic_num_minus1 + 1, ps_mvcd_ctxt->ps_cur_au->i4_frame_num, ps_sps->u1_gaps_in_frame_num_value_allowed_flag); ps_view_ctxt->s_tran_addrecon.u2_mv_top_left_inc = (ps_view_ctxt->u1_recon_mb_grp << 2) - 1; ps_view_ctxt->s_tran_addrecon.u2_mv_left_inc = (ps_view_ctxt->u1_recon_mb_grp - 1) << 4; } if((ps_sps->u1_profile_idc == HIGH_PROFILE_IDC) || (ps_sps->u1_profile_idc == MULTIVIEW_HIGH_PROFILE_IDC)) { if((ps_sps->i4_seq_scaling_matrix_present_flag) || (ps_pps->i4_pic_scaling_matrix_present_flag)) { i4_error_code = ih264d_form_scaling_matrix_picture(ps_sps, ps_pps, ps_view_ctxt); ps_view_ctxt->s_high_profile.u1_scaling_present = 1; } else { i4_error_code = ih264d_form_default_scaling_matrix(ps_view_ctxt); } if(ps_pps->i4_transform_8x8_mode_flag) { ps_view_ctxt->s_high_profile.u1_transform8x8_present = 1; } } else { i4_error_code = ih264d_form_default_scaling_matrix(ps_view_ctxt); } if(i4_error_code != OK) { return i4_error_code; } ps_view_ctxt->s_high_profile.u1_direct_8x8_inference_flag = ps_sps->u1_direct_8x8_inference_flag; ps_view_ctxt->s_high_profile.s_cavlc_ctxt = ps_view_ctxt->s_cavlc_ctxt; ps_view_ctxt->i1_recon_in_thread3_flag = 1; ps_view_ctxt->ps_cur_pic = &ps_view_ctxt->s_cur_pic; imvcd_convert_au_buf_to_view_buf(ps_mvcd_ctxt->ps_cur_au, &ps_view_ctxt->s_cur_pic, u2_view_order_id, u2_view_id); ih264d_init_deblk_tfr_ctxt(ps_view_ctxt, &ps_view_ctxt->s_pad_mgr, &ps_view_ctxt->s_tran_addrecon, ps_view_ctxt->u2_frm_wd_in_mbs, 0); ps_view_ctxt->ps_frame_buf_ip_recon = &ps_view_ctxt->s_tran_addrecon; if(ps_view_ctxt->u1_separate_parse) { ps_view_ctxt->s_tran_addrecon_parse = ps_view_ctxt->s_tran_addrecon; if((ps_view_ctxt->u4_num_cores >= 3) && ps_view_ctxt->i1_recon_in_thread3_flag) { ps_view_ctxt->s_tran_iprecon = ps_view_ctxt->s_tran_addrecon; ps_view_ctxt->ps_frame_buf_ip_recon = &ps_view_ctxt->s_tran_iprecon; } } ps_view_ctxt->ps_cur_deblk_mb = ps_view_ctxt->ps_deblk_pic; ps_view_ctxt->u4_cur_deblk_mb_num = 0; ps_view_ctxt->u4_deblk_mb_x = 0; ps_view_ctxt->u4_deblk_mb_y = 0; ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat; ps_view_ctxt->u4_first_slice_in_pic = 0; return OK; } static WORD32 imvcd_corrupted_slice_handler(mvc_dec_ctxt_t *ps_mvcd_ctxt) { dec_mb_info_t *ps_cur_mb_info; parse_pmbarams_t *ps_parse_mb_data; deblk_mb_t *ps_cur_deblk_mb; parse_part_params_t *ps_part_info; UWORD32 u4_num_mbs_next; bool b_is_end_of_row; bool b_is_slice_end; bool b_tfr_n_mb; bool b_decode_nmb; UWORD8 u1_inter_mb_type; UWORD8 u1_deblk_mb_type; UWORD16 i2_cur_mb_addr; UWORD32 u4_mb_skip_run; WORD32 i, j; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice; nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt); UWORD32 u4_num_mbs = 0; UWORD32 u4_mb_idx = ps_view_ctxt->u1_mb_idx; UWORD32 u4_remaining_mbs = (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1) - ps_view_ctxt->u2_total_mbs_coded; if(ps_view_ctxt->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) { imvcd_free_ref_and_io_bufs(&ps_mvcd_ctxt->s_mvc_au_buf_mgr, &ps_mvcd_ctxt->s_mvc_au_mv_pred_buf_mgr, ps_mvcd_ctxt->ps_cur_au->i4_pic_buf_id); return OK; } if((ISLICE == ps_slice->u1_slice_type) || (0 == ps_view_ctxt->u2_total_mbs_coded)) { yuv_buf_props_t *ps_view_buf = &ps_mvcd_ctxt->ps_cur_au->as_view_buffers[ps_cur_nalu_mvc_ext->u2_view_id]; for(i = 0; i < NUM_SP_COMPONENTS; i++) { buffer_container_t *ps_component_buf = &ps_view_buf->as_component_bufs[i]; bool b_is_chroma = ((COMPONENT_TYPES_T) i) != Y; UWORD16 u2_height = ps_view_buf->u2_height >> b_is_chroma; UWORD16 u2_width = ps_view_buf->u2_width; for(j = 0; j < u2_height; j++) { UWORD8 *pu1_data = ((UWORD8 *) ps_component_buf->pv_data) + j * ps_component_buf->i4_data_stride; memset(pu1_data, 128, u2_width * sizeof(pu1_data[0])); } } memset(ps_view_ctxt->apv_buf_id_pic_buf_map, 0, sizeof(ps_view_ctxt->apv_buf_id_pic_buf_map)); ps_view_ctxt->apv_buf_id_pic_buf_map[ps_mvcd_ctxt->ps_cur_au->i4_pic_buf_id] = &ps_view_ctxt->s_cur_pic; ps_view_ctxt->ps_ref_pic_buf_lx[0] = &ps_view_ctxt->ps_cur_pic; (ps_view_ctxt->ppv_map_ref_idx_to_poc + FRM_LIST_L0)[0] = ps_view_ctxt->ps_cur_pic->pu1_buf1; (ps_view_ctxt->ppv_map_ref_idx_to_poc + FRM_LIST_L1)[0] = NULL; } ps_view_ctxt->ps_dpb_cmds->u1_long_term_reference_flag = 0; if(ps_view_ctxt->u2_total_mbs_coded > 0) { ps_view_ctxt->u2_total_mbs_coded -= ps_view_ctxt->u2_total_mbs_coded % ps_view_ctxt->ps_cur_sps->u2_frm_wd_in_mbs; u4_remaining_mbs = (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1) - ps_view_ctxt->u2_total_mbs_coded; while(ps_view_ctxt->u4_dec_thread_created && (ps_view_ctxt->cur_dec_mb_num < ps_view_ctxt->u2_total_mbs_coded)) { NOP(1 << 10); } while(ps_view_ctxt->u4_bs_deblk_thread_created && (ps_view_ctxt->cur_recon_mb_num < ps_view_ctxt->u2_total_mbs_coded)) { NOP(1 << 10); } while(ps_view_ctxt->u4_bs_deblk_thread_created && (ps_view_ctxt->u4_cur_deblk_mb_num < ps_view_ctxt->u2_total_mbs_coded)) { NOP(1 << 10); } ps_view_ctxt->ps_nmb_info = ps_view_ctxt->ps_frm_mb_info + ps_view_ctxt->u2_total_mbs_coded; ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_cur_deblk_mb = ps_view_ctxt->ps_deblk_pic + ps_view_ctxt->u2_total_mbs_coded; } u4_num_mbs = ps_view_ctxt->u4_num_mbs_cur_nmb = 0; if(ps_view_ctxt->u1_separate_parse) { ps_cur_mb_info = ps_view_ctxt->ps_nmb_info; } else { ps_cur_mb_info = ps_view_ctxt->ps_nmb_info + ps_view_ctxt->u4_num_mbs_prev_nmb - 1; } ps_view_ctxt->u2_mby = ps_cur_mb_info->u2_mby; ps_view_ctxt->u2_mbx = ps_cur_mb_info->u2_mbx; ps_view_ctxt->u1_mb_ngbr_availablity = ps_cur_mb_info->u1_mb_ngbr_availablity; if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1)) { ps_view_ctxt->u1_pic_decode_done = 1; return OK; } /******************************************************/ /* Initializations to new slice */ /******************************************************/ ps_view_ctxt->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = (volatile void **) ps_view_ctxt->pv_map_ref_idx_to_poc_buf; ps_slice->i1_slice_alpha_c0_offset = 0; ps_slice->i1_slice_beta_offset = 0; ps_slice->u2_first_mb_in_slice = ps_view_ctxt->u2_total_mbs_coded; ps_view_ctxt->ps_parse_cur_slice->u4_first_mb_in_slice = ps_view_ctxt->u2_total_mbs_coded; ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_slice->u2_log2Y_crwd; if(ps_view_ctxt->u1_separate_parse) { ps_view_ctxt->ps_parse_cur_slice->pv_tu_coeff_data_start = ps_view_ctxt->pv_parse_tu_coeff_data; } else { ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_parse_tu_coeff_data; } /******************************************************/ /* Initializations specific to P slice */ /******************************************************/ u1_inter_mb_type = P_MB; u1_deblk_mb_type = D_INTER_MB; ps_slice->u1_slice_type = P_SLICE; ps_view_ctxt->ps_parse_cur_slice->slice_type = P_SLICE; ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb; ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params; ps_view_ctxt->u2_mbx = MOD(ps_view_ctxt->u2_total_mbs_coded - 1, ps_view_ctxt->u2_frm_wd_in_mbs); ps_view_ctxt->u2_mby = DIV(ps_view_ctxt->u2_total_mbs_coded - 1, ps_view_ctxt->u2_frm_wd_in_mbs); /******************************************************/ /* Parsing / decoding the slice */ /******************************************************/ ps_view_ctxt->u1_qp = ps_slice->u1_slice_qp; ih264d_update_qp(ps_view_ctxt, 0); u4_mb_idx = ps_view_ctxt->u1_mb_idx; ps_parse_mb_data = ps_view_ctxt->ps_parse_mb_data; u4_num_mbs = u4_mb_idx; b_is_slice_end = false; b_tfr_n_mb = false; b_decode_nmb = false; i2_cur_mb_addr = ps_view_ctxt->u2_total_mbs_coded; u4_mb_skip_run = u4_remaining_mbs; while(!b_is_slice_end) { if(i2_cur_mb_addr > ps_view_ctxt->ps_cur_sps->u2_max_mb_addr) { break; } ps_cur_mb_info = ps_view_ctxt->ps_nmb_info + u4_num_mbs; ps_view_ctxt->u4_num_mbs_cur_nmb = u4_num_mbs; ps_cur_mb_info->u1_Mux = 0; ps_cur_mb_info->u1_end_of_slice = 0; ps_view_ctxt->u4_num_pmbair = u4_num_mbs; ps_cur_deblk_mb = ps_view_ctxt->ps_deblk_mbn + u4_num_mbs; ps_parse_mb_data->u1_num_part = 1; ps_parse_mb_data->u1_isI_mb = 0; /**************************************************************/ /* Get the required information for decoding of MB */ /**************************************************************/ /* mb_x, mb_y, neighbor availablity, */ ih264d_get_mb_info_cavlc_nonmbaff(ps_view_ctxt, i2_cur_mb_addr, ps_cur_mb_info, u4_mb_skip_run); if(ps_view_ctxt->u4_app_disable_deblk_frm == 0) { ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice, ps_view_ctxt->u1_mb_ngbr_availablity, ps_view_ctxt->u1_cur_mb_fld_dec_flag); } ps_view_ctxt->i1_prev_mb_qp_delta = 0; ps_view_ctxt->u1_sub_mb_num = 0; ps_cur_mb_info->u1_mb_type = MB_SKIP; ps_cur_mb_info->u1_mb_mc_mode = PRED_16x16; ps_cur_mb_info->u1_cbp = 0; /* Storing Skip partition info */ ps_part_info = ps_view_ctxt->ps_part; ps_part_info->u1_is_direct = PART_DIRECT_16x16; ps_part_info->u1_sub_mb_num = 0; ps_view_ctxt->ps_part++; /* Update Nnzs */ ih264d_update_nnz_for_skipmb(ps_view_ctxt, ps_cur_mb_info, CAVLC); ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type; ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type; u4_mb_skip_run--; ps_cur_deblk_mb->u1_mb_qp = ps_view_ctxt->u1_qp; ps_cur_deblk_mb->u1_deblocking_mode = MB_DISABLE_FILTERING; i2_cur_mb_addr++; u4_num_mbs++; ps_parse_mb_data++; /****************************************************************/ /* Check for End Of Row and other flags that determine when to */ /* do DMA setup for N/2-Mb, Decode for N-Mb, and Transfer for */ /* N-Mb */ /****************************************************************/ u4_num_mbs_next = ps_view_ctxt->ps_cur_sps->u2_frm_wd_in_mbs - 1 - ps_view_ctxt->u2_mbx; b_is_end_of_row = (0 == u4_num_mbs_next); b_is_slice_end = !u4_mb_skip_run; ps_cur_mb_info->u1_end_of_slice = !u4_mb_skip_run; b_tfr_n_mb = (u4_num_mbs == ps_view_ctxt->u1_recon_mb_grp) || b_is_end_of_row || b_is_slice_end; b_decode_nmb = b_tfr_n_mb || b_is_slice_end; if(b_decode_nmb) { ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb(ps_view_ctxt, u4_mb_idx, u4_num_mbs); ps_parse_mb_data = ps_view_ctxt->ps_parse_mb_data; ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params; if(ps_view_ctxt->u1_separate_parse) { ih264d_parse_tfr_nmb(ps_view_ctxt, u4_mb_idx, u4_num_mbs, u4_num_mbs_next, b_tfr_n_mb, b_is_end_of_row); ps_view_ctxt->ps_nmb_info += u4_num_mbs; } else { ih264d_decode_recon_tfr_nmb(ps_view_ctxt, u4_mb_idx, u4_num_mbs, u4_num_mbs_next, b_tfr_n_mb, b_is_end_of_row); } ps_view_ctxt->u2_total_mbs_coded += u4_num_mbs; if(b_tfr_n_mb) { u4_num_mbs = 0; } u4_mb_idx = u4_num_mbs; ps_view_ctxt->u1_mb_idx = u4_num_mbs; } } ps_view_ctxt->u4_num_mbs_cur_nmb = 0; ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx; ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby; if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1)) { ps_view_ctxt->u1_pic_decode_done = 1; } return 0; } static WORD32 imvcd_parse_pslice(mvc_dec_ctxt_t *ps_mvcd_ctxt) { UWORD8 u1_num_ref_idx_l0, u1_num_ref_idx_l1; WORD32 i4_error_code; WORD32 i; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt); dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps; dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice; dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; ps_view_ctxt->s_default_mv_pred = imvcd_get_default_mv_pred(); i4_error_code = imvcd_set_ref_idx_override_flag(ps_view_ctxt); if(OK != i4_error_code) { return i4_error_code; } if(ps_slice->u1_num_ref_idx_active_override_flag) { i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l0); if(OK != i4_error_code) { return i4_error_code; } } else { u1_num_ref_idx_l0 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[0]; } u1_num_ref_idx_l1 = 0; ps_slice->u1_num_ref_idx_lx_active[0] = u1_num_ref_idx_l0; ps_slice->u1_num_ref_idx_lx_active[1] = u1_num_ref_idx_l1; ps_view_ctxt->u1_num_ref_idx_lx_active_prev = ps_slice->u1_num_ref_idx_lx_active[0]; i4_error_code = imvcd_init_ref_pic_list(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au, ps_mvcd_ctxt->u2_num_views_decoded); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_set_ref_pic_list_mod_data(ps_mvcd_ctxt); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_dpb_reorder_ref_pic_list( ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au, imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt), ps_mvcd_ctxt->u2_num_views_decoded); if(OK != i4_error_code) { return i4_error_code; } ps_view_ctxt->ps_ref_pic_buf_lx[0] = imvcd_dpb_get_view_ref_pic_list( ps_mvcd_ctxt->ps_dpb_mgr, ps_mvcd_ctxt->u2_num_views_decoded, ps_cur_nalu_mvc_ext->u2_view_id, 0); for(i = 0; i < u1_num_ref_idx_l0; i++) { if(NULL == ps_view_ctxt->ps_ref_pic_buf_lx[0][i]->pu1_buf1) { return ERROR_FEATURE_UNAVAIL; } } imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt); imvcd_init_ref_idx_to_ref_buf_map(ps_mvcd_ctxt); if(ps_pps->u1_wted_pred_flag) { i4_error_code = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm); if(i4_error_code != OK) { return i4_error_code; } ih264d_form_pred_weight_matrix(ps_view_ctxt); } else { ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd = 0; } ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat; ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd; if(ps_slice->u1_nal_ref_idc != 0) { if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read) { WORD32 i4_bit_offset = ih264d_read_mmco_commands(ps_view_ctxt); if(i4_bit_offset < 0) { return ERROR_DBP_MANAGER_T; } ps_view_ctxt->u4_bitoffset = i4_bit_offset; } else { ps_bitstrm->u4_ofst += ps_view_ctxt->u4_bitoffset; } } if(ps_pps->u1_entropy_coding_mode == CABAC) { i4_error_code = imvcd_set_cabac_init_idc(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } } i4_error_code = imvcd_set_slice_qp(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } i4_error_code = imvcd_set_slice_deblk_params(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } ps_view_ctxt->u1_slice_header_done = 1; if(ps_pps->u1_entropy_coding_mode) { ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac; ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_pmb_cabac; ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff; ih264d_init_cabac_contexts(P_SLICE, ps_view_ctxt); } else { ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc; ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_pmb_cavlc; ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff; } ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb; ps_view_ctxt->u1_B = 0; i4_error_code = ps_view_ctxt->pf_parse_inter_slice(ps_view_ctxt, ps_slice, ps_slice->u2_first_mb_in_slice); return i4_error_code; } static WORD32 imvcd_parse_bslice(mvc_dec_ctxt_t *ps_mvcd_ctxt) { UWORD8 u1_num_ref_idx_l0, u1_num_ref_idx_l1; WORD32 i4_error_code; WORD32 i, j; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; nalu_mvc_ext_t *ps_cur_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt); dec_pic_params_t *ps_pps = ps_view_ctxt->ps_cur_pps; dec_slice_params_t *ps_slice = ps_view_ctxt->ps_cur_slice; dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; ps_view_ctxt->s_default_mv_pred = imvcd_get_default_mv_pred(); i4_error_code = imvcd_set_ref_idx_override_flag(ps_view_ctxt); if(OK != i4_error_code) { return i4_error_code; } if(ps_slice->u1_num_ref_idx_active_override_flag) { i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l0); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_set_num_ref_idx_active(ps_view_ctxt, &u1_num_ref_idx_l1); if(OK != i4_error_code) { return i4_error_code; } } else { u1_num_ref_idx_l0 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[0]; u1_num_ref_idx_l1 = ps_view_ctxt->ps_cur_pps->u1_num_ref_idx_lx_active[1]; } if((0 == u1_num_ref_idx_l0) || (0 == u1_num_ref_idx_l1)) { return ERROR_FEATURE_UNAVAIL; } ps_slice->u1_num_ref_idx_lx_active[0] = u1_num_ref_idx_l0; ps_slice->u1_num_ref_idx_lx_active[1] = u1_num_ref_idx_l1; ps_view_ctxt->u1_num_ref_idx_lx_active_prev = ps_view_ctxt->ps_cur_slice->u1_num_ref_idx_lx_active[0]; i4_error_code = imvcd_init_ref_pic_list(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au, ps_mvcd_ctxt->u2_num_views_decoded); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_set_ref_pic_list_mod_data(ps_mvcd_ctxt); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_dpb_reorder_ref_pic_list( ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_nalu_mvc_ext, ps_mvcd_ctxt->ps_cur_au, imvcd_get_cur_ref_pic_list_mod_data(ps_mvcd_ctxt), ps_mvcd_ctxt->u2_num_views_decoded); if(OK != i4_error_code) { return i4_error_code; } for(i = 0; i < 2; i++) { ps_view_ctxt->ps_ref_pic_buf_lx[i] = imvcd_dpb_get_view_ref_pic_list( ps_mvcd_ctxt->ps_dpb_mgr, ps_mvcd_ctxt->u2_num_views_decoded, ps_cur_nalu_mvc_ext->u2_view_id, i); for(j = 0; j < ps_slice->u1_num_ref_idx_lx_active[i]; j++) { if(NULL == ps_view_ctxt->ps_ref_pic_buf_lx[i][j]->pu1_buf1) { return ERROR_FEATURE_UNAVAIL; } } } imvcd_set_view_buf_id_to_buf_map(ps_view_ctxt); imvcd_init_ref_idx_to_ref_buf_map(ps_mvcd_ctxt); if(ps_pps->u1_wted_bipred_idc == 1) { i4_error_code = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm); if(i4_error_code != OK) { return i4_error_code; } ih264d_form_pred_weight_matrix(ps_view_ctxt); ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat; } else if(ps_pps->u1_wted_bipred_idc == 2) { /* Implicit Weighted prediction */ ps_slice->u2_log2Y_crwd = 0x0505; ps_view_ctxt->pu4_wt_ofsts = ps_view_ctxt->pu4_wts_ofsts_mat; ih264d_get_implicit_weights(ps_view_ctxt); } else { ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd = 0; } ps_view_ctxt->ps_parse_cur_slice->u2_log2Y_crwd = ps_view_ctxt->ps_cur_slice->u2_log2Y_crwd; if(ps_slice->u1_nal_ref_idc != 0) { if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read) { WORD32 i4_bit_offset = ih264d_read_mmco_commands(ps_view_ctxt); if(i4_bit_offset < 0) { return ERROR_DBP_MANAGER_T; } ps_view_ctxt->u4_bitoffset = i4_bit_offset; } else { ps_bitstrm->u4_ofst += ps_view_ctxt->u4_bitoffset; } } if(ps_pps->u1_entropy_coding_mode == CABAC) { i4_error_code = imvcd_set_cabac_init_idc(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } } i4_error_code = imvcd_set_slice_qp(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } i4_error_code = imvcd_set_slice_deblk_params(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } ps_view_ctxt->u1_slice_header_done = 1; if(ps_pps->u1_entropy_coding_mode) { ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac; ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_bmb_cabac; ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff; ih264d_init_cabac_contexts(B_SLICE, ps_view_ctxt); } else { ps_view_ctxt->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc; ps_view_ctxt->pf_parse_inter_mb = ih264d_parse_bmb_cavlc; ps_view_ctxt->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff; } i4_error_code = ih264d_cal_col_pic(ps_view_ctxt); if(i4_error_code != OK) { return i4_error_code; } ps_view_ctxt->u1_B = 1; ps_view_ctxt->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_bmb; i4_error_code = ps_view_ctxt->pf_parse_inter_slice(ps_view_ctxt, ps_slice, ps_slice->u2_first_mb_in_slice); return i4_error_code; } static WORD32 imvcd_parse_islice(mvc_dec_ctxt_t *ps_mvcd_ctxt) { WORD32 i4_error_code; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; i4_error_code = ih264d_parse_islice(ps_view_ctxt, ps_view_ctxt->ps_cur_slice->u2_first_mb_in_slice); return i4_error_code; } static WORD32 imvcd_finish_slice_decode(mvc_dec_ctxt_t *ps_mvcd_ctxt) { WORD32 i; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status; UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded; UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views; imvcd_dpb_reset_ivp_ctxt(ps_mvcd_ctxt->ps_dpb_mgr); /* End of Picture detection */ if(ps_view_ctxt->u2_total_mbs_coded >= (ps_view_ctxt->ps_cur_sps->u2_max_mb_addr + 1)) { ps_view_ctxt->u1_pic_decode_done = 1; } else { imvcd_corrupted_slice_handler(ps_mvcd_ctxt); return ERROR_CORRUPTED_SLICE; } if((ps_view_ctxt->u1_slice_header_done) && (u2_view_order_id == (u2_num_views - 1))) { ps_view_ctxt->u1_first_slice_in_stream = 0; } if((ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id] != 0) && (0 == u2_view_order_id)) { if(!ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read) { ps_view_ctxt->ps_dpb_cmds[0] = ps_view_ctxt->s_dpb_cmds_scratch; } } /* storing last Mb X and MbY of the slice */ ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx; ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby; if((ps_err->u1_err_flag & REJECT_PB_PICS) && (ps_err->u1_cur_pic_type == PIC_TYPE_I)) { ps_err->u1_err_flag = ACCEPT_ALL_PICS; } /* Accounting for idiocy in 'ih264d_parse_sps' */ if(u2_view_order_id > 0) { for(i = 0; i < MAX_NUM_SEQ_PARAMS; i++) { if(ps_view_ctxt->ps_sps->u1_is_valid) { ps_view_ctxt->ps_cur_sps = ps_view_ctxt->ps_sps; break; } } } return OK; } WORD32 imvcd_parse_decode_slice(mvc_dec_ctxt_t *ps_mvcd_ctxt) { dec_pic_params_t *ps_pps; dec_seq_params_t *ps_sps; dec_slice_params_t *ps_cur_slice; WORD32 i4_error_code; UWORD8 u1_pps_id; UWORD8 u1_pic_order_cnt_type; dec_struct_t *ps_view_ctxt = &ps_mvcd_ctxt->s_view_dec_ctxt; nalu_mvc_ext_t *ps_nalu_mvc_ext = imvcd_get_cur_nalu_mvc_ext(ps_mvcd_ctxt); dec_bit_stream_t *ps_bitstrm = ps_view_ctxt->ps_bitstrm; pocstruct_t s_tmp_poc = {0}; dec_err_status_t *ps_err = ps_view_ctxt->ps_dec_err_status; WORD32 ai4_delta_poc[2] = {0}; WORD32 i4_poc = 0; UWORD32 u4_idr_pic_id = 0; UWORD16 u2_view_id = ps_nalu_mvc_ext->u2_view_id; UWORD16 u2_view_order_id = ps_mvcd_ctxt->u2_num_views_decoded; bool b_is_idr_slice = imvcd_is_idr_au(ps_mvcd_ctxt); UWORD16 u2_num_views = ps_mvcd_ctxt->u2_num_views; UWORD8 u1_redundant_pic_cnt = 0; const UWORD8 u1_field_pic_flag = 0; const UWORD8 u1_bottom_field_flag = 0; ps_view_ctxt->ps_cur_slice = ps_cur_slice = &ps_mvcd_ctxt->as_slices[u2_view_id]; ps_view_ctxt->ps_dpb_cmds->u1_dpb_commands_read_slc = 0; ps_cur_slice->u1_nal_unit_type = ps_mvcd_ctxt->ae_nalu_id[u2_view_order_id]; ps_cur_slice->u1_nal_ref_idc = ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id]; i4_error_code = imvcd_set_first_mb_in_slice(ps_view_ctxt); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_set_slice_type(ps_view_ctxt); if(OK != i4_error_code) { return i4_error_code; } i4_error_code = imvcd_set_cur_pps(ps_view_ctxt, &u1_pps_id); if(OK != i4_error_code) { return i4_error_code; } ps_pps = ps_view_ctxt->ps_cur_pps; ps_sps = ps_view_ctxt->ps_cur_sps; i4_error_code = imvcd_set_frame_num(ps_view_ctxt, ps_sps->u1_bits_in_frm_num); if(OK != i4_error_code) { return i4_error_code; } if(!ps_view_ctxt->u1_first_slice_in_stream && ps_view_ctxt->u4_first_slice_in_pic) { ps_view_ctxt->u2_mbx = 0xffff; ps_view_ctxt->u2_mby = 0; ps_view_ctxt->u2_total_mbs_coded = 0; if(0 == u2_view_order_id) { if(b_is_idr_slice || ps_cur_slice->u1_mmco_equalto5) { ps_view_ctxt->u2_prev_ref_frame_num = 0; } if(ps_view_ctxt->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag) { i4_error_code = imvcd_decode_gaps_in_frame_num(ps_mvcd_ctxt); if(OK != i4_error_code) { return i4_error_code; } } if(!b_is_idr_slice && ps_cur_slice->u1_nal_ref_idc) { ps_view_ctxt->u2_prev_ref_frame_num = ps_cur_slice->u2_frame_num; } imvcd_pocstruct_init(ps_view_ctxt); } } if(b_is_idr_slice) { i4_error_code = imvcd_set_idr_pic_id(ps_view_ctxt, &u4_idr_pic_id); if(OK != i4_error_code) { return i4_error_code; } /* 'ih264d_read_mmco_commands' asssumes AVC semantics */ ps_view_ctxt->u1_nal_unit_type = SLICE_IDR; } else { ps_view_ctxt->u1_nal_unit_type = SLICE_NON_IDR; } u1_pic_order_cnt_type = ps_sps->u1_pic_order_cnt_type; if(0 == u1_pic_order_cnt_type) { i4_error_code = imvcd_set_poc_lsb(ps_view_ctxt, &s_tmp_poc.i4_pic_order_cnt_lsb, ps_sps->i4_max_pic_order_cntLsb, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus); if(OK != i4_error_code) { return i4_error_code; } if(ps_pps->u1_pic_order_present_flag) { i4_error_code = imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt_bottom); if(OK != i4_error_code) { return i4_error_code; } } } if((1 == u1_pic_order_cnt_type) && !ps_sps->u1_delta_pic_order_always_zero_flag) { i4_error_code = imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt[0]); if(OK != i4_error_code) { return i4_error_code; } if(ps_pps->u1_pic_order_present_flag) { i4_error_code = imvcd_set_delta_poc(ps_view_ctxt, &s_tmp_poc.i4_delta_pic_order_cnt[1]); if(OK != i4_error_code) { return i4_error_code; } } } if(ps_pps->u1_redundant_pic_cnt_present_flag) { i4_error_code = imvcd_set_redundant_pic_cnt(ps_view_ctxt, &u1_redundant_pic_cnt); if(OK != i4_error_code) { return i4_error_code; } } ps_view_ctxt->ps_dec_err_status->u1_err_flag &= MASK_REJECT_CUR_PIC; ps_view_ctxt->u1_slice_header_done = 0; if(ps_view_ctxt->u4_first_slice_in_pic) { i4_error_code = ih264d_decode_pic_order_cnt( b_is_idr_slice, ps_cur_slice->u2_frame_num, &ps_view_ctxt->s_prev_pic_poc, &s_tmp_poc, ps_cur_slice, ps_pps, ps_mvcd_ctxt->au1_nal_ref_idc[u2_view_order_id], u1_bottom_field_flag, u1_field_pic_flag, &i4_poc); if(i4_error_code != OK) { return i4_error_code; } /* Display seq no calculations */ if(i4_poc >= ps_view_ctxt->i4_max_poc) { ps_view_ctxt->i4_max_poc = i4_poc; } /* IDR Picture or POC wrap around */ if(i4_poc == 0) { imvcd_modulate_max_disp_seq(ps_view_ctxt); } } if((0 == i4_poc) && (ps_mvcd_ctxt->ae_nalu_id[u2_view_order_id] == SLICE_IDR) && (ps_cur_slice->u1_slice_type != ISLICE)) { return ERROR_INV_SLICE_HDR_T; } /*--------------------------------------------------------------------*/ /* Copy the values read from the bitstream to the slice header and then*/ /* If the slice is first slice in picture, then do Start of Picture */ /* processing. */ /*--------------------------------------------------------------------*/ ps_cur_slice->i4_delta_pic_order_cnt[0] = ai4_delta_poc[0]; ps_cur_slice->i4_delta_pic_order_cnt[1] = ai4_delta_poc[1]; ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id; ps_cur_slice->u1_field_pic_flag = u1_field_pic_flag; ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag; ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb; ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt; ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type; ps_cur_slice->i4_poc = i4_poc; ps_cur_slice->u1_direct_8x8_inference_flag = ps_sps->u1_direct_8x8_inference_flag; if(IV_SUCCESS != imvcd_view_error_checks(ps_mvcd_ctxt)) { return ERROR_INV_SLICE_HDR_T; } if(ps_cur_slice->u1_slice_type == B_SLICE) { i4_error_code = imvcd_set_direct_spatial_mv_pred_flag(ps_view_ctxt); if(OK != i4_error_code) { return i4_error_code; } if(ps_cur_slice->u1_direct_spatial_mv_pred_flag) { ps_cur_slice->pf_decodeDirect = ih264d_decode_spatial_direct; } else { ps_cur_slice->pf_decodeDirect = ih264d_decode_temporal_direct; } ps_view_ctxt->pf_mvpred = ih264d_mvpred_nonmbaffB; } else { ps_view_ctxt->pf_mvpred = ih264d_mvpred_nonmbaff; } if(ps_view_ctxt->u4_first_slice_in_pic) { if(0 == ps_cur_slice->u2_first_mb_in_slice) { i4_error_code = imvcd_pic_init(ps_mvcd_ctxt, &s_tmp_poc, i4_poc, b_is_idr_slice); if(i4_error_code != OK) { return i4_error_code; } } else { return ERROR_INV_SLICE_HDR_T; } ps_view_ctxt->u4_output_present = 0; if(u2_view_order_id == (u2_num_views - 1)) { if(IV_SUCCESS == imvcd_get_next_display_au_buf(ps_mvcd_ctxt)) { ps_view_ctxt->u4_output_present = 1; } } if(!imvcd_dpb_is_diff_poc_valid(ps_mvcd_ctxt->ps_dpb_mgr, ps_cur_slice->i4_poc)) { return ERROR_INV_SLICE_HDR_T; } if(ps_view_ctxt->u1_separate_parse == 1) { if(!ps_view_ctxt->u4_dec_thread_created) { ithread_create(ps_view_ctxt->pv_dec_thread_handle, NULL, ih264d_decode_picture_thread, ps_view_ctxt); ps_view_ctxt->u4_dec_thread_created = 1; } if((3 == ps_view_ctxt->u4_num_cores) && (!ps_view_ctxt->u4_app_disable_deblk_frm || ps_view_ctxt->i1_recon_in_thread3_flag) && !ps_view_ctxt->u4_bs_deblk_thread_created) { ps_view_ctxt->u4_start_recon_deblk = 0; ithread_create(ps_view_ctxt->pv_bs_deblk_thread_handle, NULL, ih264d_recon_deblk_thread, ps_view_ctxt); ps_view_ctxt->u4_bs_deblk_thread_created = 1; } } } if((ps_cur_slice->u1_slice_type != B_SLICE) && (ps_view_ctxt->ps_cur_pps->u1_wted_pred_flag == 0)) { ps_view_ctxt->p_form_mb_part_info = ih264d_form_mb_part_info_bp; ps_view_ctxt->p_motion_compensate = ih264d_motion_compensate_bp; } else { ps_view_ctxt->p_form_mb_part_info = ih264d_form_mb_part_info_mp; ps_view_ctxt->p_motion_compensate = ih264d_motion_compensate_mp; } if(ps_err->u4_frm_sei_sync == ps_cur_slice->u2_frame_num) { ps_err->u1_err_flag = ACCEPT_ALL_PICS; ps_err->u4_frm_sei_sync = SYNC_FRM_DEFAULT; } ps_err->u4_cur_frm = ps_cur_slice->u2_frame_num; ps_view_ctxt->i4_submb_ofst = -SUB_BLK_SIZE; ps_view_ctxt->u2_cur_mb_addr = 0; ps_view_ctxt->ps_deblk_mbn = ps_view_ctxt->ps_deblk_pic; ps_view_ctxt->ps_mv_cur = ps_mvcd_ctxt->ps_cur_au->ps_au_mv_data->aps_mvs[u2_view_id]; ps_view_ctxt->s_tran_addrecon.pu1_dest_y = ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[Y].pv_data; ps_view_ctxt->s_tran_addrecon.pu1_dest_u = ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[UV].pv_data; ps_view_ctxt->s_tran_addrecon.pu1_dest_v = NULL; ps_view_ctxt->s_tran_addrecon.pu1_mb_y = ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[Y].pv_data; ps_view_ctxt->s_tran_addrecon.pu1_mb_u = ps_mvcd_ctxt->ps_cur_au->as_view_buffers[u2_view_id].as_component_bufs[UV].pv_data; ps_view_ctxt->s_tran_addrecon.pu1_mb_v = NULL; ps_view_ctxt->ps_part = ps_view_ctxt->ps_parse_part_params; ps_view_ctxt->u2_mbx = (MOD(ps_cur_slice->u2_first_mb_in_slice - 1, ps_sps->u2_frm_wd_in_mbs)); ps_view_ctxt->u2_mby = (DIV(ps_cur_slice->u2_first_mb_in_slice - 1, ps_sps->u2_frm_wd_in_mbs)); ps_view_ctxt->i2_prev_slice_mbx = ps_view_ctxt->u2_mbx; ps_view_ctxt->i2_prev_slice_mby = ps_view_ctxt->u2_mby; /* RBSP stop bit is used for CABAC decoding*/ ps_bitstrm->u4_max_ofst += ps_view_ctxt->ps_cur_pps->u1_entropy_coding_mode; ps_view_ctxt->u1_B = (ps_cur_slice->u1_slice_type == B_SLICE); ps_view_ctxt->u4_next_mb_skip = 0; ps_view_ctxt->ps_parse_cur_slice->u4_first_mb_in_slice = ps_cur_slice->u2_first_mb_in_slice; ps_view_ctxt->ps_parse_cur_slice->slice_type = ps_cur_slice->u1_slice_type; ps_view_ctxt->u4_start_recon_deblk = 1; ps_view_ctxt->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = ps_view_ctxt->pv_map_ref_idx_to_poc_buf; if(ps_view_ctxt->u1_separate_parse) { ps_view_ctxt->ps_parse_cur_slice->pv_tu_coeff_data_start = ps_view_ctxt->pv_parse_tu_coeff_data; } else { ps_view_ctxt->pv_proc_tu_coeff_data = ps_view_ctxt->pv_parse_tu_coeff_data; } if(0 == u2_view_order_id) { i4_error_code = imvcd_dpb_st_lt_deduplicator(ps_mvcd_ctxt->ps_dpb_mgr); if(i4_error_code < 0) { i4_error_code = ERROR_DBP_MANAGER_T; } } if(ps_cur_slice->u1_slice_type == I_SLICE) { ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= I_SLC_BIT; i4_error_code = imvcd_parse_islice(ps_mvcd_ctxt); ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type; if(ps_view_ctxt->i4_pic_type != B_SLICE && ps_view_ctxt->i4_pic_type != P_SLICE) { ps_view_ctxt->i4_pic_type = I_SLICE; } } else if(ps_cur_slice->u1_slice_type == P_SLICE) { ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= P_SLC_BIT; i4_error_code = imvcd_parse_pslice(ps_mvcd_ctxt); ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type; if(ps_view_ctxt->i4_pic_type != B_SLICE) { ps_view_ctxt->i4_pic_type = P_SLICE; } } else if(ps_cur_slice->u1_slice_type == B_SLICE) { ps_mvcd_ctxt->ps_cur_au->au4_pack_slc_typ[u2_view_order_id] |= B_SLC_BIT; i4_error_code = imvcd_parse_bslice(ps_mvcd_ctxt); ps_view_ctxt->u1_pr_sl_type = ps_cur_slice->u1_slice_type; ps_view_ctxt->i4_pic_type = B_SLICE; } else { i4_error_code = ERROR_INV_SLC_TYPE_T; } i4_error_code = imvcd_finish_slice_decode(ps_mvcd_ctxt); return i4_error_code; }