diff options
author | Hamsalekha S <hamsalekha.s@ittiam.com> | 2015-03-13 21:24:58 +0530 |
---|---|---|
committer | Hamsalekha S <hamsalekha.s@ittiam.com> | 2015-04-02 15:59:02 +0530 |
commit | 8d3d303c7942ced6a987a52db8977d768dc3605f (patch) | |
tree | cc806c96794356996b13ba9970941d0aed74a97e /decoder | |
parent | 3956d913d37327dcb340f836e604b04bd478b158 (diff) | |
download | android_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.tar.gz android_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.tar.bz2 android_external_libavc-8d3d303c7942ced6a987a52db8977d768dc3605f.zip |
Initial version
Change-Id: I7efe9a589cd24edf86e8d086b40c27cbbf8b4017
Diffstat (limited to 'decoder')
74 files changed, 60330 insertions, 0 deletions
diff --git a/decoder/arm/ih264d_function_selector.c b/decoder/arm/ih264d_function_selector.c new file mode 100755 index 0000000..1aa0c43 --- /dev/null +++ b/decoder/arm/ih264d_function_selector.c @@ -0,0 +1,101 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* ihevcd_function_selector.c +* +* @brief +* Contains functions to initialize function pointers used in hevc +* +* @author +* Naveen +* +* @par List of Functions: +* @remarks +* None +* +******************************************************************************* +*/ +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" +#include "ih264d_function_selector.h" + +void ih264d_init_function_ptr(dec_struct_t *ps_codec) +{ + + IVD_ARCH_T e_proc_arch = ps_codec->e_processor_arch; + ih264d_init_function_ptr_generic(ps_codec); + switch(e_proc_arch) + { + case ARCH_ARM_NONEON: + ih264d_init_function_ptr_generic(ps_codec); + break; +#ifndef ARMV8 + case ARCH_ARM_A5: + case ARCH_ARM_A7: + case ARCH_ARM_A9: + case ARCH_ARM_A15: + case ARCH_ARM_A9Q: + default: + ih264d_init_function_ptr_a9q(ps_codec); + break; +#else /* ARMV8 */ + case ARCH_ARMV8_GENERIC: + default: + ih264d_init_function_ptr_av8(ps_codec); + break; +#endif /* ARMV8 */ + } +} + +void ih264d_init_arch(dec_struct_t *ps_codec) +{ +#ifdef DEFAULT_ARCH +#if DEFAULT_ARCH == D_ARCH_ARM_NONEON + ps_codec->e_processor_arch = ARCH_ARM_NONEON; +#elif DEFAULT_ARCH == D_ARCH_ARMV8_GENERIC + ps_codec->e_processor_arch = ARCH_ARMV8_GENERIC; +#elif DEFAULT_ARCH == D_ARCH_ARM_NEONINTR + ps_codec->e_processor_arch = ARCH_ARM_NEONINTR; +#else + ps_codec->e_processor_arch = ARCH_ARM_A9Q; +#endif +#else + ps_codec->e_processor_arch = ARCH_ARM_A9Q; +#endif + +} diff --git a/decoder/arm/ih264d_function_selector_a9q.c b/decoder/arm/ih264d_function_selector_a9q.c new file mode 100755 index 0000000..0cf8581 --- /dev/null +++ b/decoder/arm/ih264d_function_selector_a9q.c @@ -0,0 +1,200 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* ih264e_function_selector_a9q.c +* +* @brief +* Contains functions to initialize function pointers of codec context +* +* @author +* Ittiam +* +* @par List of Functions: +* - ih264e_init_function_ptr_a9q +* +* @remarks +* None +* +******************************************************************************* +*/ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" + + +/** +******************************************************************************* +* +* @brief Initialize the intra/inter/transform/deblk function pointers of +* codec context +* +* @par Description: the current routine initializes the function pointers of +* codec context basing on the architecture in use +* +* @param[in] ps_codec +* Codec context pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void ih264d_init_function_ptr_a9q(dec_struct_t *ps_codec) +{ + + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_luma_16x16[0] = ih264_intra_pred_luma_16x16_mode_vert_a9q; + ps_codec->apf_intra_pred_luma_16x16[1] = ih264_intra_pred_luma_16x16_mode_horz_a9q; + ps_codec->apf_intra_pred_luma_16x16[2] = ih264_intra_pred_luma_16x16_mode_dc_a9q; + ps_codec->apf_intra_pred_luma_16x16[3] = ih264_intra_pred_luma_16x16_mode_plane_a9q; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_luma_4x4[0] = ih264_intra_pred_luma_4x4_mode_vert_a9q; + ps_codec->apf_intra_pred_luma_4x4[1] = ih264_intra_pred_luma_4x4_mode_horz_a9q; + ps_codec->apf_intra_pred_luma_4x4[2] = ih264_intra_pred_luma_4x4_mode_dc_a9q; + ps_codec->apf_intra_pred_luma_4x4[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_a9q; + ps_codec->apf_intra_pred_luma_4x4[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_a9q; + ps_codec->apf_intra_pred_luma_4x4[5] = ih264_intra_pred_luma_4x4_mode_vert_r_a9q; + ps_codec->apf_intra_pred_luma_4x4[6] = ih264_intra_pred_luma_4x4_mode_horz_d_a9q; + ps_codec->apf_intra_pred_luma_4x4[7] = ih264_intra_pred_luma_4x4_mode_vert_l_a9q; + ps_codec->apf_intra_pred_luma_4x4[8] = ih264_intra_pred_luma_4x4_mode_horz_u_a9q; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 8x8 */ + ps_codec->apf_intra_pred_luma_8x8[0] = ih264_intra_pred_luma_8x8_mode_vert_a9q; + ps_codec->apf_intra_pred_luma_8x8[1] = ih264_intra_pred_luma_8x8_mode_horz_a9q; + ps_codec->apf_intra_pred_luma_8x8[2] = ih264_intra_pred_luma_8x8_mode_dc_a9q; + ps_codec->apf_intra_pred_luma_8x8[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_a9q; + ps_codec->apf_intra_pred_luma_8x8[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_a9q; + ps_codec->apf_intra_pred_luma_8x8[5] = ih264_intra_pred_luma_8x8_mode_vert_r_a9q; + ps_codec->apf_intra_pred_luma_8x8[6] = ih264_intra_pred_luma_8x8_mode_horz_d_a9q; + ps_codec->apf_intra_pred_luma_8x8[7] = ih264_intra_pred_luma_8x8_mode_vert_l_a9q; + ps_codec->apf_intra_pred_luma_8x8[8] = ih264_intra_pred_luma_8x8_mode_horz_u_a9q; + + /* ih264_intra_pred_luma_8x8_mode_ref_filtering_a9q does not handle all availibilities */ + ps_codec->pf_intra_pred_ref_filtering = ih264_intra_pred_luma_8x8_mode_ref_filtering; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_chroma[0] = ih264_intra_pred_chroma_8x8_mode_vert_a9q; + ps_codec->apf_intra_pred_chroma[1] = ih264_intra_pred_chroma_8x8_mode_horz_a9q; + /* ih264_intra_pred_chroma_8x8_mode_dc_a9q does not support interlaced clips, hence using C */ + ps_codec->apf_intra_pred_chroma[2] = ih264_intra_pred_chroma_8x8_mode_dc; + ps_codec->apf_intra_pred_chroma[3] = ih264_intra_pred_chroma_8x8_mode_plane_a9q; + + + ps_codec->pf_default_weighted_pred_luma = ih264_default_weighted_pred_luma_a9q; + ps_codec->pf_default_weighted_pred_chroma = ih264_default_weighted_pred_chroma_a9q; + ps_codec->pf_weighted_pred_luma = ih264_weighted_pred_luma_a9q; + ps_codec->pf_weighted_pred_chroma = ih264_weighted_pred_chroma_a9q; + ps_codec->pf_weighted_bi_pred_luma = ih264_weighted_bi_pred_luma_a9q; + ps_codec->pf_weighted_bi_pred_chroma = ih264_weighted_bi_pred_chroma_a9q; + + /* Padding Functions */ + ps_codec->pf_pad_top = ih264_pad_top_a9q; + ps_codec->pf_pad_bottom = ih264_pad_bottom; + + ps_codec->pf_pad_left_luma = ih264_pad_left_luma_a9q; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma_a9q; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_a9q; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_a9q; + + ps_codec->pf_iquant_itrans_recon_luma_4x4 = ih264_iquant_itrans_recon_4x4_a9; + ps_codec->pf_iquant_itrans_recon_luma_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_a9; + ps_codec->pf_iquant_itrans_recon_luma_8x8 = ih264_iquant_itrans_recon_8x8_a9; + ps_codec->pf_iquant_itrans_recon_luma_8x8_dc = ih264_iquant_itrans_recon_8x8_dc_a9; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_a9; + + + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_a9; + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_a9; + + /* Init fn ptr luma deblocking */ + ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_a9; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_a9; + ps_codec->pf_deblk_luma_vert_bs4_mbaff = ih264_deblk_luma_vert_bs4_mbaff_a9; + ps_codec->pf_deblk_luma_vert_bslt4_mbaff = ih264_deblk_luma_vert_bslt4_mbaff_a9; + + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_a9; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_a9; + + /* Init fn ptr chroma deblocking */ + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_a9; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_a9; + ps_codec->pf_deblk_chroma_vert_bs4_mbaff = ih264_deblk_chroma_vert_bs4_mbaff_a9; + ps_codec->pf_deblk_chroma_vert_bslt4_mbaff = ih264_deblk_chroma_vert_bslt4_mbaff_a9; + + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_a9; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_a9; + + + /* Inter pred leaf level functions */ + ps_codec->apf_inter_pred_luma[0] = ih264_inter_pred_luma_copy_a9q; + + ps_codec->apf_inter_pred_luma[1] = ih264_inter_pred_luma_horz_qpel_a9q; + ps_codec->apf_inter_pred_luma[2] = ih264_inter_pred_luma_horz_a9q; + ps_codec->apf_inter_pred_luma[3] = ih264_inter_pred_luma_horz_qpel_a9q; + ps_codec->apf_inter_pred_luma[4] = ih264_inter_pred_luma_vert_qpel_a9q; + + ps_codec->apf_inter_pred_luma[5] = ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q; + + ps_codec->apf_inter_pred_luma[6] = ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q; + + ps_codec->apf_inter_pred_luma[7] = ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q; + + ps_codec->apf_inter_pred_luma[8] = ih264_inter_pred_luma_vert_a9q; + ps_codec->apf_inter_pred_luma[9] = ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q; + ps_codec->apf_inter_pred_luma[10] = ih264_inter_pred_luma_horz_hpel_vert_hpel_a9q; + ps_codec->apf_inter_pred_luma[11] = ih264_inter_pred_luma_horz_qpel_vert_hpel_a9q; + ps_codec->apf_inter_pred_luma[12] = ih264_inter_pred_luma_vert_qpel_a9q; + ps_codec->apf_inter_pred_luma[13] = ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q; + ps_codec->apf_inter_pred_luma[14] = ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q; + ps_codec->apf_inter_pred_luma[15] = ih264_inter_pred_luma_horz_qpel_vert_qpel_a9q; + + ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma_a9q; + + + return; +} diff --git a/decoder/arm/ih264d_function_selector_av8.c b/decoder/arm/ih264d_function_selector_av8.c new file mode 100755 index 0000000..5715ee0 --- /dev/null +++ b/decoder/arm/ih264d_function_selector_av8.c @@ -0,0 +1,191 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* ih264e_function_selector_av8.c +* +* @brief +* Contains functions to initialize function pointers of codec context +* +* @author +* Ittiam +* +* @par List of Functions: +* - ih264e_init_function_ptr_av8 +* +* @remarks +* None +* +******************************************************************************* +*/ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" +#include "ih264d_function_selector.h" + + +/** +******************************************************************************* +* +* @brief Initialize the intra/inter/transform/deblk function pointers of +* codec context +* +* @par Description: the current routine initializes the function pointers of +* codec context basing on the architecture in use +* +* @param[in] ps_codec +* Codec context pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void ih264d_init_function_ptr_av8(dec_struct_t *ps_codec) +{ + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_luma_16x16[0] = ih264_intra_pred_luma_16x16_mode_vert_av8; + ps_codec->apf_intra_pred_luma_16x16[1] = ih264_intra_pred_luma_16x16_mode_horz_av8; + ps_codec->apf_intra_pred_luma_16x16[2] = ih264_intra_pred_luma_16x16_mode_dc_av8; + ps_codec->apf_intra_pred_luma_16x16[3] = ih264_intra_pred_luma_16x16_mode_plane_av8; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_luma_4x4[0] = ih264_intra_pred_luma_4x4_mode_vert_av8; + ps_codec->apf_intra_pred_luma_4x4[1] = ih264_intra_pred_luma_4x4_mode_horz_av8; + ps_codec->apf_intra_pred_luma_4x4[2] = ih264_intra_pred_luma_4x4_mode_dc_av8; + ps_codec->apf_intra_pred_luma_4x4[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_av8; + ps_codec->apf_intra_pred_luma_4x4[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_av8; + ps_codec->apf_intra_pred_luma_4x4[5] = ih264_intra_pred_luma_4x4_mode_vert_r_av8; + ps_codec->apf_intra_pred_luma_4x4[6] = ih264_intra_pred_luma_4x4_mode_horz_d_av8; + ps_codec->apf_intra_pred_luma_4x4[7] = ih264_intra_pred_luma_4x4_mode_vert_l_av8; + ps_codec->apf_intra_pred_luma_4x4[8] = ih264_intra_pred_luma_4x4_mode_horz_u_av8; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 8x8 */ + ps_codec->apf_intra_pred_luma_8x8[0] = ih264_intra_pred_luma_8x8_mode_vert_av8; + ps_codec->apf_intra_pred_luma_8x8[1] = ih264_intra_pred_luma_8x8_mode_horz_av8; + ps_codec->apf_intra_pred_luma_8x8[2] = ih264_intra_pred_luma_8x8_mode_dc_av8; + ps_codec->apf_intra_pred_luma_8x8[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_av8; + ps_codec->apf_intra_pred_luma_8x8[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_av8; + ps_codec->apf_intra_pred_luma_8x8[5] = ih264_intra_pred_luma_8x8_mode_vert_r_av8; + ps_codec->apf_intra_pred_luma_8x8[6] = ih264_intra_pred_luma_8x8_mode_horz_d_av8; + ps_codec->apf_intra_pred_luma_8x8[7] = ih264_intra_pred_luma_8x8_mode_vert_l_av8; + ps_codec->apf_intra_pred_luma_8x8[8] = ih264_intra_pred_luma_8x8_mode_horz_u_av8; + + ps_codec->pf_intra_pred_ref_filtering = ih264_intra_pred_luma_8x8_mode_ref_filtering; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_chroma[0] = ih264_intra_pred_chroma_8x8_mode_vert_av8; + ps_codec->apf_intra_pred_chroma[1] = ih264_intra_pred_chroma_8x8_mode_horz_av8; + /* ih264_intra_pred_chroma_8x8_mode_dc_av8 does not support interlaced clips, hence using C */ + ps_codec->apf_intra_pred_chroma[2] = ih264_intra_pred_chroma_8x8_mode_dc; + ps_codec->apf_intra_pred_chroma[3] = ih264_intra_pred_chroma_8x8_mode_plane_av8; + + ps_codec->pf_default_weighted_pred_luma = ih264_default_weighted_pred_luma_av8; + ps_codec->pf_default_weighted_pred_chroma = ih264_default_weighted_pred_chroma_av8; + ps_codec->pf_weighted_pred_luma = ih264_weighted_pred_luma_av8; + ps_codec->pf_weighted_pred_chroma = ih264_weighted_pred_chroma_av8; + ps_codec->pf_weighted_bi_pred_luma = ih264_weighted_bi_pred_luma_av8; + ps_codec->pf_weighted_bi_pred_chroma = ih264_weighted_bi_pred_chroma_av8; + + /* Padding Functions */ + ps_codec->pf_pad_top = ih264_pad_top_av8; + ps_codec->pf_pad_bottom = ih264_pad_bottom; + ps_codec->pf_pad_left_luma = ih264_pad_left_luma_av8; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_av8; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma_av8; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_av8; + + + ps_codec->pf_iquant_itrans_recon_luma_4x4 = ih264_iquant_itrans_recon_4x4_av8; + ps_codec->pf_iquant_itrans_recon_luma_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_av8; + ps_codec->pf_iquant_itrans_recon_luma_8x8 = ih264_iquant_itrans_recon_8x8_av8; + ps_codec->pf_iquant_itrans_recon_luma_8x8_dc = ih264_iquant_itrans_recon_8x8_dc_av8; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_av8; + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_av8; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_av8; + + + /* Init fn ptr luma deblocking */ + ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_av8; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_av8; + ps_codec->pf_deblk_luma_vert_bs4_mbaff = ih264_deblk_luma_vert_bs4_mbaff; + ps_codec->pf_deblk_luma_vert_bslt4_mbaff = ih264_deblk_luma_vert_bslt4_mbaff; + + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_av8; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_av8; + + /* Init fn ptr chroma deblocking */ + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_av8; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_av8; + ps_codec->pf_deblk_chroma_vert_bs4_mbaff = ih264_deblk_chroma_vert_bs4_mbaff; + ps_codec->pf_deblk_chroma_vert_bslt4_mbaff = ih264_deblk_chroma_vert_bslt4_mbaff; + + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_av8; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_av8; + + /* Inter pred leaf level functions */ + ps_codec->apf_inter_pred_luma[0] = ih264_inter_pred_luma_copy_av8; + ps_codec->apf_inter_pred_luma[1] = ih264_inter_pred_luma_horz_qpel_av8; + ps_codec->apf_inter_pred_luma[2] = ih264_inter_pred_luma_horz_av8; + ps_codec->apf_inter_pred_luma[3] = ih264_inter_pred_luma_horz_qpel_av8; + ps_codec->apf_inter_pred_luma[4] = ih264_inter_pred_luma_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[5] = ih264_inter_pred_luma_horz_qpel_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[6] = ih264_inter_pred_luma_horz_hpel_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[7] = ih264_inter_pred_luma_horz_qpel_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[8] = ih264_inter_pred_luma_vert_av8; + ps_codec->apf_inter_pred_luma[9] = ih264_inter_pred_luma_horz_qpel_vert_hpel_av8; + ps_codec->apf_inter_pred_luma[10] = ih264_inter_pred_luma_horz_hpel_vert_hpel_av8; + ps_codec->apf_inter_pred_luma[11] = ih264_inter_pred_luma_horz_qpel_vert_hpel_av8; + ps_codec->apf_inter_pred_luma[12] = ih264_inter_pred_luma_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[13] = ih264_inter_pred_luma_horz_qpel_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[14] = ih264_inter_pred_luma_horz_hpel_vert_qpel_av8; + ps_codec->apf_inter_pred_luma[15] = ih264_inter_pred_luma_horz_qpel_vert_qpel_av8; + + ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma_av8; + + + return; +} diff --git a/decoder/ih264d.h b/decoder/ih264d.h new file mode 100755 index 0000000..f89e576 --- /dev/null +++ b/decoder/ih264d.h @@ -0,0 +1,482 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d.h */ +/* */ +/* Description : This file contains all the necessary structure and */ +/* enumeration definitions needed for the Application */ +/* Program Interface(API) of the Ittiam H264 ASP */ +/* Decoder on Cortex A8 - Neon platform */ +/* */ +/* List of Functions : ih264d_api_function */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 26 08 2010 100239(RCY) Draft */ +/* */ +/*****************************************************************************/ + +#ifndef _IH264D_H_ +#define _IH264D_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "iv.h" +#include "ivd.h" + + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ +#define IS_IVD_CONCEALMENT_APPLIED(x) (x & (1 << IVD_APPLIEDCONCEALMENT)) +#define IS_IVD_INSUFFICIENTDATA_ERROR(x) (x & (1 << IVD_INSUFFICIENTDATA)) +#define IS_IVD_CORRUPTEDDATA_ERROR(x) (x & (1 << IVD_CORRUPTEDDATA)) +#define IS_IVD_CORRUPTEDHEADER_ERROR(x) (x & (1 << IVD_CORRUPTEDHEADER)) +#define IS_IVD_UNSUPPORTEDINPUT_ERROR(x) (x & (1 << IVD_UNSUPPORTEDINPUT)) +#define IS_IVD_UNSUPPORTEDPARAM_ERROR(x) (x & (1 << IVD_UNSUPPORTEDPARAM)) +#define IS_IVD_FATAL_ERROR(x) (x & (1 << IVD_FATALERROR)) +#define IS_IVD_INVALID_BITSTREAM_ERROR(x) (x & (1 << IVD_INVALID_BITSTREAM)) +#define IS_IVD_INCOMPLETE_BITSTREAM_ERROR(x) (x & (1 << IVD_INCOMPLETE_BITSTREAM)) + + +/*****************************************************************************/ +/* API Function Prototype */ +/*****************************************************************************/ +IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *ps_handle, void *pv_api_ip,void *pv_api_op); + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ +/* Codec Error codes for H264 ASP Decoder */ + +typedef enum { + + IH264D_VID_HDR_DEC_NUM_FRM_BUF_NOT_SUFFICIENT = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 1, + +}IH264D_ERROR_CODES_T; + +/*****************************************************************************/ +/* Extended Structures */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Get Number of Memory Records */ +/*****************************************************************************/ + + +typedef struct { + iv_num_mem_rec_ip_t s_ivd_num_mem_rec_ip_t; +}ih264d_num_mem_rec_ip_t; + + +typedef struct{ + iv_num_mem_rec_op_t s_ivd_num_mem_rec_op_t; +}ih264d_num_mem_rec_op_t; + + +/*****************************************************************************/ +/* Fill Memory Records */ +/*****************************************************************************/ + + +typedef struct { + iv_fill_mem_rec_ip_t s_ivd_fill_mem_rec_ip_t; + WORD32 i4_level; + UWORD32 u4_num_reorder_frames; + UWORD32 u4_num_ref_frames; + UWORD32 u4_share_disp_buf; + + /* format in which codec has to give out frame data for display */ + IV_COLOR_FORMAT_T e_output_format; + + /* Number of extra display buffers that will be allocated to handle display pipeline depth */ + UWORD32 u4_num_extra_disp_buf; + +}ih264d_fill_mem_rec_ip_t; + + +typedef struct{ + iv_fill_mem_rec_op_t s_ivd_fill_mem_rec_op_t; + +}ih264d_fill_mem_rec_op_t; + +/*****************************************************************************/ +/* Retrieve Memory Records */ +/*****************************************************************************/ + + +typedef struct { + iv_retrieve_mem_rec_ip_t s_ivd_retrieve_mem_rec_ip_t; +}ih264d_retrieve_mem_rec_ip_t; + + +typedef struct{ + iv_retrieve_mem_rec_op_t s_ivd_retrieve_mem_rec_op_t; +}ih264d_retrieve_mem_rec_op_t; + + +/*****************************************************************************/ +/* Initialize decoder */ +/*****************************************************************************/ + + +typedef struct { + ivd_init_ip_t s_ivd_init_ip_t; + WORD32 i4_level; + UWORD32 u4_num_reorder_frames; + UWORD32 u4_num_ref_frames; + UWORD32 u4_share_disp_buf; + /* Number of extra display buffers that will be allocated to handle display pipeline depth */ + UWORD32 u4_num_extra_disp_buf; + +}ih264d_init_ip_t; + + +typedef struct{ + ivd_init_op_t s_ivd_init_op_t; +}ih264d_init_op_t; + + +/*****************************************************************************/ +/* Video Decode */ +/*****************************************************************************/ + + +typedef struct { + ivd_video_decode_ip_t s_ivd_video_decode_ip_t; +}ih264d_video_decode_ip_t; + + +typedef struct{ + ivd_video_decode_op_t s_ivd_video_decode_op_t; +}ih264d_video_decode_op_t; + + +/*****************************************************************************/ +/* Get Display Frame */ +/*****************************************************************************/ + + +typedef struct +{ + ivd_get_display_frame_ip_t s_ivd_get_display_frame_ip_t; +}ih264d_get_display_frame_ip_t; + + +typedef struct +{ + ivd_get_display_frame_op_t s_ivd_get_display_frame_op_t; +}ih264d_get_display_frame_op_t; + +/*****************************************************************************/ +/* Set Display Frame */ +/*****************************************************************************/ + + +typedef struct +{ + ivd_set_display_frame_ip_t s_ivd_set_display_frame_ip_t; +}ih264d_set_display_frame_ip_t; + + +typedef struct +{ + ivd_set_display_frame_op_t s_ivd_set_display_frame_op_t; +}ih264d_set_display_frame_op_t; + +/*****************************************************************************/ +/* Release Display Buffers */ +/*****************************************************************************/ + + +typedef struct +{ + ivd_rel_display_frame_ip_t s_ivd_rel_display_frame_ip_t; +}ih264d_rel_display_frame_ip_t; + + +typedef struct +{ + ivd_rel_display_frame_op_t s_ivd_rel_display_frame_op_t; +}ih264d_rel_display_frame_op_t; + + +typedef enum { + /** Set number of cores/threads to be used */ + IH264D_CMD_CTL_SET_NUM_CORES = IVD_CMD_CTL_CODEC_SUBCMD_START, + + /** Set processor details */ + IH264D_CMD_CTL_SET_PROCESSOR = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x001, + + /** Get display buffer dimensions */ + IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x100, + + /** Get VUI parameters */ + IH264D_CMD_CTL_GET_VUI_PARAMS = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x101, + + /** Enable/disable GPU, supported on select platforms */ + IH264D_CMD_CTL_GPU_ENABLE_DISABLE = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x200, + + /** Set degrade level */ + IH264D_CMD_CTL_DEGRADE = IVD_CMD_CTL_CODEC_SUBCMD_START + 0x300 +}IH264D_CMD_CTL_SUB_CMDS; +/*****************************************************************************/ +/* Video control Flush */ +/*****************************************************************************/ + + +typedef struct{ + ivd_ctl_flush_ip_t s_ivd_ctl_flush_ip_t; +}ih264d_ctl_flush_ip_t; + + +typedef struct{ + ivd_ctl_flush_op_t s_ivd_ctl_flush_op_t; +}ih264d_ctl_flush_op_t; + +/*****************************************************************************/ +/* Video control reset */ +/*****************************************************************************/ + + +typedef struct{ + ivd_ctl_reset_ip_t s_ivd_ctl_reset_ip_t; +}ih264d_ctl_reset_ip_t; + + +typedef struct{ + ivd_ctl_reset_op_t s_ivd_ctl_reset_op_t; +}ih264d_ctl_reset_op_t; + + +/*****************************************************************************/ +/* Video control Set Params */ +/*****************************************************************************/ + + +typedef struct { + ivd_ctl_set_config_ip_t s_ivd_ctl_set_config_ip_t; +}ih264d_ctl_set_config_ip_t; + + +typedef struct{ + ivd_ctl_set_config_op_t s_ivd_ctl_set_config_op_t; +}ih264d_ctl_set_config_op_t; + +/*****************************************************************************/ +/* Video control:Get Buf Info */ +/*****************************************************************************/ + + +typedef struct{ + ivd_ctl_getbufinfo_ip_t s_ivd_ctl_getbufinfo_ip_t; +}ih264d_ctl_getbufinfo_ip_t; + + + +typedef struct{ + ivd_ctl_getbufinfo_op_t s_ivd_ctl_getbufinfo_op_t; +}ih264d_ctl_getbufinfo_op_t; + + +/*****************************************************************************/ +/* Video control:Getstatus Call */ +/*****************************************************************************/ + + +typedef struct{ + ivd_ctl_getstatus_ip_t s_ivd_ctl_getstatus_ip_t; +}ih264d_ctl_getstatus_ip_t; + + + +typedef struct{ + ivd_ctl_getstatus_op_t s_ivd_ctl_getstatus_op_t; +}ih264d_ctl_getstatus_op_t; + + +/*****************************************************************************/ +/* Video control:Get Version Info */ +/*****************************************************************************/ + + +typedef struct{ + ivd_ctl_getversioninfo_ip_t s_ivd_ctl_getversioninfo_ip_t; +}ih264d_ctl_getversioninfo_ip_t; + + + +typedef struct{ + ivd_ctl_getversioninfo_op_t s_ivd_ctl_getversioninfo_op_t; +}ih264d_ctl_getversioninfo_op_t; + +typedef struct{ + + /** + * u4_size + */ + UWORD32 u4_size; + + /** + * cmd + */ + IVD_API_COMMAND_TYPE_T e_cmd; + + /** + * sub_cmd + */ + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + + /** + * Pictures that are are degraded + * 0 : No degrade + * 1 : Only on non-reference frames + * 2 : Use interval specified by u4_nondegrade_interval + * 3 : All non-key frames + * 4 : All frames + */ + WORD32 i4_degrade_pics; + + /** + * Interval for pictures which are completely decoded without any degradation + */ + WORD32 i4_nondegrade_interval; + + /** + * bit position (lsb is zero): Type of degradation + * 1 : Disable deblocking + * 2 : Faster inter prediction filters + * 3 : Fastest inter prediction filters + */ + WORD32 i4_degrade_type; + +}ih264d_ctl_degrade_ip_t; + +typedef struct +{ + /** + * u4_size + */ + UWORD32 u4_size; + + /** + * error_code + */ + UWORD32 u4_error_code; +}ih264d_ctl_degrade_op_t; + +typedef struct{ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + UWORD32 u4_disable_deblk_level; +}ih264d_ctl_disable_deblock_ip_t; + +typedef struct{ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ih264d_ctl_disable_deblock_op_t; + + +typedef struct{ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + UWORD32 u4_num_cores; +}ih264d_ctl_set_num_cores_ip_t; + +typedef struct{ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ih264d_ctl_set_num_cores_op_t; + +typedef struct +{ + /** + * i4_size + */ + UWORD32 u4_size; + /** + * cmd + */ + IVD_API_COMMAND_TYPE_T e_cmd; + /** + * sub cmd + */ + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + /** + * Processor type + */ + UWORD32 u4_arch; + /** + * SOC type + */ + UWORD32 u4_soc; + + /** + * num_cores + */ + UWORD32 u4_num_cores; + +}ih264d_ctl_set_processor_ip_t; + +typedef struct +{ + /** + * i4_size + */ + UWORD32 u4_size; + /** + * error_code + */ + UWORD32 u4_error_code; +}ih264d_ctl_set_processor_op_t; + +typedef struct{ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ih264d_ctl_get_frame_dimensions_ip_t; + + +typedef struct{ + UWORD32 u4_size; + UWORD32 u4_error_code; + UWORD32 u4_x_offset[3]; + UWORD32 u4_y_offset[3]; + UWORD32 u4_disp_wd[3]; + UWORD32 u4_disp_ht[3]; + UWORD32 u4_buffer_wd[3]; + UWORD32 u4_buffer_ht[3]; +}ih264d_ctl_get_frame_dimensions_op_t; + +#ifdef __cplusplus +} /* closing brace for extern "C" */ +#endif +#endif /* _IH264D_H_ */ diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c new file mode 100755 index 0000000..67ef5bb --- /dev/null +++ b/decoder/ih264d_api.c @@ -0,0 +1,4680 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_api.c */ +/* */ +/* Description : Has all API related functions */ +/* */ +/* */ +/* List of Functions : api_check_struct_sanity */ +/* ih264d_set_processor */ +/* ih264d_get_num_rec */ +/* ih264d_init_decoder */ +/* ih264d_init_video_decoder */ +/* ih264d_fill_num_mem_rec */ +/* ih264d_clr */ +/* ih264d_init */ +/* ih264d_map_error */ +/* ih264d_video_decode */ +/* ih264d_get_version */ +/* ih264d_get_display_frame */ +/* ih264d_set_display_frame */ +/* ih264d_set_flush_mode */ +/* ih264d_get_status */ +/* ih264d_get_buf_info */ +/* ih264d_set_params */ +/* ih264d_set_default_params */ +/* ih264d_reset */ +/* ih264d_ctl */ +/* ih264d_rel_display_frame */ +/* ih264d_set_degrade */ +/* ih264d_get_frame_dimensions */ +/* ih264d_set_num_cores */ +/* ih264d_fill_output_struct_from_context */ +/* ih264d_api_function */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 14 10 2008 100356(SKV) Draft */ +/* */ +/*****************************************************************************/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_tables.h" +#include "iv.h" +#include "ivd.h" +#include "ih264d.h" +#include "ih264d_defs.h" + +#include <string.h> +#include <limits.h> +#include <stddef.h> + +#include "ih264d_inter_pred.h" + +#include "ih264d_structs.h" +#include "ih264d_nal.h" +#include "ih264d_error_handler.h" + +#include "ih264d_defs.h" + +#include "ithread.h" +#include "ih264d_parse_slice.h" +#include "ih264d_function_selector.h" +#include "ih264_error.h" +#include "ih264_disp_mgr.h" +#include "ih264_buf_mgr.h" +#include "ih264d_deblocking.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_parse_cabac.h" +#include "ih264d_utils.h" +#include "ih264d_format_conv.h" +#include "ih264d_parse_headers.h" +#include <assert.h> + + +/*********************/ +/* Codec Versioning */ +/*********************/ +//Move this to where it is used +#define CODEC_NAME "H264VDEC" +#define CODEC_RELEASE_TYPE "production" +#define CODEC_RELEASE_VER "04.00" +#define CODEC_VENDOR "ITTIAM" +#define MAXVERSION_STRLEN 511 +#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \ + strncpy(version_string,"@(#)Id:", MAXVERSION_STRLEN); \ + strncat(version_string,codec_name, MAXVERSION_STRLEN); \ + strncat(version_string,"_", MAXVERSION_STRLEN); \ + strncat(version_string,codec_release_type, MAXVERSION_STRLEN); \ + strncat(version_string," Ver:", MAXVERSION_STRLEN); \ + strncat(version_string,codec_release_ver, MAXVERSION_STRLEN); \ + strncat(version_string," Released by ", MAXVERSION_STRLEN); \ + strncat(version_string,codec_vendor, MAXVERSION_STRLEN); \ + strncat(version_string," Build: ", MAXVERSION_STRLEN); \ + strncat(version_string,__DATE__, MAXVERSION_STRLEN); \ + strncat(version_string," @ ", MAXVERSION_STRLEN); \ + strncat(version_string,__TIME__, MAXVERSION_STRLEN); + +#define MAX_NAL_UNIT_SIZE MAX((H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_HEIGHT),MIN_NALUNIT_SIZE) +#define MIN_NALUNIT_SIZE 200000 +#define FMT_CONV_NUM_ROWS 4 + +#define MIN_IN_BUFS 1 +#define MIN_OUT_BUFS_420 3 +#define MIN_OUT_BUFS_422ILE 1 +#define MIN_OUT_BUFS_RGB565 1 +#define MIN_OUT_BUFS_420SP 2 +#define MIN_IN_BUF_SIZE (2*1024*1024) // Currently, i4_size set to 500kb, CHECK LATER + +#define NUM_FRAMES_LIMIT_ENABLED 0 + +#if NUM_FRAMES_LIMIT_ENABLED +#define NUM_FRAMES_LIMIT 10000 +#else +#define NUM_FRAMES_LIMIT 0x7FFFFFFF +#endif + + +UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height); +WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op); +WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); + +WORD32 ih264d_deblock_display(dec_struct_t *ps_dec); + +void ih264d_signal_decode_thread(dec_struct_t *ps_dec); + +void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec); +void ih264d_decode_picture_thread(dec_struct_t *ps_dec); + +WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj, + void *pv_api_ip, + void *pv_api_op); + +void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec, + ivd_video_decode_op_t *ps_dec_op); + +static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, + void *pv_api_ip, + void *pv_api_op) +{ + IVD_API_COMMAND_TYPE_T e_cmd; + UWORD32 *pu4_api_ip; + UWORD32 *pu4_api_op; + UWORD32 i, j; + + if(NULL == pv_api_op) + return (IV_FAIL); + + if(NULL == pv_api_ip) + return (IV_FAIL); + + pu4_api_ip = (UWORD32 *)pv_api_ip; + pu4_api_op = (UWORD32 *)pv_api_op; + e_cmd = *(pu4_api_ip + 1); + + /* error checks on handle */ + switch((WORD32)e_cmd) + { + case IV_CMD_GET_NUM_MEM_REC: + case IV_CMD_FILL_NUM_MEM_REC: + break; + case IV_CMD_INIT: + if(ps_handle == NULL) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_HANDLE_NULL; + return IV_FAIL; + } + + if(ps_handle->u4_size != sizeof(iv_obj_t)) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT; + H264_DEC_DEBUG_PRINT( + "Sizes do not match. Expected: %d, Got: %d", + sizeof(iv_obj_t), ps_handle->u4_size); + return IV_FAIL; + } + break; + case IVD_CMD_REL_DISPLAY_FRAME: + case IVD_CMD_SET_DISPLAY_FRAME: + case IVD_CMD_GET_DISPLAY_FRAME: + case IVD_CMD_VIDEO_DECODE: + case IV_CMD_RETRIEVE_MEMREC: + case IVD_CMD_VIDEO_CTL: + if(ps_handle == NULL) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_HANDLE_NULL; + return IV_FAIL; + } + + if(ps_handle->u4_size != sizeof(iv_obj_t)) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_handle->pv_fxns != ih264d_api_function) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL; + return IV_FAIL; + } + + if(ps_handle->pv_codec_handle == NULL) + { + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL; + return IV_FAIL; + } + break; + default: + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_INVALID_API_CMD; + return IV_FAIL; + } + + switch((WORD32)e_cmd) + { + case IV_CMD_GET_NUM_MEM_REC: + { + ih264d_num_mem_rec_ip_t *ps_ip = + (ih264d_num_mem_rec_ip_t *)pv_api_ip; + ih264d_num_mem_rec_op_t *ps_op = + (ih264d_num_mem_rec_op_t *)pv_api_op; + ps_op->s_ivd_num_mem_rec_op_t.u4_error_code = 0; + + if(ps_ip->s_ivd_num_mem_rec_ip_t.u4_size + != sizeof(ih264d_num_mem_rec_ip_t)) + { + ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if(ps_op->s_ivd_num_mem_rec_op_t.u4_size + != sizeof(ih264d_num_mem_rec_op_t)) + { + ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + } + break; + case IV_CMD_FILL_NUM_MEM_REC: + { + ih264d_fill_mem_rec_ip_t *ps_ip = + (ih264d_fill_mem_rec_ip_t *)pv_api_ip; + ih264d_fill_mem_rec_op_t *ps_op = + (ih264d_fill_mem_rec_op_t *)pv_api_op; + iv_mem_rec_t *ps_mem_rec; + WORD32 max_wd = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd; + WORD32 max_ht = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht; + + max_wd = ((max_wd + 15) >> 4) << 4; + max_ht = ((max_ht + 15) >> 4) << 4; + + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code = 0; + + if((ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > sizeof(ih264d_fill_mem_rec_ip_t)) + || (ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size + < sizeof(iv_fill_mem_rec_ip_t))) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if((ps_op->s_ivd_fill_mem_rec_op_t.u4_size + != sizeof(ih264d_fill_mem_rec_op_t)) + && (ps_op->s_ivd_fill_mem_rec_op_t.u4_size + != sizeof(iv_fill_mem_rec_op_t))) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if(max_wd < H264_MIN_FRAME_WIDTH) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_REQUESTED_WIDTH_NOT_SUPPPORTED; + return (IV_FAIL); + } + + if(max_wd > H264_MAX_FRAME_WIDTH) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_REQUESTED_WIDTH_NOT_SUPPPORTED; + return (IV_FAIL); + } + + if(max_ht < H264_MIN_FRAME_HEIGHT) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED; + return (IV_FAIL); + } + + if((max_ht * max_wd) + > (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH)) + + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED; + return (IV_FAIL); + } + + if(NULL == ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_NUM_REC_NOT_SUFFICIENT; + return (IV_FAIL); + } + + /* check memrecords sizes are correct */ + ps_mem_rec = ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location; + for(i = 0; i < MEM_REC_CNT; i++) + { + if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) + { + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + IVD_MEM_REC_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + } + break; + + case IV_CMD_INIT: + { + ih264d_init_ip_t *ps_ip = (ih264d_init_ip_t *)pv_api_ip; + ih264d_init_op_t *ps_op = (ih264d_init_op_t *)pv_api_op; + iv_mem_rec_t *ps_mem_rec; + WORD32 max_wd = ps_ip->s_ivd_init_ip_t.u4_frm_max_wd; + WORD32 max_ht = ps_ip->s_ivd_init_ip_t.u4_frm_max_ht; + + max_wd = ((max_wd + 15) >> 4) << 4; + max_ht = ((max_ht + 15) >> 4) << 4; + + ps_op->s_ivd_init_op_t.u4_error_code = 0; + + if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ih264d_init_ip_t)) + || (ps_ip->s_ivd_init_ip_t.u4_size + < sizeof(ivd_init_ip_t))) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ih264d_init_op_t)) + && (ps_op->s_ivd_init_op_t.u4_size + != sizeof(ivd_init_op_t))) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec != MEM_REC_CNT) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_NOT_SUFFICIENT; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if(max_wd < H264_MIN_FRAME_WIDTH) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if(max_wd > H264_MAX_FRAME_WIDTH) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if(max_ht < H264_MIN_FRAME_HEIGHT) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if((max_ht * max_wd) + > (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH)) + + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if(NULL == ps_ip->s_ivd_init_ip_t.pv_mem_rec_location) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_NUM_REC_NOT_SUFFICIENT; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + if((ps_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) + && (ps_ip->s_ivd_init_ip_t.e_output_format + != IV_YUV_422ILE) + && (ps_ip->s_ivd_init_ip_t.e_output_format + != IV_RGB_565) + && (ps_ip->s_ivd_init_ip_t.e_output_format + != IV_YUV_420SP_UV) + && (ps_ip->s_ivd_init_ip_t.e_output_format + != IV_YUV_420SP_VU)) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED; + H264_DEC_DEBUG_PRINT("\n"); + return (IV_FAIL); + } + + /* verify number of mem records */ + if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec < MEM_REC_CNT) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT; + H264_DEC_DEBUG_PRINT("\n"); + return IV_FAIL; + } + + ps_mem_rec = ps_ip->s_ivd_init_ip_t.pv_mem_rec_location; + /* check memrecords sizes are correct */ + for(i = 0; i < ps_ip->s_ivd_init_ip_t.u4_num_mem_rec; i++) + { + if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_MEM_REC_STRUCT_SIZE_INCORRECT; + H264_DEC_DEBUG_PRINT("i: %d\n", i); + return IV_FAIL; + } + /* check memrecords pointers are not NULL */ + + if(ps_mem_rec[i].pv_base == NULL) + { + + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_BASE_NULL; + H264_DEC_DEBUG_PRINT("i: %d\n", i); + return IV_FAIL; + + } + + } + + /* verify memtabs for overlapping regions */ + { + void *start[MEM_REC_CNT]; + void *end[MEM_REC_CNT]; + + start[0] = (void *)(ps_mem_rec[0].pv_base); + end[0] = (void *)((UWORD8 *)ps_mem_rec[0].pv_base + + ps_mem_rec[0].u4_mem_size - 1); + for(i = 1; i < MEM_REC_CNT; i++) + { + /* This array is populated to check memtab overlapp */ + start[i] = (void *)(ps_mem_rec[i].pv_base); + end[i] = (void *)((UWORD8 *)ps_mem_rec[i].pv_base + + ps_mem_rec[i].u4_mem_size - 1); + + for(j = 0; j < i; j++) + { + if((start[i] >= start[j]) && (start[i] <= end[j])) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; + H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); + return IV_FAIL; + } + + if((end[i] >= start[j]) && (end[i] <= end[j])) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; + H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); + return IV_FAIL; + } + + if((start[i] < start[j]) && (end[i] > end[j])) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; + H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); + return IV_FAIL; + } + } + + } + } + + { + iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT]; + ih264d_fill_mem_rec_ip_t s_fill_mem_rec_ip; + ih264d_fill_mem_rec_op_t s_fill_mem_rec_op; + IV_API_CALL_STATUS_T e_status; + + UWORD32 i; + s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = + IV_CMD_FILL_NUM_MEM_REC; + s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = + mem_rec_ittiam_api; + s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = + max_wd; + s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = + max_ht; + + if(ps_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, i4_level)) + { + s_fill_mem_rec_ip.i4_level = ps_ip->i4_level; + } + else + { + s_fill_mem_rec_ip.i4_level = H264_LEVEL_3_1; + } + + if(ps_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_num_ref_frames)) + { + s_fill_mem_rec_ip.u4_num_ref_frames = + ps_ip->u4_num_ref_frames; + } + else + { + s_fill_mem_rec_ip.u4_num_ref_frames = + (H264_MAX_REF_PICS + 1); + } + + if(ps_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, + u4_num_reorder_frames)) + { + s_fill_mem_rec_ip.u4_num_reorder_frames = + ps_ip->u4_num_reorder_frames; + } + else + { + s_fill_mem_rec_ip.u4_num_reorder_frames = (H264_MAX_REF_PICS + + 1); + } + + if(ps_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, + u4_num_extra_disp_buf)) + { + s_fill_mem_rec_ip.u4_num_extra_disp_buf = + ps_ip->u4_num_extra_disp_buf; + } + else + { + s_fill_mem_rec_ip.u4_num_extra_disp_buf = 0; + } + + if(ps_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_share_disp_buf)) + { +#ifndef LOGO_EN + s_fill_mem_rec_ip.u4_share_disp_buf = + ps_ip->u4_share_disp_buf; +#else + s_fill_mem_rec_ip.u4_share_disp_buf = 0; +#endif + } + else + { + s_fill_mem_rec_ip.u4_share_disp_buf = 0; + } + + s_fill_mem_rec_ip.e_output_format = + ps_ip->s_ivd_init_ip_t.e_output_format; + + if((s_fill_mem_rec_ip.e_output_format != IV_YUV_420P) + && (s_fill_mem_rec_ip.e_output_format + != IV_YUV_420SP_UV) + && (s_fill_mem_rec_ip.e_output_format + != IV_YUV_420SP_VU)) + { + s_fill_mem_rec_ip.u4_share_disp_buf = 0; + } + + s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size = + sizeof(ih264d_fill_mem_rec_ip_t); + s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size = + sizeof(ih264d_fill_mem_rec_op_t); + + for(i = 0; i < MEM_REC_CNT; i++) + mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t); + + e_status = ih264d_api_function(NULL, + (void *)&s_fill_mem_rec_ip, + (void *)&s_fill_mem_rec_op); + if(IV_FAIL == e_status) + { + ps_op->s_ivd_init_op_t.u4_error_code = + s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code; + H264_DEC_DEBUG_PRINT("Fail\n"); + return (IV_FAIL); + } + + for(i = 0; i < MEM_REC_CNT; i++) + { + if(ps_mem_rec[i].u4_mem_size + < mem_rec_ittiam_api[i].u4_mem_size) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE; + H264_DEC_DEBUG_PRINT("i: %d \n", i); + return IV_FAIL; + } + if(ps_mem_rec[i].u4_mem_alignment + != mem_rec_ittiam_api[i].u4_mem_alignment) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR; + H264_DEC_DEBUG_PRINT("i: %d \n", i); + return IV_FAIL; + } + if(ps_mem_rec[i].e_mem_type + != mem_rec_ittiam_api[i].e_mem_type) + { + UWORD32 check = IV_SUCCESS; + UWORD32 diff = mem_rec_ittiam_api[i].e_mem_type + - ps_mem_rec[i].e_mem_type; + + if((ps_mem_rec[i].e_mem_type + <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM) + && (mem_rec_ittiam_api[i].e_mem_type + >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM)) + { + check = IV_FAIL; + } + if(3 != MOD(mem_rec_ittiam_api[i].e_mem_type, 4)) + { + /* + * It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM + */ + if((diff < 1) || (diff > 3)) + { + // Difference between 1 and 3 is okay for all cases other than the two filtered + // with the MOD condition above + check = IV_FAIL; + } + } + else + { + if(diff == 1) + { + /* + * This particular case is when codec asked for External Persistent, but got + * Internal Scratch. + */ + check = IV_FAIL; + } + if((diff != 2) && (diff != 3)) + { + check = IV_FAIL; + } + } + if(check == IV_FAIL) + { + ps_op->s_ivd_init_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_init_op_t.u4_error_code |= + IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE; + H264_DEC_DEBUG_PRINT("i: %d \n", i); + return IV_FAIL; + } + } + } + } + + } + break; + + case IVD_CMD_GET_DISPLAY_FRAME: + { + ih264d_get_display_frame_ip_t *ps_ip = + (ih264d_get_display_frame_ip_t *)pv_api_ip; + ih264d_get_display_frame_op_t *ps_op = + (ih264d_get_display_frame_op_t *)pv_api_op; + + ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0; + + if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size + != sizeof(ih264d_get_display_frame_ip_t)) + && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size + != sizeof(ivd_get_display_frame_ip_t))) + { + ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if((ps_op->s_ivd_get_display_frame_op_t.u4_size + != sizeof(ih264d_get_display_frame_op_t)) + && (ps_op->s_ivd_get_display_frame_op_t.u4_size + != sizeof(ivd_get_display_frame_op_t))) + { + ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + } + break; + + case IVD_CMD_REL_DISPLAY_FRAME: + { + ih264d_rel_display_frame_ip_t *ps_ip = + (ih264d_rel_display_frame_ip_t *)pv_api_ip; + ih264d_rel_display_frame_op_t *ps_op = + (ih264d_rel_display_frame_op_t *)pv_api_op; + + ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0; + + if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size + != sizeof(ih264d_rel_display_frame_ip_t)) + && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size + != sizeof(ivd_rel_display_frame_ip_t))) + { + ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if((ps_op->s_ivd_rel_display_frame_op_t.u4_size + != sizeof(ih264d_rel_display_frame_op_t)) + && (ps_op->s_ivd_rel_display_frame_op_t.u4_size + != sizeof(ivd_rel_display_frame_op_t))) + { + ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + } + break; + + case IVD_CMD_SET_DISPLAY_FRAME: + { + ih264d_set_display_frame_ip_t *ps_ip = + (ih264d_set_display_frame_ip_t *)pv_api_ip; + ih264d_set_display_frame_op_t *ps_op = + (ih264d_set_display_frame_op_t *)pv_api_op; + UWORD32 j; + + ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0; + + if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size + != sizeof(ih264d_set_display_frame_ip_t)) + && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size + != sizeof(ivd_set_display_frame_ip_t))) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if((ps_op->s_ivd_set_display_frame_op_t.u4_size + != sizeof(ih264d_set_display_frame_op_t)) + && (ps_op->s_ivd_set_display_frame_op_t.u4_size + != sizeof(ivd_set_display_frame_op_t))) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_DISP_FRM_ZERO_OP_BUFS; + return IV_FAIL; + } + + for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs; + j++) + { + if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs + == 0) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_DISP_FRM_ZERO_OP_BUFS; + return IV_FAIL; + } + + for(i = 0; + i + < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs; + i++) + { + if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i] + == NULL) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_DISP_FRM_OP_BUF_NULL; + return IV_FAIL; + } + + if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i] + == 0) + { + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= + IVD_DISP_FRM_ZERO_OP_BUF_SIZE; + return IV_FAIL; + } + } + } + } + break; + + case IVD_CMD_VIDEO_DECODE: + { + ih264d_video_decode_ip_t *ps_ip = + (ih264d_video_decode_ip_t *)pv_api_ip; + ih264d_video_decode_op_t *ps_op = + (ih264d_video_decode_op_t *)pv_api_op; + + H264_DEC_DEBUG_PRINT("The input bytes is: %d", + ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes); + ps_op->s_ivd_video_decode_op_t.u4_error_code = 0; + + if(ps_ip->s_ivd_video_decode_ip_t.u4_size + != sizeof(ih264d_video_decode_ip_t)&& + ps_ip->s_ivd_video_decode_ip_t.u4_size != offsetof(ivd_video_decode_ip_t, s_out_buffer)) + { + ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_video_decode_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if(ps_op->s_ivd_video_decode_op_t.u4_size + != sizeof(ih264d_video_decode_op_t)&& + ps_op->s_ivd_video_decode_op_t.u4_size != offsetof(ivd_video_decode_op_t, u4_output_present)) + { + ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_video_decode_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + } + break; + + case IV_CMD_RETRIEVE_MEMREC: + { + ih264d_retrieve_mem_rec_ip_t *ps_ip = + (ih264d_retrieve_mem_rec_ip_t *)pv_api_ip; + ih264d_retrieve_mem_rec_op_t *ps_op = + (ih264d_retrieve_mem_rec_op_t *)pv_api_op; + iv_mem_rec_t *ps_mem_rec; + + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0; + + if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size + != sizeof(ih264d_retrieve_mem_rec_ip_t)) + { + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + if(ps_op->s_ivd_retrieve_mem_rec_op_t.u4_size + != sizeof(ih264d_retrieve_mem_rec_op_t)) + { + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return (IV_FAIL); + } + + ps_mem_rec = ps_ip->s_ivd_retrieve_mem_rec_ip_t.pv_mem_rec_location; + /* check memrecords sizes are correct */ + for(i = 0; i < MEM_REC_CNT; i++) + { + if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) + { + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= + IVD_MEM_REC_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + } + break; + + case IVD_CMD_VIDEO_CTL: + { + UWORD32 *pu4_ptr_cmd; + UWORD32 sub_command; + + pu4_ptr_cmd = (UWORD32 *)pv_api_ip; + pu4_ptr_cmd += 2; + sub_command = *pu4_ptr_cmd; + + switch(sub_command) + { + case IVD_CMD_CTL_SETPARAMS: + { + ih264d_ctl_set_config_ip_t *ps_ip; + ih264d_ctl_set_config_op_t *ps_op; + ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op; + + if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size + != sizeof(ih264d_ctl_set_config_ip_t)) + { + ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + //no break; is needed here + case IVD_CMD_CTL_SETDEFAULT: + { + ih264d_ctl_set_config_op_t *ps_op; + ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op; + if(ps_op->s_ivd_ctl_set_config_op_t.u4_size + != sizeof(ih264d_ctl_set_config_op_t)) + { + ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IVD_CMD_CTL_GETPARAMS: + { + ih264d_ctl_getstatus_ip_t *ps_ip; + ih264d_ctl_getstatus_op_t *ps_op; + + ps_ip = (ih264d_ctl_getstatus_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_getstatus_op_t *)pv_api_op; + if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size + != sizeof(ih264d_ctl_getstatus_ip_t)) + { + ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size + != sizeof(ih264d_ctl_getstatus_op_t)) + { + ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IVD_CMD_CTL_GETBUFINFO: + { + ih264d_ctl_getbufinfo_ip_t *ps_ip; + ih264d_ctl_getbufinfo_op_t *ps_op; + ps_ip = (ih264d_ctl_getbufinfo_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_getbufinfo_op_t *)pv_api_op; + + if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size + != sizeof(ih264d_ctl_getbufinfo_ip_t)) + { + ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size + != sizeof(ih264d_ctl_getbufinfo_op_t)) + { + ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IVD_CMD_CTL_GETVERSION: + { + ih264d_ctl_getversioninfo_ip_t *ps_ip; + ih264d_ctl_getversioninfo_op_t *ps_op; + ps_ip = (ih264d_ctl_getversioninfo_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_getversioninfo_op_t *)pv_api_op; + if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size + != sizeof(ih264d_ctl_getversioninfo_ip_t)) + { + ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size + != sizeof(ih264d_ctl_getversioninfo_op_t)) + { + ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IVD_CMD_CTL_FLUSH: + { + ih264d_ctl_flush_ip_t *ps_ip; + ih264d_ctl_flush_op_t *ps_op; + ps_ip = (ih264d_ctl_flush_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_flush_op_t *)pv_api_op; + if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size + != sizeof(ih264d_ctl_flush_ip_t)) + { + ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + if(ps_op->s_ivd_ctl_flush_op_t.u4_size + != sizeof(ih264d_ctl_flush_op_t)) + { + ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IVD_CMD_CTL_RESET: + { + ih264d_ctl_reset_ip_t *ps_ip; + ih264d_ctl_reset_op_t *ps_op; + ps_ip = (ih264d_ctl_reset_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_reset_op_t *)pv_api_op; + if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size + != sizeof(ih264d_ctl_reset_ip_t)) + { + ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + if(ps_op->s_ivd_ctl_reset_op_t.u4_size + != sizeof(ih264d_ctl_reset_op_t)) + { + ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + } + break; + + case IH264D_CMD_CTL_DEGRADE: + { + ih264d_ctl_degrade_ip_t *ps_ip; + ih264d_ctl_degrade_op_t *ps_op; + + ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op; + + if(ps_ip->u4_size != sizeof(ih264d_ctl_degrade_ip_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_op->u4_size != sizeof(ih264d_ctl_degrade_op_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if((ps_ip->i4_degrade_pics < 0) + || (ps_ip->i4_degrade_pics > 4) + || (ps_ip->i4_nondegrade_interval < 0) + || (ps_ip->i4_degrade_type < 0) + || (ps_ip->i4_degrade_type > 15)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + return IV_FAIL; + } + + break; + } + + case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS: + { + ih264d_ctl_get_frame_dimensions_ip_t *ps_ip; + ih264d_ctl_get_frame_dimensions_op_t *ps_op; + + ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op; + + if(ps_ip->u4_size + != sizeof(ih264d_ctl_get_frame_dimensions_ip_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_op->u4_size + != sizeof(ih264d_ctl_get_frame_dimensions_op_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + break; + } + + case IH264D_CMD_CTL_SET_NUM_CORES: + { + ih264d_ctl_set_num_cores_ip_t *ps_ip; + ih264d_ctl_set_num_cores_op_t *ps_op; + + ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op; + + if(ps_ip->u4_size != sizeof(ih264d_ctl_set_num_cores_ip_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_op->u4_size != sizeof(ih264d_ctl_set_num_cores_op_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2) + && (ps_ip->u4_num_cores != 3) + && (ps_ip->u4_num_cores != 4)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + return IV_FAIL; + } + break; + } + case IH264D_CMD_CTL_SET_PROCESSOR: + { + ih264d_ctl_set_processor_ip_t *ps_ip; + ih264d_ctl_set_processor_op_t *ps_op; + + ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op; + + if(ps_ip->u4_size != sizeof(ih264d_ctl_set_processor_ip_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_IP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + if(ps_op->u4_size != sizeof(ih264d_ctl_set_processor_op_t)) + { + ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_op->u4_error_code |= + IVD_OP_API_STRUCT_SIZE_INCORRECT; + return IV_FAIL; + } + + break; + } + default: + *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; + *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; + return IV_FAIL; + break; + } + } + break; + } + + return IV_SUCCESS; +} + + +/** + ******************************************************************************* + * + * @brief + * Sets Processor type + * + * @par Description: + * Sets Processor type + * + * @param[in] ps_codec_obj + * Pointer to codec object at API level + * + * @param[in] pv_api_ip + * Pointer to input argument structure + * + * @param[out] pv_api_op + * Pointer to output argument structure + * + * @returns Status + * + * @remarks + * + * + ******************************************************************************* + */ + +WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + ih264d_ctl_set_processor_ip_t *ps_ip; + ih264d_ctl_set_processor_op_t *ps_op; + dec_struct_t *ps_codec = (dec_struct_t *)dec_hdl->pv_codec_handle; + + ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op; + + ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch; + ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc; + + ih264d_init_function_ptr(ps_codec); + + ps_op->u4_error_code = 0; + return IV_SUCCESS; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_num_rec */ +/* */ +/* Description : returns number of mem records required */ +/* */ +/* Inputs : pv_api_ip input api structure */ +/* : pv_api_op output api structure */ +/* Outputs : */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_get_num_rec(void *pv_api_ip, void *pv_api_op) +{ + iv_num_mem_rec_ip_t *ps_mem_q_ip; + iv_num_mem_rec_op_t *ps_mem_q_op; + ps_mem_q_ip = (iv_num_mem_rec_ip_t *)pv_api_ip; + ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op; + UNUSED(ps_mem_q_ip); + ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT; + + return IV_SUCCESS; + +} + + +/************************************************************************** + * \if Function name : ih264d_init_decoder \endif + * + * + * \brief + * Initializes the decoder + * + * \param apiVersion : Version of the api being used. + * \param errorHandlingMechanism : Mechanism to be used for errror handling. + * \param postFilteringType: Type of post filtering operation to be used. + * \param uc_outputFormat: Format of the decoded picture [default 4:2:0]. + * \param uc_dispBufs: Number of Display Buffers. + * \param p_NALBufAPI: Pointer to NAL Buffer API. + * \param p_DispBufAPI: Pointer to Display Buffer API. + * \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder + * for memory allocation and freeing. + * + * \return + * 0 on Success and -1 on error + * + ************************************************************************** + */ +void ih264d_init_decoder(void * ps_dec_params) +{ + dec_struct_t * ps_dec = (dec_struct_t *)ps_dec_params; + dec_slice_params_t *ps_cur_slice; + pocstruct_t *ps_prev_poc, *ps_cur_poc; + + + + /* Set pic_parameter_set_id to -1 */ + + + + ps_cur_slice = ps_dec->ps_cur_slice; + ps_dec->init_done = 0; + + ps_dec->u4_num_cores = 1; + + ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0; + + ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE; + ps_dec->u4_app_disable_deblk_frm = 0; + ps_dec->i4_degrade_type = 0; + ps_dec->i4_degrade_pics = 0; + + ps_dec->i4_app_skip_mode = IVD_SKIP_NONE; + ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE; + + memset(ps_dec->ps_pps, 0, + ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS)); + memset(ps_dec->ps_sps, 0, + ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS)); + + /* Initialization of function pointers ih264d_deblock_picture function*/ + + ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff; + ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff; + + ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec; + + ps_dec->u4_num_fld_in_frm = 0; + + ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec; + + /* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/ + ps_dec->ps_sei->u1_is_valid = 0; + + /* decParams Initializations */ + ps_dec->ps_cur_pps = NULL; + ps_dec->ps_cur_sps = NULL; + ps_dec->u1_init_dec_flag = 0; + ps_dec->u1_first_nal_in_pic = 1; + ps_dec->u1_first_pb_nal_in_pic = 1; + ps_dec->u1_last_pic_not_decoded = 0; + ps_dec->u4_app_disp_width = 0; + ps_dec->i4_header_decoded = 0; + ps_dec->u4_total_frames_decoded = 0; + + ps_dec->i4_error_code = 0; + ps_dec->i4_content_type = -1; + ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0; + + ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS; //REJECT_PB_PICS; + ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN; + ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT; + ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME; + ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN; + + ps_dec->u1_pr_sl_type = 0xFF; + ps_dec->u2_mbx = 0xffff; + ps_dec->u2_mby = 0; + ps_dec->u2_total_mbs_coded = 0; + ps_cur_slice->u1_end_of_frame_signal = 0; + + /* POC initializations */ + ps_prev_poc = &ps_dec->s_prev_pic_poc; + ps_cur_poc = &ps_dec->s_cur_pic_poc; + ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0; + ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0; + ps_prev_poc->i4_delta_pic_order_cnt_bottom = + ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0; + ps_prev_poc->i4_delta_pic_order_cnt[0] = + ps_cur_poc->i4_delta_pic_order_cnt[0] = 0; + ps_prev_poc->i4_delta_pic_order_cnt[1] = + ps_cur_poc->i4_delta_pic_order_cnt[1] = 0; + ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0; + ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = + 0; + ps_prev_poc->i4_bottom_field_order_count = + ps_cur_poc->i4_bottom_field_order_count = 0; + ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0; + ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0; + ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0; + ps_cur_slice->u1_mmco_equalto5 = 0; + ps_cur_slice->u2_frame_num = 0; + + ps_dec->i4_max_poc = 0; + ps_dec->i4_prev_max_display_seq = 0; + ps_dec->u1_recon_mb_grp = 4; + + /* Field PIC initializations */ + ps_dec->u1_second_field = 0; + ps_dec->s_prev_seq_params.u1_eoseq_pending = 0; + + /* Set the cropping parameters as zero */ + ps_dec->u2_crop_offset_y = 0; + ps_dec->u2_crop_offset_uv = 0; + + /* The Initial Frame Rate Info is not Present */ + ps_dec->i4_vui_frame_rate = -1; + ps_dec->i4_pic_type = -1; + ps_dec->i4_frametype = -1; + ps_dec->i4_content_type = -1; + + ps_dec->u1_res_changed = 0; + + + ps_dec->u1_frame_decoded_flag = 0; + + /* Set the default frame seek mask mode */ + ps_dec->u4_skip_frm_mask = SKIP_NONE; + + /********************************************************/ + /* Initialize CAVLC residual decoding function pointers */ + /********************************************************/ + ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1; + ps_dec->pf_cavlc_4x4res_block[1] = + ih264d_cavlc_4x4res_block_totalcoeff_2to10; + ps_dec->pf_cavlc_4x4res_block[2] = + ih264d_cavlc_4x4res_block_totalcoeff_11to16; + + ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7; + ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8; + + ps_dec->pf_cavlc_parse_8x8block[0] = + ih264d_cavlc_parse_8x8block_none_available; + ps_dec->pf_cavlc_parse_8x8block[1] = + ih264d_cavlc_parse_8x8block_left_available; + ps_dec->pf_cavlc_parse_8x8block[2] = + ih264d_cavlc_parse_8x8block_top_available; + ps_dec->pf_cavlc_parse_8x8block[3] = + ih264d_cavlc_parse_8x8block_both_available; + + /***************************************************************************/ + /* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */ + /***************************************************************************/ + ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice; + ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice; + + ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice; + ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice; + + ps_dec->pf_fill_bs_xtra_left_edge[0] = + ih264d_fill_bs_xtra_left_edge_cur_frm; + ps_dec->pf_fill_bs_xtra_left_edge[1] = + ih264d_fill_bs_xtra_left_edge_cur_fld; + + /* Initialize Reference Pic Buffers */ + ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr); + +#if VERT_SCALE_UP_AND_422 + ps_dec->u1_vert_up_scale_flag = 1; +#else + ps_dec->u1_vert_up_scale_flag = 0; +#endif + + ps_dec->u2_prv_frame_num = 0; + ps_dec->u1_top_bottom_decoded = 0; + ps_dec->u1_dangling_field = 0; + + ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table; + + ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0]; + ps_dec->pi1_left_ref_idx_ctxt_inc = + &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0]; + ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb; + + /* ! */ + /* Initializing flush frame u4_flag */ + ps_dec->u1_flushfrm = 0; + + { + ps_dec->s_cab_dec_env.pv_codec_handle = (void*)ps_dec; + ps_dec->ps_bitstrm->pv_codec_handle = (void*)ps_dec; + ps_dec->ps_cur_slice->pv_codec_handle = (void*)ps_dec; + ps_dec->ps_dpb_mgr->pv_codec_handle = (void*)ps_dec; + } + + memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t)); + memset(ps_dec->u4_disp_buf_mapping, 0, + (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); + memset(ps_dec->u4_disp_buf_to_be_freed, 0, + (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); + + ih264d_init_arch(ps_dec); + ih264d_init_function_ptr(ps_dec); + + ps_dec->init_done = 1; + ps_dec->process_called = 1; +} + +/************************************************************************** + * \if Function name : ih264d_init_video_decoder \endif + * + * \brief + * Wrapper for the decoder init + * + * \param p_NALBufAPI: Pointer to NAL Buffer API. + * \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder + * for memory allocation and freeing. + * + * \return + * pointer to the decparams + * + ************************************************************************** + */ + +WORD32 ih264d_init_video_decoder(iv_obj_t *dec_hdl, + ih264d_init_ip_t *ps_init_ip, + ih264d_init_op_t *ps_init_op) +{ + dec_struct_t * ps_dec; + iv_mem_rec_t *memtab; + UWORD8 *pu1_extra_mem_base,*pu1_mem_base; + + memtab = ps_init_ip->s_ivd_init_ip_t.pv_mem_rec_location; + + dec_hdl->pv_codec_handle = memtab[MEM_REC_CODEC].pv_base; + ps_dec = dec_hdl->pv_codec_handle; + + memset(ps_dec, 0, sizeof(dec_struct_t)); + + if(ps_init_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, i4_level)) + { + ps_dec->u4_level_at_init = ps_init_ip->i4_level; + } + else + { + ps_dec->u4_level_at_init = H264_LEVEL_3_1; + } + + if(ps_init_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_num_ref_frames)) + { + ps_dec->u4_num_ref_frames_at_init = ps_init_ip->u4_num_ref_frames; + } + else + { + ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS; + } + + if(ps_init_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_num_reorder_frames)) + { + ps_dec->u4_num_reorder_frames_at_init = + ps_init_ip->u4_num_reorder_frames; + } + else + { + ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS; + } + + if(ps_init_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_num_extra_disp_buf)) + { + ps_dec->u4_num_extra_disp_bufs_at_init = + ps_init_ip->u4_num_extra_disp_buf; + } + else + { + ps_dec->u4_num_extra_disp_bufs_at_init = 0; + } + + if(ps_init_ip->s_ivd_init_ip_t.u4_size + > offsetof(ih264d_init_ip_t, u4_share_disp_buf)) + { +#ifndef LOGO_EN + ps_dec->u4_share_disp_buf = ps_init_ip->u4_share_disp_buf; +#else + ps_dec->u4_share_disp_buf = 0; +#endif + } + else + { + ps_dec->u4_share_disp_buf = 0; + } + + if((ps_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) + && (ps_init_ip->s_ivd_init_ip_t.e_output_format + != IV_YUV_420SP_UV) + && (ps_init_ip->s_ivd_init_ip_t.e_output_format + != IV_YUV_420SP_VU)) + { + ps_dec->u4_share_disp_buf = 0; + } + + if((ps_dec->u4_level_at_init < MIN_LEVEL_SUPPORTED) + || (ps_dec->u4_level_at_init > MAX_LEVEL_SUPPORTED)) + { + ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_LEVEL_UNSUPPORTED; + return (IV_FAIL); + } + + if(ps_dec->u4_num_ref_frames_at_init > H264_MAX_REF_PICS) + { + ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; + ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS; + } + + if(ps_dec->u4_num_reorder_frames_at_init > H264_MAX_REF_PICS) + { + ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; + ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS; + } + + if(ps_dec->u4_num_extra_disp_bufs_at_init > H264_MAX_REF_PICS) + { + ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; + ps_dec->u4_num_extra_disp_bufs_at_init = 0; + } + + if(0 == ps_dec->u4_share_disp_buf) + ps_dec->u4_num_extra_disp_bufs_at_init = 0; + + ps_dec->u4_num_disp_bufs_requested = 1; + + ps_dec->u4_width_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_wd; + ps_dec->u4_height_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_ht; + + ps_dec->u4_width_at_init = ALIGN16(ps_dec->u4_width_at_init); + ps_dec->u4_height_at_init = ALIGN16(ps_dec->u4_height_at_init); + + ps_dec->pv_dec_thread_handle = memtab[MEM_REC_THREAD_HANDLE].pv_base; + + pu1_mem_base = memtab[MEM_REC_THREAD_HANDLE].pv_base; + ps_dec->pv_bs_deblk_thread_handle = pu1_mem_base + + ithread_get_handle_size(); + + ps_dec->u4_extra_mem_used = 0; + + pu1_extra_mem_base = memtab[MEM_REC_EXTRA_MEM].pv_base; + + ps_dec->ps_dec_err_status = (dec_err_status_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + ps_dec->u4_extra_mem_used += (((sizeof(dec_err_status_t) + 127) >> 7) << 7); + + ps_dec->ps_mem_tab = memtab[MEM_REC_BACKUP].pv_base; + + memcpy(ps_dec->ps_mem_tab, memtab, sizeof(iv_mem_rec_t) * MEM_REC_CNT); + + ps_dec->ps_pps = memtab[MEM_REC_PPS].pv_base; + + ps_dec->ps_sps = memtab[MEM_REC_SPS].pv_base; + + ps_dec->ps_sei = (sei *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + ps_dec->u4_extra_mem_used += sizeof(sei); + + ps_dec->ps_dpb_mgr = memtab[MEM_REC_DPB_MGR].pv_base; + + ps_dec->ps_dpb_cmds = (dpb_commands_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + ps_dec->u4_extra_mem_used += sizeof(dpb_commands_t); + + ps_dec->ps_bitstrm = (dec_bit_stream_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + ps_dec->u4_extra_mem_used += sizeof(dec_bit_stream_t); + + ps_dec->ps_cur_slice =(dec_slice_params_t *) (pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + ps_dec->u4_extra_mem_used += sizeof(dec_slice_params_t); + + ps_dec->pv_scratch_sps_pps = (void *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); + + + ps_dec->u4_extra_mem_used += MAX(sizeof(dec_seq_params_t), + sizeof(dec_pic_params_t)); + ps_dec->ps_pred_pkd = memtab[MEM_REC_PRED_INFO_PKD].pv_base; + + + ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec; + + ps_dec->pv_dec_out = (void *)ps_init_op; + ps_dec->pv_dec_in = (void *)ps_init_ip; + + ps_dec->u1_chroma_format = + (UWORD8)(ps_init_ip->s_ivd_init_ip_t.e_output_format); + + + + ih264d_init_decoder(ps_dec); + + return (IV_SUCCESS); + +} + + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_num_mem_rec */ +/* */ +/* Description : fills memory records */ +/* */ +/* Inputs : pv_api_ip input api structure */ +/* : pv_api_op output api structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) +{ + + ih264d_fill_mem_rec_ip_t *ps_mem_q_ip; + ih264d_fill_mem_rec_op_t *ps_mem_q_op; + WORD32 level; + UWORD32 num_reorder_frames; + UWORD32 num_ref_frames; + UWORD32 num_extra_disp_bufs; + UWORD32 u4_dpb_size_num_frames; + iv_mem_rec_t *memTab; + + UWORD32 chroma_format, u4_share_disp_buf; + UWORD32 u4_total_num_mbs; + UWORD32 luma_width, luma_width_in_mbs; + UWORD32 luma_height, luma_height_in_mbs; + UWORD32 max_dpb_size; + + ps_mem_q_ip = (ih264d_fill_mem_rec_ip_t *)pv_api_ip; + ps_mem_q_op = (ih264d_fill_mem_rec_op_t *)pv_api_op; + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, i4_level)) + { + level = ps_mem_q_ip->i4_level; + } + else + { + level = H264_LEVEL_3_1; + } + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_reorder_frames)) + { + num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames; + } + else + { + num_reorder_frames = H264_MAX_REF_PICS; + } + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_ref_frames)) + { + num_ref_frames = ps_mem_q_ip->u4_num_ref_frames; + } + else + { + num_ref_frames = H264_MAX_REF_PICS; + } + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_extra_disp_buf)) + { + num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf; + } + else + { + num_extra_disp_bufs = 0; + } + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, u4_share_disp_buf)) + { +#ifndef LOGO_EN + u4_share_disp_buf = ps_mem_q_ip->u4_share_disp_buf; +#else + u4_share_disp_buf = 0; +#endif + } + else + { + u4_share_disp_buf = 0; + } + + if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size + > offsetof(ih264d_fill_mem_rec_ip_t, e_output_format)) + { + chroma_format = ps_mem_q_ip->e_output_format; + } + else + { + chroma_format = -1; + } + + if((chroma_format != IV_YUV_420P) && (chroma_format != IV_YUV_420SP_UV) + && (chroma_format != IV_YUV_420SP_VU)) + { + u4_share_disp_buf = 0; + } + if(0 == u4_share_disp_buf) + num_extra_disp_bufs = 0; + + { + + luma_height = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht; + luma_width = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd; + + luma_height = ((luma_height + 15) >> 4) << 4; + luma_width = ((luma_width + 15) >> 4) << 4; + luma_width_in_mbs = luma_width >> 4; + luma_height_in_mbs = luma_height >> 4; + u4_total_num_mbs = (luma_height * luma_width) >> 8; + } + /* + * If level is lesser than 31 and the resolution required is higher, + * then make the level at least 31. + */ + if(u4_total_num_mbs > MAX_MBS_LEVEL_30 && level < H264_LEVEL_3_1) + { + level = H264_LEVEL_3_1; + } + + if((level < MIN_LEVEL_SUPPORTED) || (level > MAX_LEVEL_SUPPORTED)) + { + ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= + ERROR_LEVEL_UNSUPPORTED; + return (IV_FAIL); + } + + if(num_ref_frames > H264_MAX_REF_PICS) + { + ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF; + num_ref_frames = H264_MAX_REF_PICS; + } + + if(num_reorder_frames > H264_MAX_REF_PICS) + { + ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF; + num_reorder_frames = H264_MAX_REF_PICS; + } + memTab = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location; + + memTab[MEM_REC_IV_OBJ].u4_mem_size = sizeof(iv_obj_t); + memTab[MEM_REC_IV_OBJ].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_IV_OBJ].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + H264_DEC_DEBUG_PRINT("MEM_REC_IV_OBJ MEM Size = %d\n", + memTab[MEM_REC_IV_OBJ].u4_mem_size); + + memTab[MEM_REC_CODEC].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_CODEC].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_CODEC].u4_mem_size = sizeof(dec_struct_t); + + { + UWORD32 mvinfo_size, mv_info_size_pad; + UWORD32 MVbank, MVbank_pad; + UWORD32 Ysize; + UWORD32 UVsize; + UWORD32 one_frm_size; + + UWORD32 extra_mem = 0; + + UWORD32 pad_len_h, pad_len_v; + + /* + * For low_delay, use num_buf as 2 - + * num_buf = (num_buf_ref) + 1; + * where num_buf_ref is 1. + */ + UWORD32 num_buf; + + { + UWORD32 num_bufs_app, num_bufs_level; + + num_bufs_app = num_ref_frames + num_reorder_frames + 1; + + if(num_bufs_app <= 1) + num_bufs_app = 2; + + num_bufs_level = ih264d_get_dpb_size_new(level, (luma_width >> 4), + (luma_height >> 4)); + + max_dpb_size = num_bufs_level; + + num_bufs_level = num_bufs_level * 2 + 1; + + num_buf = MIN(num_bufs_level, num_bufs_app); + + num_buf += num_extra_disp_bufs; + + } + + mvinfo_size = ((luma_width * (luma_height)) >> 4); + + mv_info_size_pad = ((luma_width * (PAD_MV_BANK_ROW)) >> 4); + + Ysize = ALIGN32((luma_width + (PAD_LEN_Y_H << 1))) + * (luma_height + (PAD_LEN_Y_V << 2)); + + + UVsize = Ysize >> 2; + if(u4_share_disp_buf == 1) + { + /* In case of buffers getting shared between application and library + there is no need of reference memtabs. Instead of setting the i4_size + to zero, it is reduced to a small i4_size to ensure that changes + in the code are minimal */ + + if((chroma_format == IV_YUV_420P) + || (chroma_format == IV_YUV_420SP_UV) + || (chroma_format == IV_YUV_420SP_VU)) + { + Ysize = 64; + } + if(chroma_format == IV_YUV_420SP_UV) + { + UVsize = 64; + } + } + + one_frm_size = (((Ysize + 127) >> 7) << 7) + + ((((UVsize << 1) + 127) >> 7) << 7); + + //Note that for ARM RVDS WS the sizeof(mv_pred_t) is 16 + + /*Add memory for colocated MB*/ + MVbank = sizeof(mv_pred_t) * mvinfo_size; + MVbank_pad = sizeof(mv_pred_t) * mv_info_size_pad; + + MVbank = (((MVbank + 127) >> 7) << 7); + + MVbank_pad = (((MVbank_pad + 127) >> 7) << 7); + + memTab[MEM_REC_MVBANK].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_MVBANK].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_MVBANK].u4_mem_size = (MVbank + MVbank_pad) + * (MIN(max_dpb_size, num_ref_frames) + 1); + + + memTab[MEM_REC_REF_PIC].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_REF_PIC].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_REF_PIC].u4_mem_size = one_frm_size * num_buf; + + } + + memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_DEBLK_MB_INFO].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_size = (((((u4_total_num_mbs + + MAX_MBS_IN_ROW) * sizeof(deblk_mb_t)) + 127) >> 7) << 7); + + memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_NEIGHBOR_INFO].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_size = sizeof(mb_neigbour_params_t) + * ((luma_width + 16) >> 4) * 2 * 2; + { + WORD32 size; + WORD32 num_entries; + + num_entries = MIN(MAX_FRAMES, num_ref_frames); + num_entries = 2 * ((2 * num_entries) + 1); + + size = num_entries * sizeof(void *); + size += PAD_MAP_IDX_POC * sizeof(void *); + size *= u4_total_num_mbs; + size += sizeof(dec_slice_struct_t) * u4_total_num_mbs; + memTab[MEM_REC_SLICE_HDR].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_SLICE_HDR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_SLICE_HDR].u4_mem_size = size; + } + { + + UWORD32 u4_num_entries; + + u4_num_entries = u4_total_num_mbs; + + memTab[MEM_REC_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_MB_INFO].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_MB_INFO].u4_mem_size = sizeof(dec_mb_info_t) + * u4_num_entries; + + memTab[MEM_REC_PRED_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PRED_INFO].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + + memTab[MEM_REC_PRED_INFO].u4_mem_size = sizeof(pred_info_t) * 2*32; + + memTab[MEM_REC_COEFF_DATA].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_COEFF_DATA].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_COEFF_DATA].u4_mem_size = MB_LUM_SIZE * sizeof(WORD16); + memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries + * (MAX(16 * sizeof(tu_sblk4x4_coeff_data_t),4 * sizeof(tu_blk8x8_coeff_data_t)) + + 8 * sizeof(tu_sblk4x4_coeff_data_t)); + memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries * 32; //32 bytes for each mb to store u1_prev_intra4x4_pred_mode and u1_rem_intra4x4_pred_mode data + + } + + memTab[MEM_REC_SPS].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_SPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_SPS].u4_mem_size = ((sizeof(dec_seq_params_t)) + * MAX_NUM_SEQ_PARAMS); + + memTab[MEM_REC_PPS].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_PPS].u4_mem_size = (sizeof(dec_pic_params_t)) + * MAX_NUM_PIC_PARAMS; + + { + UWORD32 u4_mem_size; + + u4_mem_size = 0; + u4_mem_size += (((sizeof(dec_err_status_t) + 127) >> 7) << 7); + u4_mem_size += sizeof(sei); + u4_mem_size += sizeof(dpb_commands_t); + u4_mem_size += sizeof(dec_bit_stream_t); + u4_mem_size += sizeof(dec_slice_params_t); + u4_mem_size += MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t)); + + memTab[MEM_REC_EXTRA_MEM].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_EXTRA_MEM].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_EXTRA_MEM].u4_mem_size = u4_mem_size; + } + + { + + UWORD32 u4_mem_size; + + u4_mem_size = 0; + u4_mem_size += ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *)); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += sizeof(ctxt_inc_mb_info_t); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += sizeof(UWORD32) * (MAX_REF_BUFS * MAX_REF_BUFS); + u4_mem_size = ALIGN64(u4_mem_size); + + u4_mem_size += MAX_REF_BUF_SIZE; + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += ((sizeof(WORD16)) * PRED_BUFFER_WIDTH + * PRED_BUFFER_HEIGHT); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += sizeof(UWORD8) * (MB_LUM_SIZE); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += sizeof(parse_pmbarams_t) * luma_width_in_mbs; //Max recon mb group*/ + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += (sizeof(parse_part_params_t) * luma_width_in_mbs) << 4; //Max recon mb group*/ + u4_mem_size = ALIGN64(u4_mem_size); + + u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); + u4_mem_size = ALIGN64(u4_mem_size); + u4_mem_size += (sizeof(UWORD32) * 3 * (MAX_REF_BUFS * MAX_REF_BUFS)) << 3; + u4_mem_size = ALIGN64(u4_mem_size); + + u4_mem_size += sizeof(UWORD32) * 2 * 3 * (MAX_REF_BUFS * MAX_REF_BUFS); + u4_mem_size = ALIGN64(u4_mem_size); + + memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_alignment = + (128 * 8) / CHAR_BIT; + memTab[MEM_REC_INTERNAL_SCRATCH].e_mem_type = + IV_EXTERNAL_CACHEABLE_SCRATCH_MEM; + memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_size = u4_mem_size; + } + + { + + UWORD32 u4_mem_used; + UWORD32 u4_numRows = MB_SIZE << 1; + UWORD32 u4_blk_wd = ((luma_width_in_mbs << 4) >> 1) + 8; + + u4_mem_used = 0; + u4_mem_used += ((luma_width_in_mbs * sizeof(deblkmb_neighbour_t)) << 1); + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += (sizeof(neighbouradd_t) << 2); + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += ((sizeof(ctxt_inc_mb_info_t)) + * (((luma_width_in_mbs + 1) << 1) + 1)); + u4_mem_used = ALIGN64(u4_mem_used); + + u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16); + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16); + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 4 + * MV_SCRATCH_BUFS); + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used = ALIGN64(u4_mem_used); + u4_numRows = BLK8x8SIZE << 1; + + u4_blk_wd = ((luma_width_in_mbs << 3) >> 1) + 8; + + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_mem_used += 32; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * ((luma_width >> 1) + 16) * 2 + * YUV420SP_FACTOR; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(UWORD8) * ((luma_width >> 1) + 16) * 2; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += sizeof(mb_neigbour_params_t) * (luma_width_in_mbs + 1) + * luma_height_in_mbs; + u4_mem_used += luma_width; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += luma_width >> 1; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += luma_width >> 1; + u4_mem_used = ALIGN64(u4_mem_used); + + u4_mem_used += ((MB_SIZE + 4) << 1) * PAD_LEN_Y_H; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H; + u4_mem_used = ALIGN64(u4_mem_used); + u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H; + u4_mem_used = ALIGN64(u4_mem_used); + memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_alignment = + (128 * 8) / CHAR_BIT; + memTab[MEM_REC_INTERNAL_PERSIST].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_size = u4_mem_used; + } + + memTab[MEM_REC_BITSBUF].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_BITSBUF].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_BITSBUF].u4_mem_size = MAX(256000, (luma_width * luma_height)); + + { + + UWORD32 u4_thread_struct_size = ithread_get_handle_size(); + + memTab[MEM_REC_THREAD_HANDLE].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_THREAD_HANDLE].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_THREAD_HANDLE].u4_mem_size = u4_thread_struct_size * 2; + + } + + memTab[MEM_REC_PARSE_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PARSE_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_PARSE_MAP].u4_mem_size = u4_total_num_mbs; + + memTab[MEM_REC_PROC_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PROC_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_PROC_MAP].u4_mem_size = u4_total_num_mbs; + + memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_SLICE_NUM_MAP].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_size = u4_total_num_mbs + * sizeof(UWORD16); + + memTab[MEM_REC_DPB_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_DPB_MGR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_DPB_MGR].u4_mem_size = sizeof(dpb_manager_t); + + memTab[MEM_REC_BACKUP].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_BACKUP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_BACKUP].u4_mem_size = sizeof(iv_mem_rec_t) * MEM_REC_CNT; + + { + + UWORD32 u4_mem_size; + + u4_mem_size = sizeof(disp_mgr_t); + u4_mem_size += sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); + u4_mem_size += sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2); + + memTab[MEM_REC_PIC_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PIC_BUF_MGR].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_PIC_BUF_MGR].u4_mem_size = u4_mem_size; + } + + { + UWORD32 u4_mem_size; + + u4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); + u4_mem_size += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2); + u4_mem_size = ALIGN128(u4_mem_size); + u4_mem_size += ((luma_width * luma_height) >> 4) + * (MIN(max_dpb_size, num_ref_frames) + 1); + memTab[MEM_REC_MV_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_MV_BUF_MGR].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + memTab[MEM_REC_MV_BUF_MGR].u4_mem_size = u4_mem_size; + } + + memTab[MEM_REC_PRED_INFO_PKD].u4_mem_alignment = (128 * 8) / CHAR_BIT; + memTab[MEM_REC_PRED_INFO_PKD].e_mem_type = + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; + + { + UWORD32 u4_num_entries; + u4_num_entries = u4_total_num_mbs; + + if(1 == num_ref_frames) + u4_num_entries *= 16; + else + u4_num_entries *= 16 * 2; + + memTab[MEM_REC_PRED_INFO_PKD].u4_mem_size = sizeof(pred_info_pkd_t) + * u4_num_entries; + } + + ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT; + + + return IV_SUCCESS; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_clr */ +/* */ +/* Description : returns memory records to app */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_clr(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + + dec_struct_t * ps_dec; + iv_retrieve_mem_rec_ip_t *dec_clr_ip; + iv_retrieve_mem_rec_op_t *dec_clr_op; + + dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip; + dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op; + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + if(ps_dec->init_done != 1) + { + //return a proper Error Code + return IV_FAIL; + } + + ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_pic_buf_mgr); + ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_mv_buf_mgr); + + memcpy(dec_clr_ip->pv_mem_rec_location, ps_dec->ps_mem_tab, + MEM_REC_CNT * (sizeof(iv_mem_rec_t))); + dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT; + + H264_DEC_DEBUG_PRINT("The clear non-conceal num mem recs: %d\n", + dec_clr_op->u4_num_mem_rec_filled); + + return IV_SUCCESS; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_init */ +/* */ +/* Description : initializes decoder */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_init(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + ih264d_init_ip_t *ps_init_ip; + ih264d_init_op_t *ps_init_op; + ps_init_ip = (ih264d_init_ip_t *)pv_api_ip; + ps_init_op = (ih264d_init_op_t *)pv_api_op; + WORD32 init_status = IV_SUCCESS; + + init_status = ih264d_init_video_decoder(dec_hdl, ps_init_ip, ps_init_op); + + if(IV_SUCCESS != init_status) + { + return init_status; + } + + return init_status; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_map_error */ +/* */ +/* Description : Maps error codes to IVD error groups */ +/* */ +/* Inputs : */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_map_error(UWORD32 i4_err_status) +{ + UWORD32 temp = 0; + + switch(i4_err_status) + { + case ERROR_MEM_ALLOC_ISRAM_T: + case ERROR_MEM_ALLOC_SDRAM_T: + case ERROR_BUF_MGR: + case ERROR_MB_GROUP_ASSGN_T: + case ERROR_FRAME_LIMIT_OVER: + case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT: + case ERROR_PROFILE_NOT_SUPPORTED: + case ERROR_INIT_NOT_DONE: + temp = 1 << IVD_FATALERROR; + H264_DEC_DEBUG_PRINT("\nFatal Error\n"); + break; + + case ERROR_DBP_MANAGER_T: + case ERROR_GAPS_IN_FRM_NUM: + case ERROR_UNKNOWN_NAL: + case ERROR_INV_MB_SLC_GRP_T: + case ERROR_MULTIPLE_SLC_GRP_T: + case ERROR_UNKNOWN_LEVEL: + case ERROR_UNAVAIL_PICBUF_T: + case ERROR_UNAVAIL_MVBUF_T: + case ERROR_UNAVAIL_DISPBUF_T: + case ERROR_NUM_REF: + case ERROR_REFIDX_ORDER_T: + case ERROR_PIC0_NOT_FOUND_T: + case ERROR_MB_TYPE: + case ERROR_SUB_MB_TYPE: + case ERROR_CBP: + case ERROR_REF_IDX: + case ERROR_NUM_MV: + case ERROR_CHROMA_PRED_MODE: + case ERROR_INTRAPRED: + case ERROR_NEXT_MB_ADDRESS_T: + case ERROR_MB_ADDRESS_T: + case ERROR_PIC1_NOT_FOUND_T: + case ERROR_CAVLC_NUM_COEFF_T: + case ERROR_CAVLC_SCAN_POS_T: + case ERROR_PRED_WEIGHT_TABLE_T: + case ERROR_CORRUPTED_SLICE: + temp = 1 << IVD_CORRUPTEDDATA; + break; + + case ERROR_NOT_SUPP_RESOLUTION: + case ERROR_FEATURE_UNAVAIL: + case ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT: + temp = 1 << IVD_UNSUPPORTEDINPUT; + break; + + case ERROR_INVALID_PIC_PARAM: + case ERROR_INVALID_SEQ_PARAM: + case ERROR_EGC_EXCEED_32_1_T: + case ERROR_EGC_EXCEED_32_2_T: + case ERROR_INV_RANGE_TEV_T: + case ERROR_INV_SLC_TYPE_T: + case ERROR_INV_POC_TYPE_T: + case ERROR_INV_RANGE_QP_T: + case ERROR_INV_SPS_PPS_T: + case ERROR_INV_SLICE_HDR_T: + temp = 1 << IVD_CORRUPTEDHEADER; + break; + + case ERROR_EOB_FLUSHBITS_T: + case ERROR_EOB_GETBITS_T: + case ERROR_EOB_GETBIT_T: + case ERROR_EOB_BYPASS_T: + case ERROR_EOB_DECISION_T: + case ERROR_EOB_TERMINATE_T: + case ERROR_EOB_READCOEFF4X4CAB_T: + temp = 1 << IVD_INSUFFICIENTDATA; + break; + case ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED: + case ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH: + temp = 1 << IVD_UNSUPPORTEDPARAM | 1 << IVD_FATALERROR; + break; + + case ERROR_DANGLING_FIELD_IN_PIC: + temp = 1 << IVD_APPLIEDCONCEALMENT; + break; + + } + + return temp; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_video_decode */ +/* */ +/* Description : handle video decode API command */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + /* ! */ + + dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + WORD32 i4_err_status = 0; + UWORD8 *pu1_buf = NULL; + WORD32 buflen; + UWORD32 u4_max_ofst, u4_length_of_start_code = 0; + + UWORD32 bytes_consumed = 0; + UWORD32 cur_slice_is_nonref = 0; + UWORD32 u4_next_is_aud; + UWORD32 u4_first_start_code_found = 0; + WORD32 ret; + WORD32 header_data_left = 0,frame_data_left = 0; + UWORD8 *pu1_bitstrm_buf; + ithread_set_name((void*)"Parse_thread"); + + + ivd_video_decode_ip_t *ps_dec_ip; + ivd_video_decode_op_t *ps_dec_op; + ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; + ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; + ps_dec->pv_dec_out = ps_dec_op; + ps_dec->process_called = 1; + ps_dec->u2_mb_skip_error = 0; + if(ps_dec->init_done != 1) + { + return IV_FAIL; + } + + /*Data memory barries instruction,so that bitstream write by the application is complete*/ + DATA_SYNC(); + + if(0 == ps_dec->u1_flushfrm) + { + if(ps_dec_ip->pv_stream_buffer == NULL) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL; + return IV_FAIL; + } + if(ps_dec_ip->u4_num_Bytes <= 0) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV; + return IV_FAIL; + + } + } + ps_dec->u1_pic_decode_done = 0; + + ps_dec_op->u4_num_bytes_consumed = 0; + + ps_dec->ps_out_buffer = NULL; + + if(ps_dec_ip->u4_size + >= offsetof(ivd_video_decode_ip_t, s_out_buffer)) + ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer; + + if(ps_dec_op->u4_size + >= offsetof(ivd_video_decode_op_t, u4_disp_buf_id) + && ps_dec->ps_out_buffer != NULL) + ps_dec->u4_fmt_conv_in_process = 1; + else + ps_dec->u4_fmt_conv_in_process = 0; + + ps_dec->u4_fmt_conv_cur_row = 0; + + ps_dec->u4_output_present = 0; + ps_dec->s_disp_op.u4_error_code = 1; + ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS; + ps_dec->u4_stop_threads = 0; + if(ps_dec->u4_fmt_conv_in_process && 0 == ps_dec->u4_share_disp_buf + && ps_dec->i4_decode_header == 0) + { + UWORD32 i; + if(ps_dec->ps_out_buffer->u4_num_bufs == 0) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS; + return IV_FAIL; + } + + for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++) + { + if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL; + return IV_FAIL; + } + + if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= + IVD_DISP_FRM_ZERO_OP_BUF_SIZE; + return IV_FAIL; + } + } + } + + if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT) + { + ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER; + return IV_FAIL; + } + + /* ! */ + ps_dec->u4_ts = ps_dec_ip->u4_ts; + + ps_dec_op->u4_error_code = 0; + ps_dec_op->e_pic_type = -1; + ps_dec_op->u4_output_present = 0; + ps_dec_op->u4_frame_decoded_flag = 0; + + ps_dec->i4_frametype = -1; + ps_dec->i4_content_type = -1; + /* + * For field pictures, set the bottom and top picture decoded u4_flag correctly. + */ + { + if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded) + { + ps_dec->u1_top_bottom_decoded = 0; + } + } + ps_dec->u4_slice_start_code_found = 0; + + /* In case the deocder is not in flush mode(in shared mode), + then decoder has to pick up a buffer to write current frame. + Check if a frame is available in such cases */ + + if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1 + && ps_dec->u1_flushfrm == 0) + { + UWORD32 i; + + WORD32 disp_avail = 0, free_id; + + /* Check if at least one buffer is available with the codec */ + /* If not then return to application with error */ + for(i = 0; i < ps_dec->u1_pic_bufs; i++) + { + if(0 == ps_dec->u4_disp_buf_mapping[i] + || 1 == ps_dec->u4_disp_buf_to_be_freed[i]) + { + disp_avail = 1; + break; + } + + } + + if(0 == disp_avail) + { + /* If something is queued for display wait for that buffer to be returned */ + + ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL; + ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); + return (IV_FAIL); + } + + while(1) + { + pic_buffer_t *ps_pic_buf; + ps_pic_buf = (pic_buffer_t *)ih264_buf_mgr_get_next_free( + (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, &free_id); + + if(ps_pic_buf == NULL) + { + UWORD32 i, display_queued = 0; + + /* check if any buffer was given for display which is not returned yet */ + for(i = 0; i < (MAX_DISP_BUFS_NEW); i++) + { + if(0 != ps_dec->u4_disp_buf_mapping[i]) + { + display_queued = 1; + break; + } + } + /* If some buffer is queued for display, then codec has to singal an error and wait + for that buffer to be returned. + If nothing is queued for display then codec has ownership of all display buffers + and it can reuse any of the existing buffers and continue decoding */ + + if(1 == display_queued) + { + /* If something is queued for display wait for that buffer to be returned */ + ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL; + ps_dec_op->u4_error_code |= (1 + << IVD_UNSUPPORTEDPARAM); + return (IV_FAIL); + } + } + else + { + /* If the buffer is with display, then mark it as in use and then look for a buffer again */ + if(1 == ps_dec->u4_disp_buf_mapping[free_id]) + { + ih264_buf_mgr_set_status( + (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + free_id, + BUF_MGR_IO); + } + else + { + /** + * Found a free buffer for present call. Release it now. + * Will be again obtained later. + */ + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + free_id, + BUF_MGR_IO); + break; + } + } + } + + } + + if(ps_dec->u4_fmt_conv_in_process && ps_dec->u1_flushfrm && + ps_dec->u1_init_dec_flag) + { + + ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, + &(ps_dec->s_disp_op)); + if(0 == ps_dec->s_disp_op.u4_error_code) + { + ps_dec->u4_fmt_conv_cur_row = 0; + ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht; + ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), + ps_dec->u4_fmt_conv_cur_row, + ps_dec->u4_fmt_conv_num_rows); + ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; + ps_dec->u4_output_present = 1; + + } + ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op)); + + ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; + ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; + + ps_dec_op->u4_new_seq = 0; + + ps_dec_op->u4_output_present = ps_dec->u4_output_present; + ps_dec_op->u4_progressive_frame_flag = + ps_dec->s_disp_op.u4_progressive_frame_flag; + ps_dec_op->e_output_format = + ps_dec->s_disp_op.e_output_format; + ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf; + ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type; + ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts; + ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; + + /*In the case of flush ,since no frame is decoded set pic type as invalid*/ + ps_dec_op->u4_is_ref_flag = -1; + ps_dec_op->e_pic_type = IV_NA_FRAME; + ps_dec_op->u4_frame_decoded_flag = 0; + + if(0 == ps_dec->s_disp_op.u4_error_code) + { + return (IV_SUCCESS); + } + else + return (IV_FAIL); + + } + if(ps_dec->u1_res_changed == 1) + { + /*if resolution has changed and all buffers have been flushed, reset decoder*/ + ih264d_init_decoder(ps_dec); + } + + ps_dec->u4_prev_nal_skipped = 0; + + ps_dec->u4_start_frame_decode = 0; + ps_dec->u2_cur_mb_addr = 0; + ps_dec->cur_dec_mb_num = 0; + ps_dec->u4_first_slice_in_pic = 1; + + ps_dec->u4_dec_thread_created = 0; + ps_dec->u4_bs_deblk_thread_created = 0; + ps_dec->u4_cur_bs_mb_num = 0; + + ps_dec->as_fmt_conv_part[0].u4_flag = 1; + ps_dec->as_fmt_conv_part[1].u4_flag = 1; + ps_dec->as_fmt_conv_part[1].u4_start_y = 0; + ps_dec->as_fmt_conv_part[1].u4_num_rows_y = 0; + + DEBUG_THREADS_PRINTF(" Starting process call\n"); + + ps_dec->u4_pic_buf_got = 0; + ps_dec->u2_skip_deblock = 0; + + do + { + + pu1_buf = (UWORD8*)ps_dec_ip->pv_stream_buffer + + ps_dec_op->u4_num_bytes_consumed; + + u4_max_ofst = ps_dec_ip->u4_num_Bytes + - ps_dec_op->u4_num_bytes_consumed; + pu1_bitstrm_buf = ps_dec->ps_mem_tab[MEM_REC_BITSBUF].pv_base; + + u4_next_is_aud = 0; + + buflen = ih264d_find_start_code(pu1_buf, 0, u4_max_ofst, + &u4_length_of_start_code, + &u4_next_is_aud); + + if(buflen == -1) + buflen = 0; + + bytes_consumed = buflen + u4_length_of_start_code; + ps_dec_op->u4_num_bytes_consumed += bytes_consumed; + + if(buflen >= MAX_NAL_UNIT_SIZE) + { + + ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op); + H264_DEC_DEBUG_PRINT( + "\nNal Size exceeded %d, Processing Stopped..\n", + MAX_NAL_UNIT_SIZE); + ps_dec->i4_error_code = 1 << IVD_CORRUPTEDDATA; + + ps_dec_op->e_pic_type = -1; + /*signal the decode thread*/ + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + ih264d_signal_decode_thread(ps_dec); + /*signal end of frame decode for curren frame*/ + + if(ps_dec->u4_pic_buf_got == 0) + { + if(ps_dec->i4_header_decoded == 3) + { + ps_dec->u2_total_mbs_coded = + ps_dec->ps_cur_sps->u2_max_mb_addr + 1; + ps_dec->ps_cur_slice->u1_end_of_frame_signal = 1; + } + + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + return IV_FAIL; + } + else + { + ps_dec->u1_pic_decode_done = 1; + continue; + } + } + + { + UWORD8 u1_firstbyte, u1_nal_ref_idc; + + if(ps_dec->i4_app_skip_mode == IVD_SKIP_B) + { + u1_firstbyte = *(pu1_buf + u4_length_of_start_code); + u1_nal_ref_idc = (UWORD8)(NAL_REF_IDC(u1_firstbyte)); + if(u1_nal_ref_idc == 0) + { + /*skip non reference frames*/ + cur_slice_is_nonref = 1; + continue; + } + else + { + if(1 == cur_slice_is_nonref) + { + /*We have encountered a referenced frame,return to app*/ + ps_dec_op->u4_num_bytes_consumed -= + bytes_consumed; + ps_dec_op->e_pic_type = IV_B_FRAME; + ps_dec_op->u4_error_code = + IVD_DEC_FRM_SKIPPED; + ps_dec_op->u4_error_code |= (1 + << IVD_UNSUPPORTEDPARAM); + ps_dec_op->u4_frame_decoded_flag = 0; + ps_dec_op->u4_size = + sizeof(ivd_video_decode_op_t); + /*signal the decode thread*/ + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + ih264d_signal_decode_thread(ps_dec); + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + + return (IV_FAIL); + } + } + + } + + } + + + if(buflen) + { + memcpy(pu1_bitstrm_buf, pu1_buf + u4_length_of_start_code, + buflen); + u4_first_start_code_found = 1; + + } + else + { + /*start code not found*/ + + if(u4_first_start_code_found == 0) + { + /*no start codes found in current process call*/ + + ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND; + ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA; + + if(ps_dec->u4_pic_buf_got == 0) + { + + ih264d_fill_output_struct_from_context(ps_dec, + ps_dec_op); + + ps_dec_op->u4_error_code = ps_dec->i4_error_code; + ps_dec_op->u4_frame_decoded_flag = 0; + + return (IV_FAIL); + } + else + { + ps_dec->u1_pic_decode_done = 1; + continue; + } + } + else + { + /* a start code has already been found earlier in the same process call*/ + continue; + } + + } + + ps_dec->u4_return_to_app = 0; + ret = ih264d_parse_nal_unit(dec_hdl, ps_dec_op, + pu1_bitstrm_buf, buflen); + if(ret != OK) + { + UWORD32 error = ih264d_map_error(ret); + ps_dec_op->u4_error_code = error | ret; + + if((ret == IVD_RES_CHANGED)||(ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED)) + { + /*dont consume the SPS*/ + ps_dec_op->u4_num_bytes_consumed -= bytes_consumed; + } + return IV_FAIL; + } + + if(ps_dec->u4_return_to_app) + { + /*We have encountered a referenced frame,return to app*/ + ps_dec_op->u4_num_bytes_consumed -= bytes_consumed; + ps_dec_op->u4_error_code = IVD_DEC_FRM_SKIPPED; + ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); + ps_dec_op->u4_frame_decoded_flag = 0; + ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); + /*signal the decode thread*/ + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + ih264d_signal_decode_thread(ps_dec); + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + return (IV_FAIL); + + } + + + + header_data_left = ((ps_dec->i4_decode_header == 1) + && (ps_dec->i4_header_decoded != 3) + && (ps_dec_op->u4_num_bytes_consumed + < ps_dec_ip->u4_num_Bytes)); + frame_data_left = (((ps_dec->i4_decode_header == 0) + && ((ps_dec->u1_pic_decode_done == 0) + || (u4_next_is_aud == 1))) + && (ps_dec_op->u4_num_bytes_consumed + < ps_dec_ip->u4_num_Bytes)); + } + while(( header_data_left == 1)||(frame_data_left == 1)); + + if((ps_dec->u2_total_mbs_coded + != (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs)) + && (ps_dec_op->u4_num_bytes_consumed + >= ps_dec_ip->u4_num_Bytes)) + { + if(ps_dec->ps_parse_cur_slice != NULL) + { + ps_dec->ps_parse_cur_slice->u2_error_flag = 1; + + ps_dec->u2_skip_deblock = 1; + } + } + if(ps_dec->u1_separate_parse) + { + + /* If Format conversion is not complete, + complete it here */ + if(ps_dec->u4_num_cores == 2) + { + ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht + - ps_dec->u4_fmt_conv_cur_row; + if(ps_dec->u4_output_present && ps_dec->u4_fmt_conv_in_process + && ps_dec->u4_fmt_conv_num_rows) + { + ps_dec->u4_fmt_conv_num_rows = MIN( + ps_dec->u4_fmt_conv_num_rows, + (ps_dec->s_disp_frame_info.u4_y_ht + - ps_dec->u4_fmt_conv_cur_row)); + if(ps_dec->u4_fmt_conv_num_rows > 64) + { + UWORD32 num_rows_first_part = (ps_dec->u4_fmt_conv_num_rows + / 2); + + /* Align it to even number */ + num_rows_first_part = (num_rows_first_part >> 1) << 1; + + /* Schedule last half of the remaining rows to be processed in second thread */ + ps_dec->as_fmt_conv_part[1].u4_start_y = + ps_dec->u4_fmt_conv_cur_row + + num_rows_first_part; + ps_dec->as_fmt_conv_part[1].u4_num_rows_y = + (ps_dec->u4_fmt_conv_num_rows + - num_rows_first_part); + ps_dec->u4_fmt_conv_num_rows = num_rows_first_part; + DATA_SYNC(); + ps_dec->as_fmt_conv_part[1].u4_flag = 2; + + } + else + { + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + } + + ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), + ps_dec->u4_fmt_conv_cur_row, + ps_dec->u4_fmt_conv_num_rows); + ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; + + } + else + { + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + } + } + else + { + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + } + + /*signal the decode thread*/ + ih264d_signal_decode_thread(ps_dec); + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + } + /* Decode thread would have completed format conversion for ps_dec->as_fmt_conv_part[1].u4_num_rows_y rows */ + + ps_dec->u4_fmt_conv_cur_row += ps_dec->as_fmt_conv_part[1].u4_num_rows_y; + + if((ps_dec_op->u4_error_code & 0xff) + != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED) + { + ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; + ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; + } + +//Report if header (sps and pps) has not been decoded yet + if(ps_dec->i4_header_decoded != 3) + { + ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA); + + } + + if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3) + { + ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA); + + } + if(ps_dec->u4_prev_nal_skipped) + { + /*We have encountered a referenced frame,return to app*/ + ps_dec_op->u4_error_code = IVD_DEC_FRM_SKIPPED; + ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); + ps_dec_op->u4_frame_decoded_flag = 0; + ps_dec_op->u4_size = sizeof(ivd_video_decode_op_t); + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + return (IV_FAIL); + + } + + if((ps_dec->u4_slice_start_code_found == 1) + && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status)) + { + /* + * For field pictures, set the bottom and top picture decoded u4_flag correctly. + */ + + if(ps_dec->u4_pic_buf_got == 0) + { + ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op); + + ps_dec_op->u4_error_code = ps_dec->i4_error_code; + ps_dec_op->u4_frame_decoded_flag = 0; + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + return (IV_FAIL); + } + + if(ps_dec->ps_cur_slice->u1_field_pic_flag) + { + if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag) + { + ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY; + } + else + { + ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY; + } + } + + /* Calling Function to deblock Picture and Display */ + ret = ih264d_deblock_display(ps_dec); + if(ret != 0) + return IV_FAIL; + + /*set to complete ,as we dont support partial frame decode*/ + if(ps_dec->i4_header_decoded == 3) + { + ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1; + } + + /*Update the i4_frametype at the end of picture*/ + if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) + { + ps_dec->i4_frametype = IV_IDR_FRAME; + } + else if(ps_dec->i4_pic_type == B_SLICE) + { + ps_dec->i4_frametype = IV_B_FRAME; + } + else if(ps_dec->i4_pic_type == P_SLICE) + { + ps_dec->i4_frametype = IV_P_FRAME; + } + else if(ps_dec->i4_pic_type == I_SLICE) + { + ps_dec->i4_frametype = IV_I_FRAME; + } + else + { + H264_DEC_DEBUG_PRINT("Shouldn't come here\n"); + } + + //Update the content type + ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag; + + ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2; + ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + - ps_dec->ps_cur_slice->u1_field_pic_flag; + + } + + /* close deblock thread if it is not closed yet*/ + if(ps_dec->u4_num_cores == 3) + { + ih264d_signal_bs_deblk_thread(ps_dec); + } + + if(ps_dec->u4_fmt_conv_in_process) + { + /* In case the decoder is configured to run in low delay mode, + * then get display buffer and then format convert. + * Note in this mode, format conversion does not run paralelly in a thread and adds to the codec cycles + */ + + if((0 == ps_dec->u4_num_reorder_frames_at_init) + && ps_dec->u1_init_dec_flag) + { + + ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, + &(ps_dec->s_disp_op)); + if(0 == ps_dec->s_disp_op.u4_error_code) + { + ps_dec->u4_fmt_conv_cur_row = 0; + ps_dec->u4_output_present = 1; + } + } + + ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op); + + /* If Format conversion is not complete, + complete it here */ + ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht + - ps_dec->u4_fmt_conv_cur_row; + DEBUG_PERF_PRINTF("ps_dec->u4_fmt_conv_num_rows = %d\n",ps_dec->u4_fmt_conv_num_rows); + if(ps_dec->u4_output_present && ps_dec->u4_fmt_conv_num_rows) + { + ps_dec->u4_fmt_conv_num_rows = MIN( + ps_dec->u4_fmt_conv_num_rows, + (ps_dec->s_disp_frame_info.u4_y_ht + - ps_dec->u4_fmt_conv_cur_row)); + ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), + ps_dec->u4_fmt_conv_cur_row, + ps_dec->u4_fmt_conv_num_rows); + ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; + } + + ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op)); + } + + if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1) + { + ps_dec_op->u4_progressive_frame_flag = 1; + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag) + && (0 == ps_dec->ps_sps->u1_mb_aff_flag)) + ps_dec_op->u4_progressive_frame_flag = 0; + + } + } + + /*Data memory barrier instruction,so that yuv write by the library is complete*/ + DATA_SYNC(); + + H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n", + ps_dec_op->u4_num_bytes_consumed); + return IV_SUCCESS; +} + +WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + char version_string[MAXVERSION_STRLEN + 1]; + + ivd_ctl_getversioninfo_ip_t *ps_ip; + ivd_ctl_getversioninfo_op_t *ps_op; + + ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip; + ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op; + UNUSED(dec_hdl); + ps_op->u4_error_code = IV_SUCCESS; + + VERSION(version_string, CODEC_NAME, CODEC_RELEASE_TYPE, CODEC_RELEASE_VER, + CODEC_VENDOR); + + if((WORD32)ps_ip->u4_version_buffer_size <= 0) + { + ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT; + return (IV_FAIL); + } + + if(ps_ip->u4_version_buffer_size >= (strnlen(version_string, MAXVERSION_STRLEN) + 1)) //(WORD32)sizeof(sizeof(version_string))) + { + strncpy(ps_ip->pv_version_buffer, version_string, MAXVERSION_STRLEN); + ps_op->u4_error_code = IV_SUCCESS; + } + else + { + ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT; + return IV_FAIL; + } + return (IV_SUCCESS); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_display_frame */ +/* */ +/* Description : */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + + ivd_get_display_frame_ip_t *dec_disp_ip; + ivd_get_display_frame_op_t *dec_disp_op; + + WORD32 u4_api_ret; + dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + dec_disp_ip = (ivd_get_display_frame_ip_t *)pv_api_ip; + dec_disp_op = (ivd_get_display_frame_op_t *)pv_api_op; + + if(ps_dec->u4_fmt_conv_in_process) + { + return IV_FAIL; + } + + { + + if(ps_dec->process_called != 1) + { + //Return Proper Error Code + } + + if(0 == ps_dec->u4_share_disp_buf) + { + UWORD32 i; + if(dec_disp_ip->s_out_buffer.u4_num_bufs == 0) + { + dec_disp_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + dec_disp_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS; + return IV_FAIL; + } + + for(i = 0; i < dec_disp_ip->s_out_buffer.u4_num_bufs; i++) + { + if(dec_disp_ip->s_out_buffer.pu1_bufs[i] == NULL) + { + dec_disp_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + dec_disp_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL; + return IV_FAIL; + } + + if(dec_disp_ip->s_out_buffer.u4_min_out_buf_size[i] == 0) + { + dec_disp_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + dec_disp_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE; + return IV_FAIL; + } + } + } + + u4_api_ret = ih264d_get_next_display_field(ps_dec, + &(dec_disp_ip->s_out_buffer), + &(ps_dec->s_disp_op)); + *dec_disp_op = (ps_dec->s_disp_op); + if(0 == dec_disp_op->u4_error_code) + { + ps_dec->u4_fmt_conv_cur_row = 0; + ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht; + ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), + ps_dec->u4_fmt_conv_cur_row, + ps_dec->u4_fmt_conv_num_rows); + ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; + + } + ih264d_release_display_field(ps_dec, dec_disp_op); + return u4_api_ret; + } + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_set_display_frame */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_set_display_frame(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + + ivd_set_display_frame_ip_t *dec_disp_ip; + ivd_set_display_frame_op_t *dec_disp_op; + + UWORD32 i, num_mvbank_req; + dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip; + dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op; + dec_disp_op->u4_error_code = 0; + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + UWORD32 level, width_mbs, height_mbs; + + level = ps_dec->u4_level_at_init; + width_mbs = ps_dec->u2_frm_wd_in_mbs; + height_mbs = ps_dec->u2_frm_ht_in_mbs; + + if((ps_dec->ps_sps->u1_vui_parameters_present_flag == 1) + && (ps_dec->ps_sps->s_vui.u4_num_reorder_frames != 64)) + { + num_mvbank_req = ps_dec->ps_sps->s_vui.u4_num_reorder_frames + 2; + } + else + { + /*if VUI is not present assume maximum possible refrence frames for the level, + * as max reorder frames*/ + num_mvbank_req = ih264d_get_dpb_size_new(level, width_mbs, + height_mbs); + } + + num_mvbank_req += ps_dec->ps_sps->u1_num_ref_frames + 1; + } + else + { + UWORD32 num_bufs_app, num_bufs_level; + UWORD32 num_ref_frames, num_reorder_frames, luma_width; + UWORD32 luma_height, level; + + num_ref_frames = ps_dec->u4_num_ref_frames_at_init; + num_reorder_frames = ps_dec->u4_num_reorder_frames_at_init; + level = ps_dec->u4_level_at_init; + luma_width = ps_dec->u4_width_at_init; + luma_height = ps_dec->u4_height_at_init; + + num_bufs_app = num_ref_frames + num_reorder_frames + 1; + + if(num_bufs_app <= 1) + num_bufs_app = 2; + + num_bufs_level = ih264d_get_dpb_size_new(level, (luma_width >> 4), + (luma_height >> 4)); + + num_bufs_level = num_bufs_level * 2 + 1; + + num_mvbank_req = MIN(num_bufs_level, num_bufs_app); + + num_mvbank_req += ps_dec->u4_num_extra_disp_bufs_at_init; + + } + + ps_dec->u4_num_disp_bufs = 0; + if(ps_dec->u4_share_disp_buf) + { + UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs; + if(u4_num_bufs > MAX_DISP_BUFS_NEW) + u4_num_bufs = MAX_DISP_BUFS_NEW; + + u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW); + u4_num_bufs = MIN(u4_num_bufs, num_mvbank_req); + + ps_dec->u4_num_disp_bufs = u4_num_bufs; + for(i = 0; i < u4_num_bufs; i++) + { + ps_dec->disp_bufs[i].u4_num_bufs = + dec_disp_ip->s_disp_buffer[i].u4_num_bufs; + + ps_dec->disp_bufs[i].buf[0] = + dec_disp_ip->s_disp_buffer[i].pu1_bufs[0]; + ps_dec->disp_bufs[i].buf[1] = + dec_disp_ip->s_disp_buffer[i].pu1_bufs[1]; + ps_dec->disp_bufs[i].buf[2] = + dec_disp_ip->s_disp_buffer[i].pu1_bufs[2]; + + ps_dec->disp_bufs[i].u4_bufsize[0] = + dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0]; + ps_dec->disp_bufs[i].u4_bufsize[1] = + dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1]; + ps_dec->disp_bufs[i].u4_bufsize[2] = + dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2]; + + } + } + return IV_SUCCESS; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_set_flush_mode */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + + dec_struct_t * ps_dec; + ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t*)pv_api_op; + ps_ctl_op->u4_error_code = 0; + + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + UNUSED(pv_api_ip); + /* ! */ + /* Signal flush frame control call */ + ps_dec->u1_flushfrm = 1; + + ih264d_release_pics_in_dpb((void *)ps_dec, + ps_dec->u1_pic_bufs); + ih264d_release_display_bufs(ps_dec); + + ps_ctl_op->u4_error_code = + ((ivd_ctl_flush_op_t*)ps_dec->pv_dec_out)->u4_error_code; //verify the value + + return IV_SUCCESS; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_status */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + + UWORD32 i; + dec_struct_t * ps_dec; + UWORD32 pic_wd, pic_ht; + ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t*)pv_api_op; + UNUSED(pv_api_ip); + ps_ctl_op->u4_error_code = 0; + + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + pic_wd = ps_dec->u4_width_at_init; + pic_ht = ps_dec->u4_height_at_init; + + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height; + ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width; + + if(0 == ps_dec->u4_share_disp_buf) + { + pic_wd = ps_dec->u2_disp_width; + pic_ht = ps_dec->u2_disp_height; + + } + else + { + pic_wd = ps_dec->u2_frm_wd_y; + pic_ht = ps_dec->u2_frm_ht_y; + } + } + else + { + ps_ctl_op->u4_pic_ht = pic_wd; + ps_ctl_op->u4_pic_wd = pic_ht; + + if(1 == ps_dec->u4_share_disp_buf) + { + pic_wd += (PAD_LEN_Y_H << 1); + pic_ht += (PAD_LEN_Y_V << 2); + + } + + } + + if(ps_dec->u4_app_disp_width > pic_wd) + pic_wd = ps_dec->u4_app_disp_width; + if(0 == ps_dec->u4_share_disp_buf) + ps_ctl_op->u4_num_disp_bufs = 1; + else + { + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + UWORD32 level, width_mbs, height_mbs; + + level = ps_dec->u4_level_at_init; + width_mbs = ps_dec->u2_frm_wd_in_mbs; + height_mbs = ps_dec->u2_frm_ht_in_mbs; + + if((ps_dec->ps_sps->u1_vui_parameters_present_flag == 1) + && (ps_dec->ps_sps->s_vui.u4_num_reorder_frames + != 64)) + { + ps_ctl_op->u4_num_disp_bufs = + ps_dec->ps_sps->s_vui.u4_num_reorder_frames + 2; + } + else + { + /*if VUI is not present assume maximum possible refrence frames for the level, + * as max reorder frames*/ + ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size_new( + level, width_mbs, height_mbs); + } + + ps_ctl_op->u4_num_disp_bufs += + ps_dec->ps_sps->u1_num_ref_frames + 1; + } + else + { + ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size_new( + ps_dec->u4_level_at_init, + (ps_dec->u4_width_at_init >> 4), + (ps_dec->u4_height_at_init >> 4)); + + ps_ctl_op->u4_num_disp_bufs += + ps_ctl_op->u4_num_disp_bufs; + + ps_ctl_op->u4_num_disp_bufs = + MIN(ps_ctl_op->u4_num_disp_bufs, + (ps_dec->u4_num_ref_frames_at_init + + ps_dec->u4_num_reorder_frames_at_init)); + + } + + ps_ctl_op->u4_num_disp_bufs = MAX( + ps_ctl_op->u4_num_disp_bufs, 6); + ps_ctl_op->u4_num_disp_bufs = MIN( + ps_ctl_op->u4_num_disp_bufs, 32); + } + + ps_ctl_op->u4_error_code = ps_dec->i4_error_code; + + ps_ctl_op->u4_frame_rate = 0; //make it proper + ps_ctl_op->u4_bit_rate = 0; //make it proper + ps_ctl_op->e_content_type = ps_dec->i4_content_type; + ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format; + ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; + + if(ps_dec->u1_chroma_format == IV_YUV_420P) + { + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; + } + else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) + { + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; + } + else if(ps_dec->u1_chroma_format == IV_RGB_565) + { + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; + } + else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) + { + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; + } + + else + { + //Invalid chroma format; Error code may be updated, verify in testing if needed + ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL; + return IV_FAIL; + } + + for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) + { + ps_ctl_op->u4_min_in_buf_size[i] = MIN_IN_BUF_SIZE; + } + + /*!*/ + if(ps_dec->u1_chroma_format == IV_YUV_420P) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); + ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) + >> 2; + ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht) + >> 2; + } + else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) + * 2; + ps_ctl_op->u4_min_out_buf_size[1] = + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + else if(ps_dec->u1_chroma_format == IV_RGB_565) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) + * 2; + ps_ctl_op->u4_min_out_buf_size[1] = + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); + ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) + >> 1; + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + + ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs; + return IV_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_buf_info */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + + dec_struct_t * ps_dec; + UWORD8 i = 0; // Default for 420P format + UWORD16 pic_wd, pic_ht; + ivd_ctl_getbufinfo_op_t *ps_ctl_op = + (ivd_ctl_getbufinfo_op_t*)pv_api_op; + UNUSED(pv_api_ip); + ps_ctl_op->u4_error_code = 0; + + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; + if(ps_dec->u1_chroma_format == IV_YUV_420P) + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; + else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; + else if(ps_dec->u1_chroma_format == IV_RGB_565) + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; + else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) + ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; + + else + { + //Invalid chroma format; Error code may be updated, verify in testing if needed + return IV_FAIL; + } + + ps_ctl_op->u4_num_disp_bufs = 1; + + for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) + { + ps_ctl_op->u4_min_in_buf_size[i] = MIN_IN_BUF_SIZE; + } + + pic_wd = ps_dec->u4_width_at_init; + pic_ht = ps_dec->u4_height_at_init; + + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + + if(0 == ps_dec->u4_share_disp_buf) + { + pic_wd = ps_dec->u2_disp_width; + pic_ht = ps_dec->u2_disp_height; + + } + else + { + pic_wd = ps_dec->u2_frm_wd_y; + pic_ht = ps_dec->u2_frm_ht_y; + } + } + else + { + if(1 == ps_dec->u4_share_disp_buf) + { + pic_wd += (PAD_LEN_Y_H << 1); + pic_ht += (PAD_LEN_Y_V << 2); + + } + } + + if((WORD32)ps_dec->u4_app_disp_width > pic_wd) + pic_wd = ps_dec->u4_app_disp_width; + + if(0 == ps_dec->u4_share_disp_buf) + ps_ctl_op->u4_num_disp_bufs = 1; + else + { + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + UWORD32 level, width_mbs, height_mbs; + + level = ps_dec->u4_level_at_init; + width_mbs = ps_dec->u2_frm_wd_in_mbs; + height_mbs = ps_dec->u2_frm_ht_in_mbs; + + if((ps_dec->ps_sps->u1_vui_parameters_present_flag == 1) + && (ps_dec->ps_sps->s_vui.u4_num_reorder_frames + != 64)) + { + ps_ctl_op->u4_num_disp_bufs = + ps_dec->ps_sps->s_vui.u4_num_reorder_frames + 2; + } + else + { + /*if VUI is not present assume maximum possible refrence frames for the level, + * as max reorder frames*/ + ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size_new( + level, width_mbs, height_mbs); + } + + ps_ctl_op->u4_num_disp_bufs += + ps_dec->ps_sps->u1_num_ref_frames + 1; + + } + else + { + ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size_new( + ps_dec->u4_level_at_init, + (ps_dec->u4_width_at_init >> 4), + (ps_dec->u4_height_at_init >> 4)); + + ps_ctl_op->u4_num_disp_bufs += + ps_ctl_op->u4_num_disp_bufs; + + ps_ctl_op->u4_num_disp_bufs = + MIN(ps_ctl_op->u4_num_disp_bufs, + (ps_dec->u4_num_ref_frames_at_init + + ps_dec->u4_num_reorder_frames_at_init)); + + } + + ps_ctl_op->u4_num_disp_bufs = MAX( + ps_ctl_op->u4_num_disp_bufs, 6); + ps_ctl_op->u4_num_disp_bufs = MIN( + ps_ctl_op->u4_num_disp_bufs, 32); + } + + /*!*/ + if(ps_dec->u1_chroma_format == IV_YUV_420P) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); + ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) + >> 2; + ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht) + >> 2; + } + else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) + * 2; + ps_ctl_op->u4_min_out_buf_size[1] = + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + else if(ps_dec->u1_chroma_format == IV_RGB_565) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) + * 2; + ps_ctl_op->u4_min_out_buf_size[1] = + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) + { + ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); + ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) + >> 1; + ps_ctl_op->u4_min_out_buf_size[2] = 0; + } + ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs; + + return IV_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_set_params */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + + dec_struct_t * ps_dec; + WORD32 ret = IV_SUCCESS; + + ivd_ctl_set_config_ip_t *ps_ctl_ip = + (ivd_ctl_set_config_ip_t *)pv_api_ip; + ivd_ctl_set_config_op_t *ps_ctl_op = + (ivd_ctl_set_config_op_t *)pv_api_op; + + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + + ps_dec->u4_skip_frm_mask = 0; + + ps_ctl_op->u4_error_code = 0; + + ps_dec->i4_app_skip_mode = ps_ctl_ip->e_frm_skip_mode; + + /*Is it really supported test it when you so the corner testing using test app*/ + + if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE) + { + + if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_P) + ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT; + else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_B) + ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT; + else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_PB) + { + ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT; + ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT; + } + else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_I) + ps_dec->u4_skip_frm_mask |= 1 << I_SLC_BIT; + else + { + //dynamic parameter not supported + //Put an appropriate error code to return the error.. + //when you do the error code tests and after that remove this comment + ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); + ret = IV_FAIL; + } + } + + if((0 != ps_dec->u4_app_disp_width) + && (ps_ctl_ip->u4_disp_wd + != ps_dec->u4_app_disp_width)) + { + ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); + ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID; + ret = IV_FAIL; + } + else + { + if((ps_ctl_ip->u4_disp_wd >= ps_dec->u2_pic_wd)/* && (ps_ctl_ip->u4_disp_wd <= ps_dec->u4_width_at_init) */) + { + ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd; + } + else if((0 == ps_dec->i4_header_decoded) /*&& (ps_ctl_ip->u4_disp_wd <= ps_dec->u4_width_at_init)*/) + { + ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd; + } + else if(ps_ctl_ip->u4_disp_wd == 0) + { + ps_dec->u4_app_disp_width = 0; + } + else + { + /* + * Set the display width to zero. This will ensure that the wrong value we had stored (0xFFFFFFFF) + * does not propogate. + */ + ps_dec->u4_app_disp_width = 0; + ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); + ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID; + ret = IV_FAIL; + } + } + if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME) + ps_dec->i4_decode_header = 0; + else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER) + ps_dec->i4_decode_header = 1; + else + { + ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); + ps_dec->i4_decode_header = 1; + ret = IV_FAIL; + } + + return ret; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_set_default_params */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 08 08 2011 100421 Copied from set_params */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_set_default_params(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + + dec_struct_t * ps_dec; + WORD32 ret = IV_SUCCESS; + + ivd_ctl_set_config_op_t *ps_ctl_op = + (ivd_ctl_set_config_op_t *)pv_api_op; + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); + UNUSED(pv_api_ip); + + + { + ps_dec->u4_app_disp_width = 0; + ps_dec->u4_skip_frm_mask = 0; + ps_dec->i4_decode_header = 1; + + ps_ctl_op->u4_error_code = 0; + } + + + return ret; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_reset */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + dec_struct_t * ps_dec; + ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *)pv_api_op; + UNUSED(pv_api_ip); + ps_ctl_op->u4_error_code = 0; + + ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); +//CHECK + if(ps_dec != NULL) + { + + ih264d_init_decoder(ps_dec); + + /* + memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t)); + memset(ps_dec->u4_disp_buf_mapping, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); + memset(ps_dec->u4_disp_buf_to_be_freed, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); + */ + } + else + { + H264_DEC_DEBUG_PRINT( + "\nReset called without Initializing the decoder\n"); + ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE; + } + + return IV_SUCCESS; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_ctl */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + ivd_ctl_set_config_ip_t *ps_ctl_ip; + ivd_ctl_set_config_op_t *ps_ctl_op; + WORD32 ret = IV_SUCCESS; + UWORD32 subcommand; + dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; + + if(ps_dec->init_done != 1) + { + //Return proper Error Code + return IV_FAIL; + } + ps_ctl_ip = (ivd_ctl_set_config_ip_t*)pv_api_ip; + ps_ctl_op = (ivd_ctl_set_config_op_t*)pv_api_op; + ps_ctl_op->u4_error_code = 0; + subcommand = ps_ctl_ip->e_sub_cmd; + + switch(subcommand) + { + case IVD_CMD_CTL_GETPARAMS: + ret = ih264d_get_status(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IVD_CMD_CTL_SETPARAMS: + ret = ih264d_set_params(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IVD_CMD_CTL_RESET: + ret = ih264d_reset(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op); + break; + case IVD_CMD_CTL_SETDEFAULT: + ret = ih264d_set_default_params(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IVD_CMD_CTL_FLUSH: + ret = ih264d_set_flush_mode(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IVD_CMD_CTL_GETBUFINFO: + ret = ih264d_get_buf_info(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IVD_CMD_CTL_GETVERSION: + ret = ih264d_get_version(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IH264D_CMD_CTL_DEGRADE: + ret = ih264d_set_degrade(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + + case IH264D_CMD_CTL_SET_NUM_CORES: + ret = ih264d_set_num_cores(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS: + ret = ih264d_get_frame_dimensions(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + case IH264D_CMD_CTL_SET_PROCESSOR: + ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + default: + H264_DEC_DEBUG_PRINT("\ndo nothing\n") + ; + break; + } + + return ret; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_rel_display_frame */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_rel_display_frame(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + + ivd_rel_display_frame_ip_t *ps_rel_ip; + ivd_rel_display_frame_op_t *ps_rel_op; + UWORD32 buf_released = 0; + + UWORD32 u4_ts = -1; + dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; + + ps_rel_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip; + ps_rel_op = (ivd_rel_display_frame_op_t *)pv_api_op; + ps_rel_op->u4_error_code = 0; + u4_ts = ps_rel_ip->u4_disp_buf_id; + + if(0 == ps_dec->u4_share_disp_buf) + { + ps_dec->u4_disp_buf_mapping[u4_ts] = 0; + ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0; + return IV_SUCCESS; + } + + if(ps_dec->pv_pic_buf_mgr != NULL) + { + if(1 == ps_dec->u4_disp_buf_mapping[u4_ts]) + { + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_rel_ip->u4_disp_buf_id, + BUF_MGR_IO); + ps_dec->u4_disp_buf_mapping[u4_ts] = 0; + buf_released = 1; + } + } + + if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released)) + ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1; + + return IV_SUCCESS; +} + +/** + ******************************************************************************* + * + * @brief + * Sets degrade params + * + * @par Description: + * Sets degrade params. + * Refer to ih264d_ctl_degrade_ip_t definition for details + * + * @param[in] ps_codec_obj + * Pointer to codec object at API level + * + * @param[in] pv_api_ip + * Pointer to input argument structure + * + * @param[out] pv_api_op + * Pointer to output argument structure + * + * @returns Status + * + * @remarks + * + * + ******************************************************************************* + */ + +WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj, + void *pv_api_ip, + void *pv_api_op) +{ + ih264d_ctl_degrade_ip_t *ps_ip; + ih264d_ctl_degrade_op_t *ps_op; + dec_struct_t *ps_codec = (dec_struct_t *)ps_codec_obj->pv_codec_handle; + + ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op; + + ps_codec->i4_degrade_type = ps_ip->i4_degrade_type; + ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval; + ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics; + + ps_op->u4_error_code = 0; + ps_codec->i4_degrade_pic_cnt = 0; + + return IV_SUCCESS; +} + +WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + ih264d_ctl_get_frame_dimensions_ip_t *ps_ip; + ih264d_ctl_get_frame_dimensions_op_t *ps_op; + dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; + UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset; + + ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip; + + ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op; + UNUSED(ps_ip); + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + disp_wd = ps_dec->u2_disp_width; + disp_ht = ps_dec->u2_disp_height; + + if(0 == ps_dec->u4_share_disp_buf) + { + buffer_wd = disp_wd; + buffer_ht = disp_ht; + } + else + { + buffer_wd = ps_dec->u2_frm_wd_y; + buffer_ht = ps_dec->u2_frm_ht_y; + } + } + else + { + + disp_wd = ps_dec->u4_width_at_init; + disp_ht = ps_dec->u4_height_at_init; + + if(0 == ps_dec->u4_share_disp_buf) + { + buffer_wd = disp_wd; + buffer_ht = disp_ht; + } + else + { + buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1); + buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2); + + } + } + if(ps_dec->u4_app_disp_width > buffer_wd) + buffer_wd = ps_dec->u4_app_disp_width; + + if(0 == ps_dec->u4_share_disp_buf) + { + x_offset = 0; + y_offset = 0; + } + else + { + y_offset = (PAD_LEN_Y_V << 1); + x_offset = PAD_LEN_Y_H; + + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid)) + && (0 != ps_dec->u2_crop_offset_y)) + { + y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y; + x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y; + } + } + + ps_op->u4_disp_wd[0] = disp_wd; + ps_op->u4_disp_ht[0] = disp_ht; + ps_op->u4_buffer_wd[0] = buffer_wd; + ps_op->u4_buffer_ht[0] = buffer_ht; + ps_op->u4_x_offset[0] = x_offset; + ps_op->u4_y_offset[0] = y_offset; + + ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) + >> 1); + ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) + >> 1); + ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] + >> 1); + ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] + >> 1); + ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = + (ps_op->u4_x_offset[0] >> 1); + ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = + (ps_op->u4_y_offset[0] >> 1); + + if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) + { + ps_op->u4_disp_wd[2] = 0; + ps_op->u4_disp_ht[2] = 0; + ps_op->u4_buffer_wd[2] = 0; + ps_op->u4_buffer_ht[2] = 0; + ps_op->u4_x_offset[2] = 0; + ps_op->u4_y_offset[2] = 0; + + ps_op->u4_disp_wd[1] <<= 1; + ps_op->u4_buffer_wd[1] <<= 1; + ps_op->u4_x_offset[1] <<= 1; + } + + return IV_SUCCESS; + +} + +WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) +{ + ih264d_ctl_set_num_cores_ip_t *ps_ip; + ih264d_ctl_set_num_cores_op_t *ps_op; + dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; + + ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip; + ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op; + ps_op->u4_error_code = 0; + ps_dec->u4_num_cores = ps_ip->u4_num_cores; + if(ps_dec->u4_num_cores == 1) + { + ps_dec->u1_separate_parse = 0; + ps_dec->pi4_ctxt_save_register_dec = ps_dec->pi4_ctxt_save_register; + } + else + { + ps_dec->u1_separate_parse = 1; + } + + /*using only upto three threads currently*/ + if(ps_dec->u4_num_cores > 3) + ps_dec->u4_num_cores = 3; + + return IV_SUCCESS; +} + +void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec, + ivd_video_decode_op_t *ps_dec_op) +{ + if((ps_dec_op->u4_error_code & 0xff) + != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED) + { + ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; + ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; + } + ps_dec_op->e_pic_type = ps_dec->i4_frametype; + + ps_dec_op->u4_new_seq = 0; + ps_dec_op->u4_output_present = ps_dec->u4_output_present; + ps_dec_op->u4_progressive_frame_flag = + ps_dec->s_disp_op.u4_progressive_frame_flag; + + ps_dec_op->u4_is_ref_flag = 1; + if(ps_dec_op->u4_frame_decoded_flag) + { + if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0) + ps_dec_op->u4_is_ref_flag = 0; + } + + ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format; + ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf; + ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type; + ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts; + ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_api_function */ +/* */ +/* Description : */ +/* */ +/* Inputs :iv_obj_t decoder handle */ +/* :pv_api_ip pointer to input structure */ +/* :pv_api_op pointer to output structure */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 10 2008 100356 Draft */ +/* */ +/*****************************************************************************/ +IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *dec_hdl, + void *pv_api_ip, + void *pv_api_op) +{ + UWORD32 command; + UWORD32 *pu2_ptr_cmd; + UWORD32 u4_api_ret; + IV_API_CALL_STATUS_T e_status; + e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op); + + if(e_status != IV_SUCCESS) + { + UWORD32 *ptr_err; + + ptr_err = (UWORD32 *)pv_api_op; + UNUSED(ptr_err); + H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1)); + return IV_FAIL; + } + + pu2_ptr_cmd = (UWORD32 *)pv_api_ip; + pu2_ptr_cmd++; + + command = *pu2_ptr_cmd; +// H264_DEC_DEBUG_PRINT("inside lib = %d\n",command); + switch(command) + { + + case IV_CMD_GET_NUM_MEM_REC: + u4_api_ret = ih264d_get_num_rec((void *)pv_api_ip, + (void *)pv_api_op); + + break; + case IV_CMD_FILL_NUM_MEM_REC: + + u4_api_ret = ih264d_fill_num_mem_rec((void *)pv_api_ip, + (void *)pv_api_op); + break; + case IV_CMD_INIT: + u4_api_ret = ih264d_init(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + + case IVD_CMD_VIDEO_DECODE: + u4_api_ret = ih264d_video_decode(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + + case IVD_CMD_GET_DISPLAY_FRAME: + u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + + break; + + case IVD_CMD_SET_DISPLAY_FRAME: + u4_api_ret = ih264d_set_display_frame(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + + break; + + case IVD_CMD_REL_DISPLAY_FRAME: + u4_api_ret = ih264d_rel_display_frame(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + + case IV_CMD_RETRIEVE_MEMREC: + u4_api_ret = ih264d_clr(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + + case IVD_CMD_VIDEO_CTL: + u4_api_ret = ih264d_ctl(dec_hdl, (void *)pv_api_ip, + (void *)pv_api_op); + break; + default: + u4_api_ret = IV_FAIL; + break; + } + + return u4_api_ret; +} diff --git a/decoder/ih264d_bitstrm.c b/decoder/ih264d_bitstrm.c new file mode 100755 index 0000000..fd41bc6 --- /dev/null +++ b/decoder/ih264d_bitstrm.c @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_bitstrm.c + * + * \brief + * Bitstream parsing routines + * + * \date + * 20/11/2002 + * + * \author AI + ************************************************************************** + */ + +#include <stdlib.h> +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_error_handler.h" + +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" + +/*! + ************************************************************************** + * \if Function name : ih264d_get_bit_h264 \endif + * + * \brief + * Read one bit from the bitstream. + * + * This is a Bitstream processing function. It reads the + * bit currently pointed by the bit pointer in the + * buffer and advances the pointer by one. It returns + * the bit (0 or 1) in the form of an unsigned integer. + * + * \return + * Returns the next bit (0 or 1) in the bitstream. + * + ************************************************************************** + */ +UWORD8 ih264d_get_bit_h264(dec_bit_stream_t *ps_stream) +{ + UWORD32 u4_code; + + GETBIT(u4_code, ps_stream->u4_ofst, ps_stream->pu4_buffer); + return (u4_code); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_get_bits_h264 \endif + * + * \brief + * Read specified number of bits from the bitstream. + * + * This is a Bitstream processing function. It reads the + * number specified number of bits from the current bit + * position and advances the bit and byte pointers + * appropriately. + * + * \return + * An unsigned 32 bit integer with its least significant bits + * containing the bits in order of their occurence in the bitstream. + * + ************************************************************************** + */ + +UWORD32 ih264d_get_bits_h264(dec_bit_stream_t *ps_bitstrm, UWORD32 u4_num_bits) +{ + UWORD32 u4_code = 0; + if(u4_num_bits) + GETBITS(u4_code, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer, u4_num_bits); + return (u4_code); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_next_bits_h264 \endif + * + * \brief + * Peek specified number of bits from the bitstream. + * + * This is a Bitstream processing function. It gets the + * specified number of bits from the buffer without + * altering the current pointers. It is equivalent to + * next_bits() function in the standard. + * + * \return + * An unsigned 32 bit integer with its least significant bits + * containing the bits in order of their occurence in the bitstream. + ************************************************************************** + */ +UWORD32 ih264d_next_bits_h264(dec_bit_stream_t *ps_bitstrm, UWORD32 u4_num_bits) +{ + UWORD32 u4_word_off = (ps_bitstrm->u4_ofst >> 5); + UWORD32 u4_bit_off = ps_bitstrm->u4_ofst & 0x1F; + UWORD32 *pu4_bitstream = ps_bitstrm->pu4_buffer; + UWORD32 u4_bits = pu4_bitstream[u4_word_off++] << u4_bit_off; + + /*************************************************************************/ + /* Test if number of bits to be read exceeds the number of bits in the */ + /* current word. If yes, read from the next word of the buffer, The bits */ + /* from both the words are concatenated to get next 32 bits in 'u4_bits' */ + /*************************************************************************/ + if(u4_bit_off > (INT_IN_BITS - u4_num_bits)) + u4_bits |= (pu4_bitstream[u4_word_off] >> (INT_IN_BITS - u4_bit_off)); + + return ((u4_bits >> (INT_IN_BITS - u4_num_bits))); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_flush_bits_h264 \endif + * + * \brief + * Flush specified number of bits from the bitstream. + * + * This function flushes the specified number of bits (marks + * as read) from the buffer. + * + * \return + * A 8 bit unsigned integer with value + * '1' on successful flush + * '0' on failure. + * + ************************************************************************** + */ +WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *ps_bitstrm, WORD32 u4_num_bits) +{ + ps_bitstrm->u4_ofst += u4_num_bits; + + if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + { + return ERROR_EOB_FLUSHBITS_T; + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_check_byte_aligned \endif + * + * \brief + * Checks whether the bit ps_bitstrm u4_ofst is at byte boundary. + * + * \param ps_bitstrm : Pointer to bitstream + * + * \return + * Returns 1 if bit ps_bitstrm u4_ofst is at byte alligned position else zero. + ************************************************************************** + */ + +UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm) +{ + if(ps_bitstrm->u4_ofst & 0x07) + return (0); + else + return (1); +} diff --git a/decoder/ih264d_bitstrm.h b/decoder/ih264d_bitstrm.h new file mode 100755 index 0000000..49cd5e7 --- /dev/null +++ b/decoder/ih264d_bitstrm.h @@ -0,0 +1,195 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_BITSTRM_H_ +#define _IH264D_BITSTRM_H_ +/*! + ************************************************************************* + * \file ih264d_bitstrm.h + * + * \brief + * Contains all the declarations of bitstream reading routines + * + * \date + * 20/11/2002 + * + * \author AI + ************************************************************************* + */ + +/* Includes */ +#include <stdio.h> +#include <stdlib.h> +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" + +#define INT_IN_BYTES 4 +#define INT_IN_BITS 32 + +/* Based on level 1.2 of baseline profile */ +/* 396[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32) + i.e 396 * 128 * 1.5 / 4 = 19008 */ +/* Based on level 3 of main profile */ +/* 1620[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32) + i.e 1620 * 128 * 1.5 / 4= 77760 */ +#define SIZE_OF_BUFFER 77760 + +/* Structure for the ps_bitstrm */ +typedef struct +{ + UWORD32 u4_ofst; /* Offset in the buffer for the current bit */ + UWORD32 *pu4_buffer; /* Bitstream Buffer */ + UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */ + void * pv_codec_handle; /* For Error Handling */ +} dec_bit_stream_t; + +/* To read the next bit */ +UWORD8 ih264d_get_bit_h264(dec_bit_stream_t *); + +/* To read the next specified number of bits */ +UWORD32 ih264d_get_bits_h264(dec_bit_stream_t *, UWORD32); + +/* To see the next specified number of bits */ +UWORD32 ih264d_next_bits_h264(dec_bit_stream_t *, UWORD32); + +/* To flush a specified number of bits*/ +WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *, WORD32); + +/*! + ************************************************************************** + * \if Function name : MoreRbspData \endif + * + * \brief + * Determines whether there is more data in RBSP or not. + * + * \param ps_bitstrm : Pointer to bitstream + * + * \return + * Returns 1 if there is more data in RBSP before rbsp_trailing_bits(). + * Otherwise it returns FALSE. + ************************************************************************** + */ + +#define MORE_RBSP_DATA(ps_bitstrm) \ + (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst) +#define EXCEED_OFFSET(ps_bitstrm) \ + (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + +void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm); +UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm); + +/*****************************************************************************/ +/* Define a macro for inlining of GETBIT: */ +/*****************************************************************************/ +#define GETBIT(u4_code, u4_offset, pu4_bitstream) \ +{ \ + UWORD32 *pu4_buf = (pu4_bitstream); \ + UWORD32 u4_word_off = ((u4_offset) >> 5); \ + UWORD32 u4_bit_off = (u4_offset) & 0x1F; \ + u4_code = pu4_buf[u4_word_off] << u4_bit_off; \ + (u4_offset)++; \ + u4_code = (u4_code >> 31); \ +} + + + +/*****************************************************************************/ +/* Define a macro for inlining of GETBITS: u4_no_bits shall not exceed 32 */ +/*****************************************************************************/ +#define GETBITS(u4_code, u4_offset, pu4_bitstream, u4_no_bits) \ +{ \ + UWORD32 *pu4_buf = (pu4_bitstream); \ + UWORD32 u4_word_off = ((u4_offset) >> 5); \ + UWORD32 u4_bit_off = (u4_offset) & 0x1F; \ + u4_code = pu4_buf[u4_word_off++] << u4_bit_off; \ + \ + if(u4_bit_off) \ + u4_code |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off)); \ + u4_code = u4_code >> (INT_IN_BITS - u4_no_bits); \ + (u4_offset) += u4_no_bits; \ +} \ + \ + +/*****************************************************************************/ +/* Define a macro for inlining of NEXTBITS */ +/*****************************************************************************/ +#define NEXTBITS(u4_word, u4_offset, pu4_bitstream, u4_no_bits) \ +{ \ + UWORD32 *pu4_buf = (pu4_bitstream); \ + UWORD32 u4_word_off = ((u4_offset) >> 5); \ + UWORD32 u4_bit_off = (u4_offset) & 0x1F; \ + u4_word = pu4_buf[u4_word_off++] << u4_bit_off; \ + if(u4_bit_off) \ + u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off)); \ + u4_word = u4_word >> (INT_IN_BITS - u4_no_bits); \ +} +/*****************************************************************************/ +/* Define a macro for inlining of NEXTBITS_32 */ +/*****************************************************************************/ +#define NEXTBITS_32(u4_word, u4_offset, pu4_bitstream) \ +{ \ + UWORD32 *pu4_buf = (pu4_bitstream); \ + UWORD32 u4_word_off = ((u4_offset) >> 5); \ + UWORD32 u4_bit_off = (u4_offset) & 0x1F; \ + \ + u4_word = pu4_buf[u4_word_off++] << u4_bit_off; \ + if(u4_bit_off) \ + u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off)); \ +} + + +/*****************************************************************************/ +/* Define a macro for inlining of FIND_ONE_IN_STREAM_32 */ +/*****************************************************************************/ +#define FIND_ONE_IN_STREAM_32(u4_ldz, u4_offset, pu4_bitstream) \ +{ \ + UWORD32 u4_word; \ + NEXTBITS_32(u4_word, u4_offset, pu4_bitstream); \ + u4_ldz = CLZ(u4_word); \ + (u4_offset) += (u4_ldz + 1); \ +} + +/*****************************************************************************/ +/* Define a macro for inlining of FIND_ONE_IN_STREAM_LEN */ +/*****************************************************************************/ +#define FIND_ONE_IN_STREAM_LEN(u4_ldz, u4_offset, pu4_bitstream, u4_len) \ +{ \ + UWORD32 u4_word; \ + NEXTBITS_32(u4_word, u4_offset, pu4_bitstream); \ + u4_ldz = CLZ(u4_word); \ + if(u4_ldz < u4_len) \ + (u4_offset) += (u4_ldz + 1); \ + else \ + { \ + u4_ldz = u4_len; \ + (u4_offset) += u4_ldz; \ + } \ +} + +/*****************************************************************************/ +/* Define a macro for inlining of FLUSHBITS */ +/*****************************************************************************/ +#define FLUSHBITS(u4_offset, u4_no_bits) \ +{ \ + (u4_offset) += (u4_no_bits); \ +} + +#endif /* _BITSTREAM_H_ */ diff --git a/decoder/ih264d_cabac.c b/decoder/ih264d_cabac.c new file mode 100755 index 0000000..38028ae --- /dev/null +++ b/decoder/ih264d_cabac.c @@ -0,0 +1,779 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_cabac.c + * + * \brief + * This file contains Binary decoding routines. + * + * \date + * 04/02/2003 + * + * \author NS + *************************************************************************** + */ +#include <string.h> +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_cabac.h" +#include "ih264d_bitstrm.h" +#include "ih264d_error_handler.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_parse_cabac.h" +#include "ih264d_tables.h" + + + +/*! + ************************************************************************** + * \if Function name : ih264d_init_cabac_dec_envirnoment \endif + * + * \brief + * This function initializes CABAC decoding envirnoment. This function + * implements 9.3.3.2.3.1 of ISO/IEC14496-10. + * + * \return + * None + * + ************************************************************************** + */ +WORD32 ih264d_init_cabac_dec_envirnoment(decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 u4_code_int_val_ofst; + + ps_cab_env->u4_code_int_range = (HALF - 2) << 23; + NEXTBITS(u4_code_int_val_ofst, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer, + 32); + FLUSHBITS(ps_bitstrm->u4_ofst, 9) + + if(ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst) + return ERROR_EOB_FLUSHBITS_T; + + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + /*brief description of the design adopted for CABAC*/ + /*according to the standard the u4_code_int_range needs to be initialized 0x 1FE(10 bits) and + 9 bits from the bit stream need to be read and into the u4_code_int_val_ofst.As and when the + u4_code_int_range becomes less than 10 bits we need to renormalize and read from the bitstream* + + In the implemented design + initially + + range_new = range <<23 + valOffset_new = valOffset << 23 + 23 bits(read from the bit stream) + + Thus we have read 23 more bits ahead of time. + + It can be mathematical proved that even with the modified range and u4_ofst the operations + like comparison and subtraction needed for a bin decode are still valid(both in the regular case and the bypass case) + + As bins are decoded..we consume the bits that we have already read into the valOffset.The clz of Range + gives us the number of bits we consumed of the 23 bits that we have read ahead of time. + + when the number bits we have consumed exceeds 23 ,we renormalize..and we read from the bitstream again*/ + +RESET_BIN_COUNTS(ps_cab_env) + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_init_cabac_contexts */ +/* */ +/* Description : This function initializes the cabac contexts */ +/* depending upon slice type and Init_Idc value. */ +/* Inputs : ps_dec, slice type */ +/* Globals : <Does it use any global variables?> */ +/* Outputs : */ +/* Returns : void */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 03 05 2005 100153) Draft */ +/* */ +/*****************************************************************************/ + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec) +{ + + bin_ctxt_model_t *p_cabac_ctxt_table_t = ps_dec->p_cabac_ctxt_table_t; + UWORD8 u1_qp_y = ps_dec->ps_cur_slice->u1_slice_qp; + UWORD8 u1_cabac_init_Idc = 0; + + if(I_SLICE != u1_slice_type) + { + u1_cabac_init_Idc = ps_dec->ps_cur_slice->u1_cabac_init_idc; + } + + { + /* MAKING ps_dec->p_ctxt_inc_mb_map a scratch buffer */ + /* 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_dec->p_ctxt_inc_mb_map - 1; + UWORD8 *pu1_temp; + WORD8 i; + 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_dec->ps_def_ctxt_mb_info = p_DefCtxt; + } + + if(u1_slice_type == I_SLICE) + { + u1_cabac_init_Idc = 3; + ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_I_SLICE; + } + else if(u1_slice_type == P_SLICE) + { + ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_P_SLICE; + ps_dec->p_mb_skip_flag_t = p_cabac_ctxt_table_t + MB_SKIP_FLAG_P_SLICE; + ps_dec->p_sub_mb_type_t = p_cabac_ctxt_table_t + SUB_MB_TYPE_P_SLICE; + } + else if(u1_slice_type == B_SLICE) + { + ps_dec->p_mb_type_t = p_cabac_ctxt_table_t + MB_TYPE_B_SLICE; + ps_dec->p_mb_skip_flag_t = p_cabac_ctxt_table_t + MB_SKIP_FLAG_B_SLICE; + ps_dec->p_sub_mb_type_t = p_cabac_ctxt_table_t + SUB_MB_TYPE_B_SLICE; + } + { + bin_ctxt_model_t *p_cabac_ctxt_table_t_tmp = p_cabac_ctxt_table_t; + if(ps_dec->ps_cur_slice->u1_field_pic_flag) + { + p_cabac_ctxt_table_t_tmp += SIGNIFICANT_COEFF_FLAG_FLD; + + } + else + { + p_cabac_ctxt_table_t_tmp += SIGNIFICANT_COEFF_FLAG_FRAME; + } + { + bin_ctxt_model_t * * p_significant_coeff_flag_t = + ps_dec->p_significant_coeff_flag_t; + p_significant_coeff_flag_t[0] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_0_OFFSET; + p_significant_coeff_flag_t[1] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_1_OFFSET; + p_significant_coeff_flag_t[2] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_2_OFFSET; + p_significant_coeff_flag_t[3] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_3_OFFSET; + p_significant_coeff_flag_t[4] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_4_OFFSET; + + p_significant_coeff_flag_t[5] = p_cabac_ctxt_table_t_tmp + + SIG_COEFF_CTXT_CAT_5_OFFSET; + + } + } + + memcpy(p_cabac_ctxt_table_t, + gau1_ih264d_cabac_ctxt_init_table[u1_cabac_init_Idc][u1_qp_y], + NUM_CABAC_CTXTS * sizeof(bin_ctxt_model_t)); +} +/*! + ************************************************************************** + * \if Function name : ih264d_decode_bin \endif + * + * \brief + * This function implements decoding process of a decision as defined + * in 9.3.3.2.2. + * + * \return + * Returns symbol decoded. + * + * \note + * It is specified in 9.3.3.2.3.2 that, one of the input to this function + * is CtxIdx. CtxIdx is used to identify state and MPS of that context + * (Refer Fig 9.11 - Flowchart for encoding a decision). To suffice that + * here we pass a pointer bin_ctxt_model_t which contains these values. + * + ************************************************************************** + */ + +UWORD32 ih264d_decode_bin(UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env) + +{ + + UWORD32 u4_qnt_int_range, u4_code_int_range, u4_code_int_val_ofst, + u4_int_range_lps; + + UWORD32 u4_symbol, u4_mps_state; + + bin_ctxt_model_t *ps_bin_ctxt; + + UWORD32 table_lookup; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + ps_bin_ctxt = ps_src_bin_ctxt + u4_ctx_inc; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + u4_mps_state = (ps_bin_ctxt->u1_mps_state); + u4_clz = CLZ(u4_code_int_range); + + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u4_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u4_mps_state >> 6) & 0x1); + + u4_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u4_mps_state, table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + + ps_bitstrm->u4_ofst = u4_offset; + } + + INC_BIN_COUNT(ps_cab_env) + + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_bin_ctxt->u1_mps_state = u4_mps_state; + + return (u4_symbol); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_terminate \endif + * + * \brief + * This function implements decoding process of a termination as defined + * 9.3.3.2.2.3 of ISO/IEC14496-10. + * + * \return + * Returns symbol decoded. + * + * \note + * This routine is called while decoding "end_of_skice_flag" and of the + * bin indicating PCM mode in MBType. + * + ************************************************************************** + */ +UWORD8 ih264d_decode_terminate(decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t * ps_stream) +{ + UWORD32 u4_symbol; + UWORD32 u4_code_int_val_ofst, u4_code_int_range; + UWORD32 u4_clz; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + u4_clz = CLZ(u4_code_int_range); + u4_code_int_range -= (2 << (23 - u4_clz)); + + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + u4_symbol = 1; + + { + + /*the u4_ofst needs to be updated before termination*/ + ps_stream->u4_ofst += u4_clz; + + } + + } + else + { + /* S=0 */ + u4_symbol = 0; + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_stream->pu4_buffer; + u4_offset = ps_stream->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + ps_stream->u4_ofst = u4_offset; + } + } + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + INC_BIN_COUNT(ps_cab_env) + + return (u4_symbol); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_bins_tunary */ +/* */ +/* Description : This function decodes bins in the case of TUNARY */ +/* binarization technique.valid_length is assumed equal to 3 */ +/* and u1_max_bins <= 4 in this functon. */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 20 11 2008 SH Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_decode_bins_tunary(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env) + +{ + UWORD32 u4_value; + UWORD32 u4_symbol; + UWORD8 u4_ctx_Inc; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + + u4_value = 0; + + /*u1_max_bins has to be less than or equal to 4, u1_max_bins <= 4 for this function*/ + + /*here the valid length is assumed to be equal to 3 ,so the calling function is expected + to duplicate CtxInc if valid lenth is 2 and cmaxbin is greater than2*/ + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + do + { + u4_ctx_Inc = u4_ctx_inc & 0xF; + u4_ctx_inc = u4_ctx_inc >> 4; + + ps_bin_ctxt = ps_src_bin_ctxt + u4_ctx_Inc; + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, + pu4_table, ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value++; + } + while((u4_value < u1_max_bins) & (u4_symbol)); + + u4_value = u4_value - 1 + u4_symbol; + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + return (u4_value); + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_bins */ +/* */ +/* Description : This function decodes bins in the case of MSB_FIRST_FLC */ +/* binarization technique.valid_length is always equal max_bins */ +/* for MSB_FIRST_FLC. assumes u1_max_bins <= 4 */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 20 11 2008 SH Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_decode_bins(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env) + +{ + UWORD32 u4_value; + UWORD32 u4_symbol, i; + UWORD32 u4_ctxt_inc; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + + i = 0; + + u4_value = 0; + + /*u1_max_bins has to be less than or equal to 4, u1_max_bins <= 4 for this fucntion*/ + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + do + { + u4_ctxt_inc = u4_ctx_inc & 0xf; + u4_ctx_inc = u4_ctx_inc >> 4; + + ps_bin_ctxt = ps_src_bin_ctxt + u4_ctxt_inc; + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, + pu4_table, ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value = (u4_value << 1) | (u4_symbol); + + i++; + } + while(i < u1_max_bins); + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + return (u4_value); + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_bins_unary */ +/* */ +/* Description : This function decodes bins in the case of UNARY */ +/* binarization technique.here the valid length is taken to 5*/ +/* and cmax is always greater than 9 */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 20 11 2008 SH Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_decode_bins_unary(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env) +{ + UWORD32 u4_value; + UWORD32 u4_symbol; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_ctx_Inc; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + + /* in this function the valid length for u4_ctx_inc is always taken to be,so if the + the valid length is lessthan 5 the caller need to duplicate accordingly*/ + + /*u1_max_bins is always greater or equal to 9 we have the check for u1_max_bins only after the 2 loop*/ + u4_value = 0; + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + do + { + u4_ctx_Inc = u4_ctx_inc & 0xf; + u4_ctx_inc = u4_ctx_inc >> 4; + + ps_bin_ctxt = ps_src_bin_ctxt + u4_ctx_Inc; + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, + pu4_table, ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value++; + + } + while(u4_symbol && u4_value < 4); + + if(u4_symbol && (u4_value < u1_max_bins)) + { + + u4_ctx_Inc = u4_ctx_inc & 0xf; + + ps_bin_ctxt = ps_src_bin_ctxt + u4_ctx_Inc; + + do + { + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, u4_code_int_val_ofst, + pu4_table, ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value++; + + } + while(u4_symbol && (u4_value < u1_max_bins)); + + } + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + u4_value = u4_value - 1 + u4_symbol; + + return (u4_value); + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_bypass_bins_unary */ +/* */ +/* Description : This function is used in the case of UNARY coding */ +/* */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 10 2005 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_decode_bypass_bins_unary(decoding_envirnoment_t *ps_cab_env, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 u4_value; + UWORD32 u4_bin; + UWORD32 u4_code_int_val_ofst, u4_code_int_range; + + UWORD32 u1_max_bins; + + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + u4_code_int_range = ps_cab_env->u4_code_int_range; + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + ps_bitstrm->u4_ofst = u4_offset; + } + + /*as it is called only form mvd*/ + u1_max_bins = 32; + u4_value = 0; + + do + { + u4_value++; + + u4_code_int_range = u4_code_int_range >> 1; + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + u4_bin = 1; + u4_code_int_val_ofst -= u4_code_int_range; + } + else + { + /* S=0 */ + u4_bin = 0; + } + + INC_BIN_COUNT(ps_cab_env);INC_BYPASS_BINS(ps_cab_env); + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + + ps_bitstrm->u4_ofst = u4_offset; + } + + } + while(u4_bin && (u4_value < u1_max_bins)); + + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + u4_value = (u4_value - 1 + u4_bin); + +return (u4_value); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_bypass_bins */ +/* */ +/* Description : This function is used in the case of FLC coding */ +/* */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 10 2005 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_decode_bypass_bins(decoding_envirnoment_t *ps_cab_env, + UWORD8 u1_max_bins, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 u4_bins; + UWORD32 u4_bin; + UWORD32 u4_code_int_val_ofst, u4_code_int_range; + + u4_bins = 0; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + u4_code_int_range = ps_cab_env->u4_code_int_range; + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + ps_bitstrm->u4_ofst = u4_offset; + } + + do + { + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + u4_bin = 1; + u4_code_int_val_ofst -= u4_code_int_range; + } + else + { + /* S=0 */ + u4_bin = 0; + } + + INC_BIN_COUNT(ps_cab_env);INC_BYPASS_BINS(ps_cab_env); + + u4_bins = ((u4_bins << 1) | u4_bin); + u1_max_bins--; + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + ps_bitstrm->u4_ofst = u4_offset; + } + + } + while(u1_max_bins); + + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + + return (u4_bins); +} + diff --git a/decoder/ih264d_cabac.h b/decoder/ih264d_cabac.h new file mode 100755 index 0000000..6ee3d52 --- /dev/null +++ b/decoder/ih264d_cabac.h @@ -0,0 +1,267 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_cabac.h + * + * \brief + * This file contains declarations of Binary decoding routines and tables. + * + * \date + * 04/02/2003 + * + * \author NS + *************************************************************************** + */ + +#ifndef _IH264D_CABAC_H_ +#define _IH264D_CABAC_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" + +#define B_BITS 10 + +#define HALF (1 << (B_BITS-1)) +#define QUARTER (1 << (B_BITS-2)) + +#define CTXT_UNUSED {0,64} +#define NUM_MB_SKIP_CTXT 6 +#define NUM_MB_TYPE_CTXT 9 +#define NUM_SUBMB_TYPE_CTXT 7 +#define NUM_REF_IDX_CTXT 6 +#define NUM_MB_QP_DELTA 4 +#define NUM_PRED_MODE 6 +#define NUM_MB_FIELD 3 +#define NUM_CBP 12 +#define NUM_CTX_MVD 14 + +/* Residual block cabac context parameters */ +#define NUM_CTX_CAT 6 +#define NUM_LUMA_CTX_CAT 3 +#define NUM_CTX_CODED_BLOCK 4 +/* Luma CtxSigCoeff + CtxLastCoeff = 15 + 15 = 30 */ +#define NUM_LUMA_CTX_SIG_COEF 30 +/* Chroma DC CtxSigCoeff + CtxLastCoeff = 3 + 3 = 6 */ +#define NUM_CTX_CHROMA_DC_SIG_COEF 6 +/* Chroma AC CtxSigCoeff + CtxLastCoeff = 14 + 14 = 28 */ +#define NUM_CTX_CHROMA_AC_SIG_COEF 28 +#define NUM_CTX_ABS_LEVEL 10 + +#define LUMA_DC_CTXCAT 0 +#define LUMA_AC_CTXCAT 1 +#define LUMA_4X4_CTXCAT 2 +#define CHROMA_DC_CTXCAT 3 +#define CHROMA_AC_CTXCAT 4 +#define LUMA_8X8_CTXCAT 5 + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ +#define NUM_CABAC_CTXTS 460 +#define QP_RANGE 52 +#define NUM_CAB_INIT_IDC_PLUS_ONE 4 +#define LAST_COEFF_CTXT_MINUS_SIG_COEFF_CTXT 61 +#define LAST_COEFF_CTXT_MINUS_SIG_COEFF_CTXT_8X8 15 + +/*bits 0 to 5 :state + bit 6:mps*/ +typedef struct +{ + UWORD8 u1_mps_state; /* state number */ +} bin_ctxt_model_t; + +typedef struct + +{ + /* Neighbour availability Variables needed to get CtxtInc, for CABAC */ + UWORD8 u1_mb_type; /** macroblock type: I/P/B/SI/SP */ + UWORD8 u1_cbp; /** Coded Block Pattern */ + UWORD8 u1_intra_chroma_pred_mode; + + /*************************************************************************/ + /* Arrangnment of DC CSBP */ + /* bits: b7 b6 b5 b4 b3 b2 b1 b0 */ + /* CSBP: x x x x x Vdc Udc Ydc */ + /*************************************************************************/ + UWORD8 u1_yuv_dc_csbp; + WORD8 i1_ref_idx[4]; + UWORD8 u1_mv[4][4]; + UWORD8 u1_transform8x8_ctxt; +} ctxt_inc_mb_info_t; + +#define ONE_RIGHT_SHIFTED_BY_8 1<<8 +#define ONE_RIGHT_SHIFTED_BY_9 1<<9 +#define ONE_RIGHT_SHIFTED_BY_14 1<<14 +typedef struct +{ + UWORD32 u4_code_int_range; + UWORD32 u4_code_int_val_ofst; + const void *cabac_table; + void * pv_codec_handle; /* For Error Handling */ +} decoding_envirnoment_t; + +WORD32 ih264d_init_cabac_dec_envirnoment(decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t *ps_bitstrm); + +UWORD32 ih264d_decode_bin(UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env); +UWORD8 ih264d_decode_terminate(decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t * ps_bitstrm); + +UWORD32 ih264d_decode_bins_tunary(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env); + +UWORD32 ih264d_decode_bins(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env); +UWORD32 ih264d_decode_bins_unary(UWORD8 u1_max_bins, + UWORD32 u4_ctx_inc, + bin_ctxt_model_t *ps_src_bin_ctxt, + dec_bit_stream_t *ps_bitstrm, + decoding_envirnoment_t *ps_cab_env); + +UWORD32 ih264d_decode_bypass_bins_unary(decoding_envirnoment_t *ps_cab_env, + dec_bit_stream_t *ps_bitstrm); + +UWORD32 ih264d_decode_bypass_bins(decoding_envirnoment_t *ps_cab_env, + UWORD8 u1_max_bins, + dec_bit_stream_t *ps_bitstrm); + +/*****************************************************************************/ +/* Function Macros */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Defining a macro for renormalization*/ +/*****************************************************************************/ + +/*we renormalize every time the number bits(which are read ahead of time) we have + consumed in the u4_ofst exceeds 23*/ + +#define RENORM_RANGE_OFFSET(u4_codeIntRange_m,u4_codeIntValOffset_m,u4_offset_m,pu4_buffer_m) \ + { \ + UWORD32 read_bits_m,u4_clz_m ; \ + u4_clz_m = CLZ(u4_codeIntRange_m); \ + NEXTBITS(read_bits_m,(u4_offset_m+23),pu4_buffer_m,u4_clz_m) \ + FLUSHBITS(u4_offset_m,(u4_clz_m)) \ + u4_codeIntRange_m = u4_codeIntRange_m << u4_clz_m; \ + u4_codeIntValOffset_m = (u4_codeIntValOffset_m << u4_clz_m) | read_bits_m; \ + } + +/*****************************************************************************/ +/* Defining a macro for checking if the symbol is MPS*/ +/*****************************************************************************/ + +#define CHECK_IF_LPS(u4_codeIntRange_m,u4_codeIntValOffset_m,u4_symbol_m, \ + u4_codeIntRangeLPS_m,u1_mps_state_m,table_lookup_m) \ +{ \ + if(u4_codeIntValOffset_m >= u4_codeIntRange_m) \ + { \ + u4_symbol_m = 1 - u4_symbol_m; \ + u4_codeIntValOffset_m -= u4_codeIntRange_m; \ + u4_codeIntRange_m = u4_codeIntRangeLPS_m; \ + u1_mps_state_m = (table_lookup_m >> 15) & 0x7F; \ + } \ +} + +/*! + ************************************************************************** + * \if Function name : DECODE_ONE_BIN_MACRO \endif + * + * \brief + * This function implements decoding process of a decision as defined + * in 9.3.3.2.2. + * + * \return + * Returns symbol decoded. + * + * \note + * It is specified in 9.3.3.2.3.2 that, one of the input to this function + * is CtxIdx. CtxIdx is used to identify state and MPS of that context + * (Refer Fig 9.11 - Flowchart for encoding a decision). To suffice that + * here we pass a pointer bin_ctxt_model_t which contains these values. + * + ************************************************************************** + */ + +#define DECODE_ONE_BIN_MACRO(p_binCtxt_arg ,u4_code_int_range,u4_code_int_val_ofst, \ + pu4_table_arg, \ + p_DecBitStream_arg,u4_symbol) \ +{ \ + bin_ctxt_model_t *p_binCtxt_m = (bin_ctxt_model_t *) p_binCtxt_arg; \ + dec_bit_stream_t *p_DecBitStream_m = (dec_bit_stream_t *) p_DecBitStream_arg; \ + const UWORD32 *pu4_table_m = (const UWORD32 *) pu4_table_arg; \ + \ + UWORD32 u4_quantCodeIntRange_m,u4_codeIntRangeLPS_m; \ + UWORD32 u1_mps_state_m; \ + UWORD32 table_lookup_m; \ + UWORD32 u4_clz_m; \ + \ + u1_mps_state_m = (p_binCtxt_m->u1_mps_state); \ + u4_clz_m = CLZ(u4_code_int_range); \ + u4_quantCodeIntRange_m = u4_code_int_range << u4_clz_m; \ + u4_quantCodeIntRange_m = (u4_quantCodeIntRange_m >> 29) & 0x3; \ + table_lookup_m = pu4_table_m[(u1_mps_state_m << 2)+u4_quantCodeIntRange_m]; \ + u4_codeIntRangeLPS_m = table_lookup_m & 0xff; \ + \ + u4_codeIntRangeLPS_m = u4_codeIntRangeLPS_m << (23 - u4_clz_m); \ + u4_code_int_range = u4_code_int_range - u4_codeIntRangeLPS_m; \ + u4_symbol = ((u1_mps_state_m>> 6) & 0x1); \ + /*if mps*/ \ + u1_mps_state_m = (table_lookup_m >> 8) & 0x7F; \ + if(u4_code_int_val_ofst >= u4_code_int_range) \ + { \ + \ + u4_symbol = 1 - u4_symbol; \ + u4_code_int_val_ofst -= u4_code_int_range; \ + u4_code_int_range = u4_codeIntRangeLPS_m; \ + u1_mps_state_m = (table_lookup_m >> 15) & 0x7F; \ + } \ + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) \ + { \ + UWORD32 *pu4_buffer,u4_offset; \ + UWORD32 read_bits,u4_clz_m ; \ + \ + pu4_buffer = p_DecBitStream_m->pu4_buffer; \ + u4_offset = p_DecBitStream_m->u4_ofst; \ + u4_clz_m = CLZ(u4_code_int_range); \ + NEXTBITS(read_bits,(u4_offset+23),pu4_buffer,u4_clz_m) \ + FLUSHBITS(u4_offset,(u4_clz_m)) \ + u4_code_int_range = u4_code_int_range << u4_clz_m; \ + u4_code_int_val_ofst= (u4_code_int_val_ofst << u4_clz_m) | read_bits; \ + \ + \ + p_DecBitStream_m->u4_ofst = u4_offset; \ + } \ + p_binCtxt_m->u1_mps_state = u1_mps_state_m; \ +} + +#endif /* _IH264D_CABAC_H_ */ diff --git a/decoder/ih264d_cabac_init_tables.c b/decoder/ih264d_cabac_init_tables.c new file mode 100755 index 0000000..2c3a55e --- /dev/null +++ b/decoder/ih264d_cabac_init_tables.c @@ -0,0 +1,9273 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _CABAC_INIT_TABLES_H_ +#define _CABAC_INIT_TABLES_H_ + +/*****************************************************************************/ +/* */ +/* File Name : ih264d_cabac_init_tables.c */ +/* */ +/* Description : This file contains the initialized cabac context */ +/* structures for all possible values of Qp (0 - 51) */ +/* Cabac_init Idc (0 - 2) and I slice. The contexts */ +/* are initialized and stored as per tables 9-11 to */ +/* 9 -23 */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 10 01 2005 SH */ +/* */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_cabac.h" + +/*combined table :guc_RTAB,NextStateLPS,NextStateMPS + input(combined_state): + bits 0-5: state + bits 6:mps + output + bits 0-7:rangeTabLPS + bits 8-14 :combined_next_state_if_mps + bits 15 -21:combined_next_state_if_lps + + */ + +const UWORD32 gau4_ih264d_cabac_table[128][4] = + { + { 2097536, 2097584, 2097616, 2097648 }, + + { 640, 679, 709, 739 }, + + { 33664, 33694, 33723, 33752 }, + + { 66683, 66710, 66738, 66765 }, + + { 66932, 66958, 66985, 67011 }, + + { 132719, 132743, 132768, 132793 }, + + { 132969, 132992, 133016, 133039 }, + + { 165988, 166010, 166032, 166054 }, + + { 199007, 199028, 199049, 199070 }, + + { 232026, 232046, 232066, 232086 }, + + { 265045, 265064, 265083, 265102 }, + + { 298065, 298083, 298101, 298119 }, + + { 298317, 298334, 298351, 298368 }, + + { 364105, 364121, 364137, 364154 }, + + { 364357, 364373, 364388, 364404 }, + + { 397378, 397392, 397407, 397422 }, + + { 430398, 430412, 430426, 430440 }, + + { 430651, 430664, 430678, 430691 }, + + { 496440, 496453, 496465, 496478 }, + + { 496693, 496705, 496717, 496729 }, + + { 529715, 529726, 529737, 529749 }, + + { 529968, 529979, 529989, 530000 }, + + { 595758, 595768, 595778, 595788 }, + + { 596011, 596021, 596031, 596040 }, + + { 629033, 629042, 629051, 629061 }, + + { 629287, 629296, 629304, 629313 }, + + { 695077, 695085, 695094, 695102 }, + + { 695331, 695339, 695347, 695355 }, + + { 728353, 728361, 728368, 728376 }, + + { 728608, 728615, 728622, 728629 }, + + { 761630, 761637, 761643, 761650 }, + + { 794653, 794659, 794665, 794672 }, + + { 794907, 794913, 794919, 794925 }, + + { 827930, 827935, 827941, 827947 }, + + { 860952, 860958, 860963, 860969 }, + + { 861207, 861212, 861217, 861223 }, + + { 894230, 894235, 894240, 894245 }, + + { 894485, 894490, 894494, 894499 }, + + { 927508, 927512, 927517, 927521 }, + + { 960531, 960535, 960539, 960543 }, + + { 960786, 960790, 960794, 960798 }, + + { 993809, 993813, 993817, 993820 }, + + { 994064, 994068, 994071, 994075 }, + + { 994319, 994323, 994326, 994329 }, + + { 1027342, 1027346, 1027349, 1027352 }, + + { 1060366, 1060369, 1060372, 1060375 }, + + { 1060621, 1060624, 1060627, 1060630 }, + + { 1093644, 1093647, 1093650, 1093653 }, + + { 1093900, 1093902, 1093905, 1093908 }, + + { 1094155, 1094158, 1094160, 1094163 }, + + { 1127179, 1127181, 1127183, 1127186 }, + + { 1127434, 1127436, 1127439, 1127441 }, + + { 1160458, 1160460, 1160462, 1160464 }, + + { 1160713, 1160715, 1160717, 1160719 }, + + { 1160969, 1160971, 1160972, 1160974 }, + + { 1193992, 1193994, 1193996, 1193998 }, + + { 1194248, 1194249, 1194251, 1194253 }, + + { 1194503, 1194505, 1194507, 1194508 }, + + { 1227527, 1227529, 1227530, 1227532 }, + + { 1227783, 1227784, 1227786, 1227787 }, + + { 1228038, 1228040, 1228041, 1228043 }, + + { 1261062, 1261063, 1261065, 1261066 }, + + { 1261062, 1261063, 1261064, 1261065 }, + + { 2080514, 2080514, 2080514, 2080514 }, + + { 16768, 16816, 16848, 16880 }, + + { 2114176, 2114215, 2114245, 2114275 }, + + { 2147200, 2147230, 2147259, 2147288 }, + + { 2180219, 2180246, 2180274, 2180301 }, + + { 2180468, 2180494, 2180521, 2180547 }, + + { 2246255, 2246279, 2246304, 2246329 }, + + { 2246505, 2246528, 2246552, 2246575 }, + + { 2279524, 2279546, 2279568, 2279590 }, + + { 2312543, 2312564, 2312585, 2312606 }, + + { 2345562, 2345582, 2345602, 2345622 }, + + { 2378581, 2378600, 2378619, 2378638 }, + + { 2411601, 2411619, 2411637, 2411655 }, + + { 2411853, 2411870, 2411887, 2411904 }, + + { 2477641, 2477657, 2477673, 2477690 }, + + { 2477893, 2477909, 2477924, 2477940 }, + + { 2510914, 2510928, 2510943, 2510958 }, + + { 2543934, 2543948, 2543962, 2543976 }, + + { 2544187, 2544200, 2544214, 2544227 }, + + { 2609976, 2609989, 2610001, 2610014 }, + + { 2610229, 2610241, 2610253, 2610265 }, + + { 2643251, 2643262, 2643273, 2643285 }, + + { 2643504, 2643515, 2643525, 2643536 }, + + { 2709294, 2709304, 2709314, 2709324 }, + + { 2709547, 2709557, 2709567, 2709576 }, + + { 2742569, 2742578, 2742587, 2742597 }, + + { 2742823, 2742832, 2742840, 2742849 }, + + { 2808613, 2808621, 2808630, 2808638 }, + + { 2808867, 2808875, 2808883, 2808891 }, + + { 2841889, 2841897, 2841904, 2841912 }, + + { 2842144, 2842151, 2842158, 2842165 }, + + { 2875166, 2875173, 2875179, 2875186 }, + + { 2908189, 2908195, 2908201, 2908208 }, + + { 2908443, 2908449, 2908455, 2908461 }, + + { 2941466, 2941471, 2941477, 2941483 }, + + { 2974488, 2974494, 2974499, 2974505 }, + + { 2974743, 2974748, 2974753, 2974759 }, + + { 3007766, 3007771, 3007776, 3007781 }, + + { 3008021, 3008026, 3008030, 3008035 }, + + { 3041044, 3041048, 3041053, 3041057 }, + + { 3074067, 3074071, 3074075, 3074079 }, + + { 3074322, 3074326, 3074330, 3074334 }, + + { 3107345, 3107349, 3107353, 3107356 }, + + { 3107600, 3107604, 3107607, 3107611 }, + + { 3107855, 3107859, 3107862, 3107865 }, + + { 3140878, 3140882, 3140885, 3140888 }, + + { 3173902, 3173905, 3173908, 3173911 }, + + { 3174157, 3174160, 3174163, 3174166 }, + + { 3207180, 3207183, 3207186, 3207189 }, + + { 3207436, 3207438, 3207441, 3207444 }, + + { 3207691, 3207694, 3207696, 3207699 }, + + { 3240715, 3240717, 3240719, 3240722 }, + + { 3240970, 3240972, 3240975, 3240977 }, + + { 3273994, 3273996, 3273998, 3274000 }, + + { 3274249, 3274251, 3274253, 3274255 }, + + { 3274505, 3274507, 3274508, 3274510 }, + + { 3307528, 3307530, 3307532, 3307534 }, + + { 3307784, 3307785, 3307787, 3307789 }, + + { 3308039, 3308041, 3308043, 3308044 }, + + { 3341063, 3341065, 3341066, 3341068 }, + + { 3341319, 3341320, 3341322, 3341323 }, + + { 3341574, 3341576, 3341577, 3341579 }, + + { 3374598, 3374599, 3374601, 3374602 }, + + { 3374598, 3374599, 3374600, 3374601 }, + + { 4194050, 4194050, 4194050, 4194050 }, + + }; + +/*****************************************************************************/ +/* Global Variable Initialization */ +/*****************************************************************************/ +const UWORD8 gau1_ih264d_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_CABAC_CTXTS] = + + { + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, 62, + 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, 20, 62, + 67, 90, 104, 126, 104, 67, 78, 65, 1, 86, 95, 2, + 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, 94, 9, 69, + 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, 0, 0, 83, + 86, 97, 72, 22, 1, 18, 78, 96, 126, 98, 101, 67, + 82, 94, 83, 110, 91, 102, 93, 126, 92, 89, 96, + 108, 17, 65, 6, 93, 74, 92, 87, 126, 9, 3, 4, 69, + 15, 68, 69, 88, 85, 78, 75, 77, 9, 13, 68, 13, 21, + 81, 0, 70, 67, 6, 76, 28, 64, 2, 28, 38, 39, 34, + 27, 93, 73, 73, 17, 14, 100, 10, 10, 10, 2, 7, 7, + 0, 3, 1, 6, 69, 6, 24, 12, 68, 64, 2, 0, 13, 24, + 19, 11, 15, 3, 4, 4, 30, 19, 20, 78, 3, 69, 35, + 23, 19, 14, 17, 19, 12, 16, 24, 1, 17, 9, 9, 5, 0, + 12, 6, 10, 11, 8, 18, 27, 10, 82, 8, 78, 17, 32, + 84, 56, 62, 60, 59, 62, 62, 57, 57, 54, 44, 36, + 33, 43, 29, 70, 67, 4, 67, 33, 31, 28, 34, 32, 25, + 20, 22, 0, 4, 64, 94, 89, 108, 76, 19, 18, 11, 64, + 4, 70, 75, 82, 102, 77, 39, 21, 15, 8, 4, 71, 83, + 87, 119, 5, 34, 27, 25, 20, 8, 5, 64, 74, 90, 70, + 34, 32, 21, 4, 5, 72, 81, 97, 5, 58, 49, 45, 36, + 23, 5, 70, 79, 85, 62, 106, 106, 87, 114, 110, 98, + 110, 106, 103, 107, 108, 112, 96, 95, 91, 93, 94, + 86, 67, 80, 85, 70, 3, 5, 2, 13, 13, 14, 9, 22, + 17, 12, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, + 64, 69, 4, 70, 19, 32, 20, 10, 29, 25, 11, 23, 31, + 19, 25, 13, 6, 20, 52, 49, 52, 52, 54, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 34, 62, 62, 62, 62, 62, + 62, 54, 37, 36, 6, 82, 75, 97, 125, 62, 62, 62, + 57, 55, 53, 41, 44, 31, 32, 22, 19, 16, 65, 71, 3, + 0, 65, 39, 43, 40, 31, 40, 39, 23, 31, 34, 21, 6, + 10, 2, 86, 23, 12, 4, 79, 71, 69, 70, 66, 68, 73, + 69, 70, 67, 1, 70, 66, 65, 0, 62, 62, 62, 62, 62, + 60, 54, 36, 4, 66, 28, 21, 18, 15, 7, 3, 1, 66, + 76, 85, 81, 77, 81, 80, 73, 74, 83, 71, 67, 2, 66, + 66, 4, 4, 62, 62, 62, 62, 61, 57, 46, 29, 1 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, 60, + 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, 65, + 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, 1, + 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, 5, 75, + 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, + 0, 0, 82, 86, 97, 71, 22, 1, 18, 77, 95, 124, + 96, 99, 65, 80, 92, 82, 108, 89, 100, 92, 125, + 91, 88, 95, 107, 18, 64, 7, 92, 73, 91, 86, 124, + 9, 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, + 13, 67, 13, 21, 80, 0, 69, 67, 6, 75, 28, 64, 2, + 28, 37, 39, 34, 27, 92, 72, 72, 17, 14, 99, 10, + 10, 10, 3, 7, 7, 1, 4, 2, 6, 68, 6, 24, 12, 68, + 64, 2, 0, 13, 23, 19, 11, 15, 4, 5, 4, 29, 19, + 20, 77, 3, 69, 35, 23, 19, 14, 17, 19, 12, 16, + 24, 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 18, 27, + 10, 81, 8, 77, 17, 31, 83, 55, 62, 59, 58, 61, + 62, 56, 56, 52, 43, 35, 32, 41, 28, 71, 67, 4, + 67, 32, 30, 27, 33, 31, 24, 19, 21, 0, 4, 64, + 93, 88, 107, 75, 20, 18, 11, 0, 5, 69, 74, 81, + 100, 76, 39, 21, 15, 8, 5, 70, 82, 86, 117, 5, + 35, 28, 25, 20, 9, 5, 64, 73, 89, 70, 35, 32, + 21, 4, 6, 71, 80, 96, 5, 58, 49, 45, 36, 23, 5, + 69, 78, 84, 62, 105, 105, 86, 112, 108, 97, 108, + 104, 101, 105, 106, 110, 95, 94, 90, 92, 92, 85, + 67, 79, 84, 69, 3, 5, 2, 13, 13, 13, 8, 22, 17, + 13, 14, 11, 22, 16, 8, 22, 19, 13, 10, 14, 0, + 64, 68, 5, 70, 19, 32, 20, 10, 29, 25, 12, 23, + 30, 19, 25, 13, 6, 19, 52, 49, 52, 51, 53, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 33, 62, 62, 62, + 62, 62, 62, 53, 36, 35, 6, 81, 74, 95, 122, 62, + 62, 62, 56, 53, 52, 40, 42, 30, 31, 21, 18, 15, + 66, 71, 3, 0, 66, 38, 42, 39, 30, 39, 38, 22, + 30, 33, 20, 5, 9, 1, 86, 23, 12, 4, 78, 70, 68, + 69, 65, 67, 71, 68, 69, 66, 3, 68, 65, 0, 2, 62, + 62, 62, 62, 62, 58, 51, 34, 2, 65, 29, 22, 19, + 16, 8, 4, 2, 65, 75, 84, 80, 76, 80, 78, 71, 73, + 82, 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 58, + 54, 43, 26, 64 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, 59, + 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, 66, + 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, 1, 85, + 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, 5, 75, 92, + 9, 69, 80, 88, 66, 73, 73, 79, 71, 5, 22, 0, 0, + 0, 81, 86, 97, 71, 21, 1, 18, 77, 95, 122, 94, + 97, 64, 78, 91, 81, 107, 88, 99, 91, 123, 91, + 88, 95, 106, 18, 64, 7, 91, 73, 90, 86, 123, 9, + 3, 4, 69, 16, 68, 68, 87, 84, 77, 74, 76, 9, 13, + 67, 13, 21, 80, 0, 69, 67, 6, 75, 27, 64, 2, 27, + 36, 38, 33, 26, 91, 72, 72, 16, 13, 99, 9, 10, + 10, 3, 7, 7, 2, 4, 2, 6, 68, 6, 23, 12, 69, 64, + 2, 64, 13, 22, 19, 11, 14, 4, 5, 4, 28, 19, 19, + 77, 3, 70, 34, 23, 19, 14, 17, 19, 12, 16, 24, + 1, 17, 9, 9, 5, 0, 12, 6, 10, 11, 8, 17, 26, 9, + 81, 8, 77, 16, 30, 83, 53, 62, 57, 56, 59, 60, + 54, 54, 50, 41, 33, 30, 39, 26, 72, 67, 4, 68, + 31, 29, 26, 32, 29, 23, 18, 20, 64, 3, 65, 93, + 88, 106, 75, 20, 18, 11, 0, 5, 69, 74, 81, 99, + 75, 39, 21, 15, 8, 5, 70, 81, 85, 115, 5, 35, + 28, 25, 20, 9, 5, 64, 73, 88, 70, 35, 32, 21, 4, + 6, 71, 80, 95, 5, 57, 48, 44, 35, 23, 5, 69, 78, + 84, 62, 104, 104, 85, 111, 107, 96, 107, 103, + 100, 104, 105, 108, 94, 93, 90, 91, 91, 85, 68, + 79, 83, 69, 3, 4, 2, 12, 12, 12, 7, 21, 17, 13, + 14, 10, 21, 16, 8, 21, 18, 13, 10, 13, 0, 64, + 68, 5, 70, 18, 31, 19, 10, 28, 24, 12, 22, 29, + 19, 25, 12, 5, 17, 51, 48, 51, 50, 52, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 32, 62, 62, 62, 62, + 62, 62, 51, 35, 34, 6, 80, 74, 94, 120, 60, 60, + 62, 54, 51, 50, 38, 40, 29, 29, 20, 16, 14, 67, + 72, 2, 0, 67, 37, 41, 37, 28, 37, 36, 21, 28, + 31, 19, 4, 8, 0, 87, 22, 11, 3, 78, 70, 68, 68, + 65, 66, 70, 67, 68, 65, 4, 67, 64, 1, 3, 62, 62, + 62, 62, 60, 55, 48, 31, 0, 65, 29, 22, 19, 16, + 9, 4, 2, 65, 75, 84, 80, 75, 80, 77, 70, 73, 81, + 69, 65, 3, 65, 64, 4, 4, 62, 62, 62, 60, 55, 50, + 39, 23, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, + 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, + 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, 84, + 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, 75, 92, + 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, 22, 0, 0, + 0, 81, 86, 97, 70, 20, 1, 18, 77, 95, 120, 92, + 96, 1, 76, 90, 80, 105, 87, 98, 90, 121, 90, 88, + 94, 105, 18, 64, 7, 91, 73, 90, 85, 121, 9, 2, + 3, 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 13, + 67, 13, 20, 80, 0, 69, 67, 6, 75, 26, 64, 2, 26, + 35, 37, 32, 25, 91, 71, 72, 15, 13, 98, 9, 10, + 10, 3, 7, 7, 3, 4, 2, 6, 67, 6, 22, 12, 70, 64, + 2, 64, 12, 21, 19, 11, 13, 4, 5, 4, 26, 19, 18, + 77, 3, 70, 33, 23, 19, 14, 17, 19, 12, 16, 24, + 1, 16, 9, 9, 5, 0, 11, 5, 9, 10, 7, 16, 25, 9, + 81, 7, 77, 15, 28, 83, 52, 62, 55, 54, 57, 58, + 52, 52, 48, 39, 32, 29, 37, 24, 73, 67, 4, 68, + 30, 28, 25, 30, 28, 21, 17, 19, 65, 3, 65, 93, + 88, 106, 74, 20, 18, 11, 0, 5, 69, 74, 80, 98, + 75, 39, 21, 15, 8, 6, 69, 80, 84, 113, 5, 35, + 28, 25, 20, 10, 5, 64, 73, 88, 70, 35, 32, 20, + 4, 6, 71, 80, 94, 5, 57, 48, 43, 34, 23, 5, 69, + 77, 83, 62, 103, 103, 85, 110, 106, 95, 105, + 102, 99, 103, 103, 107, 94, 92, 90, 91, 89, 85, + 68, 79, 83, 69, 2, 4, 2, 11, 11, 11, 6, 21, 16, + 13, 13, 10, 21, 15, 8, 20, 18, 12, 10, 12, 0, + 65, 68, 5, 71, 18, 31, 18, 10, 27, 24, 12, 21, + 28, 18, 24, 11, 5, 16, 50, 47, 51, 49, 51, 61, + 62, 62, 62, 62, 62, 62, 62, 62, 31, 62, 62, 62, + 62, 62, 62, 49, 34, 33, 6, 79, 74, 93, 118, 58, + 58, 62, 52, 49, 48, 37, 38, 27, 28, 19, 15, 12, + 68, 73, 2, 64, 68, 36, 39, 36, 26, 35, 34, 19, + 27, 29, 17, 3, 6, 65, 88, 21, 10, 2, 78, 69, 68, + 68, 64, 66, 69, 66, 67, 64, 5, 66, 0, 3, 4, 62, + 62, 62, 62, 58, 52, 45, 28, 65, 64, 30, 23, 20, + 16, 10, 5, 2, 64, 74, 84, 79, 75, 79, 76, 69, + 73, 81, 69, 65, 3, 64, 0, 4, 4, 62, 62, 62, 57, + 52, 46, 35, 19, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, + 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, 18, + 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, 84, 90, + 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, 75, 91, 8, + 70, 80, 88, 65, 72, 73, 78, 70, 5, 22, 0, 0, 0, + 80, 87, 97, 70, 19, 1, 18, 77, 95, 119, 91, 94, + 2, 75, 89, 79, 104, 85, 97, 89, 119, 90, 87, 94, + 104, 18, 64, 7, 90, 73, 89, 85, 120, 8, 2, 3, + 70, 16, 68, 68, 86, 84, 76, 74, 75, 9, 12, 67, + 13, 20, 80, 0, 69, 67, 6, 75, 26, 65, 2, 26, 34, + 36, 31, 24, 90, 71, 72, 14, 12, 98, 8, 10, 9, 3, + 7, 7, 4, 5, 2, 5, 67, 5, 21, 11, 71, 64, 2, 65, + 12, 20, 18, 10, 13, 5, 5, 4, 25, 18, 17, 77, 3, + 71, 33, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, + 9, 9, 5, 64, 11, 5, 9, 10, 7, 16, 24, 8, 81, 7, + 77, 14, 27, 83, 50, 62, 53, 52, 55, 56, 50, 50, + 46, 37, 30, 27, 34, 22, 74, 67, 3, 69, 29, 27, + 24, 29, 26, 20, 16, 17, 65, 2, 66, 93, 88, 105, + 74, 20, 18, 11, 0, 5, 69, 74, 80, 97, 74, 39, + 21, 15, 8, 6, 69, 80, 84, 111, 5, 35, 28, 25, + 20, 10, 5, 64, 73, 87, 70, 35, 31, 20, 4, 6, 71, + 80, 94, 5, 56, 47, 42, 33, 23, 5, 69, 77, 83, + 62, 102, 102, 84, 108, 105, 94, 104, 100, 98, + 101, 102, 105, 93, 92, 89, 90, 88, 84, 69, 79, + 82, 69, 2, 3, 1, 10, 10, 10, 5, 20, 16, 13, 13, + 9, 20, 15, 8, 19, 17, 12, 9, 11, 64, 65, 68, 5, + 71, 17, 30, 17, 10, 26, 23, 12, 20, 27, 18, 24, + 10, 4, 14, 49, 47, 50, 48, 49, 60, 62, 62, 62, + 62, 62, 62, 62, 62, 29, 62, 62, 62, 62, 62, 62, + 47, 33, 31, 6, 78, 73, 92, 116, 57, 56, 60, 51, + 47, 46, 35, 36, 26, 26, 17, 13, 11, 69, 74, 1, + 64, 69, 34, 38, 34, 25, 33, 32, 18, 25, 27, 16, + 2, 5, 66, 88, 20, 10, 1, 78, 69, 67, 67, 64, 65, + 68, 66, 66, 0, 6, 65, 1, 4, 5, 62, 62, 62, 61, + 55, 49, 42, 25, 68, 64, 30, 23, 20, 17, 10, 5, + 3, 64, 74, 83, 79, 74, 79, 75, 68, 73, 80, 68, + 64, 3, 64, 1, 4, 4, 62, 62, 61, 54, 49, 42, 31, + 16, 72 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, + 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, 18, + 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, 84, 89, + 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, 75, 90, 8, + 70, 80, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, + 80, 87, 97, 69, 18, 1, 18, 76, 95, 117, 89, 93, + 4, 73, 87, 78, 103, 84, 96, 88, 117, 89, 87, 93, + 103, 18, 64, 7, 90, 73, 89, 84, 118, 8, 2, 3, + 70, 16, 68, 67, 85, 84, 76, 74, 74, 9, 12, 67, + 13, 20, 79, 0, 68, 67, 6, 75, 25, 65, 2, 25, 33, + 36, 30, 23, 89, 70, 72, 13, 12, 97, 8, 10, 9, 3, + 7, 7, 5, 5, 2, 5, 67, 5, 20, 11, 72, 64, 2, 65, + 11, 19, 18, 10, 12, 5, 5, 4, 24, 18, 16, 77, 3, + 71, 32, 23, 19, 14, 17, 19, 12, 16, 23, 1, 16, + 9, 9, 5, 64, 11, 5, 8, 10, 7, 15, 23, 8, 81, 6, + 77, 13, 26, 83, 49, 61, 52, 51, 53, 54, 48, 48, + 44, 35, 28, 25, 32, 21, 75, 67, 3, 69, 28, 26, + 23, 28, 25, 18, 15, 16, 66, 2, 66, 93, 88, 105, + 74, 20, 18, 11, 0, 5, 68, 73, 79, 96, 74, 39, + 21, 15, 8, 6, 68, 79, 83, 109, 5, 35, 28, 25, + 20, 10, 5, 64, 73, 86, 70, 36, 31, 19, 4, 6, 71, + 80, 93, 5, 56, 46, 41, 32, 23, 5, 69, 77, 82, + 62, 101, 101, 83, 107, 104, 93, 103, 99, 97, + 100, 100, 103, 92, 91, 89, 90, 87, 84, 69, 78, + 81, 69, 1, 3, 1, 10, 9, 9, 4, 19, 15, 13, 12, 9, + 20, 15, 8, 18, 16, 12, 9, 10, 64, 65, 68, 5, 71, + 16, 30, 17, 10, 25, 22, 12, 19, 26, 17, 23, 9, + 3, 12, 48, 46, 50, 47, 48, 58, 62, 62, 62, 62, + 62, 62, 62, 62, 28, 62, 62, 62, 62, 62, 61, 45, + 32, 30, 6, 77, 73, 91, 114, 55, 55, 58, 49, 45, + 44, 34, 34, 25, 24, 16, 11, 9, 70, 75, 1, 64, + 70, 33, 36, 32, 23, 32, 31, 16, 24, 26, 14, 1, + 4, 67, 89, 20, 9, 0, 77, 68, 67, 67, 0, 64, 67, + 65, 65, 1, 8, 64, 2, 5, 7, 62, 62, 62, 58, 53, + 46, 39, 22, 70, 64, 31, 24, 21, 17, 11, 5, 3, 0, + 73, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, + 0, 2, 4, 4, 62, 62, 58, 51, 46, 39, 27, 12, 75 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, + 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, 17, + 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, 83, 88, + 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, 74, 90, 8, + 70, 79, 88, 64, 72, 72, 78, 69, 5, 22, 0, 0, 0, + 79, 87, 97, 69, 18, 0, 18, 76, 94, 115, 87, 91, + 5, 71, 86, 77, 101, 83, 95, 88, 116, 89, 87, 93, + 103, 19, 64, 7, 89, 72, 88, 84, 117, 8, 1, 2, + 71, 16, 68, 67, 85, 84, 75, 74, 74, 9, 12, 66, + 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 32, + 35, 30, 23, 89, 70, 72, 13, 11, 97, 7, 10, 9, 3, + 7, 7, 5, 5, 2, 5, 66, 5, 19, 11, 72, 65, 2, 66, + 11, 18, 18, 10, 11, 5, 5, 4, 22, 18, 15, 77, 3, + 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, + 9, 8, 5, 64, 10, 4, 8, 9, 6, 14, 22, 7, 81, 6, + 76, 12, 24, 83, 47, 59, 50, 49, 51, 52, 46, 46, + 42, 33, 27, 24, 30, 19, 76, 67, 3, 70, 27, 25, + 22, 26, 23, 17, 14, 15, 67, 1, 67, 93, 88, 104, + 73, 20, 18, 11, 1, 5, 68, 73, 79, 95, 73, 38, + 21, 15, 8, 7, 68, 78, 82, 107, 5, 36, 28, 25, + 20, 11, 5, 64, 72, 86, 70, 36, 31, 19, 4, 6, 70, + 79, 92, 5, 55, 46, 40, 32, 23, 5, 68, 76, 82, + 62, 101, 100, 83, 106, 103, 92, 101, 98, 96, 99, + 99, 102, 92, 90, 89, 89, 85, 84, 70, 78, 81, 69, + 1, 2, 1, 9, 8, 8, 3, 19, 15, 13, 12, 8, 19, 14, + 8, 18, 16, 11, 9, 10, 64, 66, 68, 5, 72, 16, 29, + 16, 9, 24, 22, 13, 19, 25, 17, 23, 9, 3, 11, 47, + 45, 49, 46, 47, 57, 62, 62, 62, 62, 62, 62, 62, + 61, 27, 62, 62, 62, 62, 62, 59, 43, 31, 29, 6, + 76, 73, 89, 111, 53, 53, 56, 47, 43, 42, 32, 32, + 23, 23, 15, 10, 8, 71, 76, 0, 65, 71, 32, 35, + 31, 21, 30, 29, 15, 22, 24, 13, 64, 2, 69, 90, + 19, 8, 64, 77, 68, 67, 66, 0, 64, 65, 64, 64, 2, + 9, 1, 3, 7, 8, 62, 62, 60, 56, 50, 44, 36, 20, + 72, 0, 31, 24, 21, 17, 12, 6, 3, 0, 73, 83, 78, + 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, 3, 4, 4, + 62, 62, 56, 48, 42, 35, 24, 9, 77 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, + 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, 17, + 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, 83, 87, + 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, 74, 89, 7, + 70, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, + 79, 87, 97, 68, 17, 0, 18, 76, 94, 114, 85, 90, + 7, 69, 85, 76, 100, 81, 94, 87, 114, 88, 86, 92, + 102, 19, 64, 7, 89, 72, 88, 83, 115, 7, 1, 2, + 71, 16, 68, 67, 84, 84, 75, 74, 73, 9, 11, 66, + 13, 19, 79, 0, 68, 67, 6, 75, 24, 65, 2, 24, 31, + 34, 29, 22, 88, 69, 72, 12, 11, 96, 7, 10, 8, 3, + 7, 7, 6, 6, 2, 5, 66, 5, 18, 11, 73, 65, 2, 66, + 10, 17, 17, 10, 11, 6, 5, 4, 21, 17, 14, 77, 3, + 72, 31, 23, 18, 14, 17, 19, 12, 16, 23, 1, 15, + 9, 8, 5, 64, 10, 4, 7, 9, 6, 14, 21, 7, 81, 5, + 76, 11, 23, 83, 46, 57, 48, 47, 49, 50, 44, 44, + 40, 31, 25, 22, 27, 17, 77, 67, 2, 70, 26, 24, + 21, 25, 22, 15, 13, 14, 67, 1, 67, 93, 88, 104, + 73, 20, 18, 11, 1, 5, 68, 73, 78, 94, 73, 38, + 21, 15, 8, 7, 67, 77, 82, 105, 5, 36, 28, 25, + 20, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, + 79, 92, 5, 55, 45, 39, 31, 23, 5, 68, 76, 81, + 62, 100, 99, 82, 104, 102, 91, 100, 96, 95, 97, + 97, 100, 91, 89, 88, 89, 84, 83, 70, 78, 80, 69, + 0, 2, 0, 8, 7, 7, 2, 18, 14, 13, 11, 8, 19, 14, + 8, 17, 15, 11, 8, 9, 64, 66, 68, 5, 72, 15, 29, + 15, 9, 23, 21, 13, 18, 24, 16, 22, 8, 2, 9, 46, + 45, 49, 45, 45, 55, 62, 62, 62, 62, 62, 62, 62, + 59, 25, 62, 62, 62, 62, 62, 56, 41, 30, 28, 6, + 75, 72, 88, 109, 52, 51, 54, 46, 41, 40, 31, 30, + 22, 21, 13, 8, 6, 72, 77, 0, 65, 72, 30, 33, 29, + 20, 28, 27, 13, 21, 22, 11, 65, 1, 70, 90, 18, + 8, 65, 77, 67, 66, 66, 1, 0, 64, 0, 0, 3, 10, 2, + 4, 8, 9, 62, 61, 58, 53, 48, 41, 33, 17, 74, 0, + 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, 77, + 72, 65, 72, 78, 67, 0, 3, 1, 4, 4, 4, 62, 62, + 53, 45, 39, 31, 20, 5, 80 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, + 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, + 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, 86, + 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, 89, 7, + 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, 0, 0, 0, + 78, 88, 97, 68, 16, 0, 18, 76, 94, 112, 84, 88, + 8, 68, 84, 75, 99, 80, 93, 86, 112, 88, 86, 92, + 101, 19, 64, 7, 88, 72, 87, 83, 114, 7, 0, 1, + 72, 16, 68, 67, 84, 84, 75, 74, 73, 8, 11, 66, + 13, 18, 79, 0, 68, 67, 5, 75, 23, 66, 2, 23, 29, + 33, 28, 21, 88, 69, 72, 11, 10, 96, 6, 9, 8, 3, + 7, 7, 7, 6, 2, 4, 66, 4, 17, 10, 74, 65, 2, 67, + 10, 16, 17, 9, 10, 6, 5, 4, 19, 17, 13, 77, 3, + 73, 30, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, + 9, 8, 4, 65, 9, 3, 7, 8, 5, 13, 20, 6, 81, 5, + 76, 10, 21, 83, 44, 55, 46, 45, 47, 47, 42, 42, + 38, 29, 23, 20, 25, 15, 78, 67, 2, 71, 25, 22, + 19, 23, 20, 14, 11, 12, 68, 0, 68, 93, 88, 103, + 73, 20, 18, 11, 1, 5, 68, 73, 78, 93, 72, 38, + 21, 15, 8, 7, 67, 77, 81, 104, 5, 36, 28, 25, + 19, 11, 5, 64, 72, 85, 70, 36, 30, 18, 4, 6, 70, + 79, 91, 5, 54, 44, 38, 30, 22, 5, 68, 76, 81, + 62, 99, 98, 82, 103, 101, 91, 99, 95, 94, 96, + 96, 99, 91, 89, 88, 88, 83, 83, 71, 78, 80, 69, + 0, 1, 0, 7, 6, 5, 1, 17, 14, 13, 11, 7, 18, 13, + 7, 16, 14, 10, 8, 8, 65, 67, 68, 5, 73, 14, 28, + 14, 9, 22, 20, 13, 17, 23, 16, 22, 7, 1, 7, 45, + 44, 48, 43, 44, 54, 62, 62, 62, 62, 62, 62, 62, + 56, 24, 62, 62, 62, 62, 61, 54, 39, 28, 26, 6, + 75, 72, 87, 107, 50, 49, 52, 44, 38, 38, 29, 28, + 20, 19, 12, 6, 5, 73, 78, 64, 66, 73, 29, 32, + 27, 18, 26, 25, 12, 19, 20, 10, 66, 64, 72, 91, + 17, 7, 66, 77, 67, 66, 65, 1, 0, 0, 0, 1, 4, 11, + 3, 5, 9, 10, 61, 59, 56, 51, 45, 38, 30, 14, 77, + 0, 32, 25, 22, 18, 13, 6, 4, 1, 72, 82, 78, 72, + 77, 71, 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, + 61, 51, 42, 36, 27, 16, 2, 83 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, + 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, + 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, 85, + 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, 88, 7, + 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, 0, 0, 0, + 77, 88, 97, 68, 15, 0, 18, 75, 94, 110, 82, 86, + 9, 66, 82, 74, 97, 79, 91, 85, 110, 88, 86, 92, + 100, 19, 64, 7, 87, 72, 86, 82, 113, 7, 0, 1, + 72, 16, 68, 66, 83, 83, 74, 74, 73, 8, 11, 66, + 13, 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 28, + 33, 27, 20, 87, 69, 71, 10, 9, 96, 5, 9, 8, 4, + 7, 7, 8, 6, 2, 4, 65, 4, 17, 10, 75, 65, 2, 68, + 10, 15, 17, 9, 9, 6, 5, 4, 18, 17, 13, 77, 3, + 74, 29, 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, + 9, 8, 4, 65, 9, 3, 7, 8, 5, 12, 20, 6, 81, 5, + 76, 9, 20, 83, 42, 54, 45, 44, 45, 45, 41, 41, + 36, 27, 22, 19, 23, 14, 79, 67, 2, 72, 24, 21, + 18, 22, 19, 13, 10, 11, 69, 64, 69, 93, 87, 102, + 72, 21, 18, 11, 1, 6, 67, 72, 77, 92, 71, 38, + 21, 15, 8, 8, 67, 76, 80, 102, 5, 36, 28, 25, + 19, 12, 5, 64, 72, 84, 70, 37, 30, 18, 4, 7, 70, + 79, 90, 5, 54, 44, 38, 29, 22, 5, 68, 75, 80, + 62, 98, 97, 81, 102, 99, 90, 97, 94, 92, 95, 95, + 97, 90, 88, 88, 87, 81, 83, 72, 77, 79, 69, 0, + 0, 0, 7, 5, 4, 0, 17, 14, 13, 11, 7, 17, 13, 7, + 15, 14, 10, 8, 7, 65, 67, 67, 6, 73, 14, 27, 14, + 9, 22, 20, 13, 16, 22, 16, 22, 6, 1, 6, 45, 43, + 47, 42, 43, 53, 60, 60, 62, 62, 62, 62, 62, 54, + 23, 62, 62, 62, 62, 58, 52, 38, 27, 25, 6, 74, + 72, 86, 105, 48, 48, 50, 42, 36, 37, 28, 26, 19, + 18, 11, 5, 4, 74, 78, 64, 66, 74, 28, 31, 26, + 16, 25, 24, 11, 18, 19, 9, 67, 65, 73, 92, 17, + 6, 66, 76, 67, 66, 64, 2, 1, 1, 1, 2, 5, 13, 4, + 6, 11, 12, 60, 58, 54, 49, 42, 35, 27, 11, 79, + 1, 32, 25, 23, 18, 14, 7, 4, 2, 71, 82, 77, 71, + 77, 70, 1, 71, 77, 65, 2, 3, 2, 5, 4, 3, 62, 59, + 49, 40, 33, 24, 12, 64, 85 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, + 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, + 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, 84, + 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, 87, 6, + 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, + 77, 88, 97, 67, 14, 0, 18, 75, 94, 109, 80, 85, + 11, 64, 81, 73, 96, 77, 90, 84, 108, 87, 85, 91, + 99, 19, 64, 7, 87, 72, 86, 82, 111, 6, 0, 1, 72, + 16, 68, 66, 83, 83, 74, 74, 72, 8, 10, 66, 13, + 18, 78, 0, 67, 67, 5, 74, 22, 66, 2, 22, 27, 32, + 26, 19, 86, 68, 71, 9, 9, 95, 5, 9, 7, 4, 7, 7, + 9, 7, 2, 4, 65, 4, 16, 10, 76, 65, 2, 68, 9, 14, + 16, 9, 9, 7, 5, 4, 17, 16, 12, 77, 3, 74, 29, + 22, 18, 14, 17, 18, 11, 16, 22, 0, 14, 9, 8, 4, + 65, 9, 3, 6, 8, 5, 12, 19, 5, 81, 4, 76, 8, 19, + 83, 41, 52, 43, 42, 43, 43, 39, 39, 34, 25, 20, + 17, 20, 12, 80, 67, 1, 72, 23, 20, 17, 21, 17, + 11, 9, 10, 69, 64, 69, 93, 87, 102, 72, 21, 18, + 11, 1, 6, 67, 72, 77, 91, 71, 38, 21, 15, 8, 8, + 66, 75, 80, 100, 5, 36, 28, 25, 19, 12, 5, 64, + 72, 83, 70, 37, 29, 17, 4, 7, 70, 79, 90, 5, 53, + 43, 37, 28, 22, 5, 68, 75, 80, 62, 97, 96, 80, + 100, 98, 89, 96, 92, 91, 93, 93, 95, 89, 87, 87, + 87, 80, 82, 72, 77, 78, 69, 64, 0, 64, 6, 4, 3, + 64, 16, 13, 13, 10, 6, 17, 13, 7, 14, 13, 10, 7, + 6, 65, 67, 67, 6, 73, 13, 27, 13, 9, 21, 19, 13, + 15, 21, 15, 21, 5, 0, 4, 44, 43, 47, 41, 41, 51, + 58, 58, 62, 62, 62, 62, 62, 52, 21, 59, 62, 59, + 62, 56, 49, 36, 26, 24, 6, 73, 71, 85, 103, 47, + 46, 48, 41, 34, 35, 26, 24, 18, 16, 9, 3, 2, 75, + 79, 65, 66, 75, 26, 29, 24, 15, 23, 22, 9, 16, + 17, 7, 68, 66, 74, 92, 16, 6, 67, 76, 66, 65, + 64, 2, 2, 2, 2, 3, 6, 14, 5, 7, 12, 13, 60, 56, + 52, 46, 40, 32, 24, 8, 81, 1, 33, 26, 23, 19, + 15, 7, 5, 2, 71, 81, 77, 70, 76, 69, 2, 71, 76, + 65, 2, 3, 2, 6, 4, 3, 62, 57, 46, 37, 30, 20, 8, + 68, 88 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, + 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, + 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, 83, + 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, 87, 6, + 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, 0, 0, 0, + 76, 88, 97, 67, 14, 64, 18, 75, 93, 107, 78, 83, + 12, 1, 80, 72, 94, 76, 89, 84, 107, 87, 85, 91, + 99, 20, 64, 7, 86, 71, 85, 81, 110, 6, 64, 0, + 73, 16, 68, 66, 82, 83, 73, 74, 72, 8, 10, 65, + 13, 17, 78, 0, 67, 67, 5, 74, 21, 66, 2, 21, 26, + 31, 26, 19, 86, 68, 71, 9, 8, 95, 4, 9, 7, 4, 7, + 7, 9, 7, 2, 4, 64, 4, 15, 10, 76, 66, 2, 69, 9, + 13, 16, 9, 8, 7, 5, 4, 15, 16, 11, 77, 3, 75, + 28, 22, 17, 14, 17, 18, 11, 16, 22, 0, 13, 9, 7, + 4, 65, 8, 2, 6, 7, 4, 11, 18, 5, 81, 4, 75, 7, + 17, 83, 39, 50, 41, 40, 41, 41, 37, 37, 32, 23, + 19, 16, 18, 10, 81, 67, 1, 73, 22, 19, 16, 19, + 16, 10, 8, 9, 70, 65, 70, 93, 87, 101, 71, 21, + 18, 11, 2, 6, 67, 72, 76, 90, 70, 37, 21, 15, 8, + 9, 66, 74, 79, 98, 5, 37, 28, 25, 19, 13, 5, 64, + 71, 83, 70, 37, 29, 17, 4, 7, 69, 78, 89, 5, 53, + 43, 36, 28, 22, 5, 67, 74, 79, 62, 97, 95, 80, + 99, 97, 88, 94, 91, 90, 92, 92, 94, 89, 86, 87, + 86, 78, 82, 73, 77, 78, 69, 64, 64, 64, 5, 3, 2, + 65, 16, 13, 13, 10, 6, 16, 12, 7, 14, 13, 9, 7, + 6, 65, 68, 67, 6, 74, 13, 26, 12, 8, 20, 19, 14, + 15, 20, 15, 21, 5, 0, 3, 43, 42, 46, 40, 40, 50, + 56, 56, 61, 60, 62, 62, 60, 49, 20, 57, 62, 56, + 62, 53, 47, 34, 25, 23, 6, 72, 71, 83, 100, 45, + 44, 46, 39, 32, 33, 25, 22, 16, 15, 8, 2, 1, 76, + 80, 65, 67, 76, 25, 28, 23, 13, 21, 20, 8, 15, + 15, 6, 70, 68, 76, 93, 15, 5, 68, 76, 66, 65, 0, + 3, 2, 4, 3, 4, 7, 15, 7, 8, 14, 14, 59, 55, 50, + 44, 37, 30, 21, 6, 83, 2, 33, 26, 24, 19, 16, 8, + 5, 3, 70, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, + 3, 3, 7, 4, 3, 62, 55, 44, 34, 26, 16, 5, 71, 90 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, + 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, + 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, 82, + 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, 86, 6, + 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, 0, 0, 0, + 76, 89, 97, 66, 13, 64, 18, 75, 93, 105, 77, 82, + 14, 2, 79, 71, 93, 75, 88, 83, 105, 86, 85, 90, + 98, 20, 64, 7, 86, 71, 85, 81, 108, 6, 64, 0, + 73, 16, 68, 66, 82, 83, 73, 74, 71, 8, 10, 65, + 13, 17, 78, 0, 67, 67, 5, 74, 20, 67, 2, 20, 25, + 30, 25, 18, 85, 67, 71, 8, 8, 94, 4, 9, 7, 4, 7, + 7, 10, 7, 2, 3, 64, 3, 14, 9, 77, 66, 2, 69, 8, + 12, 16, 8, 7, 7, 5, 4, 14, 16, 10, 77, 3, 75, + 27, 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, + 4, 66, 8, 2, 5, 7, 4, 10, 17, 4, 81, 3, 75, 6, + 16, 83, 38, 48, 39, 38, 39, 39, 35, 35, 30, 21, + 17, 14, 16, 8, 82, 67, 1, 73, 21, 18, 15, 18, + 14, 8, 7, 7, 71, 65, 70, 93, 87, 101, 71, 21, + 18, 11, 2, 6, 67, 72, 76, 89, 70, 37, 21, 15, 8, + 9, 65, 74, 78, 96, 5, 37, 28, 25, 19, 13, 5, 64, + 71, 82, 70, 37, 29, 16, 4, 7, 69, 78, 88, 5, 52, + 42, 35, 27, 22, 5, 67, 74, 79, 62, 96, 94, 79, + 98, 96, 87, 93, 90, 89, 91, 90, 92, 88, 86, 87, + 86, 77, 82, 73, 77, 77, 69, 65, 64, 64, 4, 2, 1, + 66, 15, 12, 13, 9, 5, 16, 12, 7, 13, 12, 9, 7, + 5, 66, 68, 67, 6, 74, 12, 26, 11, 8, 19, 18, 14, + 14, 19, 14, 20, 4, 64, 1, 42, 41, 46, 39, 39, + 48, 54, 54, 59, 57, 62, 62, 57, 47, 19, 54, 62, + 53, 58, 50, 44, 32, 24, 21, 6, 71, 71, 82, 98, + 43, 42, 44, 37, 30, 31, 23, 20, 15, 13, 7, 0, + 64, 77, 81, 66, 67, 77, 24, 26, 21, 11, 19, 18, + 6, 13, 13, 4, 71, 69, 77, 94, 14, 4, 69, 76, 65, + 65, 0, 3, 3, 5, 3, 5, 8, 16, 8, 9, 15, 15, 59, + 53, 48, 41, 35, 27, 18, 3, 86, 2, 34, 27, 24, + 19, 16, 8, 5, 3, 70, 81, 76, 69, 75, 67, 4, 71, + 75, 64, 3, 3, 3, 8, 4, 3, 61, 53, 41, 31, 23, + 12, 1, 75, 93 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, + 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, + 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, 81, + 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, 85, 5, + 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, 0, 0, 0, + 75, 89, 97, 66, 12, 64, 18, 74, 93, 104, 75, 80, + 15, 4, 77, 70, 92, 73, 87, 82, 103, 86, 84, 90, + 97, 20, 64, 7, 85, 71, 84, 80, 107, 5, 64, 0, + 73, 16, 68, 65, 81, 83, 73, 74, 71, 8, 9, 65, + 13, 17, 77, 0, 66, 67, 5, 74, 20, 67, 2, 20, 24, + 30, 24, 17, 84, 67, 71, 7, 7, 94, 3, 9, 6, 4, 7, + 7, 11, 8, 2, 3, 64, 3, 13, 9, 78, 66, 2, 70, 8, + 11, 15, 8, 7, 8, 5, 4, 13, 15, 9, 77, 3, 76, 27, + 22, 17, 14, 17, 18, 11, 16, 21, 0, 13, 9, 7, 4, + 66, 8, 2, 5, 7, 4, 10, 16, 4, 81, 3, 75, 5, 15, + 83, 36, 46, 38, 37, 37, 37, 33, 33, 28, 19, 15, + 12, 13, 7, 83, 67, 0, 74, 20, 17, 14, 17, 13, 7, + 6, 6, 71, 66, 71, 93, 87, 100, 71, 21, 18, 11, + 2, 6, 66, 71, 75, 88, 69, 37, 21, 15, 8, 9, 65, + 73, 78, 94, 5, 37, 28, 25, 19, 13, 5, 64, 71, + 81, 70, 38, 28, 16, 4, 7, 69, 78, 88, 5, 52, 41, + 34, 26, 22, 5, 67, 74, 78, 62, 95, 93, 78, 96, + 95, 86, 92, 88, 88, 89, 89, 90, 87, 85, 86, 85, + 76, 81, 74, 76, 76, 69, 65, 65, 65, 4, 1, 0, 67, + 14, 12, 13, 9, 5, 15, 12, 7, 12, 11, 9, 6, 4, + 66, 68, 67, 6, 74, 11, 25, 11, 8, 18, 17, 14, + 13, 18, 14, 20, 3, 65, 64, 41, 41, 45, 38, 37, + 47, 52, 52, 57, 55, 62, 61, 54, 45, 17, 51, 62, + 50, 54, 48, 42, 30, 23, 20, 6, 70, 70, 81, 96, + 42, 41, 42, 36, 28, 29, 22, 18, 14, 11, 5, 65, + 65, 78, 82, 66, 67, 78, 22, 25, 19, 10, 18, 17, + 5, 12, 12, 3, 72, 70, 78, 94, 14, 4, 70, 75, 65, + 64, 1, 4, 4, 6, 4, 6, 9, 18, 9, 10, 16, 17, 58, + 51, 46, 39, 32, 24, 15, 0, 88, 2, 34, 27, 25, + 20, 17, 8, 6, 4, 69, 80, 76, 68, 75, 66, 5, 70, + 74, 0, 4, 3, 4, 9, 4, 3, 59, 51, 39, 28, 20, 9, + 66, 78, 96 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, + 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, 13, + 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, 80, 80, + 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, 73, 85, 5, + 72, 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, + 75, 89, 97, 65, 11, 64, 18, 74, 93, 102, 73, 79, + 17, 6, 76, 69, 90, 72, 86, 81, 101, 85, 84, 89, + 96, 20, 64, 7, 85, 71, 84, 80, 105, 5, 65, 64, + 74, 16, 68, 65, 81, 83, 72, 74, 70, 8, 9, 65, + 13, 16, 77, 0, 66, 67, 5, 74, 19, 67, 2, 19, 23, + 29, 23, 16, 84, 66, 71, 6, 7, 93, 3, 9, 6, 4, 7, + 7, 12, 8, 2, 3, 0, 3, 12, 9, 79, 66, 2, 70, 7, + 10, 15, 8, 6, 8, 5, 4, 11, 15, 8, 77, 3, 76, 26, + 22, 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, + 66, 7, 1, 4, 6, 3, 9, 15, 3, 81, 2, 75, 4, 13, + 83, 35, 44, 36, 35, 35, 35, 31, 31, 26, 17, 14, + 11, 11, 5, 84, 67, 0, 74, 19, 16, 13, 15, 11, 5, + 5, 5, 72, 66, 71, 93, 87, 100, 70, 21, 18, 11, + 2, 6, 66, 71, 75, 87, 69, 37, 21, 15, 8, 10, 64, + 72, 77, 92, 5, 37, 28, 25, 19, 14, 5, 64, 71, + 81, 70, 38, 28, 15, 4, 7, 69, 78, 87, 5, 51, 41, + 33, 25, 22, 5, 67, 73, 78, 62, 94, 92, 78, 95, + 94, 85, 90, 87, 87, 88, 87, 89, 87, 84, 86, 85, + 74, 81, 74, 76, 76, 69, 66, 65, 65, 3, 0, 64, + 68, 14, 11, 13, 8, 4, 15, 11, 7, 11, 11, 8, 6, + 3, 66, 69, 67, 6, 75, 11, 25, 10, 8, 17, 17, 14, + 12, 17, 13, 19, 2, 65, 65, 40, 40, 45, 37, 36, + 45, 50, 50, 55, 52, 60, 59, 51, 42, 16, 48, 62, + 47, 50, 45, 39, 28, 22, 19, 6, 69, 70, 80, 94, + 40, 39, 40, 34, 26, 27, 20, 16, 12, 10, 4, 66, + 67, 79, 83, 67, 68, 79, 21, 23, 18, 8, 16, 15, + 3, 10, 10, 1, 73, 72, 80, 95, 13, 3, 71, 75, 64, + 64, 1, 4, 4, 7, 5, 7, 10, 19, 10, 11, 18, 18, + 58, 50, 44, 36, 30, 21, 12, 66, 90, 3, 35, 28, + 25, 20, 18, 9, 6, 4, 69, 80, 75, 68, 74, 65, 6, + 70, 74, 0, 4, 3, 4, 10, 4, 3, 58, 49, 36, 25, + 17, 5, 70, 82, 98 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, 44, + 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, 12, 36, + 91, 105, 112, 83, 85, 67, 65, 9, 1, 80, 79, 8, + 10, 66, 75, 85, 3, 73, 81, 89, 5, 73, 84, 5, 72, + 78, 88, 3, 69, 70, 75, 65, 5, 22, 0, 0, 0, 74, + 89, 97, 65, 10, 64, 18, 74, 93, 100, 71, 77, 18, + 8, 75, 68, 89, 71, 85, 80, 99, 85, 84, 89, 95, + 20, 64, 7, 84, 71, 83, 79, 104, 5, 65, 64, 74, + 16, 68, 65, 80, 83, 72, 74, 70, 8, 9, 65, 13, + 16, 77, 0, 66, 67, 5, 74, 18, 67, 2, 18, 22, 28, + 22, 15, 83, 66, 71, 5, 6, 93, 2, 9, 6, 4, 7, 7, + 13, 8, 2, 3, 0, 3, 11, 9, 80, 66, 2, 71, 7, 9, + 15, 8, 5, 8, 5, 4, 10, 15, 7, 77, 3, 77, 25, 22, + 17, 14, 17, 18, 11, 16, 21, 0, 12, 9, 7, 4, 66, + 7, 1, 4, 6, 3, 8, 14, 3, 81, 2, 75, 3, 12, 83, + 33, 42, 34, 33, 33, 33, 29, 29, 24, 15, 12, 9, + 9, 3, 85, 67, 0, 75, 18, 15, 12, 14, 10, 4, 4, + 4, 73, 67, 72, 93, 87, 99, 70, 21, 18, 11, 2, 6, + 66, 71, 74, 86, 68, 37, 21, 15, 8, 10, 64, 71, + 76, 90, 5, 37, 28, 25, 19, 14, 5, 64, 71, 80, + 70, 38, 28, 15, 4, 7, 69, 78, 86, 5, 51, 40, 32, + 24, 22, 5, 67, 73, 77, 62, 93, 91, 77, 94, 93, + 84, 89, 86, 86, 87, 86, 87, 86, 83, 86, 84, 73, + 81, 75, 76, 75, 69, 66, 66, 65, 2, 64, 65, 69, + 13, 11, 13, 8, 4, 14, 11, 7, 10, 10, 8, 6, 2, + 66, 69, 67, 6, 75, 10, 24, 9, 8, 16, 16, 14, 11, + 16, 13, 19, 1, 66, 67, 39, 39, 44, 36, 35, 44, + 48, 48, 53, 50, 57, 56, 48, 40, 15, 45, 59, 44, + 46, 42, 37, 26, 21, 18, 6, 68, 70, 79, 92, 38, + 37, 38, 32, 24, 25, 19, 14, 11, 8, 3, 68, 68, + 80, 84, 67, 68, 80, 20, 22, 16, 6, 14, 13, 2, 9, + 8, 0, 74, 73, 81, 96, 12, 2, 72, 75, 64, 64, 2, + 5, 5, 8, 6, 8, 11, 20, 11, 12, 19, 19, 57, 48, + 42, 34, 27, 18, 9, 69, 92, 3, 35, 28, 26, 20, + 19, 9, 6, 5, 68, 80, 75, 67, 74, 64, 7, 70, 73, + 1, 5, 3, 5, 11, 4, 3, 57, 47, 34, 22, 14, 1, 74, + 85, 101 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, 42, + 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, 11, 34, + 93, 106, 113, 81, 84, 68, 65, 9, 0, 80, 78, 8, + 9, 66, 75, 85, 2, 74, 81, 90, 5, 73, 84, 4, 73, + 78, 88, 3, 69, 70, 75, 65, 4, 22, 0, 0, 0, 74, + 90, 97, 65, 9, 65, 18, 74, 93, 99, 70, 76, 19, + 9, 74, 67, 88, 70, 84, 80, 98, 85, 84, 89, 95, + 20, 64, 7, 84, 71, 83, 79, 103, 4, 66, 65, 75, + 16, 68, 65, 80, 83, 72, 74, 70, 7, 8, 65, 12, + 15, 77, 64, 66, 67, 4, 74, 17, 68, 1, 17, 20, + 27, 21, 14, 83, 66, 71, 4, 5, 93, 1, 8, 5, 4, 7, + 7, 13, 8, 2, 2, 0, 2, 10, 8, 81, 67, 1, 72, 6, + 8, 14, 7, 4, 8, 5, 4, 8, 14, 6, 77, 3, 78, 24, + 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, + 67, 6, 0, 3, 5, 2, 7, 13, 2, 81, 1, 75, 2, 10, + 83, 31, 40, 32, 31, 31, 30, 27, 27, 22, 13, 10, + 7, 6, 1, 87, 68, 64, 76, 17, 13, 10, 12, 8, 2, + 2, 2, 74, 68, 73, 93, 87, 99, 70, 21, 18, 11, 2, + 6, 66, 71, 74, 85, 68, 36, 21, 15, 8, 10, 64, + 71, 76, 89, 4, 37, 28, 24, 18, 14, 5, 64, 71, + 80, 70, 38, 27, 14, 3, 7, 69, 78, 86, 5, 50, 39, + 31, 23, 21, 5, 67, 73, 77, 62, 93, 90, 77, 93, + 92, 84, 88, 85, 85, 86, 85, 86, 86, 83, 86, 84, + 72, 81, 76, 76, 75, 69, 67, 67, 66, 1, 65, 67, + 71, 12, 10, 13, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, + 67, 70, 67, 6, 76, 9, 23, 8, 7, 15, 15, 14, 10, + 14, 12, 18, 0, 67, 69, 38, 38, 43, 34, 33, 42, + 46, 46, 50, 47, 54, 53, 45, 37, 13, 42, 55, 41, + 41, 39, 34, 24, 19, 16, 6, 68, 70, 78, 90, 36, + 35, 36, 30, 21, 23, 17, 11, 9, 6, 1, 70, 70, 81, + 85, 68, 69, 82, 18, 20, 14, 4, 12, 11, 0, 7, 6, + 65, 76, 75, 83, 97, 11, 1, 73, 75, 64, 64, 2, 5, + 5, 9, 6, 9, 11, 21, 12, 13, 20, 20, 56, 46, 39, + 31, 24, 15, 5, 72, 95, 3, 35, 28, 26, 20, 19, 9, + 6, 5, 68, 80, 75, 67, 74, 0, 8, 70, 73, 1, 5, 3, + 5, 11, 4, 2, 55, 44, 31, 19, 10, 66, 78, 89, 104 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, 41, + 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, 11, 33, + 94, 107, 113, 78, 82, 68, 64, 10, 0, 79, 76, 9, + 9, 65, 74, 84, 2, 74, 80, 90, 5, 72, 83, 4, 73, + 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 73, + 90, 97, 64, 9, 65, 18, 73, 92, 97, 68, 74, 21, + 11, 72, 66, 86, 68, 82, 79, 96, 84, 83, 88, 94, + 21, 0, 8, 83, 70, 82, 78, 101, 4, 66, 65, 75, + 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, + 15, 76, 64, 65, 67, 4, 73, 17, 68, 1, 17, 19, + 27, 21, 14, 82, 65, 70, 4, 5, 92, 1, 8, 5, 5, 7, + 7, 14, 9, 3, 2, 1, 2, 10, 8, 81, 67, 1, 72, 6, + 7, 14, 7, 4, 9, 6, 4, 7, 14, 6, 76, 3, 78, 24, + 21, 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, + 67, 6, 0, 3, 5, 2, 7, 13, 2, 80, 1, 74, 2, 9, + 82, 30, 39, 31, 30, 29, 28, 26, 26, 20, 12, 9, + 6, 4, 0, 88, 68, 64, 76, 16, 12, 9, 11, 7, 1, 1, + 1, 74, 68, 73, 92, 86, 98, 69, 22, 18, 11, 3, 7, + 65, 70, 73, 83, 67, 36, 21, 15, 8, 11, 0, 70, + 75, 87, 4, 38, 29, 24, 18, 15, 5, 64, 70, 79, + 70, 39, 27, 14, 3, 8, 68, 77, 85, 5, 50, 39, 31, + 23, 21, 5, 66, 72, 76, 62, 92, 89, 76, 91, 90, + 83, 86, 83, 83, 84, 83, 84, 85, 82, 85, 83, 70, + 80, 76, 75, 74, 68, 67, 67, 66, 1, 65, 68, 72, + 12, 10, 14, 7, 3, 13, 10, 6, 9, 9, 7, 5, 1, 67, + 70, 66, 7, 76, 9, 23, 8, 7, 15, 15, 15, 10, 13, + 12, 18, 0, 67, 70, 38, 38, 43, 33, 32, 41, 44, + 44, 48, 45, 52, 51, 43, 35, 12, 40, 52, 38, 37, + 37, 32, 23, 18, 15, 6, 67, 69, 76, 87, 35, 34, + 35, 29, 19, 22, 16, 9, 8, 5, 0, 71, 71, 82, 85, + 68, 69, 83, 17, 19, 13, 3, 11, 10, 64, 6, 5, 66, + 77, 76, 84, 97, 11, 1, 73, 74, 0, 0, 3, 6, 6, + 11, 7, 10, 12, 23, 14, 14, 22, 22, 56, 45, 37, + 29, 22, 13, 2, 74, 97, 4, 36, 29, 27, 21, 20, + 10, 7, 6, 67, 79, 74, 66, 73, 2, 10, 69, 72, 2, + 6, 4, 6, 12, 4, 2, 54, 42, 29, 17, 7, 69, 81, + 92, 106 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, 40, + 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, 10, 31, + 96, 108, 114, 75, 81, 68, 0, 11, 0, 79, 75, 9, + 8, 65, 74, 83, 2, 74, 80, 90, 5, 72, 82, 4, 73, + 77, 88, 4, 68, 69, 74, 64, 4, 22, 0, 0, 0, 72, + 90, 97, 64, 8, 65, 18, 73, 92, 95, 66, 72, 22, + 13, 71, 65, 85, 67, 81, 78, 94, 84, 83, 88, 93, + 21, 0, 8, 82, 70, 81, 78, 100, 4, 66, 65, 75, + 17, 68, 64, 79, 82, 71, 73, 69, 7, 8, 64, 12, + 15, 76, 64, 65, 67, 4, 73, 16, 68, 1, 16, 18, + 26, 20, 13, 81, 65, 70, 3, 4, 92, 0, 8, 5, 5, 7, + 7, 15, 9, 3, 2, 1, 2, 9, 8, 82, 67, 1, 73, 6, 6, + 14, 7, 3, 9, 6, 4, 6, 14, 5, 76, 3, 79, 23, 21, + 16, 14, 17, 17, 10, 16, 20, 64, 11, 9, 6, 3, 67, + 6, 0, 3, 5, 2, 6, 12, 1, 80, 1, 74, 1, 8, 82, + 28, 37, 29, 28, 27, 26, 24, 24, 18, 10, 7, 4, 2, + 65, 89, 68, 64, 77, 15, 11, 8, 10, 5, 0, 0, 0, + 75, 69, 74, 92, 86, 97, 69, 22, 18, 11, 3, 7, + 65, 70, 73, 82, 66, 36, 21, 15, 8, 11, 0, 69, + 74, 85, 4, 38, 29, 24, 18, 15, 5, 64, 70, 78, + 70, 39, 27, 14, 3, 8, 68, 77, 84, 5, 49, 38, 30, + 22, 21, 5, 66, 72, 76, 62, 91, 88, 75, 90, 89, + 82, 85, 82, 82, 83, 82, 82, 84, 81, 85, 82, 69, + 80, 77, 75, 73, 68, 67, 68, 66, 0, 66, 69, 73, + 11, 10, 14, 7, 2, 12, 10, 6, 8, 8, 7, 5, 0, 67, + 70, 66, 7, 76, 8, 22, 7, 7, 14, 14, 15, 9, 12, + 12, 18, 64, 68, 72, 37, 37, 42, 32, 31, 40, 42, + 42, 46, 43, 49, 48, 40, 33, 11, 37, 49, 35, 33, + 34, 30, 21, 17, 14, 6, 66, 69, 75, 85, 33, 32, + 33, 27, 17, 20, 14, 7, 7, 3, 64, 73, 72, 83, 86, + 69, 69, 84, 16, 18, 11, 1, 9, 8, 65, 4, 3, 67, + 78, 77, 85, 98, 10, 0, 74, 74, 0, 0, 4, 6, 7, + 12, 8, 11, 13, 24, 15, 15, 23, 23, 55, 43, 35, + 27, 19, 10, 64, 77, 99, 4, 36, 29, 27, 21, 21, + 10, 7, 6, 67, 79, 74, 65, 73, 3, 11, 69, 71, 3, + 7, 4, 6, 13, 4, 2, 53, 40, 27, 14, 4, 73, 85, + 95, 109 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, 39, + 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, 10, 29, + 97, 109, 114, 72, 80, 68, 1, 12, 0, 78, 74, 10, + 8, 65, 73, 82, 1, 75, 80, 90, 5, 72, 82, 4, 73, + 77, 88, 5, 68, 69, 74, 0, 4, 22, 0, 0, 0, 72, + 90, 97, 0, 7, 65, 18, 73, 92, 93, 64, 71, 24, + 15, 70, 64, 83, 66, 80, 77, 92, 83, 83, 87, 92, + 21, 0, 8, 82, 70, 81, 77, 98, 4, 67, 66, 76, 17, + 68, 64, 78, 82, 70, 73, 68, 7, 8, 64, 12, 14, + 76, 64, 65, 67, 4, 73, 15, 68, 1, 15, 17, 25, + 19, 12, 81, 64, 70, 2, 4, 91, 0, 8, 5, 5, 7, 7, + 16, 9, 3, 2, 2, 2, 8, 8, 83, 67, 1, 73, 5, 5, + 14, 7, 2, 9, 6, 4, 4, 14, 4, 76, 3, 79, 22, 21, + 16, 14, 17, 17, 10, 16, 20, 64, 10, 9, 6, 3, 67, + 5, 64, 2, 4, 1, 5, 11, 1, 80, 0, 74, 0, 6, 82, + 27, 35, 27, 26, 25, 24, 22, 22, 16, 8, 6, 3, 0, + 67, 90, 68, 64, 77, 14, 10, 7, 8, 4, 65, 64, 64, + 76, 69, 74, 92, 86, 97, 68, 22, 18, 11, 3, 7, + 65, 70, 72, 81, 66, 36, 21, 15, 8, 12, 1, 68, + 73, 83, 4, 38, 29, 24, 18, 16, 5, 64, 70, 78, + 70, 39, 27, 13, 3, 8, 68, 77, 83, 5, 49, 38, 29, + 21, 21, 5, 66, 71, 75, 62, 90, 87, 75, 89, 88, + 81, 83, 81, 81, 82, 80, 81, 84, 80, 85, 82, 67, + 80, 77, 75, 73, 68, 68, 68, 66, 64, 67, 70, 74, + 11, 9, 14, 6, 2, 12, 9, 6, 7, 8, 6, 5, 64, 67, + 71, 66, 7, 77, 8, 22, 6, 7, 13, 14, 15, 8, 11, + 11, 17, 65, 68, 73, 36, 36, 42, 31, 30, 38, 40, + 40, 44, 40, 47, 46, 37, 30, 10, 34, 46, 32, 29, + 31, 27, 19, 16, 13, 6, 65, 69, 74, 83, 31, 30, + 31, 25, 15, 18, 13, 5, 5, 2, 65, 74, 74, 84, 87, + 69, 70, 85, 15, 16, 10, 64, 7, 6, 67, 3, 1, 69, + 79, 79, 87, 99, 9, 64, 75, 74, 1, 0, 4, 7, 7, + 13, 9, 12, 14, 25, 16, 16, 25, 24, 55, 42, 33, + 24, 17, 7, 67, 80, 101, 5, 37, 30, 28, 21, 22, + 11, 7, 7, 66, 79, 73, 65, 72, 4, 12, 69, 71, 3, + 7, 4, 7, 14, 4, 2, 52, 38, 24, 11, 1, 77, 89, + 99, 111 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, 37, + 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, 9, 27, + 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, 73, 10, + 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, 81, 3, 74, + 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, 0, 0, 71, + 91, 97, 0, 6, 65, 18, 73, 92, 92, 0, 69, 25, 16, + 69, 0, 82, 64, 79, 76, 90, 83, 82, 87, 91, 21, + 0, 8, 81, 70, 80, 77, 97, 3, 67, 66, 76, 17, 68, + 64, 78, 82, 70, 73, 68, 7, 7, 64, 12, 14, 76, + 64, 65, 67, 4, 73, 15, 69, 1, 15, 16, 24, 18, + 11, 80, 64, 70, 1, 3, 91, 64, 8, 4, 5, 7, 7, 17, + 10, 3, 1, 2, 1, 7, 7, 84, 67, 1, 74, 5, 4, 13, + 6, 2, 10, 6, 4, 3, 13, 3, 76, 3, 80, 22, 21, 16, + 14, 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, + 64, 2, 4, 1, 5, 10, 0, 80, 0, 74, 64, 5, 82, 25, + 33, 25, 24, 23, 22, 20, 20, 14, 6, 4, 1, 66, 69, + 91, 68, 65, 78, 13, 9, 6, 7, 2, 66, 65, 66, 76, + 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 65, + 70, 72, 80, 65, 36, 21, 15, 8, 12, 1, 68, 73, + 81, 4, 38, 29, 24, 18, 16, 5, 64, 70, 77, 70, + 39, 26, 13, 3, 8, 68, 77, 83, 5, 48, 37, 28, 20, + 21, 5, 66, 71, 75, 62, 89, 86, 74, 87, 87, 80, + 82, 79, 80, 80, 79, 79, 83, 80, 84, 81, 66, 79, + 78, 75, 72, 68, 68, 69, 67, 65, 68, 71, 75, 10, + 9, 14, 6, 1, 11, 9, 6, 6, 7, 6, 4, 65, 68, 71, + 66, 7, 77, 7, 21, 5, 7, 12, 13, 15, 7, 10, 11, + 17, 66, 69, 75, 35, 36, 41, 30, 28, 37, 38, 38, + 42, 38, 44, 43, 34, 28, 8, 31, 42, 29, 25, 29, + 25, 17, 15, 11, 6, 64, 68, 73, 81, 30, 28, 29, + 24, 13, 16, 11, 3, 4, 0, 67, 76, 75, 85, 88, 70, + 70, 86, 13, 15, 8, 65, 5, 4, 68, 1, 64, 70, 80, + 80, 88, 99, 8, 64, 76, 74, 1, 1, 5, 7, 8, 14, 9, + 13, 15, 26, 17, 17, 26, 25, 54, 40, 31, 22, 14, + 4, 70, 83, 104, 5, 37, 30, 28, 22, 22, 11, 8, 7, + 66, 78, 73, 64, 72, 5, 13, 69, 70, 4, 8, 4, 7, + 15, 4, 2, 50, 36, 22, 8, 65, 81, 93, 102, 114 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, 36, + 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, 9, 25, + 101, 111, 115, 66, 77, 68, 3, 13, 0, 78, 72, 10, + 7, 65, 73, 81, 1, 76, 79, 90, 5, 72, 80, 3, 74, + 77, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 71, + 91, 97, 1, 5, 65, 18, 72, 92, 90, 2, 68, 27, 18, + 67, 1, 81, 0, 78, 75, 88, 82, 82, 86, 90, 21, 0, + 8, 81, 70, 80, 76, 95, 3, 67, 66, 76, 17, 68, 0, + 77, 82, 70, 73, 67, 7, 7, 64, 12, 14, 75, 64, + 64, 67, 4, 73, 14, 69, 1, 14, 15, 24, 17, 10, + 79, 0, 70, 0, 3, 90, 64, 8, 4, 5, 7, 7, 18, 10, + 3, 1, 2, 1, 6, 7, 85, 67, 1, 74, 4, 3, 13, 6, 1, + 10, 6, 4, 2, 13, 2, 76, 3, 80, 21, 21, 16, 14, + 17, 17, 10, 16, 19, 64, 10, 9, 6, 3, 68, 5, 64, + 1, 4, 1, 4, 9, 0, 80, 64, 74, 65, 4, 82, 24, 31, + 24, 23, 21, 20, 18, 18, 12, 4, 2, 64, 68, 70, + 92, 68, 65, 78, 12, 8, 5, 6, 1, 68, 66, 67, 77, + 70, 75, 92, 86, 96, 68, 22, 18, 11, 3, 7, 64, + 69, 71, 79, 65, 36, 21, 15, 8, 12, 2, 67, 72, + 79, 4, 38, 29, 24, 18, 16, 5, 64, 70, 76, 70, + 40, 26, 12, 3, 8, 68, 77, 82, 5, 48, 36, 27, 19, + 21, 5, 66, 71, 74, 62, 88, 85, 73, 86, 86, 79, + 81, 78, 79, 79, 77, 77, 82, 79, 84, 81, 65, 79, + 78, 74, 71, 68, 69, 69, 67, 65, 69, 72, 76, 9, + 8, 14, 5, 1, 11, 9, 6, 5, 6, 6, 4, 66, 68, 71, + 66, 7, 77, 6, 21, 5, 7, 11, 12, 15, 6, 9, 10, + 16, 67, 70, 77, 34, 35, 41, 29, 27, 35, 36, 36, + 40, 35, 41, 41, 31, 26, 7, 28, 39, 26, 21, 26, + 22, 15, 14, 10, 6, 0, 68, 72, 79, 28, 27, 27, + 22, 11, 14, 10, 1, 3, 65, 68, 78, 77, 86, 89, + 70, 70, 87, 12, 13, 6, 67, 4, 3, 70, 0, 65, 72, + 81, 81, 89, 100, 8, 65, 77, 73, 2, 1, 5, 8, 9, + 15, 10, 14, 16, 28, 18, 18, 27, 27, 54, 38, 29, + 19, 12, 1, 73, 86, 106, 5, 38, 31, 29, 22, 23, + 11, 8, 8, 65, 78, 73, 0, 71, 6, 14, 68, 69, 4, + 8, 4, 8, 16, 4, 2, 49, 34, 19, 5, 68, 84, 97, + 106, 117 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, 35, + 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, 8, 24, + 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, 71, 11, + 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, 80, 3, 74, + 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, 0, 0, 70, + 91, 97, 1, 5, 66, 18, 72, 91, 88, 4, 66, 28, 20, + 66, 2, 79, 1, 77, 75, 87, 82, 82, 86, 90, 22, 0, + 8, 80, 69, 79, 76, 94, 3, 68, 67, 77, 17, 68, 0, + 77, 82, 69, 73, 67, 7, 7, 0, 12, 13, 75, 64, 64, + 67, 4, 73, 13, 69, 1, 13, 14, 23, 17, 10, 79, 0, + 70, 0, 2, 90, 65, 8, 4, 5, 7, 7, 18, 10, 3, 1, + 3, 1, 5, 7, 85, 68, 1, 75, 4, 2, 13, 6, 0, 10, + 6, 4, 0, 13, 1, 76, 3, 81, 20, 21, 15, 14, 17, + 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 1, 3, + 0, 3, 8, 64, 80, 64, 73, 66, 2, 82, 22, 29, 22, + 21, 19, 18, 16, 16, 10, 2, 1, 65, 70, 72, 93, + 68, 65, 79, 11, 7, 4, 4, 64, 69, 67, 68, 78, 71, + 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, + 71, 78, 64, 35, 21, 15, 8, 13, 2, 66, 71, 77, 4, + 39, 29, 24, 18, 17, 5, 64, 69, 76, 70, 40, 26, + 12, 3, 8, 67, 76, 81, 5, 47, 36, 26, 19, 21, 5, + 65, 70, 74, 62, 88, 84, 73, 85, 85, 78, 79, 77, + 78, 78, 76, 76, 82, 78, 84, 80, 0, 79, 79, 74, + 71, 68, 69, 70, 67, 66, 70, 73, 77, 9, 8, 14, 5, + 0, 10, 8, 6, 5, 6, 5, 4, 66, 68, 72, 66, 7, 78, + 6, 20, 4, 6, 10, 12, 16, 6, 8, 10, 16, 67, 70, + 78, 33, 34, 40, 28, 26, 34, 34, 34, 38, 33, 39, + 38, 28, 23, 6, 26, 36, 23, 17, 23, 20, 13, 13, + 9, 6, 1, 68, 70, 76, 26, 25, 25, 20, 9, 12, 8, + 64, 1, 66, 69, 79, 78, 87, 90, 71, 71, 88, 11, + 12, 5, 69, 2, 1, 71, 65, 67, 73, 83, 83, 91, + 101, 7, 66, 78, 73, 2, 1, 6, 8, 9, 17, 11, 15, + 17, 29, 20, 19, 29, 28, 53, 37, 27, 17, 9, 64, + 76, 88, 108, 6, 38, 31, 29, 22, 24, 12, 8, 8, + 65, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, 8, + 17, 4, 2, 48, 32, 17, 2, 72, 88, 100, 109, 119 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, 33, + 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, 8, 22, + 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, 70, 11, + 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, 79, 2, 74, + 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 70, + 91, 97, 2, 4, 66, 18, 72, 91, 87, 6, 65, 30, 22, + 65, 3, 78, 3, 76, 74, 85, 81, 81, 85, 89, 22, 0, + 8, 80, 69, 79, 75, 92, 2, 68, 67, 77, 17, 68, 0, + 76, 82, 69, 73, 66, 7, 6, 0, 12, 13, 75, 64, 64, + 67, 4, 73, 13, 69, 1, 13, 13, 22, 16, 9, 78, 1, + 70, 64, 2, 89, 65, 8, 3, 5, 7, 7, 19, 11, 3, 1, + 3, 1, 4, 7, 86, 68, 1, 75, 3, 1, 12, 6, 0, 11, + 6, 4, 64, 12, 0, 76, 3, 81, 20, 21, 15, 14, 17, + 17, 10, 16, 19, 64, 9, 9, 5, 3, 68, 4, 65, 0, 3, + 0, 3, 7, 64, 80, 65, 73, 67, 1, 82, 21, 27, 20, + 19, 17, 16, 14, 14, 8, 0, 64, 67, 73, 74, 94, + 68, 66, 79, 10, 6, 3, 3, 65, 71, 68, 69, 78, 71, + 76, 92, 86, 95, 67, 22, 18, 11, 4, 7, 64, 69, + 70, 77, 64, 35, 21, 15, 8, 13, 3, 65, 71, 75, 4, + 39, 29, 24, 18, 17, 5, 64, 69, 75, 70, 40, 25, + 11, 3, 8, 67, 76, 81, 5, 47, 35, 25, 18, 21, 5, + 65, 70, 73, 62, 87, 83, 72, 83, 84, 77, 78, 75, + 77, 76, 74, 74, 81, 77, 83, 80, 1, 78, 79, 74, + 70, 68, 70, 70, 68, 67, 71, 74, 78, 8, 7, 14, 4, + 0, 10, 8, 6, 4, 5, 5, 3, 67, 68, 72, 66, 7, 78, + 5, 20, 3, 6, 9, 11, 16, 5, 7, 9, 15, 68, 71, 80, + 32, 34, 40, 27, 24, 32, 32, 32, 36, 30, 36, 36, + 25, 21, 4, 23, 32, 20, 13, 21, 17, 11, 12, 8, 6, + 2, 67, 69, 74, 25, 23, 23, 19, 7, 10, 7, 66, 0, + 68, 71, 81, 80, 88, 91, 71, 71, 89, 9, 10, 3, + 70, 0, 64, 73, 66, 69, 75, 84, 84, 92, 101, 6, + 66, 79, 73, 3, 2, 6, 9, 10, 18, 12, 16, 18, 30, + 21, 20, 30, 29, 53, 35, 25, 14, 7, 67, 79, 91, + 110, 6, 39, 32, 30, 23, 25, 12, 9, 9, 64, 77, + 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, 9, 18, 4, 2, + 46, 30, 14, 64, 75, 92, 104, 113, 122 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, 32, + 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, 7, 20, + 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, 69, 11, + 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, 79, 2, 75, + 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, 0, 0, 69, + 92, 97, 2, 3, 66, 18, 72, 91, 85, 7, 0, 31, 23, + 64, 4, 77, 4, 75, 73, 83, 81, 81, 85, 88, 22, 0, + 8, 79, 69, 78, 75, 91, 2, 69, 68, 78, 17, 68, 0, + 76, 82, 69, 73, 66, 6, 6, 0, 12, 12, 75, 64, 64, + 67, 3, 73, 12, 70, 1, 12, 11, 21, 15, 8, 78, 1, + 70, 65, 1, 89, 66, 7, 3, 5, 7, 7, 20, 11, 3, 0, + 3, 0, 3, 6, 87, 68, 1, 76, 3, 0, 12, 5, 64, 11, + 6, 4, 66, 12, 64, 76, 3, 82, 19, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, + 64, 2, 6, 65, 80, 65, 73, 68, 64, 82, 19, 25, + 18, 17, 15, 13, 12, 12, 6, 65, 66, 69, 75, 76, + 95, 68, 66, 80, 9, 4, 1, 1, 67, 72, 70, 71, 79, + 72, 77, 92, 86, 94, 67, 22, 18, 11, 4, 7, 64, + 69, 70, 76, 0, 35, 21, 15, 8, 13, 3, 65, 70, 74, + 4, 39, 29, 24, 17, 17, 5, 64, 69, 75, 70, 40, + 25, 11, 3, 8, 67, 76, 80, 5, 46, 34, 24, 17, 20, + 5, 65, 70, 73, 62, 86, 82, 72, 82, 83, 77, 77, + 74, 76, 75, 73, 73, 81, 77, 83, 79, 2, 78, 80, + 74, 70, 68, 70, 71, 68, 68, 72, 76, 79, 7, 7, + 14, 4, 64, 9, 7, 5, 3, 4, 4, 3, 68, 69, 73, 66, + 7, 79, 4, 19, 2, 6, 8, 10, 16, 4, 6, 9, 15, 69, + 72, 82, 31, 33, 39, 25, 23, 31, 30, 30, 33, 28, + 33, 33, 22, 18, 3, 20, 29, 17, 9, 18, 15, 9, 10, + 6, 6, 2, 67, 68, 72, 23, 21, 21, 17, 4, 8, 5, + 68, 65, 70, 72, 83, 81, 89, 92, 72, 72, 90, 8, + 9, 1, 72, 65, 66, 74, 68, 71, 76, 85, 86, 94, + 102, 5, 67, 80, 73, 3, 2, 7, 9, 10, 19, 12, 17, + 19, 31, 22, 21, 31, 30, 52, 33, 23, 12, 4, 70, + 82, 94, 113, 6, 39, 32, 30, 23, 25, 12, 9, 9, + 64, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, + 18, 4, 1, 45, 28, 12, 67, 78, 96, 108, 116, 125 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, 31, + 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, 6, 18, + 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, 68, 12, + 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, 78, 2, 75, + 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, 0, 0, 68, + 92, 97, 2, 2, 66, 18, 71, 91, 83, 9, 2, 32, 25, + 1, 5, 75, 5, 73, 72, 81, 81, 81, 85, 87, 22, 0, + 8, 78, 69, 77, 74, 90, 2, 69, 68, 78, 17, 68, 1, + 75, 81, 68, 73, 66, 6, 6, 0, 12, 12, 74, 64, 0, + 67, 3, 72, 11, 70, 1, 11, 10, 21, 14, 7, 77, 1, + 69, 66, 0, 89, 67, 7, 3, 6, 7, 7, 21, 11, 3, 0, + 4, 0, 3, 6, 88, 68, 1, 77, 3, 64, 12, 5, 65, 11, + 6, 4, 67, 12, 64, 76, 3, 83, 18, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 0, 2, + 64, 1, 6, 65, 80, 65, 73, 69, 65, 82, 17, 24, + 17, 16, 13, 11, 11, 11, 4, 67, 67, 70, 77, 77, + 96, 68, 66, 81, 8, 3, 0, 0, 68, 73, 71, 72, 80, + 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, + 69, 75, 1, 35, 21, 15, 8, 14, 3, 64, 69, 72, 4, + 39, 29, 24, 17, 18, 5, 64, 69, 74, 70, 41, 25, + 11, 3, 9, 67, 76, 79, 5, 46, 34, 24, 16, 20, 5, + 65, 69, 72, 62, 85, 81, 71, 81, 81, 76, 75, 73, + 74, 74, 72, 71, 80, 76, 83, 78, 4, 78, 81, 73, + 69, 68, 70, 72, 68, 68, 73, 77, 80, 7, 7, 14, 4, + 64, 8, 7, 5, 2, 4, 4, 3, 69, 69, 73, 65, 8, 79, + 4, 18, 2, 6, 8, 10, 16, 3, 5, 9, 15, 70, 72, 83, + 31, 32, 38, 24, 22, 30, 28, 28, 31, 26, 31, 30, + 20, 16, 2, 17, 26, 14, 5, 15, 13, 8, 9, 5, 6, 3, + 67, 67, 70, 21, 20, 19, 15, 2, 7, 4, 70, 66, 71, + 73, 84, 82, 90, 92, 72, 72, 91, 7, 8, 0, 74, 66, + 67, 75, 69, 72, 77, 86, 87, 95, 103, 5, 68, 80, + 72, 3, 2, 8, 10, 11, 20, 13, 18, 20, 33, 23, 22, + 33, 32, 51, 32, 21, 10, 1, 73, 85, 97, 115, 7, + 39, 32, 31, 23, 26, 13, 9, 10, 0, 77, 71, 2, 70, + 10, 19, 67, 67, 7, 11, 4, 10, 19, 4, 1, 44, 26, + 10, 69, 81, 99, 112, 119, 126 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, 29, + 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, 6, 16, + 109, 116, 118, 11, 71, 68, 7, 16, 0, 76, 67, 12, + 4, 64, 71, 78, 64, 78, 77, 91, 5, 71, 77, 1, 75, + 76, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 68, + 92, 97, 3, 1, 66, 18, 71, 91, 82, 11, 3, 34, 27, + 2, 6, 74, 7, 72, 71, 79, 80, 80, 84, 86, 22, 0, + 8, 78, 69, 77, 74, 88, 1, 69, 68, 78, 17, 68, 1, + 75, 81, 68, 73, 65, 6, 5, 0, 12, 12, 74, 64, 0, + 67, 3, 72, 11, 70, 1, 11, 9, 20, 13, 6, 76, 2, + 69, 67, 0, 88, 67, 7, 2, 6, 7, 7, 22, 12, 3, 0, + 4, 0, 2, 6, 89, 68, 1, 77, 2, 65, 11, 5, 65, 12, + 6, 4, 68, 11, 65, 76, 3, 83, 18, 20, 15, 14, 17, + 16, 9, 16, 18, 65, 8, 9, 5, 2, 69, 3, 66, 64, 2, + 64, 1, 5, 66, 80, 66, 73, 70, 66, 82, 16, 22, + 15, 14, 11, 9, 9, 9, 2, 69, 69, 72, 80, 79, 97, + 68, 67, 81, 7, 2, 64, 64, 70, 75, 72, 73, 80, + 73, 78, 92, 85, 93, 66, 23, 18, 11, 4, 8, 0, 68, + 69, 74, 1, 35, 21, 15, 8, 14, 4, 0, 69, 70, 4, + 39, 29, 24, 17, 18, 5, 64, 69, 73, 70, 41, 24, + 10, 3, 9, 67, 76, 79, 5, 45, 33, 23, 15, 20, 5, + 65, 69, 72, 62, 84, 80, 70, 79, 80, 75, 74, 71, + 73, 72, 70, 69, 79, 75, 82, 78, 5, 77, 81, 73, + 68, 68, 71, 72, 69, 69, 74, 78, 81, 6, 6, 14, 3, + 65, 8, 7, 5, 1, 3, 4, 2, 70, 69, 73, 65, 8, 79, + 3, 18, 1, 6, 7, 9, 16, 2, 4, 8, 14, 71, 73, 85, + 30, 32, 38, 23, 20, 28, 26, 26, 29, 23, 28, 28, + 17, 14, 0, 14, 22, 11, 1, 13, 10, 6, 8, 4, 6, 4, + 66, 66, 68, 20, 18, 17, 14, 0, 5, 2, 72, 67, 73, + 75, 86, 84, 91, 93, 73, 72, 92, 5, 6, 65, 75, + 68, 69, 77, 71, 74, 79, 87, 88, 96, 103, 4, 68, + 81, 72, 4, 3, 8, 10, 12, 21, 14, 19, 21, 34, 24, + 23, 34, 33, 51, 30, 19, 7, 64, 76, 88, 100, 117, + 7, 40, 33, 31, 24, 27, 13, 10, 10, 0, 76, 71, 3, + 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, 42, + 24, 7, 72, 84, 103, 116, 123, 126 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, 28, + 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, 5, 15, + 110, 117, 119, 14, 70, 68, 7, 17, 0, 75, 66, 13, + 3, 0, 70, 77, 65, 78, 77, 91, 5, 70, 77, 1, 75, + 75, 88, 8, 65, 67, 71, 3, 4, 22, 0, 0, 0, 67, + 92, 97, 3, 1, 67, 18, 71, 90, 80, 13, 5, 35, 29, + 3, 7, 72, 8, 71, 71, 78, 80, 80, 84, 86, 23, 0, + 8, 77, 68, 76, 73, 87, 1, 70, 69, 79, 17, 68, 1, + 74, 81, 67, 73, 65, 6, 5, 1, 12, 11, 74, 64, 0, + 67, 3, 72, 10, 70, 1, 10, 8, 19, 13, 6, 76, 2, + 69, 67, 64, 88, 68, 7, 2, 6, 7, 7, 22, 12, 3, 0, + 5, 0, 1, 6, 89, 69, 1, 78, 2, 66, 11, 5, 66, 12, + 6, 4, 70, 11, 66, 76, 3, 84, 17, 20, 14, 14, 17, + 16, 9, 16, 18, 65, 7, 9, 4, 2, 69, 2, 67, 64, 1, + 65, 0, 4, 66, 80, 66, 72, 71, 68, 82, 14, 20, + 13, 12, 9, 7, 7, 7, 0, 71, 70, 73, 82, 81, 98, + 68, 67, 82, 6, 1, 65, 66, 71, 76, 73, 74, 81, + 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, + 68, 73, 2, 34, 21, 15, 8, 15, 4, 1, 68, 68, 4, + 40, 29, 24, 17, 19, 5, 64, 68, 73, 70, 41, 24, + 10, 3, 9, 66, 75, 78, 5, 45, 33, 22, 15, 20, 5, + 64, 68, 71, 62, 84, 79, 70, 78, 79, 74, 72, 70, + 72, 71, 69, 68, 79, 74, 82, 77, 7, 77, 82, 73, + 68, 68, 71, 73, 69, 70, 75, 79, 82, 6, 6, 14, 3, + 65, 7, 6, 5, 1, 3, 3, 2, 70, 69, 74, 65, 8, 80, + 3, 17, 0, 5, 6, 9, 17, 2, 3, 8, 14, 71, 73, 86, + 29, 31, 37, 22, 19, 27, 24, 24, 27, 21, 26, 25, + 14, 11, 64, 12, 19, 8, 66, 10, 8, 4, 7, 3, 6, 5, + 66, 64, 65, 18, 16, 15, 12, 65, 3, 1, 74, 69, + 74, 76, 87, 85, 92, 94, 73, 73, 93, 4, 5, 66, + 77, 70, 71, 78, 72, 76, 80, 89, 90, 98, 104, 3, + 69, 82, 72, 4, 3, 9, 11, 12, 23, 15, 20, 22, 35, + 26, 24, 36, 34, 50, 29, 17, 5, 67, 78, 91, 102, + 119, 8, 40, 33, 32, 24, 28, 14, 10, 11, 1, 76, + 70, 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, + 1, 41, 22, 5, 75, 88, 107, 119, 126, 126 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, 27, + 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, 5, 13, + 112, 118, 119, 17, 69, 68, 8, 18, 0, 75, 65, 13, + 3, 0, 70, 76, 65, 79, 77, 91, 5, 70, 76, 1, 76, + 75, 88, 9, 65, 67, 71, 4, 4, 22, 0, 0, 0, 67, + 93, 97, 4, 0, 67, 18, 71, 90, 78, 14, 6, 37, 30, + 4, 8, 71, 9, 70, 70, 76, 79, 80, 83, 85, 23, 0, + 8, 77, 68, 76, 73, 85, 1, 70, 69, 79, 17, 68, 1, + 74, 81, 67, 73, 64, 6, 5, 1, 12, 11, 74, 64, 0, + 67, 3, 72, 9, 71, 1, 9, 7, 18, 12, 5, 75, 3, 69, + 68, 64, 87, 68, 7, 2, 6, 7, 7, 23, 12, 3, 64, 5, + 64, 0, 5, 90, 69, 1, 78, 1, 67, 11, 4, 67, 12, + 6, 4, 71, 11, 67, 76, 3, 84, 16, 20, 14, 14, 17, + 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, 67, 65, 1, + 65, 64, 3, 67, 80, 67, 72, 72, 69, 82, 13, 18, + 11, 10, 7, 5, 5, 5, 65, 73, 72, 75, 84, 83, 99, + 68, 67, 82, 5, 0, 66, 67, 73, 78, 74, 76, 82, + 74, 79, 92, 85, 92, 65, 23, 18, 11, 5, 8, 0, 68, + 68, 72, 2, 34, 21, 15, 8, 15, 5, 1, 67, 66, 4, + 40, 29, 24, 17, 19, 5, 64, 68, 72, 70, 41, 24, + 9, 3, 9, 66, 75, 77, 5, 44, 32, 21, 14, 20, 5, + 64, 68, 71, 62, 83, 78, 69, 77, 78, 73, 71, 69, + 71, 70, 67, 66, 78, 74, 82, 77, 8, 77, 82, 73, + 67, 68, 72, 73, 69, 71, 76, 80, 83, 5, 5, 14, 2, + 66, 7, 6, 5, 0, 2, 3, 2, 71, 70, 74, 65, 8, 80, + 2, 17, 64, 5, 5, 8, 17, 1, 2, 7, 13, 72, 74, 88, + 28, 30, 37, 21, 18, 25, 22, 22, 25, 18, 23, 23, + 11, 9, 65, 9, 16, 5, 70, 7, 5, 2, 6, 1, 6, 6, + 66, 0, 0, 16, 14, 13, 10, 67, 1, 64, 76, 70, 76, + 77, 89, 87, 93, 95, 74, 73, 94, 3, 3, 68, 79, + 72, 73, 80, 74, 78, 82, 90, 91, 99, 105, 2, 70, + 83, 72, 5, 3, 9, 11, 13, 24, 15, 21, 23, 36, 27, + 25, 37, 35, 50, 27, 15, 2, 69, 81, 94, 105, 122, + 8, 41, 34, 32, 24, 28, 14, 10, 11, 1, 76, 70, 4, + 68, 13, 22, 67, 65, 8, 12, 4, 11, 22, 4, 1, 40, + 20, 2, 78, 91, 111, 123, 126, 126 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, 25, + 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, 4, 11, + 114, 119, 120, 20, 67, 68, 9, 18, 0, 75, 64, 13, + 2, 0, 70, 76, 65, 79, 76, 91, 5, 70, 75, 0, 76, + 75, 88, 9, 64, 66, 70, 4, 4, 22, 0, 0, 0, 66, + 93, 97, 4, 64, 67, 18, 70, 90, 77, 16, 8, 38, + 32, 6, 9, 70, 11, 69, 69, 74, 79, 79, 83, 84, + 23, 0, 8, 76, 68, 75, 72, 84, 0, 70, 69, 79, 17, + 68, 2, 73, 81, 67, 73, 64, 6, 4, 1, 12, 11, 73, + 64, 1, 67, 3, 72, 9, 71, 1, 9, 6, 18, 11, 4, 74, + 3, 69, 69, 65, 87, 69, 7, 1, 6, 7, 7, 24, 13, 3, + 64, 5, 64, 64, 5, 91, 69, 1, 79, 1, 68, 10, 4, + 67, 13, 6, 4, 72, 10, 68, 76, 3, 85, 16, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 7, 9, 4, 2, 70, 2, + 67, 65, 1, 65, 64, 2, 67, 80, 67, 72, 73, 70, + 82, 11, 16, 10, 9, 5, 3, 3, 3, 67, 75, 74, 77, + 87, 84, 100, 68, 68, 83, 4, 64, 67, 68, 74, 79, + 75, 77, 82, 75, 80, 92, 85, 91, 65, 23, 18, 11, + 5, 8, 1, 67, 67, 71, 3, 34, 21, 15, 8, 15, 5, 2, + 67, 64, 4, 40, 29, 24, 17, 19, 5, 64, 68, 71, + 70, 42, 23, 9, 3, 9, 66, 75, 77, 5, 44, 31, 20, + 13, 20, 5, 64, 68, 70, 62, 82, 77, 68, 75, 77, + 72, 70, 67, 70, 68, 66, 64, 77, 73, 81, 76, 9, + 76, 83, 72, 66, 68, 72, 74, 70, 71, 77, 81, 84, + 4, 5, 14, 2, 66, 6, 6, 5, 64, 1, 3, 1, 72, 70, + 74, 65, 8, 80, 1, 16, 64, 5, 4, 7, 17, 0, 1, 7, + 13, 73, 75, 90, 27, 30, 36, 20, 16, 24, 20, 20, + 23, 16, 20, 20, 8, 7, 67, 6, 12, 2, 74, 5, 3, 0, + 5, 0, 6, 7, 65, 1, 2, 15, 13, 11, 9, 69, 64, 65, + 78, 71, 78, 79, 91, 88, 94, 96, 74, 73, 95, 1, + 2, 70, 80, 73, 74, 81, 75, 79, 83, 91, 92, 100, + 105, 2, 70, 84, 71, 5, 4, 10, 12, 14, 25, 16, + 22, 24, 38, 28, 26, 38, 37, 49, 25, 13, 0, 72, + 84, 97, 108, 124, 8, 41, 34, 33, 25, 29, 14, 11, + 12, 2, 75, 70, 5, 68, 14, 23, 66, 64, 9, 13, 4, + 12, 23, 4, 1, 38, 18, 0, 81, 94, 114, 126, 126, + 126 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, 24, + 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, 4, 9, + 115, 120, 120, 23, 66, 68, 10, 19, 0, 74, 0, 14, + 2, 0, 69, 75, 66, 80, 76, 91, 5, 70, 75, 0, 76, + 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 66, + 93, 97, 5, 65, 67, 18, 70, 90, 75, 18, 9, 40, + 34, 7, 10, 68, 12, 68, 68, 72, 78, 79, 82, 83, + 23, 0, 8, 76, 68, 75, 72, 82, 0, 71, 70, 80, 17, + 68, 2, 73, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, + 64, 1, 67, 3, 72, 8, 71, 1, 8, 5, 17, 10, 3, 74, + 4, 69, 70, 65, 86, 69, 7, 1, 6, 7, 7, 25, 13, 3, + 64, 6, 64, 65, 5, 92, 69, 1, 79, 0, 69, 10, 4, + 68, 13, 6, 4, 74, 10, 69, 76, 3, 85, 15, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, + 68, 66, 0, 66, 65, 1, 68, 80, 68, 72, 74, 72, + 82, 10, 14, 8, 7, 3, 1, 1, 1, 69, 77, 75, 78, + 89, 86, 101, 68, 68, 83, 3, 65, 68, 70, 76, 81, + 76, 78, 83, 75, 80, 92, 85, 91, 64, 23, 18, 11, + 5, 8, 1, 67, 67, 70, 3, 34, 21, 15, 8, 16, 6, 3, + 66, 1, 4, 40, 29, 24, 17, 20, 5, 64, 68, 71, 70, + 42, 23, 8, 3, 9, 66, 75, 76, 5, 43, 31, 19, 12, + 20, 5, 64, 67, 70, 62, 81, 76, 68, 74, 76, 71, + 68, 66, 69, 67, 64, 0, 77, 72, 81, 76, 11, 76, + 83, 72, 66, 68, 73, 74, 70, 72, 78, 82, 85, 4, + 4, 14, 1, 67, 6, 5, 5, 65, 1, 2, 1, 73, 70, 75, + 65, 8, 81, 1, 16, 65, 5, 3, 7, 17, 64, 0, 6, 12, + 74, 75, 91, 26, 29, 36, 19, 15, 22, 18, 18, 21, + 13, 18, 18, 5, 4, 68, 3, 9, 64, 78, 2, 0, 65, 4, + 64, 6, 8, 65, 2, 4, 13, 11, 9, 7, 71, 66, 67, + 80, 73, 79, 80, 92, 90, 95, 97, 75, 74, 96, 0, + 0, 71, 82, 75, 76, 83, 77, 81, 85, 92, 94, 102, + 106, 1, 71, 85, 71, 6, 4, 10, 12, 14, 26, 17, + 23, 25, 39, 29, 27, 40, 38, 49, 24, 11, 66, 74, + 87, 100, 111, 126, 9, 42, 35, 33, 25, 30, 15, + 11, 12, 2, 75, 69, 5, 67, 15, 24, 66, 64, 9, 13, + 4, 12, 24, 4, 1, 37, 16, 66, 84, 97, 118, 126, + 126, 126 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, 23, + 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, 3, 7, + 117, 121, 121, 26, 65, 68, 11, 20, 0, 74, 1, 14, + 1, 0, 69, 74, 66, 80, 76, 91, 5, 70, 74, 0, 76, + 75, 88, 10, 64, 66, 70, 5, 4, 22, 0, 0, 0, 65, + 93, 97, 5, 66, 67, 18, 70, 90, 73, 20, 11, 41, + 36, 8, 11, 67, 13, 67, 67, 70, 78, 79, 82, 82, + 23, 0, 8, 75, 68, 74, 71, 81, 0, 71, 70, 80, 17, + 68, 2, 72, 81, 66, 73, 0, 6, 4, 1, 12, 10, 73, + 64, 1, 67, 3, 72, 7, 71, 1, 7, 4, 16, 9, 2, 73, + 4, 69, 71, 66, 86, 70, 7, 1, 6, 7, 7, 26, 13, 3, + 64, 6, 64, 66, 5, 93, 69, 1, 80, 0, 70, 10, 4, + 69, 13, 6, 4, 75, 10, 70, 76, 3, 86, 14, 20, 14, + 14, 17, 16, 9, 16, 17, 65, 6, 9, 4, 2, 70, 1, + 68, 66, 0, 66, 66, 0, 68, 80, 68, 72, 75, 73, + 82, 8, 12, 6, 5, 1, 64, 64, 64, 71, 79, 77, 80, + 91, 88, 102, 68, 68, 84, 2, 66, 69, 71, 77, 82, + 77, 79, 84, 76, 81, 92, 85, 90, 64, 23, 18, 11, + 5, 8, 1, 67, 66, 69, 4, 34, 21, 15, 8, 16, 6, 4, + 65, 3, 4, 40, 29, 24, 17, 20, 5, 64, 68, 70, 70, + 42, 23, 8, 3, 9, 66, 75, 75, 5, 43, 30, 18, 11, + 20, 5, 64, 67, 69, 62, 80, 75, 67, 73, 75, 70, + 67, 65, 68, 66, 0, 2, 76, 71, 81, 75, 12, 76, + 84, 72, 65, 68, 73, 75, 70, 73, 79, 83, 86, 3, + 4, 14, 1, 67, 5, 5, 5, 66, 0, 2, 1, 74, 70, 75, + 65, 8, 81, 0, 15, 66, 5, 2, 6, 17, 65, 64, 6, + 12, 75, 76, 93, 25, 28, 35, 18, 14, 21, 16, 16, + 19, 11, 15, 15, 2, 2, 69, 0, 6, 67, 82, 64, 65, + 67, 3, 65, 6, 9, 65, 3, 6, 11, 9, 7, 5, 73, 68, + 68, 82, 74, 81, 81, 94, 91, 96, 98, 75, 74, 97, + 64, 64, 73, 84, 77, 78, 84, 78, 83, 86, 93, 95, + 103, 107, 0, 72, 86, 71, 6, 4, 11, 13, 15, 27, + 18, 24, 26, 40, 30, 28, 41, 39, 48, 22, 9, 68, + 77, 90, 103, 114, 126, 9, 42, 35, 34, 25, 31, + 15, 11, 13, 3, 75, 69, 6, 67, 16, 25, 66, 0, 10, + 14, 4, 13, 25, 4, 1, 36, 14, 68, 87, 100, 122, + 126, 126, 126 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, 21, + 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, 100, 2, + 5, 119, 122, 122, 28, 64, 69, 11, 20, 64, 74, 2, + 14, 0, 0, 69, 74, 67, 81, 76, 92, 5, 70, 74, 64, + 77, 75, 88, 10, 64, 66, 70, 5, 3, 22, 0, 0, 0, + 65, 94, 97, 5, 67, 68, 18, 70, 90, 72, 21, 12, + 42, 37, 9, 12, 66, 14, 66, 67, 69, 78, 79, 82, + 82, 23, 0, 8, 75, 68, 74, 71, 80, 64, 72, 71, + 81, 17, 68, 2, 72, 81, 66, 73, 0, 5, 3, 1, 11, + 9, 73, 65, 1, 67, 2, 72, 6, 72, 0, 6, 2, 15, 8, + 1, 73, 4, 69, 72, 67, 86, 71, 6, 0, 6, 7, 7, 26, + 13, 3, 65, 6, 65, 67, 4, 94, 70, 0, 81, 64, 71, + 9, 3, 70, 13, 6, 4, 77, 9, 71, 76, 3, 87, 13, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 67, 64, 69, 80, 69, 72, + 76, 75, 82, 6, 10, 4, 3, 64, 67, 66, 66, 73, 81, + 79, 82, 94, 90, 104, 69, 69, 85, 1, 68, 71, 73, + 79, 84, 79, 81, 85, 77, 82, 92, 85, 90, 64, 23, + 18, 11, 5, 8, 1, 67, 66, 68, 4, 33, 21, 15, 8, + 16, 6, 4, 65, 4, 3, 40, 29, 23, 16, 20, 5, 64, + 68, 70, 70, 42, 22, 7, 2, 9, 66, 75, 75, 5, 42, + 29, 17, 10, 19, 5, 64, 67, 69, 62, 80, 74, 67, + 72, 74, 70, 66, 64, 67, 65, 1, 3, 76, 71, 81, + 75, 13, 76, 85, 72, 65, 68, 74, 76, 71, 74, 80, + 85, 88, 2, 3, 14, 0, 68, 4, 4, 4, 67, 64, 1, 0, + 75, 71, 76, 65, 8, 82, 64, 14, 67, 4, 1, 5, 17, + 66, 66, 5, 11, 76, 77, 95, 24, 27, 34, 16, 12, + 19, 14, 14, 16, 8, 12, 12, 64, 64, 71, 66, 2, + 70, 87, 67, 68, 69, 1, 67, 6, 9, 65, 4, 8, 9, 7, + 5, 3, 76, 70, 70, 85, 76, 83, 83, 96, 93, 97, + 99, 76, 75, 99, 66, 66, 75, 86, 79, 80, 86, 80, + 85, 88, 95, 97, 105, 108, 64, 73, 87, 71, 6, 4, + 11, 13, 15, 28, 18, 25, 26, 41, 31, 29, 42, 40, + 47, 20, 6, 71, 80, 93, 107, 117, 126, 9, 42, 35, + 34, 25, 31, 15, 11, 13, 3, 75, 69, 6, 67, 17, + 26, 66, 0, 10, 14, 4, 13, 25, 4, 0, 34, 11, 71, + 90, 104, 126, 126, 126, 126 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, 20, + 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, 101, 2, + 4, 120, 123, 122, 31, 1, 69, 12, 21, 64, 73, 4, + 15, 0, 1, 68, 73, 67, 81, 75, 92, 5, 69, 73, 64, + 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, 0, + 64, 94, 97, 6, 67, 68, 18, 69, 89, 70, 23, 14, + 44, 39, 11, 13, 64, 16, 64, 66, 67, 77, 78, 81, + 81, 24, 1, 9, 74, 67, 73, 70, 78, 64, 72, 71, + 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, + 9, 72, 65, 2, 67, 2, 71, 6, 72, 0, 6, 1, 15, 8, + 1, 72, 5, 68, 72, 67, 85, 71, 6, 0, 7, 7, 7, 27, + 14, 4, 65, 7, 65, 67, 4, 94, 70, 0, 81, 64, 72, + 9, 3, 70, 14, 7, 4, 78, 9, 71, 75, 3, 87, 13, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 67, 64, 69, 79, 69, 71, + 76, 76, 81, 5, 9, 3, 2, 66, 69, 67, 67, 75, 82, + 80, 83, 96, 91, 105, 69, 69, 85, 0, 69, 72, 74, + 80, 85, 80, 82, 85, 77, 82, 91, 84, 89, 0, 24, + 18, 11, 6, 9, 2, 66, 65, 66, 5, 33, 21, 15, 8, + 17, 7, 5, 64, 6, 3, 41, 30, 23, 16, 21, 5, 64, + 67, 69, 70, 43, 22, 7, 2, 10, 65, 74, 74, 5, 42, + 29, 17, 10, 19, 5, 0, 66, 68, 62, 79, 73, 66, + 70, 72, 69, 64, 1, 65, 0, 3, 5, 75, 70, 80, 74, + 15, 75, 85, 71, 64, 67, 74, 76, 71, 74, 80, 86, + 89, 2, 3, 15, 0, 68, 4, 4, 4, 67, 64, 1, 0, 75, + 71, 76, 64, 9, 82, 64, 14, 67, 4, 1, 5, 18, 66, + 67, 5, 11, 76, 77, 96, 24, 27, 34, 15, 11, 18, + 12, 12, 14, 6, 10, 10, 66, 66, 72, 68, 64, 73, + 91, 69, 70, 70, 0, 68, 6, 10, 64, 6, 11, 8, 6, + 4, 2, 78, 71, 71, 87, 77, 84, 84, 97, 94, 98, + 99, 76, 75, 100, 67, 67, 76, 87, 80, 81, 87, 81, + 86, 89, 96, 98, 106, 108, 64, 73, 87, 70, 7, 5, + 12, 14, 16, 30, 19, 26, 27, 43, 33, 30, 44, 42, + 47, 19, 4, 73, 82, 95, 110, 119, 126, 10, 43, + 36, 35, 26, 32, 16, 12, 14, 4, 74, 68, 7, 66, + 19, 28, 65, 1, 11, 15, 5, 14, 26, 4, 0, 33, 9, + 73, 92, 107, 126, 126, 126, 126 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, 19, + 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, 102, 1, + 2, 122, 124, 123, 34, 2, 69, 13, 22, 64, 73, 5, + 15, 64, 1, 68, 72, 67, 81, 75, 92, 5, 69, 72, + 64, 77, 74, 88, 11, 0, 65, 69, 6, 3, 22, 0, 0, + 0, 0, 94, 97, 6, 68, 68, 18, 69, 89, 68, 25, 16, + 45, 41, 12, 14, 0, 17, 0, 65, 65, 77, 78, 81, + 80, 24, 1, 9, 73, 67, 72, 70, 77, 64, 72, 71, + 81, 18, 68, 3, 71, 80, 65, 72, 1, 5, 3, 2, 11, + 9, 72, 65, 2, 67, 2, 71, 5, 72, 0, 5, 0, 14, 7, + 0, 71, 5, 68, 73, 68, 85, 72, 6, 0, 7, 7, 7, 28, + 14, 4, 65, 7, 65, 68, 4, 95, 70, 0, 82, 64, 73, + 9, 3, 71, 14, 7, 4, 79, 9, 72, 75, 3, 88, 12, + 19, 13, 14, 17, 15, 8, 16, 16, 66, 5, 9, 3, 1, + 71, 0, 69, 67, 64, 67, 68, 65, 70, 79, 69, 71, + 77, 77, 81, 3, 7, 1, 0, 68, 71, 69, 69, 77, 84, + 82, 85, 98, 93, 106, 69, 69, 86, 64, 70, 73, 75, + 82, 86, 81, 83, 86, 78, 83, 91, 84, 88, 0, 24, + 18, 11, 6, 9, 2, 66, 65, 65, 6, 33, 21, 15, 8, + 17, 7, 6, 0, 8, 3, 41, 30, 23, 16, 21, 5, 64, + 67, 68, 70, 43, 22, 7, 2, 10, 65, 74, 73, 5, 41, + 28, 16, 9, 19, 5, 0, 66, 68, 62, 78, 72, 65, 69, + 71, 68, 0, 2, 64, 1, 4, 7, 74, 69, 80, 73, 16, + 75, 86, 71, 0, 67, 74, 77, 71, 75, 81, 87, 90, + 1, 3, 15, 0, 69, 3, 4, 4, 68, 65, 1, 0, 76, 71, + 76, 64, 9, 82, 65, 13, 68, 4, 0, 4, 18, 67, 68, + 5, 11, 77, 78, 98, 23, 26, 33, 14, 10, 17, 10, + 10, 12, 4, 7, 7, 69, 68, 73, 71, 67, 76, 95, 72, + 72, 72, 64, 69, 6, 11, 64, 7, 13, 6, 4, 2, 0, + 80, 73, 73, 89, 78, 86, 85, 99, 95, 99, 100, 77, + 75, 101, 68, 68, 78, 89, 82, 83, 88, 83, 88, 90, + 97, 99, 107, 109, 65, 74, 88, 70, 7, 5, 13, 14, + 17, 31, 20, 27, 28, 44, 34, 31, 45, 43, 46, 17, + 2, 75, 85, 98, 113, 122, 126, 10, 43, 36, 35, + 26, 33, 16, 12, 14, 4, 74, 68, 8, 66, 20, 29, + 65, 2, 12, 16, 5, 14, 27, 4, 0, 32, 7, 75, 95, + 110, 126, 126, 126, 126 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, + 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, 103, + 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, 64, 72, + 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, 5, 69, 72, + 64, 77, 74, 88, 12, 0, 65, 69, 7, 3, 22, 0, 0, + 0, 0, 94, 97, 7, 69, 68, 18, 69, 89, 66, 27, 17, + 47, 43, 13, 15, 2, 18, 1, 64, 0, 76, 78, 80, 79, + 24, 1, 9, 73, 67, 72, 69, 75, 64, 73, 72, 82, + 18, 68, 3, 70, 80, 64, 72, 2, 5, 3, 2, 11, 8, + 72, 65, 2, 67, 2, 71, 4, 72, 0, 4, 64, 13, 6, + 64, 71, 6, 68, 74, 68, 84, 72, 6, 0, 7, 7, 7, + 29, 14, 4, 65, 8, 65, 69, 4, 96, 70, 0, 82, 65, + 74, 9, 3, 72, 14, 7, 4, 81, 9, 73, 75, 3, 88, + 11, 19, 13, 14, 17, 15, 8, 16, 16, 66, 4, 9, 3, + 1, 71, 64, 70, 68, 65, 68, 69, 66, 70, 79, 70, + 71, 78, 79, 81, 2, 5, 64, 65, 70, 73, 71, 71, + 79, 86, 83, 86, 100, 95, 107, 69, 69, 86, 65, + 71, 74, 77, 83, 88, 82, 84, 87, 78, 83, 91, 84, + 88, 1, 24, 18, 11, 6, 9, 2, 66, 64, 64, 6, 33, + 21, 15, 8, 18, 8, 7, 1, 10, 3, 41, 30, 23, 16, + 22, 5, 64, 67, 68, 70, 43, 22, 6, 2, 10, 65, 74, + 72, 5, 41, 28, 15, 8, 19, 5, 0, 65, 67, 62, 77, + 71, 65, 68, 70, 67, 2, 3, 0, 2, 6, 8, 74, 68, + 80, 73, 18, 75, 86, 71, 0, 67, 75, 77, 71, 76, + 82, 88, 91, 1, 2, 15, 64, 69, 3, 3, 4, 69, 65, + 0, 0, 77, 71, 77, 64, 9, 83, 65, 13, 69, 4, 64, + 4, 18, 68, 69, 4, 10, 78, 78, 99, 22, 25, 33, + 13, 9, 15, 8, 8, 10, 1, 5, 5, 72, 71, 74, 74, + 70, 79, 99, 75, 75, 74, 65, 70, 6, 12, 64, 8, + 15, 4, 2, 0, 65, 82, 75, 74, 91, 80, 87, 86, + 100, 97, 100, 101, 77, 76, 102, 69, 70, 79, 91, + 84, 85, 90, 84, 90, 92, 98, 101, 109, 110, 66, + 75, 89, 70, 8, 5, 13, 15, 17, 32, 21, 28, 29, + 45, 35, 32, 47, 44, 46, 16, 0, 78, 87, 101, 116, + 125, 126, 11, 44, 37, 36, 26, 34, 17, 12, 15, 5, + 74, 67, 8, 65, 21, 30, 65, 2, 12, 16, 5, 15, 28, + 4, 0, 31, 5, 78, 98, 113, 126, 126, 126, 126 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, + 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, 104, + 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, 64, 72, + 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, 5, 69, 71, + 65, 78, 74, 88, 12, 1, 65, 68, 7, 3, 22, 0, 0, + 0, 1, 95, 97, 7, 70, 68, 18, 69, 89, 65, 28, 19, + 48, 44, 14, 16, 3, 20, 2, 0, 2, 76, 77, 80, 78, + 24, 1, 9, 72, 67, 71, 69, 74, 65, 73, 72, 82, + 18, 68, 3, 70, 80, 64, 72, 2, 5, 2, 2, 11, 8, + 72, 65, 2, 67, 2, 71, 4, 73, 0, 4, 65, 12, 5, + 65, 70, 6, 68, 75, 69, 84, 73, 6, 64, 7, 7, 7, + 30, 15, 4, 66, 8, 66, 70, 3, 97, 70, 0, 83, 65, + 75, 8, 2, 72, 15, 7, 4, 82, 8, 74, 75, 3, 89, + 11, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, + 1, 72, 64, 70, 68, 65, 68, 69, 67, 71, 79, 70, + 71, 79, 80, 81, 0, 3, 66, 67, 72, 75, 73, 73, + 81, 88, 85, 88, 103, 97, 108, 69, 70, 87, 66, + 72, 75, 78, 85, 89, 83, 86, 87, 79, 84, 91, 84, + 87, 1, 24, 18, 11, 6, 9, 2, 66, 64, 0, 7, 33, + 21, 15, 8, 18, 8, 7, 1, 12, 3, 41, 30, 23, 16, + 22, 5, 64, 67, 67, 70, 43, 21, 6, 2, 10, 65, 74, + 72, 5, 40, 27, 14, 7, 19, 5, 0, 65, 67, 62, 76, + 70, 64, 66, 69, 66, 3, 5, 1, 4, 7, 10, 73, 68, + 79, 72, 19, 74, 87, 71, 1, 67, 75, 78, 72, 77, + 83, 89, 92, 0, 2, 15, 64, 70, 2, 3, 4, 70, 66, + 0, 64, 78, 72, 77, 64, 9, 83, 66, 12, 70, 4, 65, + 3, 18, 69, 70, 4, 10, 79, 79, 101, 21, 25, 32, + 12, 7, 14, 6, 6, 8, 64, 2, 2, 75, 73, 76, 77, + 74, 82, 103, 77, 77, 76, 66, 72, 6, 13, 0, 9, + 17, 3, 0, 65, 66, 84, 77, 76, 93, 81, 89, 88, + 102, 98, 101, 102, 78, 76, 103, 71, 71, 81, 92, + 86, 87, 91, 86, 92, 93, 99, 102, 110, 110, 67, + 75, 90, 70, 8, 6, 14, 15, 18, 33, 21, 29, 30, + 46, 36, 33, 48, 45, 45, 14, 65, 80, 90, 104, + 119, 126, 126, 11, 44, 37, 36, 27, 34, 17, 13, + 15, 5, 73, 67, 9, 65, 22, 31, 65, 3, 13, 17, 5, + 15, 29, 4, 0, 29, 3, 80, 101, 116, 126, 126, + 126, 126 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, 15, + 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, 105, 0, + 67, 126, 126, 124, 43, 6, 69, 16, 24, 64, 72, 8, + 16, 65, 1, 67, 70, 68, 83, 74, 92, 5, 69, 70, + 65, 78, 74, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, + 0, 1, 95, 97, 8, 71, 68, 18, 68, 89, 0, 30, 20, + 50, 46, 16, 17, 4, 21, 3, 1, 4, 75, 77, 79, 77, + 24, 1, 9, 72, 67, 71, 68, 72, 65, 73, 72, 82, + 18, 68, 4, 69, 80, 64, 72, 3, 5, 2, 2, 11, 8, + 71, 65, 3, 67, 2, 71, 3, 73, 0, 3, 66, 12, 4, + 66, 69, 7, 68, 76, 69, 83, 73, 6, 64, 7, 7, 7, + 31, 15, 4, 66, 8, 66, 71, 3, 98, 70, 0, 83, 66, + 76, 8, 2, 73, 15, 7, 4, 83, 8, 75, 75, 3, 89, + 10, 19, 13, 14, 17, 15, 8, 16, 15, 66, 4, 9, 3, + 1, 72, 64, 70, 69, 65, 68, 70, 68, 71, 79, 71, + 71, 80, 81, 81, 64, 1, 67, 68, 74, 77, 75, 75, + 83, 90, 87, 90, 105, 98, 109, 69, 70, 87, 67, + 73, 76, 79, 86, 91, 84, 87, 88, 79, 84, 91, 84, + 87, 1, 24, 18, 11, 6, 9, 3, 65, 0, 1, 7, 33, 21, + 15, 8, 18, 9, 8, 2, 14, 3, 41, 30, 23, 16, 22, + 5, 64, 67, 66, 70, 44, 21, 5, 2, 10, 65, 74, 71, + 5, 40, 26, 13, 6, 19, 5, 0, 65, 66, 62, 75, 69, + 0, 65, 68, 65, 4, 6, 2, 5, 9, 12, 72, 67, 79, + 72, 20, 74, 87, 70, 2, 67, 76, 78, 72, 77, 84, + 90, 93, 64, 1, 15, 65, 70, 2, 3, 4, 71, 67, 0, + 64, 79, 72, 77, 64, 9, 83, 67, 12, 70, 4, 66, 2, + 18, 70, 71, 3, 9, 80, 80, 103, 20, 24, 32, 11, + 6, 12, 4, 4, 6, 67, 64, 0, 78, 75, 77, 80, 77, + 85, 107, 80, 80, 78, 67, 73, 6, 14, 0, 10, 19, + 1, 64, 67, 68, 86, 79, 77, 95, 82, 91, 89, 104, + 100, 102, 103, 78, 76, 104, 72, 73, 83, 94, 87, + 88, 93, 87, 93, 95, 100, 103, 111, 111, 67, 76, + 91, 69, 9, 6, 14, 16, 19, 34, 22, 30, 31, 48, + 37, 34, 49, 47, 45, 12, 67, 83, 92, 107, 122, + 126, 126, 11, 45, 38, 37, 27, 35, 17, 13, 16, 6, + 73, 67, 10, 64, 23, 32, 64, 4, 13, 17, 5, 16, + 30, 4, 0, 28, 1, 83, 104, 119, 126, 126, 126, + 126 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, 14, + 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, 106, 64, + 68, 126, 126, 125, 46, 7, 69, 16, 25, 64, 71, 9, + 17, 66, 2, 66, 69, 69, 83, 74, 92, 5, 68, 70, + 65, 78, 73, 88, 13, 1, 64, 68, 8, 3, 22, 0, 0, + 0, 2, 95, 97, 8, 71, 69, 18, 68, 88, 2, 32, 22, + 51, 48, 17, 18, 6, 22, 4, 1, 5, 75, 77, 79, 77, + 25, 1, 9, 71, 66, 70, 68, 71, 65, 74, 73, 83, + 18, 68, 4, 69, 80, 0, 72, 3, 5, 2, 3, 11, 7, 71, + 65, 3, 67, 2, 71, 2, 73, 0, 2, 67, 11, 4, 66, + 69, 7, 68, 76, 70, 83, 74, 6, 64, 7, 7, 7, 31, + 15, 4, 66, 9, 66, 72, 3, 98, 71, 0, 84, 66, 77, + 8, 2, 74, 15, 7, 4, 85, 8, 76, 75, 3, 90, 9, 19, + 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, 72, + 65, 71, 69, 66, 69, 71, 69, 72, 79, 71, 70, 81, + 83, 81, 66, 64, 69, 70, 76, 79, 77, 77, 85, 92, + 88, 91, 107, 100, 110, 69, 70, 88, 68, 74, 77, + 81, 88, 92, 85, 88, 89, 80, 85, 91, 84, 86, 2, + 24, 18, 11, 7, 9, 3, 65, 0, 2, 8, 32, 21, 15, 8, + 19, 9, 9, 3, 16, 3, 42, 30, 23, 16, 23, 5, 64, + 66, 66, 70, 44, 21, 5, 2, 10, 64, 73, 70, 5, 39, + 26, 12, 6, 19, 5, 1, 64, 66, 62, 75, 68, 0, 64, + 67, 64, 6, 7, 3, 6, 10, 13, 72, 66, 79, 71, 22, + 74, 88, 70, 2, 67, 76, 79, 72, 78, 85, 91, 94, + 64, 1, 15, 65, 71, 1, 2, 4, 71, 67, 64, 64, 79, + 72, 78, 64, 9, 84, 67, 11, 71, 3, 67, 2, 19, 70, + 72, 3, 9, 80, 80, 104, 19, 23, 31, 10, 5, 11, 2, + 2, 4, 69, 66, 66, 81, 78, 78, 82, 80, 88, 111, + 83, 82, 80, 68, 74, 6, 15, 0, 12, 22, 64, 66, + 69, 70, 88, 81, 79, 97, 84, 92, 90, 105, 101, + 103, 104, 79, 77, 105, 73, 74, 84, 96, 89, 90, + 94, 89, 95, 96, 102, 105, 113, 112, 68, 77, 92, + 69, 9, 6, 15, 16, 19, 36, 23, 31, 32, 49, 39, + 35, 51, 48, 44, 11, 69, 85, 95, 109, 125, 126, + 126, 12, 45, 38, 37, 27, 36, 18, 13, 16, 6, 73, + 66, 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, + 0, 27, 64, 85, 107, 123, 126, 126, 126, 126 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, 12, + 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, 107, 64, + 70, 126, 126, 125, 49, 8, 69, 17, 25, 64, 71, + 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, 5, 68, + 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, + 0, 0, 2, 95, 97, 9, 72, 69, 18, 68, 88, 3, 34, + 23, 53, 50, 18, 19, 7, 24, 5, 2, 7, 74, 76, 78, + 76, 25, 1, 9, 71, 66, 70, 67, 69, 66, 74, 73, + 83, 18, 68, 4, 68, 80, 0, 72, 4, 5, 1, 3, 11, 7, + 71, 65, 3, 67, 2, 71, 2, 73, 0, 2, 68, 10, 3, + 67, 68, 8, 68, 77, 70, 82, 74, 6, 65, 7, 7, 7, + 32, 16, 4, 66, 9, 66, 73, 3, 99, 71, 0, 84, 67, + 78, 7, 2, 74, 16, 7, 4, 86, 7, 77, 75, 3, 90, 9, + 19, 12, 14, 17, 15, 8, 16, 15, 66, 3, 9, 2, 1, + 72, 65, 71, 70, 66, 69, 71, 70, 72, 79, 72, 70, + 82, 84, 81, 67, 66, 71, 72, 78, 81, 79, 79, 87, + 94, 90, 93, 110, 102, 111, 69, 71, 88, 69, 75, + 78, 82, 89, 94, 86, 89, 89, 80, 85, 91, 84, 86, + 2, 24, 18, 11, 7, 9, 3, 65, 1, 3, 8, 32, 21, 15, + 8, 19, 10, 10, 3, 18, 3, 42, 30, 23, 16, 23, 5, + 64, 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 70, 5, + 39, 25, 11, 5, 19, 5, 1, 64, 65, 62, 74, 67, 1, + 1, 66, 0, 7, 9, 4, 8, 12, 15, 71, 65, 78, 71, + 23, 73, 88, 70, 3, 67, 77, 79, 73, 79, 86, 92, + 95, 65, 0, 15, 66, 71, 1, 2, 4, 72, 68, 64, 65, + 80, 72, 78, 64, 9, 84, 68, 11, 72, 3, 68, 1, 19, + 71, 73, 2, 8, 81, 81, 106, 18, 23, 31, 9, 3, 9, + 0, 0, 2, 72, 69, 68, 84, 80, 80, 85, 84, 91, + 115, 85, 85, 82, 69, 75, 6, 16, 1, 13, 24, 65, + 68, 71, 71, 90, 83, 80, 99, 85, 94, 92, 107, + 103, 104, 105, 79, 77, 106, 75, 76, 86, 97, 91, + 92, 96, 90, 97, 98, 103, 106, 114, 112, 69, 77, + 93, 69, 10, 7, 15, 17, 20, 37, 24, 32, 33, 50, + 40, 36, 52, 49, 44, 9, 71, 88, 97, 112, 126, + 126, 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, + 72, 66, 11, 0, 25, 34, 64, 5, 14, 18, 5, 17, 32, + 4, 0, 25, 66, 88, 110, 126, 126, 126, 126, 126 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, 11, + 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, 109, 65, + 72, 126, 126, 126, 51, 9, 69, 18, 26, 64, 71, + 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, 5, 68, + 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, 3, 22, 0, + 0, 0, 3, 96, 97, 9, 73, 69, 18, 68, 88, 5, 35, + 25, 54, 51, 19, 20, 8, 25, 6, 3, 9, 74, 76, 78, + 75, 25, 1, 9, 70, 66, 69, 67, 68, 66, 75, 74, + 84, 18, 68, 4, 68, 80, 0, 72, 4, 4, 1, 3, 11, 6, + 71, 65, 3, 67, 1, 71, 1, 74, 0, 1, 70, 9, 2, 68, + 68, 8, 68, 78, 71, 82, 75, 5, 65, 7, 7, 7, 33, + 16, 4, 67, 9, 67, 74, 2, 100, 71, 0, 85, 67, 79, + 7, 1, 75, 16, 7, 4, 88, 7, 78, 75, 3, 91, 8, 18, + 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, 2, 0, 73, + 66, 72, 70, 67, 70, 72, 71, 73, 79, 72, 70, 83, + 86, 81, 69, 68, 73, 74, 80, 84, 81, 81, 89, 96, + 92, 95, 112, 104, 112, 69, 71, 89, 70, 77, 80, + 84, 91, 95, 88, 91, 90, 81, 86, 91, 84, 85, 2, + 24, 18, 11, 7, 9, 3, 65, 1, 4, 9, 32, 21, 15, 8, + 19, 10, 10, 4, 19, 3, 42, 30, 23, 15, 23, 5, 64, + 66, 65, 70, 44, 20, 4, 2, 10, 64, 73, 69, 5, 38, + 24, 10, 4, 18, 5, 1, 64, 65, 62, 73, 66, 1, 2, + 65, 0, 8, 10, 5, 9, 13, 16, 71, 65, 78, 70, 24, + 73, 89, 70, 3, 67, 77, 80, 73, 80, 87, 94, 96, + 66, 0, 15, 66, 72, 0, 1, 3, 73, 69, 65, 65, 81, + 73, 79, 64, 9, 85, 69, 10, 73, 3, 69, 0, 19, 72, + 74, 2, 8, 82, 82, 108, 17, 22, 30, 7, 2, 8, 65, + 65, 64, 74, 72, 71, 87, 83, 81, 88, 87, 94, 119, + 88, 87, 84, 71, 77, 6, 16, 1, 14, 26, 67, 70, + 73, 73, 93, 85, 82, 101, 87, 96, 93, 109, 104, + 105, 106, 80, 78, 107, 76, 77, 88, 99, 93, 94, + 97, 92, 99, 99, 104, 108, 116, 113, 70, 78, 94, + 69, 10, 7, 16, 17, 20, 38, 24, 33, 34, 51, 41, + 37, 53, 50, 43, 7, 73, 90, 100, 115, 126, 126, + 126, 12, 46, 39, 38, 28, 37, 18, 14, 17, 7, 72, + 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, 17, 32, 4, + 64, 24, 68, 90, 113, 126, 126, 126, 126, 126 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, 10, + 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, 110, 66, + 74, 126, 126, 126, 54, 11, 69, 19, 27, 64, 70, + 12, 18, 68, 2, 65, 67, 70, 84, 73, 93, 5, 68, + 68, 66, 79, 73, 88, 14, 2, 0, 67, 9, 3, 22, 0, + 0, 0, 4, 96, 97, 9, 74, 69, 18, 67, 88, 7, 37, + 27, 55, 53, 21, 21, 10, 26, 8, 4, 11, 74, 76, + 78, 74, 25, 1, 9, 69, 66, 68, 66, 67, 66, 75, + 74, 84, 18, 68, 5, 67, 79, 1, 72, 4, 4, 1, 3, + 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 71, 9, + 1, 69, 67, 8, 67, 79, 72, 82, 76, 5, 65, 8, 7, + 7, 34, 16, 4, 67, 10, 67, 74, 2, 101, 71, 0, 86, + 67, 80, 7, 1, 76, 16, 7, 4, 89, 7, 78, 75, 3, + 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, + 2, 0, 73, 66, 72, 70, 67, 70, 73, 71, 73, 79, + 72, 70, 84, 87, 81, 71, 69, 74, 75, 82, 86, 82, + 82, 91, 98, 93, 96, 114, 105, 113, 69, 71, 90, + 71, 78, 81, 85, 92, 96, 89, 92, 91, 82, 87, 91, + 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 5, 10, + 32, 21, 15, 8, 20, 10, 11, 5, 21, 3, 42, 30, 23, + 15, 24, 5, 64, 66, 64, 70, 45, 20, 4, 2, 11, 64, + 73, 68, 5, 38, 24, 10, 3, 18, 5, 1, 0, 64, 62, + 72, 65, 2, 3, 0, 1, 10, 11, 7, 10, 14, 18, 70, + 64, 78, 69, 26, 73, 90, 69, 4, 67, 77, 81, 73, + 80, 88, 95, 97, 66, 0, 15, 66, 72, 64, 1, 3, 74, + 69, 65, 65, 82, 73, 79, 0, 10, 85, 69, 9, 73, 3, + 69, 0, 19, 73, 75, 2, 8, 83, 82, 109, 17, 21, + 29, 6, 1, 7, 67, 67, 66, 76, 74, 74, 89, 85, 82, + 91, 90, 97, 123, 91, 89, 85, 72, 78, 6, 17, 1, + 15, 28, 69, 71, 75, 75, 95, 86, 83, 103, 88, 97, + 94, 110, 105, 106, 106, 80, 78, 108, 77, 78, 89, + 101, 94, 95, 98, 93, 100, 100, 105, 109, 117, + 114, 70, 79, 94, 68, 10, 7, 17, 18, 21, 39, 25, + 34, 35, 53, 42, 38, 55, 52, 42, 6, 75, 92, 103, + 118, 126, 126, 126, 13, 46, 39, 39, 28, 38, 19, + 14, 18, 8, 72, 65, 12, 0, 27, 37, 0, 6, 16, 20, + 5, 18, 33, 4, 64, 23, 70, 92, 115, 126, 126, + 126, 126, 126 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, 8, + 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, 66, + 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, 70, + 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, 68, + 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, 22, 0, + 0, 0, 4, 96, 97, 10, 75, 69, 18, 67, 88, 8, 39, + 28, 57, 55, 22, 22, 11, 28, 9, 5, 13, 73, 75, + 77, 73, 25, 1, 9, 69, 66, 68, 66, 65, 67, 75, + 74, 84, 18, 68, 5, 67, 79, 1, 72, 5, 4, 0, 3, + 11, 6, 70, 65, 4, 67, 1, 70, 0, 74, 0, 0, 72, 8, + 0, 70, 66, 9, 67, 80, 72, 81, 76, 5, 66, 8, 7, + 7, 35, 17, 4, 67, 10, 67, 75, 2, 102, 71, 0, 86, + 68, 81, 6, 1, 76, 17, 7, 4, 90, 6, 79, 75, 3, + 92, 7, 18, 12, 14, 17, 14, 7, 16, 14, 67, 2, 9, + 2, 0, 73, 66, 72, 71, 67, 70, 73, 72, 74, 79, + 73, 70, 85, 88, 81, 72, 71, 76, 77, 84, 88, 84, + 84, 93, 100, 95, 98, 117, 107, 114, 69, 72, 90, + 72, 79, 82, 86, 94, 98, 90, 93, 91, 82, 87, 91, + 83, 84, 3, 25, 18, 11, 7, 10, 4, 64, 2, 6, 10, + 32, 21, 15, 8, 20, 11, 12, 5, 23, 3, 42, 30, 23, + 15, 24, 5, 64, 66, 0, 70, 45, 19, 3, 2, 11, 64, + 73, 68, 5, 37, 23, 9, 2, 18, 5, 1, 0, 64, 62, + 71, 64, 3, 5, 1, 2, 11, 13, 8, 12, 16, 20, 69, + 0, 77, 69, 27, 72, 90, 69, 5, 67, 78, 81, 74, + 81, 89, 96, 98, 67, 64, 15, 67, 73, 64, 1, 3, + 75, 70, 65, 66, 83, 73, 79, 0, 10, 85, 70, 9, + 74, 3, 70, 64, 19, 74, 76, 1, 7, 84, 83, 111, + 16, 21, 29, 5, 64, 5, 69, 69, 68, 79, 77, 76, + 92, 87, 84, 94, 94, 100, 126, 93, 92, 87, 73, + 79, 6, 18, 2, 16, 30, 70, 73, 77, 76, 97, 88, + 85, 105, 89, 99, 96, 112, 107, 107, 107, 81, 78, + 109, 79, 80, 91, 102, 96, 97, 100, 95, 102, 102, + 106, 110, 118, 114, 71, 79, 95, 68, 11, 8, 17, + 18, 22, 40, 26, 35, 36, 54, 43, 39, 56, 53, 42, + 4, 77, 95, 105, 121, 126, 126, 126, 13, 47, 40, + 39, 29, 39, 19, 15, 18, 8, 71, 65, 13, 1, 28, + 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 21, 72, 95, + 118, 126, 126, 126, 126, 126 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, 7, + 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, 67, + 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, 69, + 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, 67, + 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, 22, 0, + 0, 0, 5, 96, 97, 10, 75, 70, 18, 67, 87, 10, 41, + 30, 58, 57, 23, 23, 13, 29, 10, 5, 14, 73, 75, + 77, 73, 26, 1, 9, 68, 65, 67, 65, 64, 67, 76, + 75, 85, 18, 68, 5, 66, 79, 2, 72, 5, 4, 0, 4, + 11, 5, 70, 65, 4, 67, 1, 70, 64, 74, 0, 64, 73, + 7, 0, 70, 66, 9, 67, 80, 73, 81, 77, 5, 66, 8, + 7, 7, 35, 17, 4, 67, 11, 67, 76, 2, 102, 72, 0, + 87, 68, 82, 6, 1, 77, 17, 7, 4, 92, 6, 80, 75, + 3, 93, 6, 18, 11, 14, 17, 14, 7, 16, 14, 67, 1, + 9, 1, 0, 73, 67, 73, 71, 68, 71, 74, 73, 74, 79, + 73, 69, 86, 90, 81, 74, 73, 78, 79, 86, 90, 86, + 86, 95, 102, 96, 99, 119, 109, 115, 69, 72, 91, + 73, 80, 83, 88, 95, 99, 91, 94, 92, 83, 88, 91, + 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 7, 11, + 31, 21, 15, 8, 21, 11, 13, 6, 25, 3, 43, 30, 23, + 15, 25, 5, 64, 65, 0, 70, 45, 19, 3, 2, 11, 0, + 72, 67, 5, 37, 23, 8, 2, 18, 5, 2, 1, 0, 62, 71, + 0, 3, 6, 2, 3, 13, 14, 9, 13, 17, 21, 69, 1, 77, + 68, 29, 72, 91, 69, 5, 67, 78, 82, 74, 82, 90, + 97, 99, 67, 64, 15, 67, 73, 65, 0, 3, 75, 70, + 66, 66, 83, 73, 80, 0, 10, 86, 70, 8, 75, 2, 71, + 64, 20, 74, 77, 1, 7, 84, 83, 112, 15, 20, 28, + 4, 65, 4, 71, 71, 70, 81, 79, 79, 95, 90, 85, + 96, 97, 103, 126, 96, 94, 89, 74, 80, 6, 19, 2, + 18, 33, 72, 75, 79, 78, 99, 90, 86, 107, 91, + 100, 97, 113, 108, 108, 108, 81, 79, 110, 80, + 81, 92, 104, 98, 99, 101, 96, 104, 103, 108, + 112, 120, 115, 72, 80, 96, 68, 11, 8, 18, 19, + 22, 42, 27, 36, 37, 55, 45, 40, 58, 54, 41, 3, + 79, 97, 108, 123, 126, 126, 126, 14, 47, 40, 40, + 29, 40, 20, 15, 19, 9, 71, 64, 13, 1, 29, 39, 0, + 7, 17, 21, 5, 19, 35, 4, 64, 20, 74, 97, 121, + 126, 126, 126, 126, 126 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, 6, + 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, 67, + 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, 69, + 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, 67, + 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, 22, 0, + 0, 0, 5, 97, 97, 11, 76, 70, 18, 67, 87, 12, 42, + 31, 60, 58, 24, 24, 14, 30, 11, 6, 16, 72, 75, + 76, 72, 26, 1, 9, 68, 65, 67, 65, 1, 67, 76, 75, + 85, 18, 68, 5, 66, 79, 2, 72, 6, 4, 0, 4, 11, 5, + 70, 65, 4, 67, 1, 70, 65, 75, 0, 65, 74, 6, 64, + 71, 65, 10, 67, 81, 73, 80, 77, 5, 66, 8, 7, 7, + 36, 17, 4, 68, 11, 68, 77, 1, 103, 72, 0, 87, + 69, 83, 6, 0, 78, 17, 7, 4, 93, 6, 81, 75, 3, + 93, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, + 1, 0, 74, 67, 73, 72, 68, 71, 75, 74, 75, 79, + 74, 69, 87, 91, 81, 75, 75, 80, 81, 88, 92, 88, + 88, 97, 104, 98, 101, 121, 111, 116, 69, 72, 91, + 74, 81, 84, 89, 97, 101, 92, 96, 93, 83, 88, 91, + 83, 83, 4, 25, 18, 11, 8, 10, 4, 64, 3, 8, 11, + 31, 21, 15, 8, 21, 12, 13, 7, 27, 3, 43, 30, 23, + 15, 25, 5, 64, 65, 1, 70, 45, 19, 2, 2, 11, 0, + 72, 66, 5, 36, 22, 7, 1, 18, 5, 2, 1, 0, 62, 70, + 1, 4, 7, 3, 4, 14, 15, 10, 14, 19, 23, 68, 1, + 77, 68, 30, 72, 91, 69, 6, 67, 79, 82, 74, 83, + 91, 98, 100, 68, 65, 15, 68, 74, 65, 0, 3, 76, + 71, 66, 66, 84, 74, 80, 0, 10, 86, 71, 8, 76, 2, + 72, 65, 20, 75, 78, 0, 6, 85, 84, 114, 14, 19, + 28, 3, 66, 2, 73, 73, 72, 84, 82, 81, 98, 92, + 86, 99, 100, 106, 126, 99, 97, 91, 75, 82, 6, + 20, 2, 19, 35, 74, 77, 81, 80, 101, 92, 88, 109, + 92, 102, 98, 115, 110, 109, 109, 82, 79, 111, + 81, 83, 94, 106, 100, 101, 103, 98, 106, 105, + 109, 113, 121, 116, 73, 81, 97, 68, 12, 8, 18, + 19, 23, 43, 27, 37, 38, 56, 46, 41, 59, 55, 41, + 1, 81, 100, 110, 126, 126, 126, 126, 14, 48, 41, + 40, 29, 40, 20, 15, 19, 9, 71, 64, 14, 2, 30, + 40, 0, 8, 17, 21, 5, 19, 36, 4, 64, 19, 76, 100, + 124, 126, 126, 126, 126, 126 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, 4, + 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, 68, + 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, 69, + 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, 67, + 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, 22, 0, + 0, 0, 6, 97, 97, 11, 77, 70, 18, 66, 87, 13, 44, + 33, 61, 60, 26, 25, 15, 32, 12, 7, 18, 72, 74, + 76, 71, 26, 1, 9, 67, 65, 66, 64, 2, 68, 76, 75, + 85, 18, 68, 6, 65, 79, 2, 72, 6, 4, 64, 4, 11, + 5, 69, 65, 5, 67, 1, 70, 65, 75, 0, 65, 75, 6, + 65, 72, 64, 10, 67, 82, 74, 80, 78, 5, 67, 8, 7, + 7, 37, 18, 4, 68, 11, 68, 78, 1, 104, 72, 0, 88, + 69, 84, 5, 0, 78, 18, 7, 4, 94, 5, 82, 75, 3, + 94, 5, 18, 11, 14, 17, 14, 7, 16, 13, 67, 1, 9, + 1, 0, 74, 67, 73, 72, 68, 71, 75, 75, 75, 79, + 74, 69, 88, 92, 81, 77, 77, 81, 82, 90, 94, 90, + 90, 99, 106, 100, 103, 124, 112, 117, 69, 73, + 92, 75, 82, 85, 90, 98, 102, 93, 97, 93, 84, 89, + 91, 83, 82, 4, 25, 18, 11, 8, 10, 5, 0, 4, 9, + 12, 31, 21, 15, 8, 21, 12, 14, 7, 29, 3, 43, 30, + 23, 15, 25, 5, 64, 65, 2, 70, 46, 18, 2, 2, 11, + 0, 72, 66, 5, 36, 21, 6, 0, 18, 5, 2, 1, 1, 62, + 69, 2, 5, 9, 4, 5, 15, 17, 11, 16, 20, 25, 67, + 2, 76, 67, 31, 71, 92, 68, 7, 67, 79, 83, 75, + 83, 92, 99, 101, 69, 65, 15, 68, 74, 66, 0, 3, + 77, 72, 66, 67, 85, 74, 80, 0, 10, 86, 72, 7, + 76, 2, 73, 66, 20, 76, 79, 0, 6, 86, 85, 116, + 13, 19, 27, 2, 68, 1, 75, 75, 74, 86, 85, 84, + 101, 94, 88, 102, 104, 109, 126, 101, 99, 93, + 76, 83, 6, 21, 3, 20, 37, 75, 78, 83, 81, 103, + 94, 89, 111, 93, 104, 100, 117, 111, 110, 110, + 82, 79, 112, 83, 84, 96, 107, 101, 102, 104, 99, + 107, 106, 110, 114, 122, 116, 73, 81, 98, 67, + 12, 9, 19, 20, 24, 44, 28, 38, 39, 58, 47, 42, + 60, 57, 40, 64, 83, 102, 113, 126, 126, 126, + 126, 14, 48, 41, 41, 30, 41, 20, 16, 20, 10, 70, + 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, 20, 37, 4, + 64, 17, 78, 102, 126, 126, 126, 126, 126, 126 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, 3, + 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, 68, + 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, 68, + 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, 67, 65, + 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, 0, + 0, 6, 97, 97, 12, 78, 70, 18, 66, 87, 15, 46, + 34, 62, 62, 27, 26, 17, 33, 13, 8, 20, 71, 74, + 75, 70, 26, 1, 9, 67, 65, 66, 64, 4, 68, 77, 76, + 86, 18, 68, 6, 65, 79, 3, 72, 7, 4, 64, 4, 11, + 4, 69, 65, 5, 67, 1, 70, 66, 75, 0, 66, 76, 5, + 66, 73, 64, 11, 67, 83, 74, 79, 78, 5, 67, 8, 7, + 7, 38, 18, 4, 68, 12, 68, 79, 1, 105, 72, 0, 88, + 70, 85, 5, 0, 79, 18, 7, 4, 96, 5, 83, 75, 3, + 94, 4, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, + 1, 0, 74, 68, 74, 73, 69, 72, 76, 76, 76, 79, + 75, 69, 89, 94, 81, 78, 79, 83, 84, 92, 96, 92, + 92, 101, 108, 101, 104, 126, 114, 118, 69, 73, + 92, 76, 83, 86, 92, 100, 104, 94, 98, 94, 84, + 89, 91, 83, 82, 5, 25, 18, 11, 8, 10, 5, 0, 4, + 10, 12, 31, 21, 15, 8, 22, 13, 15, 8, 31, 3, 43, + 30, 23, 15, 26, 5, 64, 65, 2, 70, 46, 18, 1, 2, + 11, 0, 72, 65, 5, 35, 21, 5, 64, 18, 5, 2, 2, 1, + 62, 68, 3, 5, 10, 5, 6, 17, 18, 12, 17, 22, 26, + 67, 3, 76, 67, 33, 71, 92, 68, 7, 67, 80, 83, + 75, 84, 93, 100, 102, 69, 66, 15, 69, 75, 66, + 64, 3, 78, 72, 67, 67, 86, 74, 81, 0, 10, 87, + 72, 7, 77, 2, 74, 66, 20, 77, 80, 64, 5, 87, 85, + 117, 12, 18, 27, 1, 69, 64, 77, 77, 76, 89, 87, + 86, 104, 97, 89, 105, 107, 112, 126, 104, 102, + 95, 77, 84, 6, 22, 3, 21, 39, 77, 80, 85, 83, + 105, 96, 91, 113, 95, 105, 101, 118, 113, 111, + 111, 83, 80, 113, 84, 86, 97, 109, 103, 104, + 106, 101, 109, 108, 111, 116, 124, 117, 74, 82, + 99, 67, 13, 9, 19, 20, 24, 45, 29, 39, 40, 59, + 48, 43, 62, 58, 40, 65, 85, 105, 115, 126, 126, + 126, 126, 15, 49, 42, 41, 30, 42, 21, 16, 20, + 10, 70, 0, 15, 3, 32, 42, 1, 9, 18, 22, 5, 20, + 38, 4, 64, 16, 80, 105, 126, 126, 126, 126, 126, + 126 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, + 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, + 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, + 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, 67, + 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, 22, 0, + 0, 0, 7, 97, 97, 12, 79, 70, 18, 66, 87, 17, 48, + 36, 62, 62, 28, 27, 18, 34, 14, 9, 22, 71, 74, + 75, 69, 26, 1, 9, 66, 65, 65, 0, 5, 68, 77, 76, + 86, 18, 68, 6, 64, 79, 3, 72, 7, 4, 64, 4, 11, + 4, 69, 65, 5, 67, 1, 70, 67, 75, 0, 67, 77, 4, + 67, 74, 0, 11, 67, 84, 75, 79, 79, 5, 67, 8, 7, + 7, 39, 18, 4, 68, 12, 68, 80, 1, 106, 72, 0, 89, + 70, 86, 5, 0, 80, 18, 7, 4, 97, 5, 84, 75, 3, + 95, 3, 18, 11, 14, 17, 14, 7, 16, 13, 67, 0, 9, + 1, 0, 74, 68, 74, 73, 69, 72, 77, 77, 76, 79, + 75, 69, 90, 95, 81, 80, 81, 85, 86, 94, 98, 94, + 94, 103, 110, 103, 106, 126, 116, 119, 69, 73, + 93, 77, 84, 87, 93, 101, 105, 95, 99, 95, 85, + 90, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, 5, + 11, 13, 31, 21, 15, 8, 22, 13, 16, 9, 33, 3, 43, + 30, 23, 15, 26, 5, 64, 65, 3, 70, 46, 18, 1, 2, + 11, 0, 72, 64, 5, 35, 20, 4, 65, 18, 5, 2, 2, 2, + 62, 67, 4, 6, 11, 6, 7, 18, 19, 13, 18, 23, 28, + 66, 4, 76, 66, 34, 71, 93, 68, 8, 67, 80, 84, + 75, 85, 94, 101, 103, 70, 66, 15, 69, 75, 67, + 64, 3, 79, 73, 67, 67, 87, 74, 81, 0, 10, 87, + 73, 6, 78, 2, 75, 67, 20, 78, 81, 64, 5, 88, 86, + 119, 11, 17, 26, 0, 70, 65, 79, 79, 78, 91, 90, + 89, 107, 99, 90, 108, 110, 115, 126, 107, 104, + 97, 78, 85, 6, 23, 3, 22, 41, 79, 82, 87, 85, + 107, 98, 92, 115, 96, 107, 102, 120, 114, 112, + 112, 83, 80, 114, 85, 87, 99, 111, 105, 106, + 107, 102, 111, 109, 112, 117, 125, 118, 75, 83, + 100, 67, 13, 9, 20, 21, 25, 46, 30, 40, 41, 60, + 49, 44, 62, 59, 39, 67, 87, 107, 118, 126, 126, + 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, 21, + 11, 70, 0, 16, 3, 33, 43, 1, 10, 19, 23, 5, 21, + 39, 4, 64, 15, 82, 107, 126, 126, 126, 126, 126, + 126 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, + 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, 118, + 70, 87, 126, 126, 126, 62, 19, 70, 24, 31, 65, + 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, 94, 5, 67, + 64, 69, 81, 72, 88, 17, 4, 1, 65, 12, 2, 22, 0, + 0, 0, 7, 98, 97, 12, 80, 71, 18, 66, 87, 18, 49, + 37, 62, 62, 29, 28, 19, 35, 15, 9, 23, 71, 74, + 75, 69, 26, 1, 9, 66, 65, 65, 0, 6, 69, 78, 77, + 87, 18, 68, 6, 64, 79, 3, 72, 7, 3, 65, 4, 10, + 3, 69, 66, 5, 67, 0, 70, 68, 76, 64, 68, 79, 3, + 68, 75, 0, 11, 67, 85, 76, 79, 80, 4, 68, 8, 7, + 7, 39, 18, 4, 69, 12, 69, 81, 0, 107, 73, 64, + 90, 71, 87, 4, 64, 81, 18, 7, 4, 99, 4, 85, 75, + 3, 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, + 9, 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, + 79, 76, 69, 91, 97, 81, 82, 83, 87, 88, 96, 101, + 96, 96, 105, 112, 105, 108, 126, 118, 121, 70, + 74, 94, 78, 86, 89, 95, 103, 107, 97, 101, 96, + 86, 91, 91, 83, 81, 5, 25, 18, 11, 8, 10, 5, 0, + 5, 12, 13, 30, 21, 15, 8, 22, 13, 16, 9, 34, 2, + 43, 30, 22, 14, 26, 5, 64, 65, 3, 70, 46, 17, 0, + 1, 11, 0, 72, 64, 5, 34, 19, 3, 66, 17, 5, 2, 2, + 2, 62, 67, 5, 6, 12, 7, 7, 19, 20, 14, 19, 24, + 29, 66, 4, 76, 66, 35, 71, 94, 68, 8, 67, 81, + 85, 76, 86, 95, 103, 105, 71, 67, 15, 70, 76, + 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 0, 10, + 88, 74, 5, 79, 1, 76, 68, 20, 79, 83, 65, 4, 89, + 87, 121, 10, 16, 25, 65, 72, 67, 81, 81, 81, 94, + 93, 92, 110, 102, 92, 111, 114, 118, 126, 110, + 107, 99, 80, 87, 6, 23, 3, 23, 43, 81, 84, 89, + 87, 110, 100, 94, 118, 98, 109, 104, 122, 116, + 113, 113, 84, 81, 116, 87, 89, 101, 113, 107, + 108, 109, 104, 113, 111, 114, 119, 126, 119, 76, + 84, 101, 67, 13, 9, 20, 21, 25, 47, 30, 41, 41, + 61, 50, 45, 62, 60, 38, 69, 90, 110, 121, 126, + 126, 126, 126, 15, 49, 42, 42, 30, 43, 21, 16, + 21, 11, 70, 0, 16, 3, 34, 44, 1, 10, 19, 23, 5, + 21, 39, 4, 65, 13, 85, 110, 126, 126, 126, 126, + 126, 126 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, + 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, 119, + 70, 88, 126, 126, 126, 62, 21, 70, 25, 32, 65, + 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, 94, 5, 66, + 0, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, + 0, 0, 8, 98, 97, 13, 80, 71, 18, 65, 86, 20, 51, + 39, 62, 62, 31, 29, 21, 37, 17, 10, 25, 70, 73, + 74, 68, 27, 2, 10, 65, 64, 64, 1, 8, 69, 78, 77, + 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, + 68, 66, 6, 67, 0, 69, 68, 76, 64, 68, 80, 3, 68, + 75, 1, 12, 66, 85, 76, 78, 80, 4, 68, 9, 7, 7, + 40, 19, 5, 69, 13, 69, 81, 0, 107, 73, 64, 90, + 71, 88, 4, 64, 81, 19, 8, 4, 100, 4, 85, 74, 3, + 96, 2, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, + 0, 64, 75, 69, 75, 74, 70, 73, 78, 78, 77, 78, + 76, 68, 91, 98, 80, 83, 84, 88, 89, 98, 103, 97, + 97, 107, 113, 106, 109, 126, 119, 122, 70, 74, + 94, 79, 87, 90, 96, 104, 108, 98, 102, 96, 86, + 91, 90, 82, 80, 6, 26, 18, 11, 9, 11, 6, 1, 6, + 14, 14, 30, 21, 15, 8, 23, 14, 17, 10, 36, 2, + 44, 31, 22, 14, 27, 5, 64, 64, 4, 70, 47, 17, 0, + 1, 12, 1, 71, 0, 5, 34, 19, 3, 66, 17, 5, 3, 3, + 3, 62, 66, 6, 7, 14, 9, 8, 21, 22, 16, 21, 26, + 31, 65, 5, 75, 65, 37, 70, 94, 67, 9, 66, 81, + 85, 76, 86, 95, 104, 106, 71, 67, 16, 70, 76, + 68, 65, 2, 80, 74, 68, 68, 88, 75, 82, 1, 11, + 88, 74, 5, 79, 1, 76, 68, 21, 79, 84, 65, 4, 89, + 87, 122, 10, 16, 25, 66, 73, 68, 83, 83, 83, 96, + 95, 94, 112, 104, 93, 113, 117, 121, 126, 112, + 109, 100, 81, 88, 6, 24, 4, 25, 46, 82, 85, 90, + 88, 112, 101, 95, 120, 99, 110, 105, 123, 117, + 114, 113, 84, 81, 117, 88, 90, 102, 114, 108, + 109, 110, 105, 114, 112, 115, 120, 126, 119, 76, + 84, 101, 66, 14, 10, 21, 22, 26, 49, 31, 42, 42, + 62, 52, 46, 62, 62, 38, 70, 92, 112, 123, 126, + 126, 126, 126, 16, 50, 43, 43, 31, 44, 22, 17, + 22, 12, 69, 1, 17, 4, 36, 46, 2, 11, 20, 24, 6, + 22, 40, 4, 65, 12, 87, 112, 126, 126, 126, 126, + 126, 126 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, + 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, 120, + 71, 90, 126, 126, 126, 62, 22, 70, 26, 33, 65, + 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, 94, 5, 66, + 1, 69, 81, 71, 88, 18, 5, 2, 64, 13, 2, 22, 0, + 0, 0, 9, 98, 97, 13, 81, 71, 18, 65, 86, 22, 53, + 41, 62, 62, 32, 30, 22, 38, 18, 11, 27, 70, 73, + 74, 67, 27, 2, 10, 64, 64, 0, 1, 9, 69, 78, 77, + 87, 19, 68, 7, 0, 78, 4, 71, 8, 3, 65, 5, 10, 3, + 68, 66, 6, 67, 0, 69, 69, 76, 64, 69, 81, 2, 69, + 76, 2, 12, 66, 86, 77, 78, 81, 4, 68, 9, 7, 7, + 41, 19, 5, 69, 13, 69, 82, 0, 108, 73, 64, 91, + 71, 89, 4, 64, 82, 19, 8, 4, 101, 4, 86, 74, 3, + 97, 1, 17, 10, 14, 17, 13, 6, 16, 12, 68, 64, 9, + 0, 64, 75, 69, 75, 74, 70, 73, 79, 79, 78, 78, + 76, 68, 92, 99, 80, 85, 86, 90, 91, 100, 105, + 99, 99, 109, 115, 108, 111, 126, 121, 123, 70, + 74, 95, 80, 88, 91, 97, 106, 109, 99, 103, 97, + 87, 92, 90, 82, 79, 6, 26, 18, 11, 9, 11, 6, 1, + 6, 15, 15, 30, 21, 15, 8, 23, 14, 18, 11, 38, 2, + 44, 31, 22, 14, 27, 5, 64, 64, 5, 70, 47, 17, 0, + 1, 12, 1, 71, 1, 5, 33, 18, 2, 67, 17, 5, 3, 3, + 3, 62, 65, 7, 8, 15, 10, 9, 22, 23, 17, 22, 27, + 33, 64, 6, 75, 64, 38, 70, 95, 67, 10, 66, 81, + 86, 76, 87, 96, 105, 107, 72, 67, 16, 70, 77, + 69, 65, 2, 81, 75, 68, 68, 89, 75, 82, 1, 11, + 88, 75, 4, 80, 1, 77, 69, 21, 80, 85, 65, 4, 90, + 88, 124, 9, 15, 24, 67, 74, 69, 85, 85, 85, 98, + 98, 97, 115, 106, 94, 116, 120, 124, 126, 115, + 111, 102, 82, 89, 6, 25, 4, 26, 48, 84, 87, 92, + 90, 114, 103, 97, 122, 100, 112, 106, 125, 118, + 115, 114, 85, 81, 118, 89, 91, 104, 116, 110, + 111, 111, 107, 116, 113, 116, 121, 126, 120, 77, + 85, 102, 66, 14, 10, 22, 22, 27, 50, 32, 43, 43, + 62, 53, 47, 62, 62, 37, 72, 94, 114, 126, 126, + 126, 126, 126, 16, 50, 43, 43, 31, 45, 22, 17, + 22, 12, 69, 1, 18, 4, 37, 47, 2, 12, 21, 25, 6, + 22, 41, 4, 65, 11, 89, 114, 126, 126, 126, 126, + 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, + 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, 121, + 71, 92, 126, 126, 126, 62, 23, 70, 27, 34, 65, + 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, 94, 5, 66, + 1, 69, 81, 71, 88, 19, 5, 2, 64, 14, 2, 22, 0, + 0, 0, 9, 98, 97, 14, 82, 71, 18, 65, 86, 24, 55, + 42, 62, 62, 33, 31, 24, 39, 19, 12, 29, 69, 73, + 73, 66, 27, 2, 10, 64, 64, 0, 2, 11, 69, 79, 78, + 88, 19, 68, 7, 1, 78, 5, 71, 9, 3, 65, 5, 10, 2, + 68, 66, 6, 67, 0, 69, 70, 76, 64, 70, 82, 1, 70, + 77, 2, 13, 66, 87, 77, 77, 81, 4, 68, 9, 7, 7, + 42, 19, 5, 69, 14, 69, 83, 0, 109, 73, 64, 91, + 72, 90, 4, 64, 83, 19, 8, 4, 103, 4, 87, 74, 3, + 97, 0, 17, 10, 14, 17, 13, 6, 16, 12, 68, 65, 9, + 0, 64, 75, 70, 76, 75, 71, 74, 80, 80, 78, 78, + 77, 68, 93, 101, 80, 86, 88, 92, 93, 102, 107, + 101, 101, 111, 117, 109, 112, 126, 123, 124, 70, + 74, 95, 81, 89, 92, 99, 107, 111, 100, 104, 98, + 87, 92, 90, 82, 79, 7, 26, 18, 11, 9, 11, 6, 1, + 7, 16, 15, 30, 21, 15, 8, 24, 15, 19, 12, 40, 2, + 44, 31, 22, 14, 28, 5, 64, 64, 5, 70, 47, 17, + 64, 1, 12, 1, 71, 2, 5, 33, 18, 1, 68, 17, 5, 3, + 4, 4, 62, 64, 8, 8, 16, 11, 10, 24, 24, 18, 23, + 29, 34, 64, 7, 75, 64, 40, 70, 95, 67, 10, 66, + 82, 86, 76, 88, 97, 106, 108, 72, 68, 16, 71, + 77, 69, 66, 2, 82, 75, 69, 68, 90, 75, 83, 1, + 11, 89, 75, 4, 81, 1, 78, 69, 21, 81, 86, 66, 3, + 91, 88, 125, 8, 14, 24, 68, 75, 71, 87, 87, 87, + 101, 100, 99, 118, 109, 95, 119, 123, 126, 126, + 118, 114, 104, 83, 90, 6, 26, 4, 27, 50, 86, 89, + 94, 92, 116, 105, 98, 124, 102, 113, 107, 126, + 120, 116, 115, 85, 82, 119, 90, 93, 105, 118, + 112, 113, 113, 108, 118, 115, 117, 123, 126, + 121, 78, 86, 103, 66, 15, 10, 22, 23, 27, 51, + 33, 44, 44, 62, 54, 48, 62, 62, 37, 73, 96, 117, + 126, 126, 126, 126, 126, 17, 51, 44, 44, 31, 46, + 23, 17, 23, 13, 69, 2, 18, 5, 38, 48, 2, 12, 21, + 25, 6, 23, 42, 4, 65, 10, 91, 117, 126, 126, + 126, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 38, 62, + 62, 54, 22, 118, 65, 71, 79, 11, 13, 70, 9, 29, + 41, 62, 61, 27, 69, 126, 101, 76, 71, 79, 11, + 69, 90, 11, 20, 69, 82, 96, 4, 75, 87, 100, 7, + 74, 85, 4, 81, 86, 95, 66, 77, 70, 86, 72, 2, + 22, 0, 0, 0, 83, 86, 97, 72, 22, 1, 48, 12, 80, + 126, 91, 96, 81, 98, 102, 97, 119, 99, 110, 102, + 126, 80, 89, 94, 92, 24, 65, 84, 126, 73, 104, + 91, 126, 8, 7, 8, 2, 10, 68, 74, 88, 103, 91, + 89, 92, 76, 87, 110, 105, 78, 112, 99, 126, 126, + 126, 126, 66, 78, 71, 72, 4, 8, 70, 75, 89, 119, + 75, 43, 41, 126, 9, 2, 5, 3, 2, 67, 84, 74, 65, + 11, 6, 2, 69, 70, 8, 71, 5, 2, 22, 38, 31, 20, + 16, 19, 12, 17, 25, 66, 25, 21, 29, 89, 18, 35, + 32, 62, 62, 48, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 53, 62, 62, 62, 62, 62, 62, 62, 56, 62, + 62, 62, 27, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 53, 45, 38, 22, 75, 72, 77, 28, 32, 28, + 33, 18, 21, 18, 37, 9, 66, 7, 73, 67, 116, 112, + 71, 2, 10, 66, 77, 80, 84, 87, 126, 101, 24, 10, + 2, 75, 77, 91, 107, 111, 122, 76, 19, 11, 6, 5, + 72, 69, 69, 74, 86, 66, 29, 31, 32, 11, 8, 67, + 73, 89, 11, 59, 55, 55, 44, 26, 2, 73, 70, 78, + 62, 126, 124, 110, 126, 124, 105, 121, 117, 102, + 117, 116, 122, 95, 100, 95, 111, 114, 89, 80, + 82, 85, 81, 72, 64, 67, 7, 69, 69, 69, 69, 67, + 77, 64, 2, 67, 64, 6, 65, 66, 1, 12, 66, 71, 75, + 70, 72, 3, 26, 16, 28, 26, 22, 22, 15, 22, 22, + 4, 13, 23, 66, 13, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 54, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 49, 37, 26, 8, 65, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 43, 33, + 19, 15, 14, 18, 41, 41, 42, 43, 35, 39, 29, 21, + 24, 13, 70, 9, 71, 83, 31, 14, 9, 85, 81, 77, + 81, 80, 73, 74, 83, 71, 67, 2, 66, 66, 4, 4, 62, + 62, 62, 62, 62, 60, 53, 36, 6, 71, 39, 27, 21, + 11, 6, 0, 65, 67, 82, 81, 76, 72, 78, 72, 68, + 70, 76, 66, 1, 6, 2, 3, 9, 5, 62, 62, 62, 62, + 62, 60, 53, 36, 6 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 37, + 61, 62, 55, 22, 116, 65, 70, 78, 11, 13, 69, + 9, 28, 40, 61, 58, 25, 70, 124, 100, 75, 70, + 78, 11, 69, 89, 11, 20, 68, 81, 95, 4, 75, 86, + 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, + 71, 2, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 48, + 12, 80, 124, 89, 94, 79, 95, 100, 95, 117, 97, + 108, 100, 124, 80, 88, 93, 91, 24, 65, 83, + 124, 72, 103, 90, 125, 8, 7, 8, 2, 11, 68, 73, + 87, 102, 90, 88, 91, 75, 86, 108, 103, 77, + 110, 97, 122, 122, 123, 124, 65, 77, 70, 71, + 4, 9, 69, 74, 88, 116, 74, 41, 40, 124, 9, 3, + 5, 4, 3, 66, 82, 73, 64, 11, 6, 2, 68, 69, 7, + 70, 5, 2, 22, 37, 31, 20, 16, 19, 12, 17, 24, + 65, 25, 21, 29, 89, 18, 35, 32, 62, 62, 47, + 62, 62, 62, 61, 62, 62, 62, 62, 62, 62, 52, + 62, 62, 62, 62, 62, 62, 62, 54, 62, 60, 62, + 26, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 61, 52, 44, 37, 21, 75, 72, 77, 28, 31, 27, + 32, 17, 20, 17, 36, 8, 66, 6, 73, 67, 115, + 110, 70, 3, 10, 65, 76, 79, 83, 86, 124, 99, + 25, 11, 3, 74, 76, 89, 105, 109, 120, 75, 20, + 12, 7, 6, 71, 68, 68, 73, 85, 66, 30, 31, 32, + 11, 9, 66, 73, 88, 11, 59, 55, 54, 43, 26, 3, + 72, 69, 77, 62, 124, 122, 108, 124, 122, 103, + 119, 115, 100, 115, 114, 119, 94, 99, 94, 109, + 112, 88, 79, 81, 84, 80, 71, 64, 67, 7, 69, + 69, 69, 68, 66, 76, 0, 2, 66, 0, 6, 64, 65, 1, + 12, 65, 70, 74, 69, 71, 3, 25, 16, 27, 26, 22, + 22, 15, 22, 22, 4, 13, 22, 66, 12, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 52, 62, 62, 62, 62, 62, 62, 62, 61, 62, 48, + 36, 25, 8, 65, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 42, 32, 18, 15, 14, 17, 40, + 40, 41, 41, 34, 38, 28, 20, 23, 12, 70, 8, 71, + 83, 30, 13, 8, 84, 80, 76, 80, 78, 71, 73, 82, + 70, 66, 3, 65, 65, 4, 4, 62, 62, 62, 62, 60, + 56, 49, 32, 4, 70, 39, 28, 22, 12, 7, 1, 64, + 66, 81, 80, 75, 71, 77, 71, 67, 69, 75, 65, 2, + 6, 3, 4, 9, 5, 62, 62, 62, 62, 60, 56, 49, 32, + 4 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 36, + 59, 61, 55, 22, 114, 65, 70, 77, 11, 12, 69, + 8, 26, 39, 58, 54, 22, 72, 121, 99, 75, 70, + 77, 11, 69, 88, 11, 19, 68, 81, 94, 4, 75, 86, + 99, 7, 73, 84, 4, 80, 85, 94, 65, 76, 70, 85, + 71, 2, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 47, + 12, 80, 122, 88, 93, 77, 93, 99, 94, 115, 96, + 107, 99, 122, 80, 88, 93, 91, 24, 65, 82, 122, + 72, 102, 89, 123, 8, 7, 8, 1, 11, 68, 73, 86, + 101, 89, 87, 90, 75, 85, 107, 102, 76, 109, + 96, 117, 118, 120, 121, 65, 77, 70, 71, 4, 9, + 69, 74, 88, 114, 74, 39, 38, 121, 9, 3, 5, 4, + 3, 66, 80, 72, 64, 11, 6, 2, 67, 68, 6, 70, 5, + 2, 21, 36, 30, 20, 15, 19, 12, 17, 23, 65, 24, + 20, 28, 89, 18, 34, 31, 62, 62, 46, 60, 62, + 62, 59, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 62, 52, 62, 58, 62, 24, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 50, + 42, 35, 19, 75, 72, 78, 27, 30, 26, 31, 16, + 19, 16, 34, 7, 66, 5, 74, 68, 114, 109, 69, 3, + 10, 65, 75, 78, 82, 85, 122, 98, 25, 11, 3, + 73, 75, 88, 103, 107, 118, 74, 21, 13, 8, 7, + 70, 68, 68, 73, 84, 66, 31, 31, 31, 11, 9, 66, + 73, 88, 11, 59, 54, 53, 42, 26, 3, 72, 69, 77, + 62, 123, 121, 107, 122, 120, 102, 117, 113, + 99, 113, 112, 117, 93, 98, 94, 108, 110, 88, + 79, 81, 83, 80, 71, 64, 67, 6, 69, 69, 69, 68, + 66, 75, 0, 2, 66, 0, 6, 64, 65, 1, 11, 65, 70, + 74, 69, 70, 2, 24, 16, 26, 25, 21, 21, 15, 21, + 21, 4, 13, 21, 66, 11, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 62, 59, 59, 46, 34, 24, 7, 66, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 40, 30, 16, 14, 13, 15, 39, 39, 39, 39, + 32, 36, 26, 19, 21, 11, 71, 7, 72, 84, 28, 12, + 7, 84, 80, 75, 80, 77, 70, 73, 81, 69, 65, 3, + 65, 64, 4, 4, 62, 62, 62, 62, 57, 52, 45, 28, + 1, 70, 39, 28, 22, 12, 8, 1, 64, 66, 81, 80, + 75, 71, 77, 70, 66, 69, 75, 65, 2, 6, 3, 5, 9, + 5, 62, 62, 62, 62, 57, 52, 45, 28, 1 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 34, 57, + 60, 55, 22, 112, 65, 69, 76, 11, 12, 69, 8, + 25, 38, 56, 51, 20, 73, 118, 98, 75, 69, 76, + 11, 70, 87, 11, 19, 68, 81, 94, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 84, 94, 65, 76, 70, 85, 71, + 2, 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 46, 11, + 80, 119, 87, 92, 76, 91, 97, 92, 113, 94, 106, + 98, 120, 80, 88, 92, 91, 24, 65, 81, 120, 72, + 101, 89, 121, 8, 6, 7, 1, 11, 68, 72, 86, 100, + 88, 87, 89, 74, 84, 105, 100, 76, 108, 95, + 112, 113, 117, 118, 65, 77, 70, 70, 4, 9, 68, + 73, 87, 112, 74, 37, 36, 118, 9, 3, 5, 4, 3, + 65, 79, 71, 64, 11, 6, 2, 67, 67, 5, 70, 5, 1, + 21, 35, 30, 20, 15, 19, 12, 17, 22, 65, 23, + 19, 28, 89, 18, 34, 31, 62, 62, 45, 58, 62, + 62, 57, 62, 62, 62, 62, 62, 61, 48, 62, 62, + 62, 62, 62, 62, 60, 50, 62, 56, 62, 22, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 48, + 40, 34, 17, 75, 72, 78, 26, 29, 25, 30, 15, + 18, 15, 32, 6, 67, 4, 75, 68, 114, 107, 68, 4, + 10, 65, 74, 78, 82, 85, 120, 97, 25, 11, 4, + 72, 74, 87, 102, 106, 116, 73, 21, 13, 8, 7, + 69, 67, 68, 73, 84, 66, 31, 31, 30, 11, 9, 66, + 73, 87, 11, 58, 54, 52, 41, 26, 3, 72, 69, 77, + 62, 122, 119, 106, 121, 119, 101, 115, 111, + 98, 112, 110, 115, 93, 97, 93, 107, 108, 87, + 79, 81, 83, 79, 71, 64, 67, 6, 69, 69, 70, 67, + 65, 74, 0, 2, 65, 0, 6, 64, 65, 1, 11, 65, 70, + 74, 69, 70, 1, 23, 16, 25, 24, 20, 21, 15, 20, + 20, 4, 13, 20, 66, 10, 62, 62, 61, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, + 62, 62, 62, 62, 62, 57, 57, 44, 32, 22, 6, 67, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, + 60, 38, 28, 15, 13, 12, 14, 37, 37, 37, 37, + 31, 34, 24, 18, 20, 10, 72, 6, 73, 85, 27, 11, + 6, 84, 79, 75, 79, 76, 69, 73, 81, 69, 65, 3, + 64, 0, 4, 4, 62, 62, 62, 59, 54, 48, 41, 24, + 65, 70, 39, 28, 22, 12, 8, 2, 64, 66, 80, 80, + 75, 70, 76, 69, 65, 69, 74, 65, 2, 6, 3, 5, 9, + 5, 62, 62, 62, 59, 54, 48, 41, 24, 65 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 33, 55, + 59, 55, 21, 110, 65, 69, 75, 10, 11, 69, 7, + 23, 37, 53, 47, 17, 75, 115, 97, 75, 69, 75, + 10, 70, 86, 11, 18, 68, 80, 93, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 84, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 45, 11, + 80, 117, 86, 91, 74, 89, 96, 91, 112, 93, 104, + 97, 118, 80, 87, 92, 91, 24, 65, 80, 118, 72, + 101, 88, 119, 8, 6, 7, 0, 11, 68, 72, 85, 99, + 87, 86, 88, 74, 84, 104, 99, 75, 107, 94, 107, + 109, 114, 115, 65, 76, 70, 70, 4, 9, 68, 73, + 87, 110, 74, 35, 34, 116, 9, 4, 5, 4, 3, 65, + 77, 70, 0, 10, 6, 2, 66, 67, 4, 70, 5, 1, 20, + 34, 29, 19, 14, 19, 12, 17, 21, 65, 22, 18, + 27, 89, 17, 33, 30, 62, 62, 44, 56, 62, 62, + 55, 62, 62, 62, 62, 62, 59, 46, 59, 62, 62, + 62, 62, 62, 57, 48, 62, 54, 62, 21, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 55, 46, 38, + 32, 15, 75, 72, 79, 25, 28, 24, 28, 14, 16, + 14, 31, 5, 67, 3, 75, 69, 113, 106, 67, 4, 10, + 64, 74, 77, 81, 84, 118, 95, 25, 12, 4, 72, + 73, 86, 100, 104, 115, 73, 22, 14, 9, 8, 68, + 67, 68, 72, 83, 66, 32, 31, 30, 10, 9, 66, 73, + 87, 11, 58, 53, 51, 40, 26, 3, 71, 69, 77, 62, + 120, 118, 105, 119, 117, 100, 114, 110, 97, + 110, 109, 113, 92, 96, 93, 106, 107, 87, 79, + 81, 82, 79, 71, 65, 67, 5, 69, 69, 70, 67, 65, + 73, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, + 69, 69, 0, 22, 16, 24, 24, 19, 20, 15, 19, 19, + 4, 13, 19, 66, 9, 62, 62, 60, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, + 62, 62, 62, 62, 54, 54, 42, 30, 21, 5, 67, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 57, + 36, 26, 13, 12, 12, 12, 36, 36, 36, 35, 29, + 32, 23, 17, 18, 9, 73, 4, 74, 85, 25, 9, 4, + 83, 79, 74, 79, 75, 68, 73, 80, 68, 64, 3, 64, + 1, 4, 4, 62, 62, 62, 56, 50, 44, 36, 20, 68, + 69, 39, 28, 22, 12, 9, 2, 64, 66, 80, 80, 75, + 70, 76, 69, 64, 69, 74, 64, 3, 6, 3, 6, 9, 5, + 62, 62, 62, 56, 50, 44, 36, 20, 68 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 32, 53, + 58, 55, 21, 108, 65, 69, 74, 10, 11, 69, 6, + 21, 36, 51, 44, 15, 77, 112, 96, 74, 69, 74, + 10, 70, 85, 11, 18, 68, 80, 92, 4, 75, 86, 99, + 7, 73, 83, 4, 80, 83, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 44, 10, + 80, 114, 85, 90, 72, 87, 94, 89, 110, 91, 103, + 96, 115, 80, 87, 91, 90, 24, 65, 79, 116, 72, + 100, 88, 117, 8, 5, 6, 0, 11, 68, 71, 85, 98, + 86, 86, 87, 73, 83, 102, 97, 74, 105, 93, 102, + 105, 111, 112, 64, 76, 69, 69, 4, 9, 67, 73, + 86, 108, 74, 33, 32, 113, 9, 4, 5, 4, 3, 64, + 76, 69, 0, 10, 6, 2, 66, 66, 3, 69, 5, 0, 20, + 33, 29, 19, 14, 19, 12, 17, 20, 64, 21, 18, + 27, 89, 17, 32, 29, 62, 62, 43, 55, 62, 62, + 53, 62, 62, 62, 62, 61, 57, 44, 57, 62, 60, + 62, 62, 62, 55, 46, 62, 52, 62, 19, 62, 62, + 62, 62, 62, 62, 62, 62, 61, 58, 53, 44, 37, + 30, 13, 75, 72, 79, 24, 27, 23, 27, 13, 15, + 13, 29, 4, 68, 2, 76, 70, 112, 104, 66, 5, 10, + 64, 73, 77, 81, 83, 116, 94, 25, 12, 5, 71, + 72, 85, 99, 103, 113, 72, 23, 15, 10, 8, 67, + 66, 67, 72, 83, 66, 32, 31, 29, 10, 9, 66, 73, + 86, 11, 57, 52, 50, 39, 26, 3, 71, 69, 76, 62, + 119, 116, 103, 117, 116, 99, 112, 108, 96, + 108, 107, 111, 91, 95, 92, 105, 105, 87, 79, + 80, 82, 78, 71, 65, 67, 5, 69, 69, 71, 66, 65, + 72, 0, 2, 65, 0, 6, 64, 65, 1, 10, 65, 70, 74, + 69, 69, 64, 21, 16, 23, 23, 19, 19, 15, 19, + 18, 4, 13, 18, 66, 8, 62, 62, 59, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 44, 62, 62, + 62, 62, 62, 62, 61, 52, 52, 40, 29, 19, 5, 68, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 61, 55, + 54, 34, 24, 12, 12, 11, 10, 35, 34, 34, 33, + 27, 30, 21, 16, 17, 8, 73, 3, 75, 86, 24, 8, + 3, 83, 79, 73, 78, 74, 67, 72, 79, 68, 64, 3, + 0, 2, 4, 4, 62, 62, 59, 53, 47, 40, 32, 16, + 71, 69, 39, 28, 22, 12, 9, 2, 0, 65, 79, 80, + 75, 69, 76, 68, 0, 69, 74, 64, 3, 6, 4, 6, 9, + 5, 62, 62, 59, 53, 47, 40, 32, 16, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 30, 51, + 57, 55, 21, 107, 65, 68, 74, 10, 10, 68, 6, + 20, 34, 48, 40, 12, 78, 110, 95, 74, 68, 74, + 10, 71, 85, 11, 17, 68, 80, 92, 4, 75, 85, 98, + 7, 72, 82, 4, 79, 83, 93, 65, 76, 70, 85, 70, + 2, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 44, 10, + 80, 112, 84, 89, 71, 84, 93, 88, 108, 90, 102, + 95, 113, 80, 87, 91, 90, 24, 65, 78, 113, 72, + 99, 87, 115, 7, 5, 6, 64, 12, 68, 71, 84, 98, + 86, 85, 86, 73, 82, 101, 96, 74, 104, 92, 97, + 100, 108, 109, 64, 76, 69, 69, 4, 9, 67, 72, + 86, 106, 73, 31, 30, 110, 9, 4, 5, 4, 4, 64, + 74, 68, 0, 10, 6, 2, 65, 65, 2, 69, 5, 0, 19, + 32, 28, 19, 13, 19, 12, 17, 18, 64, 20, 17, + 26, 89, 17, 32, 29, 62, 62, 42, 53, 62, 62, + 51, 62, 62, 62, 62, 57, 55, 43, 55, 62, 58, + 62, 62, 62, 52, 44, 62, 50, 62, 17, 62, 62, + 62, 62, 62, 62, 62, 62, 59, 56, 50, 42, 35, + 29, 12, 75, 72, 80, 23, 26, 22, 26, 12, 14, + 12, 27, 3, 68, 1, 77, 70, 112, 103, 65, 5, 10, + 64, 72, 76, 80, 83, 114, 93, 26, 12, 5, 70, + 71, 84, 97, 101, 111, 71, 23, 15, 10, 9, 66, + 66, 67, 72, 82, 66, 33, 31, 28, 10, 9, 66, 73, + 86, 10, 57, 52, 49, 38, 25, 3, 71, 69, 76, 62, + 118, 115, 102, 116, 114, 98, 110, 106, 95, + 107, 105, 109, 91, 94, 92, 104, 103, 86, 79, + 80, 81, 78, 71, 65, 67, 4, 69, 69, 71, 66, 64, + 71, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, + 69, 68, 65, 20, 16, 22, 22, 18, 19, 15, 18, + 18, 4, 12, 16, 67, 7, 62, 62, 58, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 42, 62, 62, + 62, 62, 62, 62, 58, 50, 49, 38, 27, 18, 4, 69, + 62, 62, 62, 62, 62, 62, 62, 62, 61, 58, 52, + 51, 32, 23, 10, 11, 10, 9, 33, 33, 32, 31, 26, + 28, 19, 15, 15, 7, 74, 2, 76, 87, 22, 7, 2, + 83, 78, 73, 78, 73, 66, 72, 79, 67, 0, 3, 0, + 3, 4, 4, 62, 62, 57, 50, 44, 36, 28, 12, 74, + 69, 39, 28, 22, 12, 10, 3, 0, 65, 79, 79, 74, + 69, 75, 67, 1, 68, 73, 64, 3, 6, 4, 7, 9, 5, + 62, 62, 57, 50, 44, 36, 28, 12, 74 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 29, 49, + 56, 55, 21, 105, 65, 68, 73, 9, 10, 68, 5, 18, + 33, 46, 37, 10, 80, 107, 94, 74, 68, 73, 9, + 71, 84, 11, 17, 68, 79, 91, 4, 75, 85, 98, 7, + 72, 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, + 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 43, 9, 80, + 109, 83, 88, 69, 82, 91, 86, 107, 88, 100, 94, + 111, 80, 86, 90, 90, 24, 65, 77, 111, 72, 98, + 87, 113, 7, 4, 5, 64, 12, 68, 70, 84, 97, 85, + 85, 85, 72, 81, 99, 94, 73, 103, 91, 92, 96, + 105, 106, 64, 75, 69, 68, 4, 9, 66, 72, 85, + 104, 73, 29, 28, 107, 9, 5, 5, 4, 4, 0, 73, + 67, 1, 9, 6, 2, 65, 65, 1, 69, 5, 64, 19, 31, + 28, 18, 13, 19, 12, 17, 17, 64, 19, 16, 26, + 89, 17, 31, 28, 60, 62, 41, 51, 62, 62, 49, + 62, 61, 62, 62, 54, 53, 41, 52, 62, 55, 62, + 62, 62, 49, 42, 62, 48, 62, 16, 62, 62, 62, + 62, 62, 62, 62, 62, 57, 53, 48, 40, 33, 27, + 10, 75, 72, 80, 22, 25, 21, 24, 11, 13, 11, + 26, 2, 69, 0, 77, 71, 111, 101, 64, 6, 10, 0, + 72, 76, 80, 82, 112, 91, 26, 13, 6, 70, 70, + 83, 96, 100, 109, 71, 24, 16, 11, 9, 65, 65, + 67, 71, 82, 66, 33, 31, 28, 9, 9, 66, 73, 85, + 10, 56, 51, 48, 37, 25, 3, 70, 69, 76, 62, + 116, 113, 101, 114, 113, 97, 109, 105, 94, + 105, 104, 107, 90, 93, 91, 103, 101, 86, 79, + 80, 81, 77, 71, 66, 67, 4, 69, 69, 72, 65, 64, + 70, 0, 2, 64, 1, 6, 0, 64, 1, 9, 65, 70, 74, + 69, 68, 66, 19, 16, 21, 22, 17, 18, 15, 17, + 17, 4, 12, 15, 67, 6, 61, 62, 57, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 40, 62, 62, + 62, 62, 62, 62, 56, 48, 47, 36, 25, 16, 3, 69, + 62, 62, 62, 62, 62, 62, 62, 62, 59, 56, 50, + 48, 30, 21, 9, 10, 10, 7, 32, 31, 31, 29, 24, + 26, 18, 14, 14, 6, 75, 0, 77, 87, 21, 5, 0, + 82, 78, 72, 77, 72, 65, 72, 78, 67, 0, 3, 1, + 4, 4, 4, 62, 62, 54, 47, 40, 32, 24, 8, 77, + 68, 39, 28, 22, 12, 10, 3, 0, 65, 78, 79, 74, + 68, 75, 66, 2, 68, 73, 0, 4, 6, 4, 7, 9, 5, + 62, 62, 54, 47, 40, 32, 24, 8, 77 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 27, 46, + 55, 55, 20, 103, 66, 68, 72, 9, 9, 68, 4, 16, + 32, 43, 33, 7, 82, 104, 93, 74, 68, 72, 9, 72, + 83, 11, 16, 68, 79, 91, 3, 76, 85, 98, 7, 72, + 82, 4, 79, 82, 92, 65, 76, 70, 85, 69, 2, 22, + 0, 0, 0, 78, 88, 97, 68, 16, 0, 42, 9, 81, + 107, 82, 87, 68, 80, 90, 85, 105, 87, 99, 93, + 109, 80, 86, 90, 90, 24, 65, 76, 109, 72, 98, + 86, 111, 7, 4, 5, 65, 12, 68, 70, 83, 96, 84, + 84, 85, 72, 81, 98, 93, 73, 102, 90, 88, 92, + 102, 104, 64, 75, 69, 68, 3, 9, 66, 72, 85, + 102, 73, 27, 26, 105, 9, 5, 5, 4, 4, 0, 71, + 67, 1, 9, 5, 2, 64, 64, 64, 69, 5, 64, 18, 29, + 27, 18, 12, 19, 12, 16, 16, 64, 18, 15, 25, + 89, 16, 30, 27, 58, 62, 39, 49, 62, 62, 46, + 62, 59, 62, 62, 50, 51, 39, 50, 62, 53, 62, + 62, 62, 46, 40, 62, 46, 62, 14, 62, 62, 62, + 62, 62, 62, 62, 60, 55, 51, 46, 38, 31, 25, 8, + 75, 73, 81, 21, 23, 20, 23, 10, 11, 9, 24, 1, + 69, 64, 78, 72, 111, 100, 0, 6, 10, 0, 71, 75, + 79, 82, 110, 90, 26, 13, 6, 69, 69, 82, 94, + 98, 108, 70, 24, 16, 11, 10, 64, 65, 67, 71, + 81, 67, 34, 31, 27, 9, 9, 66, 73, 85, 10, 56, + 50, 47, 36, 25, 3, 70, 69, 76, 62, 115, 112, + 100, 113, 111, 96, 107, 103, 93, 104, 102, + 105, 90, 93, 91, 102, 100, 86, 79, 80, 80, 77, + 71, 66, 67, 3, 69, 69, 72, 65, 64, 69, 0, 1, + 64, 1, 5, 0, 64, 1, 8, 65, 70, 74, 69, 67, 67, + 18, 16, 19, 21, 16, 17, 14, 16, 16, 4, 12, 14, + 67, 4, 60, 60, 56, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 60, 38, 62, 62, 62, 62, 62, 62, + 53, 45, 44, 34, 23, 15, 2, 70, 62, 62, 62, 62, + 62, 62, 62, 62, 56, 53, 47, 45, 28, 19, 7, 9, + 9, 5, 30, 30, 29, 27, 22, 24, 16, 12, 12, 4, + 76, 64, 78, 88, 19, 4, 64, 82, 78, 72, 77, 71, + 64, 72, 78, 66, 1, 3, 1, 4, 4, 3, 62, 60, 51, + 44, 37, 28, 19, 3, 80, 68, 39, 28, 22, 12, 11, + 3, 0, 65, 78, 79, 74, 68, 75, 66, 2, 68, 73, + 0, 4, 6, 4, 8, 9, 4, 62, 60, 51, 44, 37, 28, + 19, 3, 80 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 26, 44, + 54, 56, 20, 101, 66, 67, 71, 9, 8, 68, 4, 15, + 31, 41, 29, 4, 83, 101, 92, 73, 67, 71, 9, 72, + 82, 11, 16, 67, 79, 90, 3, 76, 85, 98, 7, 72, + 81, 4, 79, 82, 92, 65, 76, 70, 84, 69, 2, 22, + 0, 0, 0, 77, 88, 97, 68, 15, 0, 41, 9, 81, + 105, 80, 86, 66, 78, 88, 84, 103, 85, 98, 91, + 106, 80, 86, 90, 89, 24, 65, 75, 107, 71, 97, + 85, 109, 7, 4, 5, 65, 12, 68, 70, 82, 95, 83, + 83, 84, 71, 80, 97, 91, 72, 100, 89, 83, 87, + 98, 101, 0, 75, 68, 67, 3, 9, 66, 71, 84, 99, + 73, 25, 25, 102, 9, 5, 5, 4, 4, 1, 69, 66, 1, + 9, 5, 2, 0, 0, 65, 68, 5, 64, 17, 28, 26, 18, + 11, 19, 12, 16, 15, 0, 17, 15, 24, 89, 16, 30, + 27, 56, 62, 38, 48, 62, 62, 44, 60, 57, 62, + 62, 47, 49, 37, 48, 62, 51, 62, 62, 62, 44, + 38, 62, 44, 62, 12, 62, 62, 62, 62, 62, 62, + 60, 58, 53, 49, 44, 37, 30, 24, 6, 75, 73, 81, + 21, 22, 19, 22, 9, 10, 8, 22, 0, 69, 65, 79, + 72, 110, 99, 1, 6, 10, 0, 70, 74, 78, 81, 107, + 89, 26, 13, 6, 68, 68, 81, 92, 96, 106, 69, + 25, 17, 12, 11, 0, 65, 66, 71, 80, 67, 35, 31, + 26, 9, 10, 65, 73, 84, 10, 56, 50, 46, 35, 25, + 3, 70, 69, 75, 62, 114, 111, 98, 111, 109, 95, + 105, 101, 92, 102, 100, 103, 89, 92, 90, 101, + 98, 85, 78, 79, 79, 76, 71, 66, 67, 2, 69, 69, + 72, 65, 0, 68, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, + 69, 73, 69, 66, 67, 17, 16, 18, 20, 16, 17, + 14, 16, 15, 4, 12, 13, 67, 3, 59, 59, 56, 61, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 36, + 62, 62, 62, 62, 62, 62, 50, 43, 42, 33, 22, + 14, 2, 71, 62, 62, 62, 62, 62, 62, 62, 62, 54, + 51, 45, 43, 26, 17, 5, 9, 8, 4, 29, 29, 27, + 25, 21, 23, 14, 11, 10, 3, 76, 65, 78, 89, 17, + 3, 65, 82, 77, 71, 77, 70, 1, 71, 77, 65, 2, + 3, 2, 5, 4, 3, 62, 58, 49, 41, 34, 24, 15, 64, + 83, 68, 39, 28, 23, 13, 12, 4, 1, 64, 78, 79, + 74, 68, 74, 65, 3, 68, 72, 0, 4, 6, 5, 9, 9, + 4, 62, 58, 49, 41, 34, 24, 15, 64, 83 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 25, 42, + 53, 56, 20, 99, 66, 67, 70, 8, 8, 68, 3, 13, + 30, 38, 26, 2, 85, 98, 91, 73, 67, 70, 8, 72, + 81, 11, 15, 67, 78, 89, 3, 76, 85, 98, 7, 72, + 81, 4, 79, 81, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 77, 88, 97, 67, 14, 0, 40, 8, 81, + 102, 79, 85, 64, 76, 87, 82, 102, 84, 96, 90, + 104, 80, 85, 89, 89, 24, 65, 74, 105, 71, 96, + 85, 107, 7, 3, 4, 66, 12, 68, 69, 82, 94, 82, + 83, 83, 71, 79, 95, 90, 71, 99, 88, 78, 83, + 95, 98, 0, 74, 68, 67, 3, 9, 65, 71, 84, 97, + 73, 23, 23, 99, 9, 6, 5, 4, 4, 1, 68, 65, 2, + 8, 5, 2, 0, 0, 66, 68, 5, 65, 17, 27, 26, 17, + 11, 19, 12, 16, 14, 0, 16, 14, 24, 89, 16, 29, + 26, 54, 62, 37, 46, 62, 62, 42, 57, 55, 62, + 62, 43, 47, 35, 45, 61, 48, 62, 62, 62, 41, + 36, 58, 42, 62, 11, 62, 62, 62, 62, 62, 60, + 58, 56, 51, 46, 42, 35, 28, 22, 4, 75, 73, 82, + 20, 21, 18, 20, 8, 9, 7, 21, 64, 70, 66, 79, + 73, 109, 97, 2, 7, 10, 1, 70, 74, 78, 80, 105, + 87, 26, 14, 7, 68, 67, 80, 91, 95, 104, 69, + 26, 18, 13, 11, 1, 64, 66, 70, 80, 67, 35, 31, + 26, 8, 10, 65, 73, 84, 10, 55, 49, 45, 34, 25, + 3, 69, 69, 75, 62, 112, 109, 97, 109, 108, 94, + 104, 100, 91, 100, 99, 101, 88, 91, 90, 100, + 96, 85, 78, 79, 79, 76, 71, 67, 67, 2, 69, 69, + 73, 64, 0, 67, 1, 1, 0, 1, 5, 0, 64, 1, 7, 65, + 69, 73, 69, 66, 68, 16, 16, 17, 20, 15, 16, + 14, 15, 14, 4, 12, 12, 67, 2, 58, 58, 55, 59, + 60, 62, 62, 62, 62, 62, 62, 62, 62, 55, 34, + 62, 62, 62, 62, 62, 62, 48, 41, 39, 31, 20, + 12, 1, 71, 62, 62, 62, 62, 62, 62, 62, 62, 52, + 48, 43, 40, 24, 15, 4, 8, 8, 2, 28, 27, 26, + 23, 19, 21, 13, 10, 9, 2, 77, 67, 79, 89, 16, + 1, 67, 81, 77, 70, 76, 69, 2, 71, 76, 65, 2, + 3, 2, 6, 4, 3, 62, 56, 46, 38, 30, 20, 11, 68, + 86, 67, 39, 28, 23, 13, 12, 4, 1, 64, 77, 79, + 74, 67, 74, 64, 4, 68, 72, 1, 5, 6, 5, 9, 9, + 4, 62, 56, 46, 38, 30, 20, 11, 68, 86 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 23, 40, + 52, 56, 20, 98, 66, 66, 70, 8, 7, 67, 3, 12, + 28, 36, 22, 64, 86, 96, 90, 73, 66, 70, 8, 73, + 81, 11, 15, 67, 78, 89, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 81, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 76, 88, 97, 67, 14, 64, 40, 8, 81, + 100, 78, 84, 0, 73, 85, 81, 100, 82, 95, 89, + 102, 80, 85, 89, 89, 24, 65, 73, 102, 71, 95, + 84, 105, 6, 3, 4, 66, 13, 68, 69, 81, 94, 82, + 82, 82, 70, 78, 94, 88, 71, 98, 87, 73, 78, + 92, 95, 0, 74, 68, 66, 3, 9, 65, 70, 83, 95, + 72, 21, 21, 96, 9, 6, 5, 4, 5, 2, 66, 64, 2, + 8, 5, 2, 1, 1, 67, 68, 5, 65, 16, 26, 25, 17, + 10, 19, 12, 16, 12, 0, 15, 13, 23, 89, 16, 29, + 26, 52, 62, 36, 44, 61, 62, 40, 55, 53, 62, + 62, 40, 45, 34, 43, 57, 46, 62, 62, 62, 38, + 34, 55, 40, 62, 9, 62, 62, 62, 62, 62, 58, 55, + 54, 49, 44, 39, 33, 26, 21, 3, 75, 73, 82, 19, + 20, 17, 19, 7, 8, 6, 19, 65, 70, 67, 80, 73, + 109, 96, 3, 7, 10, 1, 69, 73, 77, 80, 103, 86, + 27, 14, 7, 67, 66, 79, 89, 93, 102, 68, 26, + 18, 13, 12, 2, 64, 66, 70, 79, 67, 36, 31, 25, + 8, 10, 65, 73, 83, 9, 55, 49, 44, 33, 24, 3, + 69, 69, 75, 62, 111, 108, 96, 108, 106, 93, + 102, 98, 90, 99, 97, 99, 88, 90, 89, 99, 94, + 84, 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 73, + 64, 1, 66, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, + 73, 69, 65, 69, 15, 16, 16, 19, 14, 16, 14, + 14, 14, 4, 11, 10, 68, 1, 56, 57, 54, 58, 58, + 62, 62, 62, 62, 62, 62, 62, 62, 52, 32, 62, + 62, 62, 62, 62, 62, 45, 39, 37, 29, 18, 11, 0, + 72, 62, 62, 62, 62, 62, 62, 60, 59, 49, 46, + 40, 37, 22, 14, 2, 7, 7, 1, 26, 26, 24, 21, + 18, 19, 11, 9, 7, 1, 78, 68, 80, 90, 14, 0, + 68, 81, 76, 70, 76, 68, 3, 71, 76, 64, 3, 3, + 3, 7, 4, 3, 62, 54, 44, 35, 27, 16, 7, 72, 89, + 67, 39, 28, 23, 13, 13, 5, 1, 64, 77, 78, 73, + 67, 73, 0, 5, 67, 71, 1, 5, 6, 5, 10, 9, 4, + 62, 54, 44, 35, 27, 16, 7, 72, 89 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 22, 38, + 51, 56, 19, 96, 66, 66, 69, 8, 7, 67, 2, 10, + 27, 33, 19, 66, 88, 93, 89, 73, 66, 69, 8, 73, + 80, 11, 14, 67, 78, 88, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 80, 91, 65, 76, 70, 84, 68, 2, 22, + 0, 0, 0, 76, 89, 97, 66, 13, 64, 39, 7, 81, + 97, 77, 83, 2, 71, 84, 79, 98, 81, 94, 88, + 100, 80, 85, 88, 89, 24, 65, 72, 100, 71, 95, + 84, 103, 6, 2, 3, 67, 13, 68, 68, 81, 93, 81, + 82, 81, 70, 78, 92, 87, 70, 97, 86, 68, 74, + 89, 92, 0, 74, 68, 66, 3, 9, 64, 70, 83, 93, + 72, 19, 19, 94, 9, 6, 5, 4, 5, 2, 65, 0, 2, 8, + 5, 2, 1, 2, 68, 68, 5, 66, 16, 25, 25, 17, 10, + 19, 12, 16, 11, 0, 14, 12, 23, 89, 15, 28, 25, + 50, 62, 35, 42, 59, 60, 38, 52, 51, 62, 62, + 36, 43, 32, 41, 54, 43, 58, 62, 62, 35, 32, + 51, 38, 62, 7, 62, 62, 62, 62, 62, 56, 53, 52, + 47, 42, 37, 31, 24, 19, 1, 75, 73, 83, 18, 19, + 16, 18, 6, 6, 5, 17, 66, 71, 68, 81, 74, 108, + 94, 4, 8, 10, 1, 68, 73, 77, 79, 101, 85, 27, + 14, 8, 66, 65, 78, 88, 92, 101, 67, 27, 19, + 14, 12, 3, 0, 66, 70, 79, 67, 36, 31, 24, 8, + 10, 65, 73, 83, 9, 54, 48, 43, 32, 24, 3, 69, + 69, 75, 62, 110, 106, 95, 106, 105, 92, 100, + 96, 89, 97, 95, 97, 87, 89, 89, 98, 93, 84, + 78, 79, 78, 75, 71, 67, 67, 1, 69, 69, 74, 0, + 1, 65, 1, 1, 1, 2, 5, 1, 0, 1, 6, 65, 69, 73, + 69, 65, 70, 14, 16, 15, 18, 13, 15, 14, 13, + 13, 4, 11, 9, 68, 0, 55, 56, 53, 56, 56, 62, + 61, 62, 62, 62, 62, 62, 61, 50, 30, 62, 62, + 62, 62, 62, 59, 43, 36, 34, 27, 16, 9, 64, 73, + 62, 62, 62, 62, 62, 62, 57, 56, 47, 43, 38, + 34, 20, 12, 1, 6, 6, 64, 25, 24, 22, 19, 16, + 17, 9, 8, 6, 0, 79, 69, 81, 91, 13, 64, 69, + 81, 76, 69, 75, 67, 4, 71, 75, 64, 3, 3, 3, 8, + 4, 3, 61, 52, 41, 32, 24, 12, 2, 76, 92, 67, + 39, 28, 23, 13, 13, 5, 1, 64, 76, 78, 73, 66, + 73, 0, 6, 67, 71, 1, 5, 6, 5, 10, 9, 4, 61, + 52, 41, 32, 24, 12, 2, 76, 92 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 21, 36, + 50, 56, 19, 94, 66, 66, 68, 7, 6, 67, 1, 8, + 26, 31, 15, 69, 90, 90, 88, 72, 66, 68, 7, 73, + 79, 11, 14, 67, 77, 87, 3, 76, 84, 97, 7, 71, + 80, 4, 78, 80, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 38, 7, 81, + 95, 76, 82, 4, 69, 82, 78, 97, 79, 92, 87, 97, + 80, 84, 88, 88, 24, 65, 71, 98, 71, 94, 83, + 101, 6, 2, 3, 67, 13, 68, 68, 80, 92, 80, 81, + 80, 69, 77, 91, 85, 69, 95, 85, 0, 70, 86, 89, + 1, 73, 67, 65, 3, 9, 64, 70, 82, 91, 72, 17, + 17, 91, 9, 7, 5, 4, 5, 3, 0, 1, 3, 7, 5, 2, 2, + 2, 69, 67, 5, 66, 15, 24, 24, 16, 9, 19, 12, + 16, 10, 1, 13, 12, 22, 89, 15, 27, 24, 48, 62, + 34, 41, 57, 58, 36, 50, 49, 62, 62, 33, 41, + 30, 38, 51, 41, 55, 62, 62, 33, 30, 48, 36, + 62, 6, 62, 62, 62, 61, 60, 54, 51, 50, 45, 39, + 35, 29, 23, 17, 64, 75, 73, 83, 17, 18, 15, + 16, 5, 5, 4, 16, 67, 71, 69, 81, 75, 107, 93, + 5, 8, 10, 2, 68, 72, 76, 78, 99, 83, 27, 15, + 8, 66, 64, 77, 86, 90, 99, 67, 28, 20, 15, 13, + 4, 0, 65, 69, 78, 67, 37, 31, 24, 7, 10, 65, + 73, 82, 9, 54, 47, 42, 31, 24, 3, 68, 69, 74, + 62, 108, 105, 93, 104, 103, 91, 99, 95, 88, + 95, 94, 95, 86, 88, 88, 97, 91, 84, 78, 78, + 77, 74, 71, 68, 67, 0, 69, 69, 74, 0, 1, 64, + 1, 1, 1, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, + 71, 13, 16, 14, 18, 13, 14, 14, 13, 12, 4, 11, + 8, 68, 64, 54, 55, 52, 54, 54, 62, 59, 61, 62, + 59, 62, 62, 58, 47, 28, 62, 62, 62, 62, 59, + 56, 40, 34, 32, 25, 15, 8, 64, 73, 62, 62, 62, + 62, 59, 59, 55, 53, 45, 41, 36, 31, 18, 10, + 64, 6, 6, 66, 24, 23, 21, 17, 14, 15, 8, 7, 4, + 64, 79, 71, 82, 91, 11, 66, 71, 80, 76, 68, + 75, 66, 5, 70, 74, 0, 4, 3, 4, 9, 4, 3, 60, + 50, 38, 29, 20, 8, 65, 80, 95, 66, 39, 28, 23, + 13, 14, 5, 2, 0, 76, 78, 73, 66, 73, 1, 7, 67, + 71, 2, 6, 6, 6, 11, 9, 4, 60, 50, 38, 29, 20, + 8, 65, 80, 95 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 19, 34, + 49, 56, 19, 92, 66, 65, 67, 7, 6, 67, 1, 7, + 25, 28, 12, 71, 91, 87, 87, 72, 65, 67, 7, 74, + 78, 11, 13, 67, 77, 87, 3, 76, 84, 97, 7, 71, + 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 75, 89, 97, 65, 11, 64, 37, 6, 81, + 92, 75, 81, 5, 67, 81, 76, 95, 78, 91, 86, 95, + 80, 84, 87, 88, 24, 65, 70, 96, 71, 93, 83, + 99, 6, 1, 2, 68, 13, 68, 67, 80, 91, 79, 81, + 79, 69, 76, 89, 84, 69, 94, 84, 5, 65, 83, 86, + 1, 73, 67, 65, 3, 9, 0, 69, 82, 89, 72, 15, + 15, 88, 9, 7, 5, 4, 5, 3, 1, 2, 3, 7, 5, 2, 2, + 3, 70, 67, 5, 67, 15, 23, 24, 16, 9, 19, 12, + 16, 9, 1, 12, 11, 22, 89, 15, 27, 24, 46, 61, + 33, 39, 55, 55, 34, 47, 47, 62, 62, 29, 39, + 28, 36, 48, 38, 52, 61, 62, 30, 28, 44, 34, + 62, 4, 60, 62, 60, 58, 57, 52, 49, 48, 43, 37, + 33, 27, 21, 16, 66, 75, 73, 84, 16, 17, 14, + 15, 4, 4, 3, 14, 68, 72, 70, 82, 75, 107, 91, + 6, 9, 10, 2, 67, 72, 76, 78, 97, 82, 27, 15, + 9, 65, 0, 76, 85, 89, 97, 66, 28, 20, 15, 13, + 5, 1, 65, 69, 78, 67, 37, 31, 23, 7, 10, 65, + 73, 82, 9, 53, 47, 41, 30, 24, 3, 68, 69, 74, + 62, 107, 103, 92, 103, 102, 90, 97, 93, 87, + 94, 92, 93, 86, 87, 88, 96, 89, 83, 78, 78, + 77, 74, 71, 68, 67, 0, 69, 69, 75, 1, 2, 0, 1, + 1, 2, 2, 5, 1, 0, 1, 5, 65, 69, 73, 69, 64, + 72, 12, 16, 13, 17, 12, 14, 14, 12, 11, 4, 11, + 7, 68, 65, 53, 54, 51, 53, 52, 60, 57, 59, 59, + 57, 62, 60, 55, 45, 26, 62, 62, 62, 62, 55, + 53, 38, 32, 29, 23, 13, 6, 65, 74, 62, 62, 62, + 60, 56, 57, 52, 50, 42, 38, 33, 28, 16, 8, 65, + 5, 5, 67, 22, 21, 19, 15, 13, 13, 6, 6, 3, 65, + 80, 72, 83, 92, 10, 67, 72, 80, 75, 68, 74, + 65, 6, 70, 74, 0, 4, 3, 4, 10, 4, 3, 59, 48, + 36, 26, 17, 4, 69, 84, 98, 66, 39, 28, 23, 13, + 14, 6, 2, 0, 75, 78, 73, 65, 72, 2, 8, 67, 70, + 2, 6, 6, 6, 11, 9, 4, 59, 48, 36, 26, 17, 4, + 69, 84, 98 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 18, 32, + 48, 56, 19, 90, 66, 65, 66, 7, 5, 67, 0, 5, + 24, 26, 8, 74, 93, 84, 86, 72, 65, 66, 7, 74, + 77, 11, 13, 67, 77, 86, 3, 76, 84, 97, 7, 71, + 79, 4, 78, 79, 90, 65, 76, 70, 84, 67, 2, 22, + 0, 0, 0, 74, 89, 97, 65, 10, 64, 36, 6, 81, + 90, 74, 80, 7, 65, 79, 75, 93, 76, 90, 85, 93, + 80, 84, 87, 88, 24, 65, 69, 94, 71, 92, 82, + 97, 6, 1, 2, 68, 13, 68, 67, 79, 90, 78, 80, + 78, 68, 75, 88, 82, 68, 93, 83, 10, 2, 80, 83, + 1, 73, 67, 64, 3, 9, 0, 69, 81, 87, 72, 13, + 13, 85, 9, 7, 5, 4, 5, 4, 3, 3, 3, 7, 5, 2, 3, + 4, 71, 67, 5, 67, 14, 22, 23, 16, 8, 19, 12, + 16, 8, 1, 11, 10, 21, 89, 15, 26, 23, 44, 58, + 32, 37, 53, 53, 32, 45, 45, 62, 62, 26, 37, + 26, 34, 45, 36, 49, 57, 62, 27, 26, 41, 32, + 62, 2, 58, 62, 58, 56, 55, 50, 47, 46, 41, 35, + 31, 25, 19, 14, 68, 75, 73, 84, 15, 16, 13, + 14, 3, 3, 2, 12, 69, 72, 71, 83, 76, 106, 90, + 7, 9, 10, 2, 66, 71, 75, 77, 95, 81, 27, 15, + 9, 64, 1, 75, 83, 87, 95, 65, 29, 21, 16, 14, + 6, 1, 65, 69, 77, 67, 38, 31, 22, 7, 10, 65, + 73, 81, 9, 53, 46, 40, 29, 24, 3, 68, 69, 74, + 62, 106, 102, 91, 101, 100, 89, 95, 91, 86, + 92, 90, 91, 85, 86, 87, 95, 87, 83, 78, 78, + 76, 73, 71, 68, 67, 64, 69, 69, 75, 1, 2, 1, + 1, 1, 2, 2, 5, 1, 0, 1, 4, 65, 69, 73, 69, 0, + 73, 11, 16, 12, 16, 11, 13, 14, 11, 10, 4, 11, + 6, 68, 66, 52, 53, 50, 51, 50, 58, 55, 57, 57, + 54, 61, 57, 52, 42, 24, 62, 62, 62, 62, 52, + 50, 35, 30, 27, 21, 11, 5, 66, 75, 62, 62, 62, + 58, 53, 54, 50, 47, 40, 36, 31, 25, 14, 6, 67, + 4, 4, 69, 21, 20, 17, 13, 11, 11, 4, 5, 1, 66, + 81, 73, 84, 93, 8, 68, 73, 80, 75, 67, 74, 64, + 7, 70, 73, 1, 5, 3, 5, 11, 4, 3, 58, 46, 33, + 23, 14, 0, 73, 88, 101, 66, 39, 28, 23, 13, + 15, 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, + 2, 6, 6, 6, 12, 9, 4, 58, 46, 33, 23, 14, 0, + 73, 88, 101 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 16, 29, + 47, 56, 18, 89, 67, 65, 66, 6, 4, 67, 64, 3, + 22, 23, 4, 77, 95, 82, 86, 72, 65, 66, 6, 75, + 77, 11, 12, 67, 77, 86, 2, 77, 84, 97, 6, 71, + 79, 4, 78, 79, 90, 65, 76, 71, 84, 67, 2, 22, + 0, 0, 0, 74, 90, 97, 65, 9, 65, 35, 5, 82, 88, + 73, 79, 8, 0, 78, 74, 92, 75, 89, 84, 91, 80, + 84, 87, 88, 24, 65, 69, 92, 71, 92, 82, 96, 5, + 0, 1, 69, 13, 68, 67, 79, 90, 78, 80, 78, 68, + 75, 87, 81, 68, 92, 82, 14, 6, 77, 81, 1, 73, + 67, 64, 2, 9, 0, 69, 81, 85, 72, 11, 11, 83, + 9, 7, 5, 4, 5, 4, 4, 3, 3, 6, 4, 2, 3, 4, 73, + 67, 5, 68, 13, 20, 22, 15, 7, 19, 12, 15, 6, + 1, 10, 9, 20, 89, 14, 25, 22, 41, 54, 30, 35, + 50, 50, 29, 42, 43, 55, 62, 22, 34, 24, 31, + 41, 33, 45, 52, 59, 24, 24, 37, 30, 62, 0, 55, + 59, 55, 53, 52, 47, 44, 43, 39, 32, 28, 23, + 17, 12, 70, 75, 74, 85, 14, 14, 11, 12, 1, 1, + 0, 10, 70, 73, 72, 84, 77, 106, 89, 7, 9, 10, + 2, 66, 71, 75, 77, 93, 80, 27, 15, 9, 64, 1, + 74, 82, 86, 94, 65, 29, 21, 16, 14, 7, 1, 65, + 69, 77, 68, 38, 30, 21, 6, 10, 65, 73, 81, 8, + 52, 45, 38, 28, 23, 3, 68, 69, 74, 62, 105, + 101, 90, 100, 99, 88, 94, 90, 85, 91, 89, 89, + 85, 86, 87, 94, 86, 83, 78, 78, 76, 73, 71, + 69, 68, 65, 69, 70, 76, 1, 2, 2, 1, 0, 2, 2, + 4, 1, 0, 1, 3, 65, 69, 73, 69, 0, 74, 10, 16, + 10, 15, 10, 12, 13, 10, 9, 4, 10, 4, 69, 68, + 50, 51, 49, 49, 48, 55, 52, 54, 54, 51, 58, + 54, 48, 39, 22, 62, 62, 61, 60, 48, 46, 32, + 27, 24, 19, 9, 3, 67, 76, 59, 60, 60, 55, 50, + 51, 47, 43, 37, 33, 28, 22, 12, 4, 69, 3, 3, + 71, 19, 18, 15, 10, 9, 9, 2, 3, 64, 68, 82, + 75, 85, 94, 6, 70, 75, 80, 75, 67, 74, 0, 8, + 70, 73, 1, 5, 3, 5, 11, 4, 2, 56, 44, 30, 19, + 10, 67, 78, 93, 104, 66, 39, 28, 23, 13, 15, + 6, 2, 0, 75, 78, 73, 65, 72, 3, 9, 67, 70, 2, + 6, 6, 6, 12, 8, 3, 56, 44, 30, 19, 10, 67, 78, + 93, 104 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 15, 27, + 46, 57, 18, 87, 67, 64, 65, 6, 4, 66, 64, 2, + 21, 21, 1, 79, 96, 79, 85, 71, 64, 65, 6, 75, + 76, 11, 12, 66, 76, 85, 2, 77, 83, 96, 6, 70, + 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 73, 90, 97, 64, 9, 65, 35, 5, 82, 85, + 71, 77, 10, 3, 76, 72, 90, 73, 87, 82, 88, 80, + 83, 86, 87, 24, 65, 68, 89, 70, 91, 81, 94, 5, + 0, 1, 69, 14, 68, 66, 78, 89, 77, 79, 77, 67, + 74, 85, 79, 67, 90, 80, 19, 11, 73, 78, 2, 72, + 66, 0, 2, 10, 1, 68, 80, 82, 71, 9, 10, 80, 9, + 8, 5, 5, 6, 5, 6, 4, 4, 6, 4, 2, 4, 5, 74, 66, + 5, 68, 13, 19, 22, 15, 7, 19, 12, 15, 5, 2, + 10, 9, 20, 89, 14, 25, 22, 39, 51, 29, 34, 48, + 48, 27, 40, 41, 49, 62, 19, 32, 23, 29, 38, + 31, 42, 48, 55, 22, 22, 34, 28, 62, 64, 53, + 57, 53, 51, 50, 45, 42, 41, 37, 30, 26, 22, + 16, 11, 71, 75, 74, 85, 14, 13, 10, 11, 0, 0, + 64, 9, 71, 73, 73, 84, 77, 105, 87, 8, 10, 10, + 3, 65, 70, 74, 76, 90, 78, 28, 16, 10, 0, 2, + 72, 80, 84, 92, 64, 30, 22, 17, 15, 8, 2, 64, + 68, 76, 68, 39, 30, 21, 6, 11, 64, 73, 80, 8, + 52, 45, 37, 27, 23, 4, 67, 68, 73, 62, 103, + 99, 88, 98, 97, 86, 92, 88, 83, 89, 87, 86, + 84, 85, 86, 92, 84, 82, 77, 77, 75, 72, 70, + 69, 68, 65, 69, 70, 76, 2, 3, 3, 2, 0, 3, 3, + 4, 2, 1, 1, 3, 64, 68, 72, 68, 1, 74, 9, 16, + 9, 15, 10, 12, 13, 10, 9, 4, 10, 3, 69, 69, + 49, 50, 49, 48, 47, 53, 50, 52, 52, 49, 56, + 52, 45, 37, 20, 61, 60, 57, 56, 45, 43, 30, + 25, 22, 18, 8, 2, 67, 76, 57, 58, 58, 53, 48, + 49, 45, 40, 35, 31, 26, 20, 11, 3, 70, 3, 3, + 72, 18, 17, 14, 8, 8, 8, 1, 2, 65, 69, 82, 76, + 85, 94, 5, 71, 76, 79, 74, 66, 73, 2, 10, 69, + 72, 2, 6, 4, 6, 12, 4, 2, 55, 42, 28, 16, 7, + 71, 82, 97, 106, 65, 39, 29, 24, 14, 16, 7, 3, + 1, 74, 77, 72, 64, 71, 4, 10, 66, 69, 3, 7, 6, + 7, 13, 8, 3, 55, 42, 28, 16, 7, 71, 82, 97, + 106 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 14, 25, + 45, 57, 18, 85, 67, 64, 64, 6, 3, 66, 65, 0, + 20, 18, 66, 82, 98, 76, 84, 71, 64, 64, 6, 75, + 75, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, + 78, 4, 77, 78, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 72, 90, 97, 64, 8, 65, 34, 5, 82, 83, + 70, 76, 12, 5, 75, 71, 88, 72, 86, 81, 86, 80, + 83, 86, 87, 24, 65, 67, 87, 70, 90, 80, 92, 5, + 0, 1, 70, 14, 68, 66, 77, 88, 76, 78, 76, 67, + 73, 84, 78, 66, 89, 79, 24, 15, 70, 75, 2, 72, + 66, 0, 2, 10, 1, 68, 80, 80, 71, 7, 8, 77, 9, + 8, 5, 5, 6, 5, 8, 5, 4, 6, 4, 2, 5, 6, 75, 66, + 5, 68, 12, 18, 21, 15, 6, 19, 12, 15, 4, 2, 9, + 8, 19, 89, 14, 24, 21, 37, 48, 28, 32, 46, 46, + 25, 38, 39, 43, 62, 15, 30, 21, 27, 35, 29, + 39, 44, 51, 19, 20, 31, 26, 62, 66, 51, 55, + 51, 49, 48, 43, 40, 39, 35, 28, 24, 20, 14, 9, + 73, 75, 74, 86, 13, 12, 9, 10, 64, 64, 65, 7, + 72, 73, 74, 85, 78, 104, 86, 9, 10, 10, 3, 64, + 69, 73, 75, 88, 77, 28, 16, 10, 1, 3, 71, 78, + 82, 90, 0, 31, 23, 18, 16, 9, 2, 64, 68, 75, + 68, 40, 30, 20, 6, 11, 64, 73, 80, 8, 52, 44, + 36, 26, 23, 4, 67, 68, 73, 62, 102, 98, 87, + 96, 95, 85, 90, 86, 82, 87, 85, 84, 83, 84, + 86, 91, 82, 82, 77, 77, 74, 72, 70, 69, 68, + 66, 69, 70, 76, 2, 3, 4, 2, 0, 3, 3, 4, 2, 1, + 1, 2, 64, 68, 72, 68, 2, 75, 8, 16, 8, 14, 9, + 11, 13, 9, 8, 4, 10, 2, 69, 70, 48, 49, 48, + 46, 45, 51, 48, 50, 50, 46, 53, 49, 42, 34, + 18, 57, 56, 53, 51, 42, 40, 27, 23, 19, 16, 6, + 1, 68, 77, 55, 56, 55, 51, 45, 46, 42, 37, 33, + 28, 24, 17, 9, 1, 72, 2, 2, 74, 17, 16, 12, 6, + 6, 6, 64, 1, 67, 70, 83, 77, 86, 95, 3, 72, + 77, 79, 74, 65, 73, 3, 11, 69, 71, 3, 7, 4, 6, + 13, 4, 2, 54, 40, 25, 13, 4, 75, 86, 101, 109, + 65, 39, 29, 24, 14, 17, 7, 3, 1, 74, 77, 72, + 64, 71, 5, 11, 66, 69, 3, 7, 6, 7, 14, 8, 3, + 54, 40, 25, 13, 4, 75, 86, 101, 109 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 12, 23, + 44, 57, 18, 83, 67, 0, 0, 6, 3, 66, 65, 64, + 19, 16, 69, 84, 99, 73, 83, 71, 0, 0, 6, 76, + 74, 11, 11, 66, 76, 84, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 77, 89, 64, 75, 71, 83, 66, 2, 22, + 0, 0, 0, 72, 90, 97, 0, 7, 65, 33, 4, 82, 80, + 69, 75, 13, 7, 73, 69, 86, 70, 85, 80, 84, 80, + 83, 85, 87, 24, 65, 66, 85, 70, 89, 80, 90, 5, + 64, 0, 70, 14, 68, 65, 77, 87, 75, 78, 75, 66, + 72, 82, 76, 66, 88, 78, 29, 20, 67, 72, 2, 72, + 66, 1, 2, 10, 2, 67, 79, 78, 71, 5, 6, 74, 9, + 8, 5, 5, 6, 6, 9, 6, 4, 6, 4, 2, 5, 7, 76, 66, + 5, 69, 12, 17, 21, 15, 6, 19, 12, 15, 3, 2, 8, + 7, 19, 89, 14, 24, 21, 35, 45, 27, 30, 44, 43, + 23, 35, 37, 36, 62, 12, 28, 19, 25, 32, 26, + 36, 40, 47, 16, 18, 27, 24, 62, 68, 49, 53, + 49, 46, 45, 41, 38, 37, 33, 26, 22, 18, 12, 8, + 75, 75, 74, 86, 12, 11, 8, 9, 65, 65, 66, 5, + 73, 74, 75, 86, 78, 104, 84, 10, 11, 10, 3, 0, + 69, 73, 75, 86, 76, 28, 16, 11, 2, 4, 70, 77, + 81, 88, 1, 31, 23, 18, 16, 10, 3, 64, 68, 75, + 68, 40, 30, 19, 6, 11, 64, 73, 79, 8, 51, 44, + 35, 25, 23, 4, 67, 68, 73, 62, 101, 96, 86, + 95, 94, 84, 88, 84, 81, 86, 83, 82, 83, 83, + 85, 90, 80, 81, 77, 77, 74, 71, 70, 69, 68, + 66, 69, 70, 77, 3, 4, 5, 2, 0, 4, 3, 4, 2, 1, + 1, 2, 64, 68, 72, 68, 2, 76, 7, 16, 7, 13, 8, + 11, 13, 8, 7, 4, 10, 1, 69, 71, 47, 48, 47, + 45, 43, 49, 46, 48, 47, 44, 50, 46, 39, 32, + 16, 53, 52, 49, 46, 38, 37, 25, 21, 17, 14, 4, + 64, 69, 78, 53, 53, 53, 48, 42, 44, 40, 34, + 30, 26, 21, 14, 7, 64, 73, 1, 1, 75, 15, 14, + 10, 4, 5, 4, 66, 0, 68, 71, 84, 78, 87, 96, 2, + 73, 78, 79, 73, 65, 72, 4, 12, 69, 71, 3, 7, + 4, 7, 14, 4, 2, 53, 38, 23, 10, 1, 79, 90, + 105, 112, 65, 39, 29, 24, 14, 17, 8, 3, 1, 73, + 77, 72, 0, 70, 6, 12, 66, 68, 3, 7, 6, 7, 14, + 8, 3, 53, 38, 23, 10, 1, 79, 90, 105, 112 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 21, + 43, 57, 17, 81, 67, 0, 1, 5, 2, 66, 66, 66, + 18, 13, 73, 87, 101, 70, 82, 71, 0, 1, 5, 76, + 73, 11, 10, 66, 75, 83, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 77, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 71, 91, 97, 0, 6, 65, 32, 4, 82, 78, + 68, 74, 15, 9, 72, 68, 85, 69, 83, 79, 82, 80, + 82, 85, 87, 24, 65, 65, 83, 70, 89, 79, 88, 5, + 64, 0, 71, 14, 68, 65, 76, 86, 74, 77, 74, 66, + 72, 81, 75, 65, 87, 77, 34, 24, 64, 69, 2, 71, + 66, 1, 2, 10, 2, 67, 79, 76, 71, 3, 4, 72, 9, + 9, 5, 5, 6, 6, 11, 7, 5, 5, 4, 2, 6, 7, 77, + 66, 5, 69, 11, 16, 20, 14, 5, 19, 12, 15, 2, + 2, 7, 6, 18, 89, 13, 23, 20, 33, 41, 26, 28, + 42, 41, 21, 33, 35, 30, 62, 8, 26, 17, 22, 29, + 24, 32, 35, 43, 13, 16, 24, 22, 62, 69, 47, + 51, 46, 44, 43, 39, 36, 35, 31, 23, 20, 16, + 10, 6, 77, 75, 74, 87, 11, 10, 7, 7, 66, 67, + 67, 4, 74, 74, 76, 86, 79, 103, 83, 11, 11, + 10, 4, 0, 68, 72, 74, 84, 74, 28, 17, 11, 2, + 5, 69, 75, 79, 87, 1, 32, 24, 19, 17, 11, 3, + 64, 67, 74, 68, 41, 30, 19, 5, 11, 64, 73, 79, + 8, 51, 43, 34, 24, 23, 4, 66, 68, 73, 62, 99, + 95, 85, 93, 92, 83, 87, 83, 80, 84, 82, 80, + 82, 82, 85, 89, 79, 81, 77, 77, 73, 71, 70, + 70, 68, 67, 69, 70, 77, 3, 4, 6, 2, 0, 4, 3, + 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 77, 6, 16, + 6, 13, 7, 10, 13, 7, 6, 4, 10, 0, 69, 72, 46, + 47, 46, 43, 41, 47, 44, 45, 45, 41, 47, 43, + 36, 29, 14, 48, 48, 45, 41, 35, 33, 22, 18, + 14, 12, 2, 65, 70, 78, 50, 51, 50, 46, 39, 41, + 37, 31, 28, 23, 19, 11, 5, 66, 75, 0, 1, 77, + 14, 13, 9, 2, 3, 2, 67, 64, 70, 72, 85, 80, + 88, 96, 0, 75, 80, 78, 73, 64, 72, 5, 13, 69, + 70, 4, 8, 4, 7, 15, 4, 2, 52, 36, 20, 7, 66, + 83, 95, 109, 115, 64, 39, 29, 24, 14, 18, 8, + 3, 1, 73, 77, 72, 0, 70, 6, 13, 66, 68, 4, 8, + 6, 7, 15, 8, 3, 52, 36, 20, 7, 66, 83, 95, + 109, 115 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 10, 19, + 42, 57, 17, 79, 67, 0, 2, 5, 2, 66, 67, 68, + 17, 11, 76, 89, 103, 67, 81, 70, 0, 2, 5, 76, + 72, 11, 10, 66, 75, 82, 2, 77, 83, 96, 6, 70, + 77, 4, 77, 76, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 71, 91, 97, 1, 5, 65, 31, 3, 82, 75, + 67, 73, 17, 11, 70, 66, 83, 67, 82, 78, 79, + 80, 82, 84, 86, 24, 65, 64, 81, 70, 88, 79, + 86, 5, 65, 64, 71, 14, 68, 64, 76, 85, 73, 77, + 73, 65, 71, 79, 73, 64, 85, 76, 39, 28, 2, 66, + 3, 71, 65, 2, 2, 10, 3, 67, 78, 74, 71, 1, 2, + 69, 9, 9, 5, 5, 6, 7, 12, 8, 5, 5, 4, 2, 6, 8, + 78, 65, 5, 70, 11, 15, 20, 14, 5, 19, 12, 15, + 1, 3, 6, 6, 18, 89, 13, 22, 19, 31, 38, 25, + 27, 40, 39, 19, 30, 33, 24, 62, 5, 24, 15, 20, + 26, 21, 29, 31, 39, 11, 14, 20, 20, 62, 71, + 45, 49, 44, 42, 41, 37, 34, 33, 29, 21, 18, + 14, 9, 4, 79, 75, 74, 87, 10, 9, 6, 6, 67, 68, + 68, 2, 75, 75, 77, 87, 80, 102, 81, 12, 12, + 10, 4, 1, 68, 72, 73, 82, 73, 28, 17, 12, 3, + 6, 68, 74, 78, 85, 2, 33, 25, 20, 17, 12, 4, + 0, 67, 74, 68, 41, 30, 18, 5, 11, 64, 73, 78, + 8, 50, 42, 33, 23, 23, 4, 66, 68, 72, 62, 98, + 93, 83, 91, 91, 82, 85, 81, 79, 82, 80, 78, + 81, 81, 84, 88, 77, 81, 77, 76, 73, 70, 70, + 70, 68, 67, 69, 70, 78, 4, 4, 7, 2, 0, 4, 3, + 4, 2, 1, 1, 1, 64, 68, 72, 68, 3, 78, 5, 16, + 5, 12, 7, 9, 13, 7, 5, 4, 10, 64, 69, 73, 45, + 46, 45, 41, 39, 45, 42, 43, 42, 38, 44, 40, + 33, 27, 12, 44, 44, 41, 36, 32, 30, 20, 16, + 12, 10, 1, 67, 70, 79, 48, 48, 48, 44, 36, 38, + 35, 28, 26, 21, 17, 8, 3, 68, 76, 0, 0, 79, + 13, 11, 7, 0, 1, 0, 69, 65, 71, 73, 85, 81, + 89, 97, 64, 76, 81, 78, 73, 0, 71, 6, 14, 68, + 69, 4, 8, 4, 8, 16, 4, 2, 51, 34, 17, 4, 69, + 87, 99, 113, 118, 64, 39, 29, 24, 14, 18, 8, + 4, 2, 72, 77, 72, 1, 70, 7, 14, 66, 68, 4, 8, + 6, 8, 15, 8, 3, 51, 34, 17, 4, 69, 87, 99, + 113, 118 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 17, + 41, 57, 17, 78, 67, 1, 2, 5, 1, 65, 67, 69, + 15, 8, 80, 92, 104, 65, 80, 70, 1, 2, 5, 77, + 72, 11, 9, 66, 75, 82, 2, 77, 82, 95, 6, 69, + 76, 4, 76, 76, 88, 64, 75, 71, 83, 65, 2, 22, + 0, 0, 0, 70, 91, 97, 1, 5, 66, 31, 3, 82, 73, + 66, 72, 18, 14, 69, 65, 81, 66, 81, 77, 77, + 80, 82, 84, 86, 24, 65, 0, 78, 70, 87, 78, 84, + 4, 65, 64, 72, 15, 68, 64, 75, 85, 73, 76, 72, + 65, 70, 78, 72, 64, 84, 75, 44, 33, 5, 0, 3, + 71, 65, 2, 2, 10, 3, 66, 78, 72, 70, 64, 0, + 66, 9, 9, 5, 5, 7, 7, 14, 9, 5, 5, 4, 2, 7, 9, + 79, 65, 5, 70, 10, 14, 19, 14, 4, 19, 12, 15, + 64, 3, 5, 5, 17, 89, 13, 22, 19, 29, 35, 24, + 25, 37, 36, 17, 28, 31, 17, 62, 1, 22, 14, 18, + 22, 19, 26, 27, 34, 8, 12, 17, 18, 62, 73, 43, + 47, 42, 39, 38, 35, 31, 31, 27, 19, 15, 12, 7, + 3, 80, 75, 74, 88, 9, 8, 5, 5, 68, 69, 69, 0, + 76, 75, 78, 88, 80, 102, 80, 13, 12, 10, 4, 2, + 67, 71, 73, 80, 72, 29, 17, 12, 4, 7, 67, 72, + 76, 83, 3, 33, 25, 20, 18, 13, 4, 0, 67, 73, + 68, 42, 30, 17, 5, 11, 64, 73, 78, 7, 50, 42, + 32, 22, 22, 4, 66, 68, 72, 62, 97, 92, 82, 90, + 89, 81, 83, 79, 78, 81, 78, 76, 81, 80, 84, + 87, 75, 80, 77, 76, 72, 70, 70, 70, 68, 68, + 69, 70, 78, 4, 5, 8, 2, 0, 5, 4, 4, 3, 2, 1, + 0, 64, 68, 72, 68, 4, 79, 4, 16, 4, 11, 6, 9, + 13, 6, 5, 4, 9, 66, 70, 74, 43, 45, 44, 40, + 37, 43, 40, 41, 40, 36, 41, 38, 30, 24, 10, + 40, 40, 37, 32, 28, 27, 17, 14, 9, 8, 64, 68, + 71, 80, 46, 46, 45, 41, 33, 36, 32, 25, 23, + 18, 14, 5, 1, 69, 78, 64, 64, 80, 11, 10, 5, + 65, 0, 65, 71, 66, 73, 74, 86, 82, 90, 98, 66, + 77, 82, 78, 72, 0, 71, 7, 15, 68, 69, 5, 9, 4, + 8, 17, 4, 2, 50, 32, 15, 1, 72, 91, 103, 117, + 121, 64, 39, 29, 24, 14, 19, 9, 4, 2, 72, 76, + 71, 1, 69, 8, 15, 65, 67, 4, 8, 6, 8, 16, 8, + 3, 50, 32, 15, 1, 72, 91, 103, 117, 121 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 7, 15, + 40, 57, 17, 76, 67, 1, 3, 4, 1, 65, 68, 71, + 14, 6, 83, 94, 106, 1, 79, 70, 1, 3, 4, 77, + 71, 11, 9, 66, 74, 81, 2, 77, 82, 95, 6, 69, + 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, + 0, 0, 0, 70, 91, 97, 2, 4, 66, 30, 2, 82, 70, + 65, 71, 20, 16, 67, 0, 80, 64, 79, 76, 75, 80, + 81, 83, 86, 24, 65, 1, 76, 70, 86, 78, 82, 4, + 66, 65, 72, 15, 68, 0, 75, 84, 72, 76, 71, 64, + 69, 76, 70, 0, 83, 74, 49, 37, 8, 3, 3, 70, + 65, 3, 2, 10, 4, 66, 77, 70, 70, 66, 65, 0, 9, + 10, 5, 5, 7, 8, 15, 10, 6, 4, 4, 2, 7, 9, 80, + 65, 5, 71, 10, 13, 19, 13, 4, 19, 12, 15, 65, + 3, 4, 4, 17, 89, 13, 21, 18, 27, 32, 23, 23, + 35, 34, 15, 25, 29, 11, 62, 65, 20, 12, 15, + 19, 16, 23, 22, 30, 5, 10, 13, 16, 62, 74, 41, + 45, 40, 37, 36, 33, 29, 29, 25, 16, 13, 10, 5, + 1, 82, 75, 74, 88, 8, 7, 4, 3, 69, 70, 70, 64, + 77, 76, 79, 88, 81, 101, 78, 14, 13, 10, 5, 2, + 67, 71, 72, 78, 70, 29, 18, 13, 4, 8, 66, 71, + 75, 81, 3, 34, 26, 21, 18, 14, 5, 0, 66, 73, + 68, 42, 30, 17, 4, 11, 64, 73, 77, 7, 49, 41, + 31, 21, 22, 4, 65, 68, 72, 62, 95, 90, 81, 88, + 88, 80, 82, 78, 77, 79, 77, 74, 80, 79, 83, + 86, 73, 80, 77, 76, 72, 69, 70, 71, 68, 68, + 69, 70, 79, 5, 5, 9, 2, 0, 5, 4, 4, 3, 2, 1, + 0, 64, 68, 72, 68, 4, 80, 3, 16, 3, 11, 5, 8, + 13, 5, 4, 4, 9, 67, 70, 75, 42, 44, 43, 38, + 35, 41, 38, 38, 37, 33, 38, 35, 27, 22, 8, 35, + 36, 33, 27, 25, 24, 15, 12, 7, 6, 66, 70, 72, + 80, 43, 43, 43, 39, 30, 33, 30, 22, 21, 16, + 12, 2, 64, 71, 79, 65, 64, 82, 10, 8, 4, 67, + 65, 67, 72, 67, 74, 75, 87, 84, 91, 98, 67, + 79, 84, 77, 72, 1, 70, 8, 16, 68, 68, 5, 9, 4, + 9, 18, 4, 2, 49, 30, 12, 65, 76, 95, 107, 121, + 124, 0, 39, 29, 24, 14, 19, 9, 4, 2, 71, 76, + 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 16, 8, + 3, 49, 30, 12, 65, 76, 95, 107, 121, 124 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 5, 12, + 39, 57, 16, 74, 68, 1, 4, 4, 0, 65, 69, 73, + 13, 3, 87, 97, 108, 4, 78, 70, 1, 4, 4, 78, + 70, 11, 8, 66, 74, 81, 1, 78, 82, 95, 6, 69, + 76, 4, 76, 75, 87, 64, 75, 71, 83, 64, 2, 22, + 0, 0, 0, 69, 92, 97, 2, 3, 66, 29, 2, 83, 68, + 64, 70, 21, 18, 66, 1, 78, 0, 78, 75, 73, 80, + 81, 83, 86, 24, 65, 2, 74, 70, 86, 77, 80, 4, + 66, 65, 73, 15, 68, 0, 74, 83, 71, 75, 71, 64, + 69, 75, 69, 0, 82, 73, 53, 41, 11, 5, 3, 70, + 65, 3, 1, 10, 4, 66, 77, 68, 70, 68, 67, 2, 9, + 10, 5, 5, 7, 8, 17, 10, 6, 4, 3, 2, 8, 10, 82, + 65, 5, 71, 9, 11, 18, 13, 3, 19, 12, 14, 66, + 3, 3, 3, 16, 89, 12, 20, 17, 25, 28, 21, 21, + 33, 31, 12, 23, 27, 4, 62, 69, 18, 10, 13, 16, + 14, 19, 18, 26, 2, 8, 10, 14, 62, 76, 39, 42, + 37, 34, 33, 30, 27, 26, 23, 14, 11, 8, 3, 64, + 84, 75, 75, 89, 7, 5, 3, 2, 70, 72, 72, 66, + 78, 76, 80, 89, 82, 101, 77, 15, 13, 10, 5, 3, + 66, 70, 72, 76, 69, 29, 18, 13, 5, 9, 65, 69, + 73, 80, 4, 34, 26, 21, 19, 15, 5, 0, 66, 72, + 69, 43, 30, 16, 4, 11, 64, 73, 77, 7, 49, 40, + 30, 20, 22, 4, 65, 68, 72, 62, 94, 89, 80, 87, + 86, 79, 80, 76, 76, 78, 75, 72, 80, 79, 83, + 85, 72, 80, 77, 76, 71, 69, 70, 71, 68, 69, + 69, 70, 79, 5, 5, 10, 2, 64, 5, 4, 3, 3, 2, 1, + 64, 64, 68, 72, 68, 5, 81, 2, 16, 1, 10, 4, 7, + 12, 4, 3, 4, 9, 68, 70, 77, 41, 42, 42, 36, + 33, 39, 36, 36, 35, 30, 35, 32, 24, 19, 6, 31, + 32, 28, 22, 21, 20, 12, 9, 4, 4, 68, 71, 73, + 81, 41, 41, 40, 36, 27, 30, 27, 19, 18, 13, 9, + 64, 66, 73, 81, 66, 65, 84, 8, 7, 2, 69, 67, + 69, 74, 69, 76, 77, 88, 85, 92, 99, 69, 80, + 85, 77, 72, 1, 70, 9, 17, 68, 68, 6, 10, 4, 9, + 18, 4, 1, 48, 28, 9, 68, 79, 99, 112, 126, + 126, 0, 39, 29, 24, 14, 20, 9, 4, 2, 71, 76, + 71, 2, 69, 9, 16, 65, 67, 5, 9, 6, 8, 17, 8, + 2, 48, 28, 9, 68, 79, 99, 112, 126, 126 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 4, 10, + 38, 58, 16, 72, 68, 2, 5, 4, 64, 65, 69, 74, + 12, 1, 91, 100, 109, 7, 77, 69, 2, 5, 4, 78, + 69, 11, 8, 65, 74, 80, 1, 78, 82, 95, 6, 69, + 75, 4, 76, 75, 87, 64, 75, 71, 82, 64, 2, 22, + 0, 0, 0, 68, 92, 97, 2, 2, 66, 28, 2, 83, 66, + 1, 69, 23, 20, 64, 2, 76, 2, 77, 73, 70, 80, + 81, 83, 85, 24, 65, 3, 72, 69, 85, 76, 78, 4, + 66, 65, 73, 15, 68, 0, 73, 82, 70, 74, 70, 0, + 68, 74, 67, 1, 80, 72, 58, 46, 15, 8, 4, 70, + 64, 4, 1, 10, 4, 65, 76, 65, 70, 70, 68, 5, 9, + 10, 5, 5, 7, 9, 19, 11, 6, 4, 3, 2, 9, 11, 83, + 64, 5, 71, 8, 10, 17, 13, 2, 19, 12, 14, 67, + 4, 2, 3, 15, 89, 12, 20, 17, 23, 25, 20, 20, + 31, 29, 10, 21, 25, 65, 62, 72, 16, 8, 11, 13, + 12, 16, 14, 22, 0, 6, 7, 12, 62, 78, 37, 40, + 35, 32, 31, 28, 25, 24, 21, 12, 9, 7, 2, 65, + 86, 75, 75, 89, 7, 4, 2, 1, 71, 73, 73, 68, + 79, 76, 81, 90, 82, 100, 76, 16, 13, 10, 5, 4, + 65, 69, 71, 73, 68, 29, 18, 13, 6, 10, 64, 67, + 71, 78, 5, 35, 27, 22, 20, 16, 5, 1, 66, 71, + 69, 44, 30, 15, 4, 12, 0, 73, 76, 7, 49, 40, + 29, 19, 22, 4, 65, 68, 71, 62, 93, 88, 78, 85, + 84, 78, 78, 74, 75, 76, 73, 70, 79, 78, 82, + 84, 70, 79, 76, 75, 70, 68, 70, 71, 68, 70, + 69, 70, 79, 5, 6, 11, 3, 64, 6, 4, 3, 3, 2, 1, + 65, 64, 67, 71, 68, 6, 81, 1, 16, 0, 9, 4, 7, + 12, 4, 2, 4, 9, 69, 70, 78, 40, 41, 42, 35, + 31, 37, 34, 34, 33, 28, 32, 29, 21, 16, 4, 27, + 28, 24, 17, 18, 17, 9, 7, 2, 3, 69, 72, 73, + 82, 39, 39, 38, 34, 25, 28, 25, 16, 16, 11, 7, + 66, 68, 75, 83, 66, 66, 85, 7, 6, 0, 71, 68, + 70, 76, 70, 78, 78, 88, 86, 92, 100, 71, 81, + 86, 77, 71, 2, 70, 10, 19, 67, 67, 7, 11, 4, + 10, 19, 4, 1, 47, 26, 7, 71, 82, 103, 116, + 126, 126, 0, 39, 29, 25, 15, 21, 10, 5, 3, 71, + 76, 71, 2, 68, 10, 17, 65, 66, 5, 9, 6, 9, 18, + 8, 2, 47, 26, 7, 71, 82, 103, 116, 126, 126 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 3, 8, 37, + 58, 16, 70, 68, 2, 6, 3, 64, 65, 70, 76, 11, + 65, 94, 102, 111, 10, 76, 69, 2, 6, 3, 78, 68, + 11, 7, 65, 73, 79, 1, 78, 82, 95, 6, 69, 75, + 4, 76, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, + 0, 68, 92, 97, 3, 1, 66, 27, 1, 83, 0, 2, 68, + 25, 22, 0, 4, 75, 3, 75, 72, 68, 80, 80, 82, + 85, 24, 65, 4, 70, 69, 84, 76, 76, 4, 67, 66, + 74, 15, 68, 1, 73, 81, 69, 74, 69, 0, 67, 72, + 66, 2, 79, 71, 62, 50, 18, 11, 4, 69, 64, 4, + 1, 10, 5, 65, 76, 0, 70, 72, 70, 8, 9, 11, 5, + 5, 7, 9, 20, 12, 7, 3, 3, 2, 9, 11, 84, 64, 5, + 72, 8, 9, 17, 12, 2, 19, 12, 14, 68, 4, 1, 2, + 15, 89, 12, 19, 16, 21, 22, 19, 18, 29, 27, 8, + 18, 23, 71, 62, 76, 14, 6, 8, 10, 9, 13, 9, + 18, 66, 4, 3, 10, 62, 79, 35, 38, 33, 30, 29, + 26, 23, 22, 19, 9, 7, 5, 0, 67, 88, 75, 75, + 90, 6, 3, 1, 64, 72, 74, 74, 69, 80, 77, 82, + 90, 83, 99, 74, 17, 14, 10, 6, 4, 65, 69, 70, + 71, 66, 29, 19, 14, 6, 11, 0, 66, 70, 76, 5, + 36, 28, 23, 20, 17, 6, 1, 65, 71, 69, 44, 30, + 15, 3, 12, 0, 73, 76, 7, 48, 39, 28, 18, 22, + 4, 64, 68, 71, 62, 91, 86, 77, 83, 83, 77, 77, + 73, 74, 74, 72, 68, 78, 77, 82, 83, 68, 79, + 76, 75, 70, 68, 70, 72, 68, 70, 69, 70, 80, 6, + 6, 12, 3, 64, 6, 4, 3, 3, 2, 1, 65, 64, 67, + 71, 68, 6, 82, 0, 16, 64, 9, 3, 6, 12, 3, 1, + 4, 9, 70, 70, 79, 39, 40, 41, 33, 29, 35, 32, + 31, 30, 25, 29, 26, 18, 14, 2, 22, 24, 20, 12, + 15, 14, 7, 5, 64, 1, 71, 74, 74, 82, 36, 36, + 35, 32, 22, 25, 22, 13, 14, 8, 5, 69, 70, 77, + 84, 67, 66, 87, 6, 4, 64, 73, 70, 72, 77, 71, + 79, 79, 89, 88, 93, 100, 72, 83, 88, 76, 71, + 3, 69, 11, 20, 67, 66, 7, 11, 4, 10, 20, 4, 1, + 46, 24, 4, 74, 86, 107, 120, 126, 126, 1, 39, + 29, 25, 15, 21, 10, 5, 3, 70, 76, 71, 3, 68, + 11, 18, 65, 66, 6, 10, 6, 9, 18, 8, 2, 46, 24, + 4, 74, 86, 107, 120, 126, 126 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 1, 6, 36, + 58, 16, 69, 68, 3, 6, 3, 65, 64, 70, 77, 9, + 67, 98, 105, 112, 12, 75, 69, 3, 6, 3, 79, 68, + 11, 7, 65, 73, 79, 1, 78, 81, 94, 6, 68, 74, + 4, 75, 74, 86, 64, 75, 71, 82, 0, 2, 22, 0, 0, + 0, 67, 92, 97, 3, 1, 67, 27, 1, 83, 2, 3, 67, + 26, 25, 2, 5, 73, 5, 74, 71, 66, 80, 80, 82, + 85, 24, 65, 5, 67, 69, 83, 75, 74, 3, 67, 66, + 74, 16, 68, 1, 72, 81, 69, 73, 68, 1, 66, 71, + 64, 2, 78, 70, 62, 55, 21, 14, 4, 69, 64, 5, + 1, 10, 5, 64, 75, 2, 69, 74, 72, 11, 9, 11, 5, + 5, 8, 10, 22, 13, 7, 3, 3, 2, 10, 12, 85, 64, + 5, 72, 7, 8, 16, 12, 1, 19, 12, 14, 70, 4, 0, + 1, 14, 89, 12, 19, 16, 19, 19, 18, 16, 26, 24, + 6, 16, 21, 78, 62, 79, 12, 5, 6, 6, 7, 10, 5, + 13, 69, 2, 0, 8, 62, 81, 33, 36, 31, 27, 26, + 24, 20, 20, 17, 7, 4, 3, 65, 68, 89, 75, 75, + 90, 5, 2, 0, 65, 73, 75, 75, 71, 81, 77, 83, + 91, 83, 99, 73, 18, 14, 10, 6, 5, 64, 68, 70, + 69, 65, 30, 19, 14, 7, 12, 1, 64, 68, 74, 6, + 36, 28, 23, 21, 18, 6, 1, 65, 70, 69, 45, 30, + 14, 3, 12, 0, 73, 75, 6, 48, 39, 27, 17, 21, + 4, 64, 68, 71, 62, 90, 85, 76, 82, 81, 76, 75, + 71, 73, 73, 70, 66, 78, 76, 81, 82, 66, 78, + 76, 75, 69, 67, 70, 72, 68, 71, 69, 70, 80, 6, + 7, 13, 3, 64, 7, 5, 3, 4, 3, 1, 66, 64, 67, + 71, 68, 7, 83, 64, 16, 65, 8, 2, 6, 12, 2, 1, + 4, 8, 72, 71, 80, 37, 39, 40, 32, 27, 33, 30, + 29, 28, 23, 26, 24, 15, 11, 0, 18, 20, 16, 8, + 11, 11, 4, 3, 66, 64, 73, 75, 75, 83, 34, 34, + 33, 29, 19, 23, 20, 10, 11, 6, 2, 72, 72, 78, + 86, 68, 67, 88, 4, 3, 66, 75, 71, 74, 79, 72, + 81, 80, 90, 89, 94, 101, 74, 84, 89, 76, 70, + 3, 69, 12, 21, 67, 66, 8, 12, 4, 11, 21, 4, 1, + 45, 22, 2, 77, 89, 111, 124, 126, 126, 1, 39, + 29, 25, 15, 22, 11, 5, 3, 70, 75, 70, 3, 67, + 12, 19, 64, 65, 6, 10, 6, 9, 19, 8, 2, 45, 22, + 2, 77, 89, 111, 124, 126, 126 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 0, 4, 35, + 58, 15, 67, 68, 3, 7, 3, 65, 64, 71, 79, 8, + 70, 101, 107, 114, 15, 74, 69, 3, 7, 3, 79, + 67, 11, 6, 65, 73, 78, 1, 78, 81, 94, 6, 68, + 74, 4, 75, 73, 86, 64, 75, 71, 82, 0, 2, 22, + 0, 0, 0, 67, 93, 97, 4, 0, 67, 26, 0, 83, 5, + 4, 66, 28, 27, 3, 7, 71, 6, 73, 70, 64, 80, + 80, 81, 85, 24, 65, 6, 65, 69, 83, 75, 72, 3, + 68, 67, 75, 16, 68, 2, 72, 80, 68, 73, 67, 1, + 66, 69, 0, 3, 77, 69, 62, 59, 24, 17, 4, 69, + 64, 5, 1, 10, 6, 64, 75, 4, 69, 76, 74, 13, 9, + 11, 5, 5, 8, 10, 23, 14, 7, 3, 3, 2, 10, 13, + 86, 64, 5, 73, 7, 7, 16, 12, 1, 19, 12, 14, + 71, 4, 64, 0, 14, 89, 11, 18, 15, 17, 15, 17, + 14, 24, 22, 4, 13, 19, 84, 62, 83, 10, 3, 4, + 3, 4, 6, 1, 9, 72, 0, 67, 6, 62, 83, 31, 34, + 28, 25, 24, 22, 18, 18, 15, 5, 2, 1, 67, 70, + 91, 75, 75, 91, 4, 1, 64, 66, 74, 77, 76, 73, + 82, 78, 84, 92, 84, 98, 71, 19, 15, 10, 6, 6, + 64, 68, 69, 67, 64, 30, 19, 15, 8, 13, 2, 0, + 67, 73, 7, 37, 29, 24, 21, 19, 7, 1, 65, 70, + 69, 45, 30, 13, 3, 12, 0, 73, 75, 6, 47, 38, + 26, 16, 21, 4, 64, 68, 71, 62, 89, 83, 75, 80, + 80, 75, 73, 69, 72, 71, 68, 64, 77, 75, 81, + 81, 65, 78, 76, 75, 69, 67, 70, 72, 68, 71, + 69, 70, 81, 7, 7, 14, 3, 64, 7, 5, 3, 4, 3, 1, + 66, 64, 67, 71, 68, 7, 84, 65, 16, 66, 7, 1, + 5, 12, 1, 0, 4, 8, 73, 71, 81, 36, 38, 39, 30, + 25, 31, 28, 27, 25, 20, 23, 21, 12, 9, 65, 14, + 16, 12, 3, 8, 7, 2, 0, 69, 66, 75, 77, 76, 84, + 32, 31, 30, 27, 16, 20, 17, 7, 9, 3, 0, 75, + 74, 80, 87, 69, 68, 90, 3, 1, 68, 77, 73, 76, + 81, 73, 82, 81, 91, 90, 95, 102, 75, 85, 90, + 76, 70, 4, 68, 13, 22, 67, 65, 8, 12, 4, 11, + 22, 4, 1, 44, 20, 64, 80, 92, 115, 126, 126, + 126, 1, 39, 29, 25, 15, 22, 11, 5, 3, 69, 75, + 70, 4, 67, 12, 20, 64, 65, 6, 10, 6, 9, 19, 8, + 2, 44, 20, 64, 80, 92, 115, 126, 126, 126 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 64, 2, 34, + 58, 15, 65, 68, 3, 8, 2, 66, 64, 72, 81, 7, + 72, 105, 110, 116, 18, 73, 68, 3, 8, 2, 79, + 66, 11, 6, 65, 72, 77, 1, 78, 81, 94, 6, 68, + 74, 4, 75, 73, 85, 64, 75, 71, 82, 1, 2, 22, + 0, 0, 0, 66, 93, 97, 4, 64, 67, 25, 0, 83, 7, + 5, 65, 30, 29, 5, 8, 70, 8, 71, 69, 2, 80, 79, + 81, 84, 24, 65, 7, 0, 69, 82, 74, 70, 3, 68, + 67, 75, 16, 68, 2, 71, 79, 67, 72, 66, 2, 65, + 68, 2, 4, 75, 68, 62, 62, 27, 20, 5, 68, 0, 6, + 1, 10, 6, 64, 74, 6, 69, 78, 76, 16, 9, 12, 5, + 5, 8, 11, 25, 15, 8, 2, 3, 2, 11, 13, 87, 0, + 5, 73, 6, 6, 15, 11, 0, 19, 12, 14, 72, 5, 65, + 0, 13, 89, 11, 17, 14, 15, 12, 16, 13, 22, 20, + 2, 11, 17, 90, 62, 86, 8, 1, 1, 0, 2, 3, 67, + 5, 74, 65, 70, 4, 62, 84, 29, 32, 26, 23, 22, + 20, 16, 16, 13, 2, 0, 64, 68, 72, 93, 75, 75, + 91, 3, 0, 65, 68, 75, 78, 77, 74, 83, 78, 85, + 92, 85, 97, 70, 20, 15, 10, 7, 6, 0, 67, 68, + 65, 1, 30, 20, 15, 8, 14, 3, 2, 65, 71, 7, 38, + 30, 25, 22, 20, 7, 2, 64, 69, 69, 46, 30, 13, + 2, 12, 0, 73, 74, 6, 47, 37, 25, 15, 21, 4, 0, + 68, 70, 62, 87, 82, 73, 78, 78, 74, 72, 68, + 71, 69, 67, 1, 76, 74, 80, 80, 0, 78, 76, 74, + 68, 66, 70, 73, 68, 72, 69, 70, 81, 7, 7, 15, + 3, 64, 7, 5, 3, 4, 3, 1, 67, 64, 67, 71, 68, + 8, 85, 66, 16, 67, 7, 1, 4, 12, 1, 64, 4, 8, + 74, 71, 82, 35, 37, 38, 28, 23, 29, 26, 24, + 23, 17, 20, 18, 9, 6, 67, 9, 12, 8, 65, 5, 4, + 64, 65, 71, 68, 76, 78, 76, 84, 29, 29, 28, + 25, 13, 17, 15, 4, 7, 1, 65, 78, 76, 82, 89, + 69, 68, 92, 2, 0, 69, 79, 75, 78, 82, 74, 84, + 82, 91, 92, 96, 102, 77, 87, 92, 75, 70, 5, + 68, 14, 23, 66, 64, 9, 13, 4, 12, 23, 4, 1, + 43, 18, 67, 83, 96, 119, 126, 126, 126, 2, 39, + 29, 25, 15, 23, 11, 6, 4, 69, 75, 70, 4, 67, + 13, 21, 64, 65, 7, 11, 6, 10, 20, 8, 2, 43, + 18, 67, 83, 96, 119, 126, 126, 126 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 66, 0, + 33, 58, 15, 0, 68, 4, 9, 2, 66, 64, 72, 82, 6, + 75, 108, 112, 117, 21, 72, 68, 4, 9, 2, 80, + 65, 11, 5, 65, 72, 77, 1, 78, 81, 94, 6, 68, + 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, 22, + 0, 0, 0, 66, 93, 97, 5, 65, 67, 24, 64, 83, + 10, 6, 64, 31, 31, 6, 10, 68, 9, 70, 68, 4, + 80, 79, 80, 84, 24, 65, 8, 2, 69, 81, 74, 68, + 3, 69, 68, 76, 16, 68, 3, 71, 78, 66, 72, 65, + 2, 64, 66, 3, 4, 74, 67, 62, 62, 30, 23, 5, + 68, 0, 6, 1, 10, 7, 0, 74, 8, 69, 80, 78, 19, + 9, 12, 5, 5, 8, 11, 26, 16, 8, 2, 3, 2, 11, + 14, 88, 0, 5, 74, 6, 5, 15, 11, 0, 19, 12, 14, + 73, 5, 66, 64, 13, 89, 11, 17, 14, 13, 9, 15, + 11, 20, 17, 0, 8, 15, 97, 62, 90, 6, 64, 64, + 66, 64, 0, 71, 1, 77, 67, 74, 2, 62, 86, 27, + 30, 24, 20, 19, 18, 14, 14, 11, 0, 65, 66, 70, + 73, 95, 75, 75, 92, 2, 64, 66, 69, 76, 79, 78, + 76, 84, 79, 86, 93, 85, 97, 68, 21, 16, 10, 7, + 7, 0, 67, 68, 0, 2, 30, 20, 16, 9, 15, 4, 3, + 64, 69, 8, 38, 30, 25, 22, 21, 8, 2, 64, 69, + 69, 46, 30, 12, 2, 12, 0, 73, 74, 6, 46, 37, + 24, 14, 21, 4, 0, 68, 70, 62, 86, 80, 72, 77, + 77, 73, 70, 66, 70, 68, 65, 3, 76, 73, 80, 79, + 2, 77, 76, 74, 68, 66, 70, 73, 68, 72, 69, 70, + 82, 8, 8, 16, 3, 64, 8, 5, 3, 4, 3, 1, 67, 64, + 67, 71, 68, 8, 86, 67, 16, 68, 6, 0, 4, 12, 0, + 65, 4, 8, 75, 71, 83, 34, 36, 37, 27, 21, 27, + 24, 22, 20, 15, 17, 15, 6, 4, 69, 5, 8, 4, 70, + 1, 1, 66, 67, 74, 70, 78, 80, 77, 85, 27, 26, + 25, 22, 10, 15, 12, 1, 4, 65, 68, 81, 78, 84, + 90, 70, 69, 93, 0, 65, 71, 81, 76, 80, 84, 75, + 85, 83, 92, 93, 97, 103, 78, 88, 93, 75, 69, + 5, 67, 15, 24, 66, 64, 9, 13, 4, 12, 24, 4, 1, + 42, 16, 69, 86, 99, 123, 126, 126, 126, 2, 39, + 29, 25, 15, 23, 12, 6, 4, 68, 75, 70, 5, 66, + 14, 22, 64, 64, 7, 11, 6, 10, 20, 8, 2, 42, + 16, 69, 86, 99, 123, 126, 126, 126 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 67, 65, + 32, 58, 15, 2, 68, 4, 10, 2, 67, 64, 73, 84, + 5, 77, 112, 115, 119, 24, 71, 68, 4, 10, 2, + 80, 64, 11, 5, 65, 72, 76, 1, 78, 81, 94, 6, + 68, 73, 4, 75, 72, 85, 64, 75, 71, 82, 1, 2, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 23, 64, + 83, 12, 7, 0, 33, 33, 8, 11, 66, 11, 69, 67, + 6, 80, 79, 80, 84, 24, 65, 9, 4, 69, 80, 73, + 66, 3, 69, 68, 76, 16, 68, 3, 70, 77, 65, 71, + 64, 3, 0, 65, 5, 5, 73, 66, 62, 62, 33, 26, 5, + 68, 0, 7, 1, 10, 7, 0, 73, 10, 69, 82, 80, 22, + 9, 12, 5, 5, 8, 12, 28, 17, 8, 2, 3, 2, 12, + 15, 89, 0, 5, 74, 5, 4, 14, 11, 64, 19, 12, + 14, 74, 5, 67, 65, 12, 89, 11, 16, 13, 11, 6, + 14, 9, 18, 15, 65, 6, 13, 103, 62, 93, 4, 66, + 66, 69, 66, 66, 75, 66, 80, 69, 77, 0, 62, 88, + 25, 28, 22, 18, 17, 16, 12, 12, 9, 65, 67, 68, + 72, 75, 97, 75, 75, 92, 1, 65, 67, 70, 77, 80, + 79, 78, 85, 79, 87, 94, 86, 96, 67, 22, 16, + 10, 7, 8, 1, 66, 67, 2, 3, 30, 20, 16, 10, 16, + 5, 5, 1, 67, 9, 39, 31, 26, 23, 22, 8, 2, 64, + 68, 69, 47, 30, 11, 2, 12, 0, 73, 73, 6, 46, + 36, 23, 13, 21, 4, 0, 68, 70, 62, 85, 79, 71, + 75, 75, 72, 68, 64, 69, 66, 0, 5, 75, 72, 79, + 78, 4, 77, 76, 74, 67, 65, 70, 73, 68, 73, 69, + 70, 82, 8, 8, 17, 3, 64, 8, 5, 3, 4, 3, 1, 68, + 64, 67, 71, 68, 9, 87, 68, 16, 69, 5, 64, 3, + 12, 64, 66, 4, 8, 76, 71, 84, 33, 35, 36, 25, + 19, 25, 22, 20, 18, 12, 14, 12, 3, 1, 71, 1, + 4, 0, 75, 65, 65, 69, 69, 76, 72, 80, 81, 78, + 86, 25, 24, 23, 20, 7, 12, 10, 65, 2, 67, 70, + 84, 80, 86, 92, 71, 70, 95, 64, 66, 73, 83, + 78, 82, 86, 76, 87, 84, 93, 94, 98, 104, 80, + 89, 94, 75, 69, 6, 67, 16, 25, 66, 0, 10, 14, + 4, 13, 25, 4, 1, 41, 14, 72, 89, 102, 126, + 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, + 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, + 6, 10, 21, 8, 2, 41, 14, 72, 89, 102, 126, + 126, 126, 126 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 69, 68, + 31, 58, 14, 3, 69, 4, 10, 1, 68, 64, 74, 86, + 3, 80, 116, 118, 121, 26, 71, 68, 4, 10, 1, + 81, 64, 11, 4, 65, 72, 76, 0, 79, 81, 94, 5, + 68, 73, 4, 75, 72, 85, 64, 75, 72, 82, 1, 2, + 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 22, 65, + 84, 14, 8, 1, 34, 35, 9, 12, 65, 12, 68, 66, + 8, 80, 79, 80, 84, 24, 65, 9, 6, 69, 80, 73, + 65, 2, 70, 69, 77, 16, 68, 3, 70, 77, 65, 71, + 64, 3, 0, 64, 6, 5, 72, 65, 62, 62, 36, 28, 5, + 68, 0, 7, 0, 10, 7, 0, 73, 12, 69, 84, 82, 24, + 9, 12, 5, 5, 8, 12, 29, 17, 8, 1, 2, 2, 12, + 15, 91, 0, 5, 75, 4, 2, 13, 10, 65, 19, 12, + 13, 76, 5, 68, 66, 11, 89, 10, 15, 12, 8, 2, + 12, 7, 15, 12, 68, 3, 11, 110, 62, 97, 1, 68, + 69, 73, 69, 70, 80, 71, 83, 71, 81, 65, 62, + 90, 22, 25, 19, 15, 14, 13, 9, 9, 7, 68, 70, + 70, 74, 77, 99, 75, 76, 93, 0, 67, 69, 72, 79, + 82, 81, 80, 86, 80, 88, 95, 87, 96, 66, 22, + 16, 10, 7, 8, 1, 66, 67, 4, 4, 30, 20, 16, 10, + 16, 6, 6, 2, 66, 9, 39, 31, 26, 23, 23, 8, 2, + 64, 68, 70, 47, 29, 10, 1, 12, 0, 73, 73, 5, + 45, 35, 21, 12, 20, 4, 0, 68, 70, 62, 84, 78, + 70, 74, 74, 71, 67, 0, 68, 65, 1, 7, 75, 72, + 79, 77, 5, 77, 76, 74, 67, 65, 70, 74, 69, 74, + 69, 71, 83, 8, 8, 18, 3, 65, 8, 5, 2, 4, 3, 1, + 69, 64, 67, 71, 68, 9, 88, 69, 16, 71, 4, 65, + 2, 11, 65, 67, 4, 7, 78, 72, 86, 31, 33, 35, + 23, 17, 22, 19, 17, 15, 9, 11, 9, 64, 65, 73, + 67, 0, 68, 80, 69, 69, 72, 72, 79, 74, 82, 83, + 79, 87, 22, 21, 20, 17, 4, 9, 7, 69, 64, 70, + 73, 87, 82, 88, 94, 72, 71, 97, 66, 68, 75, + 86, 80, 84, 88, 78, 89, 86, 94, 96, 99, 105, + 82, 91, 96, 75, 69, 6, 67, 17, 26, 66, 0, 10, + 14, 4, 13, 25, 4, 0, 39, 12, 75, 93, 106, 126, + 126, 126, 126, 2, 39, 29, 25, 15, 24, 12, 6, + 4, 68, 75, 70, 5, 66, 15, 23, 64, 64, 7, 11, + 6, 10, 21, 7, 1, 39, 12, 75, 93, 106, 126, + 126, 126, 126 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 70, 70, + 30, 59, 14, 5, 69, 5, 11, 1, 68, 0, 74, 87, 2, + 82, 119, 120, 122, 29, 70, 67, 5, 11, 1, 81, + 0, 11, 4, 64, 71, 75, 0, 79, 80, 93, 5, 67, + 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 64, 94, 97, 6, 67, 68, 22, 65, 84, 17, + 10, 3, 36, 38, 11, 14, 0, 14, 66, 64, 11, 80, + 78, 79, 83, 24, 65, 10, 9, 68, 79, 72, 0, 2, + 70, 69, 77, 17, 68, 4, 69, 76, 64, 70, 0, 4, + 1, 1, 8, 6, 70, 0, 62, 62, 40, 31, 6, 67, 1, + 8, 0, 11, 8, 1, 72, 15, 68, 86, 83, 27, 9, 13, + 5, 6, 9, 13, 31, 18, 9, 1, 2, 2, 13, 16, 92, + 1, 5, 75, 4, 1, 13, 10, 65, 19, 12, 13, 77, 6, + 68, 66, 11, 89, 10, 15, 12, 6, 64, 11, 6, 13, + 10, 70, 1, 9, 116, 62, 100, 64, 69, 71, 76, + 71, 73, 84, 75, 85, 73, 84, 67, 62, 91, 20, + 23, 17, 13, 12, 11, 7, 7, 5, 70, 72, 71, 75, + 78, 100, 75, 76, 93, 0, 68, 70, 73, 80, 83, + 82, 81, 87, 80, 89, 95, 87, 95, 64, 23, 17, + 10, 8, 9, 2, 65, 66, 7, 6, 31, 21, 17, 11, 17, + 8, 8, 4, 64, 10, 40, 32, 27, 24, 24, 9, 3, 0, + 67, 70, 48, 29, 10, 1, 13, 1, 73, 72, 5, 45, + 35, 20, 11, 20, 5, 1, 67, 69, 62, 82, 76, 68, + 72, 72, 69, 65, 2, 66, 0, 3, 10, 74, 71, 78, + 75, 7, 76, 75, 73, 66, 64, 69, 74, 69, 74, 69, + 71, 83, 9, 9, 19, 4, 65, 9, 6, 2, 5, 4, 1, 69, + 0, 66, 70, 67, 10, 88, 70, 16, 72, 4, 65, 2, + 11, 65, 67, 4, 7, 79, 72, 87, 30, 32, 35, 22, + 16, 20, 17, 15, 13, 7, 9, 7, 67, 67, 75, 71, + 66, 72, 84, 72, 72, 74, 74, 81, 75, 83, 84, + 79, 87, 20, 19, 18, 15, 2, 7, 5, 72, 66, 72, + 75, 89, 83, 89, 95, 72, 71, 98, 67, 69, 76, + 88, 81, 85, 89, 79, 90, 87, 94, 97, 99, 105, + 83, 92, 97, 74, 68, 7, 66, 19, 28, 65, 1, 11, + 15, 5, 14, 26, 4, 0, 38, 10, 77, 96, 109, 126, + 126, 126, 126, 3, 39, 30, 26, 16, 25, 13, 7, + 5, 67, 74, 69, 6, 65, 16, 24, 0, 0, 8, 12, 6, + 11, 22, 7, 1, 38, 10, 77, 96, 109, 126, 126, + 126, 126 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 71, 72, + 29, 59, 14, 7, 69, 5, 12, 1, 69, 0, 75, 89, 1, + 85, 123, 123, 124, 32, 69, 67, 5, 12, 1, 81, + 1, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, + 72, 4, 74, 71, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 0, 94, 97, 6, 68, 68, 21, 65, 84, 19, + 11, 4, 38, 40, 12, 15, 2, 15, 65, 0, 13, 80, + 78, 79, 83, 24, 65, 11, 11, 68, 78, 71, 2, 2, + 70, 69, 78, 17, 68, 4, 68, 75, 0, 69, 1, 4, 2, + 2, 9, 7, 69, 1, 62, 62, 43, 34, 6, 67, 1, 8, + 0, 11, 8, 1, 72, 17, 68, 88, 85, 30, 9, 13, 5, + 6, 9, 13, 33, 19, 9, 1, 2, 2, 14, 17, 93, 1, + 5, 75, 3, 0, 12, 10, 66, 19, 12, 13, 78, 6, + 69, 67, 10, 89, 10, 14, 11, 4, 67, 10, 4, 11, + 8, 72, 64, 7, 122, 62, 104, 66, 71, 73, 79, + 73, 76, 88, 79, 88, 75, 87, 69, 62, 93, 18, + 21, 15, 11, 10, 9, 5, 5, 3, 72, 74, 73, 77, + 80, 102, 75, 76, 94, 64, 69, 71, 74, 81, 84, + 83, 83, 88, 80, 90, 96, 88, 94, 0, 24, 17, 10, + 8, 10, 3, 64, 65, 9, 7, 31, 21, 17, 12, 18, 9, + 10, 6, 1, 11, 41, 33, 28, 25, 25, 9, 3, 0, 66, + 70, 49, 29, 9, 1, 13, 1, 73, 72, 5, 45, 34, + 19, 10, 20, 5, 1, 67, 69, 62, 81, 75, 67, 70, + 70, 68, 0, 4, 65, 2, 5, 12, 73, 70, 78, 74, 9, + 76, 75, 73, 65, 64, 69, 74, 69, 75, 69, 71, + 83, 9, 9, 20, 4, 65, 9, 6, 2, 5, 4, 1, 70, 0, + 66, 70, 67, 11, 89, 71, 16, 73, 3, 66, 1, 11, + 66, 68, 4, 7, 80, 72, 88, 29, 31, 34, 20, 14, + 18, 15, 13, 11, 4, 6, 4, 70, 70, 77, 75, 70, + 76, 89, 75, 75, 77, 76, 84, 77, 85, 85, 80, + 88, 18, 17, 15, 13, 64, 4, 2, 75, 68, 75, 77, + 92, 85, 91, 97, 73, 72, 100, 68, 70, 78, 90, + 83, 87, 91, 80, 92, 88, 95, 98, 100, 106, 85, + 93, 98, 74, 68, 8, 66, 20, 29, 65, 2, 12, 16, + 5, 14, 27, 4, 0, 37, 8, 80, 99, 112, 126, 126, + 126, 126, 3, 39, 30, 26, 16, 26, 13, 7, 5, 67, + 74, 69, 6, 65, 17, 25, 0, 0, 8, 12, 6, 11, 23, + 7, 1, 37, 8, 80, 99, 112, 126, 126, 126, 126 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 73, 74, + 28, 59, 14, 9, 69, 6, 13, 1, 69, 0, 75, 90, 0, + 87, 126, 125, 125, 35, 68, 67, 6, 13, 1, 82, + 2, 11, 3, 64, 71, 74, 0, 79, 80, 93, 5, 67, + 71, 4, 74, 70, 84, 0, 74, 72, 81, 2, 2, 22, 0, + 0, 0, 0, 94, 97, 7, 69, 68, 20, 66, 84, 22, + 12, 5, 39, 42, 14, 17, 4, 17, 64, 1, 15, 80, + 78, 78, 83, 24, 65, 12, 13, 68, 77, 71, 4, 2, + 71, 70, 78, 17, 68, 5, 68, 74, 1, 69, 2, 5, 3, + 4, 11, 7, 68, 2, 62, 62, 46, 37, 6, 67, 1, 9, + 0, 11, 9, 2, 71, 19, 68, 90, 87, 33, 9, 13, 5, + 6, 9, 14, 34, 20, 9, 1, 2, 2, 14, 18, 94, 1, + 5, 76, 3, 64, 12, 10, 66, 19, 12, 13, 79, 6, + 70, 68, 10, 89, 10, 14, 11, 2, 70, 9, 2, 9, 5, + 74, 67, 5, 126, 62, 107, 68, 73, 75, 82, 76, + 79, 92, 83, 91, 77, 91, 71, 62, 95, 16, 19, + 13, 8, 7, 7, 3, 3, 1, 74, 76, 75, 79, 81, 104, + 75, 76, 94, 65, 70, 72, 75, 82, 85, 84, 85, + 89, 81, 91, 97, 88, 94, 2, 25, 18, 10, 8, 11, + 3, 64, 65, 11, 8, 31, 21, 18, 13, 19, 10, 11, + 7, 3, 12, 41, 33, 28, 25, 26, 10, 3, 0, 66, + 70, 49, 29, 8, 1, 13, 1, 73, 71, 5, 44, 34, + 18, 9, 20, 5, 1, 67, 69, 62, 80, 73, 66, 69, + 69, 67, 2, 6, 64, 3, 7, 14, 73, 69, 77, 73, + 11, 75, 75, 73, 65, 0, 69, 74, 69, 75, 69, 71, + 84, 10, 10, 21, 4, 65, 10, 6, 2, 5, 4, 1, 70, + 0, 66, 70, 67, 11, 90, 72, 16, 74, 2, 67, 1, + 11, 67, 69, 4, 7, 81, 72, 89, 28, 30, 33, 19, + 12, 16, 13, 11, 8, 2, 3, 1, 73, 72, 79, 79, + 74, 80, 94, 79, 78, 79, 78, 86, 79, 87, 87, + 81, 89, 16, 14, 13, 10, 67, 2, 0, 78, 71, 77, + 80, 95, 87, 93, 98, 74, 73, 101, 70, 72, 80, + 92, 84, 89, 93, 81, 93, 89, 96, 99, 101, 107, + 86, 94, 99, 74, 67, 8, 65, 21, 30, 65, 2, 12, + 16, 5, 15, 28, 4, 0, 36, 6, 82, 102, 115, 126, + 126, 126, 126, 3, 39, 30, 26, 16, 26, 14, 7, + 5, 66, 74, 69, 7, 64, 18, 26, 0, 1, 8, 12, 6, + 11, 23, 7, 1, 36, 6, 82, 102, 115, 126, 126, + 126, 126 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 74, 76, + 27, 59, 13, 11, 69, 6, 14, 0, 70, 0, 76, 92, + 64, 90, 126, 126, 126, 38, 67, 67, 6, 14, 0, + 82, 3, 11, 2, 64, 70, 73, 0, 79, 80, 93, 5, + 67, 71, 4, 74, 70, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 19, 66, 84, + 24, 13, 6, 41, 44, 15, 18, 5, 18, 1, 2, 17, + 80, 77, 78, 83, 24, 65, 13, 15, 68, 77, 70, 6, + 2, 71, 70, 79, 17, 68, 5, 67, 73, 2, 68, 3, 5, + 3, 5, 12, 8, 67, 3, 62, 62, 49, 40, 6, 66, 1, + 9, 0, 11, 9, 2, 71, 21, 68, 92, 89, 35, 9, 14, + 5, 6, 9, 14, 36, 21, 10, 0, 2, 2, 15, 18, 95, + 1, 5, 76, 2, 65, 11, 9, 67, 19, 12, 13, 80, 6, + 71, 69, 9, 89, 9, 13, 10, 0, 74, 8, 0, 7, 3, + 76, 69, 3, 126, 62, 111, 70, 75, 78, 85, 78, + 83, 97, 87, 94, 79, 94, 73, 62, 96, 14, 17, + 10, 6, 5, 5, 1, 1, 64, 77, 78, 77, 81, 83, + 106, 75, 76, 95, 66, 71, 73, 77, 83, 87, 85, + 86, 90, 81, 92, 97, 89, 93, 3, 26, 18, 10, 9, + 11, 4, 0, 64, 13, 10, 31, 22, 18, 13, 20, 11, + 13, 9, 4, 12, 42, 34, 29, 26, 27, 10, 3, 1, + 65, 70, 50, 29, 8, 0, 13, 1, 73, 71, 5, 44, + 33, 17, 8, 20, 5, 2, 67, 69, 62, 78, 72, 65, + 67, 67, 66, 3, 7, 0, 5, 8, 16, 72, 68, 77, 72, + 12, 75, 75, 73, 64, 0, 69, 75, 69, 76, 69, 71, + 84, 10, 10, 22, 4, 65, 10, 6, 2, 5, 4, 1, 71, + 0, 66, 70, 67, 12, 91, 73, 16, 75, 2, 68, 0, + 11, 68, 70, 4, 7, 82, 72, 90, 27, 29, 32, 17, + 10, 14, 11, 8, 6, 64, 0, 65, 76, 75, 81, 84, + 78, 84, 99, 82, 82, 82, 81, 89, 81, 89, 88, + 82, 89, 13, 12, 10, 8, 70, 64, 66, 81, 73, 80, + 82, 98, 89, 95, 100, 75, 73, 103, 71, 73, 81, + 94, 86, 91, 94, 82, 95, 90, 97, 101, 102, 107, + 88, 96, 101, 73, 67, 9, 65, 22, 31, 65, 3, 13, + 17, 5, 15, 29, 4, 0, 35, 4, 85, 105, 119, 126, + 126, 126, 126, 4, 39, 30, 26, 16, 27, 14, 7, + 5, 66, 74, 69, 7, 64, 18, 27, 0, 1, 9, 13, 6, + 11, 24, 7, 1, 35, 4, 85, 105, 119, 126, 126, + 126, 126 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 75, 78, + 26, 59, 13, 13, 69, 6, 15, 0, 70, 0, 77, 94, + 65, 92, 126, 126, 126, 41, 66, 66, 6, 15, 0, + 82, 4, 11, 2, 64, 70, 72, 0, 79, 80, 93, 5, + 67, 71, 4, 74, 69, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 18, 67, 84, + 27, 14, 7, 43, 46, 17, 20, 7, 20, 2, 3, 20, + 80, 77, 77, 82, 24, 65, 14, 17, 68, 76, 70, 8, + 2, 72, 71, 79, 17, 68, 6, 67, 72, 3, 68, 4, 6, + 4, 7, 14, 9, 65, 4, 62, 62, 52, 43, 7, 66, 2, + 10, 0, 11, 10, 2, 70, 23, 68, 94, 91, 38, 9, + 14, 5, 6, 9, 15, 37, 22, 10, 0, 2, 2, 15, 19, + 96, 2, 5, 77, 2, 66, 11, 9, 67, 19, 12, 13, + 81, 7, 72, 69, 9, 89, 9, 12, 9, 65, 77, 7, 64, + 5, 1, 78, 72, 1, 126, 62, 114, 72, 77, 80, 88, + 81, 86, 101, 91, 96, 81, 98, 75, 62, 98, 12, + 15, 8, 4, 3, 3, 64, 64, 66, 79, 80, 79, 82, + 85, 108, 75, 76, 95, 67, 72, 74, 78, 84, 88, + 86, 88, 91, 82, 93, 98, 90, 92, 5, 27, 19, 10, + 9, 12, 4, 0, 0, 15, 11, 31, 22, 19, 14, 21, + 12, 14, 10, 6, 13, 43, 35, 30, 26, 28, 11, 4, + 1, 65, 70, 50, 29, 7, 0, 13, 1, 73, 70, 5, 43, + 32, 16, 7, 20, 5, 2, 67, 68, 62, 77, 70, 0, + 65, 66, 65, 5, 9, 1, 7, 10, 18, 71, 67, 76, + 71, 14, 75, 75, 72, 64, 1, 69, 75, 69, 76, 69, + 71, 85, 11, 10, 23, 4, 65, 10, 6, 2, 5, 4, 1, + 71, 0, 66, 70, 67, 12, 92, 74, 16, 76, 1, 68, + 64, 11, 68, 71, 4, 7, 83, 72, 91, 26, 28, 31, + 15, 8, 12, 9, 6, 3, 67, 66, 68, 79, 77, 83, + 88, 82, 88, 104, 85, 85, 84, 83, 91, 83, 90, + 90, 82, 90, 11, 9, 8, 6, 73, 67, 68, 84, 75, + 82, 84, 101, 91, 97, 101, 75, 74, 105, 72, 75, + 83, 96, 88, 93, 96, 83, 96, 91, 97, 102, 103, + 108, 89, 97, 102, 73, 67, 10, 64, 23, 32, 64, + 4, 13, 17, 5, 16, 30, 4, 0, 34, 2, 88, 108, + 122, 126, 126, 126, 126, 4, 39, 30, 26, 16, + 27, 14, 8, 6, 65, 74, 69, 8, 64, 19, 28, 0, 1, + 9, 13, 6, 12, 24, 7, 1, 34, 2, 88, 108, 122, + 126, 126, 126, 126 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 77, 80, + 25, 59, 13, 14, 69, 7, 15, 0, 71, 1, 77, 95, + 67, 95, 126, 126, 126, 43, 65, 66, 7, 15, 0, + 83, 4, 11, 1, 64, 70, 72, 0, 79, 79, 92, 5, + 66, 70, 4, 73, 69, 83, 0, 74, 72, 81, 3, 2, + 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 18, 67, 84, + 29, 15, 8, 44, 49, 18, 21, 9, 21, 3, 4, 22, + 80, 77, 77, 82, 24, 65, 15, 20, 68, 75, 69, + 10, 1, 72, 71, 80, 18, 68, 6, 66, 72, 3, 67, + 5, 6, 5, 8, 15, 9, 64, 5, 62, 62, 55, 46, 7, + 66, 2, 10, 0, 11, 10, 3, 70, 25, 67, 96, 93, + 41, 9, 14, 5, 6, 10, 15, 39, 23, 10, 0, 2, 2, + 16, 20, 97, 2, 5, 77, 1, 67, 10, 9, 68, 19, + 12, 13, 83, 7, 73, 70, 8, 89, 9, 12, 9, 67, + 80, 6, 66, 2, 65, 80, 74, 64, 126, 62, 118, + 74, 78, 82, 92, 83, 89, 105, 96, 99, 83, 101, + 77, 62, 100, 10, 13, 6, 1, 0, 1, 67, 66, 68, + 81, 83, 81, 84, 86, 109, 75, 76, 96, 68, 73, + 75, 79, 85, 89, 87, 90, 92, 82, 94, 99, 90, + 92, 6, 28, 19, 10, 9, 13, 5, 1, 0, 17, 12, 32, + 22, 19, 15, 22, 13, 16, 12, 8, 14, 43, 35, 30, + 27, 29, 11, 4, 1, 64, 70, 51, 29, 6, 0, 13, 1, + 73, 70, 4, 43, 32, 15, 6, 19, 5, 2, 67, 68, + 62, 76, 69, 1, 64, 64, 64, 7, 11, 2, 8, 12, + 20, 71, 66, 76, 70, 16, 74, 75, 72, 0, 1, 69, + 75, 69, 77, 69, 71, 85, 11, 11, 24, 4, 65, 11, + 7, 2, 6, 5, 1, 72, 0, 66, 70, 67, 13, 93, 75, + 16, 77, 0, 69, 64, 11, 69, 71, 4, 6, 85, 73, + 92, 24, 27, 30, 14, 6, 10, 7, 4, 1, 69, 69, + 70, 82, 80, 85, 92, 86, 92, 108, 89, 88, 87, + 85, 94, 85, 92, 91, 83, 91, 9, 7, 5, 3, 76, + 69, 71, 87, 78, 85, 87, 104, 93, 98, 103, 76, + 75, 106, 74, 76, 85, 98, 89, 95, 98, 84, 98, + 92, 98, 103, 104, 109, 91, 98, 103, 73, 66, + 10, 64, 24, 33, 64, 4, 14, 18, 5, 16, 31, 4, + 0, 33, 0, 90, 111, 125, 126, 126, 126, 126, 4, + 39, 30, 26, 16, 28, 15, 8, 6, 65, 73, 68, 8, + 0, 20, 29, 1, 2, 9, 13, 6, 12, 25, 7, 1, 33, + 0, 90, 111, 125, 126, 126, 126, 126 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 78, 82, + 24, 59, 13, 16, 69, 7, 16, 64, 71, 1, 78, 97, + 68, 97, 126, 126, 126, 46, 64, 66, 7, 16, 64, + 83, 5, 11, 1, 64, 69, 71, 0, 79, 79, 92, 5, + 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, + 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 17, 68, 84, + 32, 16, 9, 46, 51, 20, 23, 10, 23, 5, 5, 24, + 80, 76, 76, 82, 24, 65, 16, 22, 68, 74, 69, + 12, 1, 73, 72, 80, 18, 68, 7, 66, 71, 4, 67, + 6, 7, 6, 10, 17, 10, 0, 6, 62, 62, 58, 49, 7, + 65, 2, 11, 0, 11, 11, 3, 69, 27, 67, 98, 95, + 44, 9, 15, 5, 6, 10, 16, 40, 24, 11, 64, 2, 2, + 16, 20, 98, 2, 5, 78, 1, 68, 10, 8, 68, 19, + 12, 13, 84, 7, 74, 71, 8, 89, 9, 11, 8, 69, + 83, 5, 68, 0, 67, 82, 77, 66, 126, 62, 121, + 76, 80, 85, 95, 86, 92, 110, 100, 102, 85, + 105, 79, 62, 101, 8, 11, 4, 64, 65, 64, 69, + 68, 70, 84, 85, 83, 86, 88, 111, 75, 76, 96, + 69, 74, 76, 81, 86, 90, 88, 91, 93, 83, 95, + 99, 91, 91, 8, 29, 20, 10, 10, 13, 5, 1, 1, + 19, 14, 32, 23, 20, 15, 23, 14, 17, 13, 10, + 14, 44, 36, 31, 27, 30, 12, 4, 2, 64, 70, 51, + 29, 6, 64, 13, 1, 73, 69, 4, 42, 31, 14, 5, + 19, 5, 3, 67, 68, 62, 74, 67, 2, 1, 0, 0, 8, + 12, 3, 10, 13, 22, 70, 65, 75, 69, 18, 74, 75, + 72, 0, 2, 69, 76, 69, 77, 69, 71, 86, 12, 11, + 25, 4, 65, 11, 7, 2, 6, 5, 1, 72, 0, 66, 70, + 67, 13, 94, 76, 16, 78, 0, 70, 65, 11, 70, 72, + 4, 6, 86, 73, 93, 23, 26, 29, 12, 4, 8, 5, 1, + 65, 72, 72, 73, 85, 82, 87, 97, 90, 96, 113, + 92, 91, 89, 87, 96, 87, 94, 93, 84, 91, 6, 4, + 3, 1, 79, 72, 73, 90, 80, 87, 89, 107, 95, + 100, 104, 77, 75, 108, 75, 78, 86, 100, 91, + 97, 99, 85, 99, 93, 99, 105, 105, 109, 92, + 100, 105, 72, 66, 11, 0, 25, 34, 64, 5, 14, + 18, 5, 17, 32, 4, 0, 32, 65, 93, 114, 126, + 126, 126, 126, 126, 5, 39, 30, 26, 16, 28, 15, + 8, 6, 64, 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, + 6, 12, 25, 7, 1, 32, 65, 93, 114, 126, 126, + 126, 126, 126 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 80, 85, + 23, 59, 12, 18, 70, 7, 17, 64, 72, 1, 79, 99, + 69, 100, 126, 126, 126, 49, 0, 66, 7, 17, 64, + 84, 6, 11, 0, 64, 69, 71, 64, 80, 79, 92, 5, + 66, 70, 4, 73, 68, 82, 0, 74, 72, 81, 4, 2, + 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 16, 68, 85, + 34, 17, 10, 47, 53, 21, 24, 12, 24, 6, 6, 26, + 80, 76, 76, 82, 24, 65, 17, 24, 68, 74, 68, + 14, 1, 73, 72, 81, 18, 68, 7, 65, 70, 5, 66, + 6, 7, 6, 11, 18, 10, 1, 7, 62, 62, 61, 51, 7, + 65, 2, 11, 64, 11, 11, 3, 69, 29, 67, 100, 97, + 46, 9, 15, 5, 6, 10, 16, 42, 24, 11, 64, 1, 2, + 17, 21, 100, 2, 5, 78, 0, 70, 9, 8, 69, 19, + 12, 12, 85, 7, 75, 72, 7, 89, 8, 10, 7, 71, + 87, 3, 70, 65, 70, 85, 79, 68, 126, 62, 125, + 78, 82, 87, 98, 88, 96, 114, 104, 105, 87, + 108, 81, 62, 103, 6, 8, 1, 67, 68, 67, 71, 71, + 72, 86, 87, 85, 88, 90, 113, 75, 77, 97, 70, + 76, 77, 82, 87, 92, 90, 93, 94, 83, 96, 100, + 92, 91, 9, 30, 20, 10, 10, 14, 6, 2, 1, 21, + 15, 32, 23, 20, 16, 24, 15, 19, 15, 11, 15, + 44, 36, 31, 28, 31, 12, 4, 2, 0, 71, 52, 29, + 5, 64, 13, 1, 73, 69, 4, 42, 30, 13, 4, 19, 5, + 3, 67, 68, 62, 73, 66, 3, 2, 2, 1, 10, 14, 4, + 11, 15, 24, 70, 65, 75, 68, 19, 74, 75, 72, 1, + 2, 69, 76, 69, 78, 69, 71, 86, 12, 11, 26, 4, + 66, 11, 7, 1, 6, 5, 1, 73, 0, 66, 70, 67, 14, + 95, 77, 16, 80, 64, 71, 66, 10, 71, 73, 4, 6, + 87, 73, 95, 22, 24, 28, 10, 2, 6, 3, 64, 67, + 75, 75, 76, 88, 85, 89, 101, 94, 101, 118, 96, + 95, 92, 90, 99, 89, 96, 94, 85, 92, 4, 2, 0, + 65, 82, 75, 76, 93, 83, 90, 92, 110, 97, 102, + 106, 78, 76, 110, 77, 79, 88, 102, 93, 99, + 101, 87, 101, 95, 100, 106, 106, 110, 94, 101, + 106, 72, 66, 11, 0, 26, 35, 64, 5, 15, 19, 5, + 17, 32, 4, 64, 31, 67, 96, 117, 126, 126, 126, + 126, 126, 5, 39, 30, 26, 16, 29, 15, 8, 6, 64, + 73, 68, 9, 0, 21, 30, 1, 2, 10, 14, 6, 12, 26, + 7, 0, 31, 67, 96, 117, 126, 126, 126, 126, 126 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 81, 87, + 22, 60, 12, 20, 70, 8, 18, 64, 73, 1, 79, 100, + 70, 102, 126, 126, 126, 52, 1, 65, 8, 18, 64, + 84, 7, 11, 0, 0, 69, 70, 64, 80, 79, 92, 5, + 66, 69, 4, 73, 68, 82, 0, 74, 72, 80, 4, 2, + 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 15, 68, 85, + 36, 19, 11, 49, 55, 23, 25, 14, 26, 7, 8, 29, + 80, 76, 76, 81, 24, 65, 18, 26, 67, 73, 67, + 16, 1, 73, 72, 81, 18, 68, 7, 64, 69, 6, 65, + 7, 8, 7, 12, 20, 11, 3, 8, 62, 62, 62, 54, 8, + 65, 3, 12, 64, 11, 11, 4, 68, 32, 67, 102, 98, + 49, 9, 15, 5, 6, 10, 17, 44, 25, 11, 64, 1, 2, + 18, 22, 101, 3, 5, 78, 64, 71, 8, 8, 70, 19, + 12, 12, 86, 8, 76, 72, 6, 89, 8, 10, 7, 73, + 90, 2, 71, 67, 72, 87, 81, 70, 126, 62, 126, + 80, 84, 89, 101, 90, 99, 118, 108, 107, 89, + 111, 83, 62, 105, 4, 6, 64, 69, 70, 69, 73, + 73, 74, 88, 89, 86, 89, 91, 115, 75, 77, 97, + 70, 77, 78, 83, 88, 93, 91, 95, 95, 83, 97, + 101, 92, 90, 10, 31, 20, 10, 10, 15, 7, 3, 2, + 24, 16, 32, 23, 20, 17, 25, 16, 21, 17, 13, + 16, 45, 37, 32, 29, 32, 12, 5, 2, 1, 71, 53, + 29, 4, 64, 14, 2, 73, 68, 4, 42, 30, 12, 3, + 19, 5, 3, 67, 67, 62, 72, 65, 5, 4, 4, 2, 12, + 16, 5, 13, 17, 26, 69, 64, 74, 67, 21, 73, 74, + 71, 2, 3, 69, 76, 69, 79, 69, 71, 86, 12, 12, + 27, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, + 67, 15, 95, 78, 16, 81, 65, 71, 66, 10, 71, + 74, 4, 6, 88, 73, 96, 21, 23, 28, 9, 0, 4, 1, + 66, 69, 77, 78, 79, 91, 88, 91, 105, 98, 105, + 123, 99, 98, 95, 92, 101, 90, 97, 95, 85, 93, + 2, 0, 65, 67, 84, 77, 78, 96, 85, 92, 94, 112, + 99, 104, 108, 78, 77, 111, 78, 80, 90, 104, + 94, 100, 103, 88, 103, 96, 100, 107, 106, 111, + 96, 102, 107, 72, 65, 12, 0, 27, 37, 0, 6, 16, + 20, 5, 18, 33, 4, 64, 30, 69, 98, 120, 126, + 126, 126, 126, 126, 5, 39, 30, 27, 17, 30, 16, + 9, 7, 64, 73, 68, 9, 1, 22, 31, 1, 3, 10, 14, + 6, 13, 27, 7, 0, 30, 69, 98, 120, 126, 126, + 126, 126, 126 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 82, 89, + 21, 60, 12, 22, 70, 8, 19, 65, 73, 1, 80, 102, + 71, 105, 126, 126, 126, 55, 2, 65, 8, 19, 65, + 84, 8, 11, 64, 0, 68, 69, 64, 80, 79, 92, 5, + 66, 69, 4, 73, 67, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 14, 69, + 85, 39, 20, 12, 51, 57, 24, 27, 15, 27, 9, 9, + 31, 80, 75, 75, 81, 24, 65, 19, 28, 67, 72, + 67, 18, 1, 74, 73, 82, 18, 68, 8, 64, 68, 7, + 65, 8, 8, 8, 14, 21, 12, 4, 9, 62, 62, 62, 57, + 8, 64, 3, 12, 64, 11, 12, 4, 68, 34, 67, 104, + 100, 52, 9, 16, 5, 6, 10, 17, 45, 26, 12, 65, + 1, 2, 18, 22, 102, 3, 5, 79, 64, 72, 8, 7, 70, + 19, 12, 12, 87, 8, 77, 73, 6, 89, 8, 9, 6, 75, + 93, 1, 73, 69, 74, 89, 84, 72, 126, 62, 126, + 82, 86, 92, 104, 93, 102, 123, 112, 110, 91, + 115, 85, 62, 106, 2, 4, 66, 71, 72, 71, 75, + 75, 76, 91, 91, 88, 91, 93, 117, 75, 77, 98, + 71, 78, 79, 85, 89, 94, 92, 96, 96, 84, 98, + 101, 93, 89, 12, 32, 21, 10, 11, 15, 7, 3, 3, + 26, 18, 32, 24, 21, 17, 26, 17, 22, 18, 15, + 16, 46, 38, 33, 29, 33, 13, 5, 3, 1, 71, 53, + 29, 4, 65, 14, 2, 73, 68, 4, 41, 29, 11, 2, + 19, 5, 4, 67, 67, 62, 70, 0, 6, 6, 5, 3, 13, + 17, 6, 15, 18, 28, 68, 0, 74, 66, 23, 73, 74, + 71, 2, 3, 69, 77, 69, 79, 69, 71, 87, 13, 12, + 28, 5, 66, 12, 7, 1, 6, 5, 1, 74, 0, 65, 69, + 67, 15, 96, 79, 16, 82, 65, 72, 67, 10, 72, + 75, 4, 6, 89, 73, 97, 20, 22, 27, 7, 65, 2, + 64, 69, 72, 80, 81, 82, 94, 90, 93, 110, 102, + 109, 126, 102, 101, 97, 94, 104, 92, 99, 97, + 86, 93, 64, 66, 68, 69, 87, 80, 81, 99, 87, + 95, 96, 115, 101, 106, 109, 79, 77, 113, 79, + 82, 91, 106, 96, 102, 104, 89, 104, 97, 101, + 109, 107, 111, 97, 104, 109, 71, 65, 13, 1, + 28, 38, 0, 7, 16, 20, 5, 18, 34, 4, 64, 29, + 71, 101, 123, 126, 126, 126, 126, 126, 6, 39, + 30, 27, 17, 30, 16, 9, 7, 0, 73, 68, 10, 1, + 23, 32, 1, 3, 11, 15, 6, 13, 27, 7, 0, 29, 71, + 101, 123, 126, 126, 126, 126, 126 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 84, 91, + 20, 60, 12, 23, 70, 9, 19, 65, 74, 2, 80, 103, + 73, 107, 126, 126, 126, 57, 3, 65, 9, 19, 65, + 85, 8, 11, 64, 0, 68, 69, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 67, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 14, 69, + 85, 41, 21, 13, 52, 60, 26, 28, 17, 29, 10, + 10, 33, 80, 75, 75, 81, 24, 65, 20, 31, 67, + 71, 66, 20, 0, 74, 73, 82, 19, 68, 8, 0, 68, + 7, 64, 9, 9, 9, 15, 23, 12, 5, 10, 62, 62, 62, + 60, 8, 64, 3, 13, 64, 11, 12, 5, 67, 36, 66, + 106, 102, 55, 9, 16, 5, 6, 11, 18, 47, 27, 12, + 65, 1, 2, 19, 23, 103, 3, 5, 79, 65, 73, 7, 7, + 71, 19, 12, 12, 89, 8, 78, 74, 5, 89, 8, 9, 6, + 77, 96, 0, 75, 72, 77, 91, 86, 74, 126, 62, + 126, 84, 87, 94, 108, 95, 105, 126, 117, 113, + 93, 118, 87, 62, 108, 0, 2, 68, 74, 75, 73, + 78, 77, 78, 93, 94, 90, 93, 94, 118, 75, 77, + 98, 72, 79, 80, 86, 90, 95, 93, 98, 97, 84, + 99, 102, 93, 89, 13, 33, 21, 10, 11, 16, 8, 4, + 3, 28, 19, 33, 24, 21, 18, 27, 18, 24, 20, 17, + 17, 46, 38, 33, 30, 34, 13, 5, 3, 2, 71, 54, + 29, 3, 65, 14, 2, 73, 67, 3, 41, 29, 10, 1, + 18, 5, 4, 67, 67, 62, 69, 1, 7, 7, 7, 4, 15, + 19, 7, 16, 20, 30, 68, 1, 73, 65, 25, 72, 74, + 71, 3, 4, 69, 77, 69, 80, 69, 71, 87, 13, 13, + 29, 5, 66, 13, 8, 1, 7, 6, 1, 75, 0, 65, 69, + 67, 16, 97, 80, 16, 83, 66, 73, 67, 10, 73, + 75, 4, 5, 91, 74, 98, 18, 21, 26, 6, 67, 0, + 66, 71, 74, 82, 84, 84, 97, 93, 95, 114, 106, + 113, 126, 106, 104, 100, 96, 106, 94, 101, 98, + 87, 94, 66, 68, 70, 72, 90, 82, 83, 102, 90, + 97, 99, 118, 103, 107, 111, 80, 78, 114, 81, + 83, 93, 108, 97, 104, 106, 90, 106, 98, 102, + 110, 108, 112, 99, 105, 110, 71, 64, 13, 1, + 29, 39, 0, 7, 17, 21, 5, 19, 35, 4, 64, 28, + 73, 103, 126, 126, 126, 126, 126, 126, 6, 39, + 30, 27, 17, 31, 17, 9, 7, 0, 72, 67, 10, 2, + 24, 33, 2, 4, 11, 15, 6, 13, 28, 7, 0, 28, 73, + 103, 126, 126, 126, 126, 126, 126 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 85, 93, + 19, 60, 11, 25, 70, 9, 20, 65, 74, 2, 81, 105, + 74, 110, 126, 126, 126, 60, 4, 65, 9, 20, 65, + 85, 9, 11, 65, 0, 68, 68, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 66, 81, 0, 74, 72, 80, 5, 2, + 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 13, 70, + 85, 44, 22, 14, 54, 62, 27, 30, 19, 30, 11, + 11, 35, 80, 75, 74, 81, 24, 65, 21, 33, 67, + 71, 66, 22, 0, 75, 74, 83, 19, 68, 9, 0, 67, + 8, 64, 10, 9, 9, 17, 24, 13, 6, 11, 62, 62, + 62, 62, 8, 64, 3, 13, 64, 11, 13, 5, 67, 38, + 66, 108, 104, 57, 9, 16, 5, 6, 11, 18, 48, 28, + 12, 65, 1, 2, 19, 24, 104, 3, 5, 80, 65, 74, + 7, 7, 71, 19, 12, 12, 90, 8, 79, 75, 5, 89, 7, + 8, 5, 79, 100, 64, 77, 74, 79, 93, 89, 76, + 126, 62, 126, 86, 89, 96, 111, 98, 109, 126, + 121, 116, 95, 122, 89, 62, 110, 65, 0, 71, 76, + 77, 75, 80, 79, 80, 95, 96, 92, 95, 96, 120, + 75, 77, 99, 73, 80, 81, 87, 91, 97, 94, 100, + 98, 85, 100, 103, 94, 88, 15, 34, 22, 10, 11, + 17, 8, 4, 4, 30, 20, 33, 24, 22, 19, 28, 19, + 25, 21, 18, 18, 47, 39, 34, 30, 35, 14, 5, 3, + 2, 71, 54, 29, 2, 65, 14, 2, 73, 67, 3, 40, + 28, 9, 0, 18, 5, 4, 67, 67, 62, 68, 3, 8, 9, + 8, 5, 17, 21, 8, 18, 22, 32, 67, 2, 73, 64, + 26, 72, 74, 71, 3, 4, 69, 77, 69, 80, 69, 71, + 88, 14, 13, 30, 5, 66, 13, 8, 1, 7, 6, 1, 75, + 0, 65, 69, 67, 16, 98, 81, 16, 84, 67, 74, 68, + 10, 74, 76, 4, 5, 92, 74, 99, 17, 20, 25, 4, + 69, 65, 68, 73, 77, 85, 87, 87, 100, 95, 97, + 118, 110, 117, 126, 109, 108, 102, 99, 109, + 96, 103, 100, 88, 95, 68, 71, 73, 74, 93, 85, + 86, 105, 92, 100, 101, 121, 105, 109, 112, 81, + 79, 116, 82, 85, 95, 110, 99, 106, 108, 91, + 107, 99, 103, 111, 109, 113, 100, 106, 111, + 71, 64, 14, 2, 30, 40, 0, 8, 17, 21, 5, 19, + 36, 4, 64, 27, 75, 106, 126, 126, 126, 126, + 126, 126, 6, 39, 30, 27, 17, 31, 17, 9, 7, 1, + 72, 67, 11, 2, 24, 34, 2, 4, 11, 15, 6, 13, + 28, 7, 0, 27, 75, 106, 126, 126, 126, 126, + 126, 126 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 86, 95, + 18, 60, 11, 27, 70, 9, 21, 66, 75, 2, 82, 107, + 75, 112, 126, 126, 126, 62, 5, 64, 9, 21, 66, + 85, 10, 11, 65, 0, 67, 67, 64, 80, 78, 91, 5, + 65, 68, 4, 72, 66, 80, 0, 74, 72, 80, 6, 2, + 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 12, 70, + 85, 46, 23, 15, 56, 62, 29, 31, 20, 32, 13, + 12, 38, 80, 74, 74, 80, 24, 65, 22, 35, 67, + 70, 65, 24, 0, 75, 74, 83, 19, 68, 9, 1, 66, + 9, 0, 11, 10, 10, 18, 26, 14, 8, 12, 62, 62, + 62, 62, 9, 0, 4, 14, 64, 11, 13, 5, 66, 40, + 66, 110, 106, 60, 9, 17, 5, 6, 11, 19, 50, 29, + 13, 66, 1, 2, 20, 24, 105, 4, 5, 80, 66, 75, + 6, 6, 72, 19, 12, 12, 91, 9, 80, 75, 4, 89, 7, + 7, 4, 81, 103, 65, 78, 76, 81, 95, 91, 78, + 126, 62, 126, 88, 91, 99, 114, 100, 112, 126, + 125, 118, 97, 125, 91, 62, 111, 67, 65, 73, + 78, 79, 77, 82, 81, 82, 98, 98, 94, 96, 98, + 122, 75, 77, 99, 74, 81, 82, 89, 92, 98, 95, + 101, 99, 85, 101, 103, 95, 87, 16, 35, 22, 10, + 12, 17, 9, 5, 5, 32, 22, 33, 25, 22, 19, 29, + 20, 27, 23, 20, 18, 48, 40, 35, 31, 36, 14, 6, + 4, 3, 71, 55, 29, 2, 66, 14, 2, 73, 66, 3, 40, + 27, 8, 64, 18, 5, 5, 67, 66, 62, 66, 4, 10, + 11, 10, 6, 18, 22, 9, 20, 23, 34, 66, 3, 72, + 0, 28, 72, 74, 70, 4, 5, 69, 78, 69, 81, 69, + 71, 88, 14, 13, 31, 5, 66, 13, 8, 1, 7, 6, 1, + 76, 0, 65, 69, 67, 17, 99, 82, 16, 85, 67, 74, + 69, 10, 74, 77, 4, 5, 93, 74, 100, 16, 19, 24, + 2, 71, 67, 70, 76, 79, 88, 90, 90, 103, 98, + 99, 123, 114, 121, 126, 112, 111, 105, 101, + 111, 98, 104, 101, 88, 95, 71, 73, 75, 76, 96, + 88, 88, 108, 94, 102, 103, 124, 107, 111, 114, + 81, 79, 118, 83, 86, 96, 112, 101, 108, 109, + 92, 109, 100, 103, 113, 110, 113, 102, 108, + 113, 70, 64, 15, 2, 31, 41, 1, 9, 18, 22, 5, + 20, 37, 4, 64, 26, 77, 109, 126, 126, 126, + 126, 126, 126, 7, 39, 30, 27, 17, 32, 17, 10, + 8, 1, 72, 67, 11, 2, 25, 35, 2, 4, 12, 16, 6, + 14, 29, 7, 0, 26, 77, 109, 126, 126, 126, 126, + 126, 126 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 88, 97, + 17, 60, 11, 29, 70, 10, 22, 66, 75, 2, 82, + 108, 76, 115, 126, 126, 126, 62, 6, 64, 10, + 22, 66, 86, 11, 11, 66, 0, 67, 67, 64, 80, 78, + 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, + 6, 2, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 11, + 71, 85, 49, 24, 16, 57, 62, 30, 33, 22, 33, + 14, 13, 40, 80, 74, 73, 80, 24, 65, 23, 37, + 67, 69, 65, 26, 0, 76, 75, 84, 19, 68, 10, 1, + 65, 10, 0, 12, 10, 11, 20, 27, 14, 9, 13, 62, + 62, 62, 62, 9, 0, 4, 14, 64, 11, 14, 6, 66, + 42, 66, 112, 108, 62, 9, 17, 5, 6, 11, 19, 51, + 30, 13, 66, 1, 2, 20, 25, 106, 4, 5, 81, 66, + 76, 6, 6, 72, 19, 12, 12, 92, 9, 81, 76, 4, + 89, 7, 7, 4, 83, 106, 66, 80, 78, 84, 97, 94, + 80, 126, 62, 126, 90, 93, 101, 117, 103, 115, + 126, 126, 121, 99, 126, 93, 62, 113, 69, 67, + 75, 81, 82, 79, 84, 83, 84, 100, 100, 96, 98, + 99, 124, 75, 77, 100, 75, 82, 83, 90, 93, 99, + 96, 103, 100, 86, 102, 104, 95, 87, 18, 36, + 23, 10, 12, 18, 9, 5, 5, 34, 23, 33, 25, 23, + 20, 30, 21, 28, 24, 22, 19, 48, 40, 35, 31, + 37, 15, 6, 4, 3, 71, 55, 29, 1, 66, 14, 2, 73, + 66, 3, 39, 27, 7, 65, 18, 5, 5, 67, 66, 62, + 65, 6, 11, 12, 11, 7, 20, 24, 10, 21, 25, 36, + 66, 4, 72, 1, 30, 71, 74, 70, 4, 5, 69, 78, + 69, 81, 69, 71, 89, 15, 14, 32, 5, 66, 14, 8, + 1, 7, 6, 1, 76, 0, 65, 69, 67, 17, 100, 83, + 16, 86, 68, 75, 69, 10, 75, 78, 4, 5, 94, 74, + 101, 15, 18, 23, 1, 73, 69, 72, 78, 82, 90, + 93, 93, 106, 100, 101, 126, 118, 125, 126, + 116, 114, 107, 103, 114, 100, 106, 103, 89, + 96, 73, 76, 78, 79, 99, 90, 91, 111, 97, 105, + 106, 126, 109, 113, 115, 82, 80, 119, 85, 88, + 98, 114, 102, 110, 111, 93, 110, 101, 104, + 114, 111, 114, 103, 109, 114, 70, 0, 15, 3, + 32, 42, 1, 9, 18, 22, 5, 20, 38, 4, 64, 25, + 79, 111, 126, 126, 126, 126, 126, 126, 7, 39, + 30, 27, 17, 32, 18, 10, 8, 2, 72, 67, 12, 3, + 26, 36, 2, 5, 12, 16, 6, 14, 29, 7, 0, 25, 79, + 111, 126, 126, 126, 126, 126, 126 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 89, 99, + 16, 60, 11, 31, 70, 10, 23, 66, 76, 2, 83, + 110, 77, 117, 126, 126, 126, 62, 7, 64, 10, + 23, 66, 86, 12, 11, 66, 0, 67, 66, 64, 80, 78, + 91, 5, 65, 67, 4, 72, 65, 80, 0, 74, 72, 80, + 6, 2, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 10, + 71, 85, 51, 25, 17, 59, 62, 32, 34, 24, 35, + 15, 14, 42, 80, 74, 73, 80, 24, 65, 24, 39, + 67, 68, 64, 28, 0, 76, 75, 84, 19, 68, 10, 2, + 64, 11, 1, 13, 11, 12, 21, 29, 15, 10, 14, 62, + 62, 62, 62, 9, 0, 4, 15, 64, 11, 14, 6, 65, + 44, 66, 114, 110, 62, 9, 17, 5, 6, 11, 20, 53, + 31, 13, 66, 1, 2, 21, 26, 107, 4, 5, 81, 67, + 77, 5, 6, 73, 19, 12, 12, 93, 9, 82, 77, 3, + 89, 7, 6, 3, 85, 109, 67, 82, 80, 86, 99, 96, + 82, 126, 62, 126, 92, 95, 103, 120, 105, 118, + 126, 126, 124, 101, 126, 95, 62, 115, 71, 69, + 77, 83, 84, 81, 86, 85, 86, 102, 102, 98, 100, + 101, 126, 75, 77, 100, 76, 83, 84, 91, 94, + 100, 97, 105, 101, 86, 103, 105, 96, 86, 19, + 37, 23, 10, 12, 19, 10, 6, 6, 36, 24, 33, 25, + 23, 21, 31, 22, 30, 26, 24, 20, 49, 41, 36, + 32, 38, 15, 6, 4, 4, 71, 56, 29, 0, 66, 14, 2, + 73, 65, 3, 39, 26, 6, 66, 18, 5, 5, 67, 66, + 62, 64, 7, 12, 14, 13, 8, 22, 26, 11, 23, 27, + 38, 65, 5, 71, 2, 32, 71, 74, 70, 5, 6, 69, + 78, 69, 82, 69, 71, 89, 15, 14, 33, 5, 66, 14, + 8, 1, 7, 6, 1, 77, 0, 65, 69, 67, 18, 101, 84, + 16, 87, 69, 76, 70, 10, 76, 79, 4, 5, 95, 74, + 102, 14, 17, 22, 64, 75, 71, 74, 80, 84, 93, + 96, 96, 109, 103, 103, 126, 122, 126, 126, + 119, 117, 110, 105, 116, 102, 108, 104, 90, + 97, 75, 78, 80, 81, 102, 93, 93, 114, 99, 107, + 108, 126, 111, 115, 117, 83, 81, 121, 86, 89, + 100, 116, 104, 112, 113, 94, 112, 102, 105, + 115, 112, 115, 105, 110, 115, 70, 0, 16, 3, + 33, 43, 1, 10, 19, 23, 5, 21, 39, 4, 64, 24, + 81, 114, 126, 126, 126, 126, 126, 126, 7, 39, + 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, 3, + 27, 37, 2, 5, 12, 16, 6, 14, 30, 7, 0, 24, 81, + 114, 126, 126, 126, 126, 126, 126 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 91, 102, + 15, 60, 10, 32, 71, 10, 23, 67, 77, 2, 84, + 112, 79, 120, 126, 126, 126, 62, 7, 64, 10, + 23, 67, 87, 12, 11, 67, 0, 67, 66, 65, 81, 78, + 91, 4, 65, 67, 4, 72, 65, 80, 0, 74, 73, 80, + 6, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 9, + 72, 86, 53, 26, 18, 60, 62, 33, 35, 25, 36, + 16, 15, 44, 80, 74, 73, 80, 24, 65, 24, 41, + 67, 68, 64, 29, 64, 77, 76, 85, 19, 68, 10, 2, + 64, 11, 1, 13, 11, 12, 22, 30, 15, 11, 15, 62, + 62, 62, 62, 9, 0, 4, 15, 65, 11, 14, 6, 65, + 46, 66, 116, 112, 62, 9, 17, 5, 6, 11, 20, 54, + 31, 13, 67, 0, 2, 21, 26, 109, 4, 5, 82, 68, + 79, 4, 5, 74, 19, 12, 11, 95, 9, 83, 78, 2, + 89, 6, 5, 2, 88, 113, 69, 84, 83, 89, 102, 99, + 84, 126, 62, 126, 95, 97, 106, 124, 108, 122, + 126, 126, 126, 103, 126, 97, 62, 117, 74, 72, + 80, 86, 87, 84, 89, 88, 88, 105, 105, 100, + 102, 103, 126, 75, 78, 101, 77, 85, 86, 93, + 96, 102, 99, 107, 102, 87, 104, 106, 97, 86, + 20, 37, 23, 10, 12, 19, 10, 6, 6, 38, 25, 33, + 25, 23, 21, 31, 23, 31, 27, 25, 20, 49, 41, + 36, 32, 39, 15, 6, 4, 4, 72, 56, 28, 64, 67, + 14, 2, 73, 65, 2, 38, 25, 4, 67, 17, 5, 5, 67, + 66, 62, 0, 8, 13, 15, 14, 9, 23, 27, 12, 24, + 28, 40, 65, 5, 71, 3, 33, 71, 74, 70, 5, 6, + 69, 79, 70, 83, 69, 72, 90, 15, 14, 34, 5, 67, + 14, 8, 0, 7, 6, 1, 78, 0, 65, 69, 67, 18, 102, + 85, 16, 89, 70, 77, 71, 9, 77, 80, 4, 4, 97, + 75, 104, 12, 15, 21, 66, 77, 74, 77, 83, 87, + 96, 99, 99, 113, 106, 105, 126, 126, 126, 126, + 123, 121, 113, 108, 119, 104, 110, 106, 91, + 98, 78, 81, 83, 84, 105, 96, 96, 118, 102, + 110, 111, 126, 113, 117, 119, 84, 82, 123, 88, + 91, 102, 119, 106, 114, 115, 96, 114, 104, + 106, 117, 113, 116, 107, 112, 117, 70, 0, 16, + 3, 34, 44, 1, 10, 19, 23, 5, 21, 39, 4, 65, + 22, 83, 117, 126, 126, 126, 126, 126, 126, 7, + 39, 30, 27, 17, 33, 18, 10, 8, 2, 72, 67, 12, + 3, 27, 37, 2, 5, 12, 16, 6, 14, 30, 6, 64, 22, + 83, 117, 126, 126, 126, 126, 126, 126 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 92, 104, + 14, 61, 10, 34, 71, 11, 24, 67, 77, 3, 84, + 113, 80, 122, 126, 126, 126, 62, 8, 0, 11, 24, + 67, 87, 13, 11, 67, 1, 66, 65, 65, 81, 77, 90, + 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, + 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 9, 72, 86, + 56, 28, 20, 62, 62, 35, 37, 27, 38, 18, 17, + 47, 80, 73, 72, 79, 24, 65, 25, 44, 66, 67, 0, + 31, 64, 77, 76, 85, 20, 68, 11, 3, 0, 12, 2, + 14, 12, 13, 24, 32, 16, 13, 17, 62, 62, 62, + 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 49, 65, + 118, 113, 62, 9, 18, 5, 7, 12, 21, 56, 32, 14, + 67, 0, 2, 22, 27, 110, 5, 5, 82, 68, 80, 4, 5, + 74, 19, 12, 11, 96, 10, 83, 78, 2, 89, 6, 5, + 2, 90, 116, 70, 85, 85, 91, 104, 101, 86, 126, + 62, 126, 97, 98, 108, 126, 110, 125, 126, 126, + 126, 105, 126, 99, 62, 118, 76, 74, 82, 88, + 89, 86, 91, 90, 90, 107, 107, 101, 103, 104, + 126, 75, 78, 101, 77, 86, 87, 94, 97, 103, + 100, 108, 103, 87, 105, 106, 97, 85, 22, 38, + 24, 10, 13, 20, 11, 7, 7, 41, 27, 34, 26, 24, + 22, 32, 25, 33, 29, 27, 21, 50, 42, 37, 33, + 40, 16, 7, 5, 5, 72, 57, 28, 64, 67, 15, 3, + 73, 64, 2, 38, 25, 3, 68, 17, 6, 6, 66, 65, + 62, 2, 10, 15, 17, 16, 11, 25, 29, 14, 26, 30, + 43, 64, 6, 70, 5, 35, 70, 73, 69, 6, 7, 68, + 79, 70, 83, 69, 72, 90, 16, 15, 35, 6, 67, 15, + 9, 0, 8, 7, 1, 78, 1, 64, 68, 66, 19, 102, 86, + 16, 90, 70, 77, 71, 9, 77, 80, 4, 4, 98, 75, + 105, 11, 14, 21, 67, 78, 76, 79, 85, 89, 98, + 101, 101, 116, 108, 107, 126, 126, 126, 126, + 126, 124, 115, 110, 121, 105, 111, 107, 91, + 98, 80, 83, 85, 86, 107, 98, 98, 121, 104, + 112, 113, 126, 114, 118, 120, 84, 82, 124, 89, + 92, 103, 121, 107, 115, 116, 97, 115, 105, + 106, 118, 113, 116, 108, 113, 118, 69, 1, 17, + 4, 36, 46, 2, 11, 20, 24, 6, 22, 40, 4, 65, + 21, 85, 119, 126, 126, 126, 126, 126, 126, 8, + 39, 31, 28, 18, 34, 19, 11, 9, 3, 71, 66, 13, + 4, 28, 38, 3, 6, 13, 17, 6, 15, 31, 6, 64, 21, + 85, 119, 126, 126, 126, 126, 126, 126 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 93, 106, + 13, 61, 10, 36, 71, 11, 25, 67, 78, 3, 85, + 115, 81, 125, 126, 126, 126, 62, 9, 0, 11, 25, + 67, 87, 14, 11, 68, 1, 66, 64, 65, 81, 77, 90, + 4, 64, 66, 4, 71, 64, 79, 1, 73, 73, 79, 7, 2, + 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 8, 72, 86, + 58, 29, 21, 62, 62, 36, 38, 29, 39, 19, 18, + 49, 80, 73, 72, 79, 24, 65, 26, 46, 66, 66, 1, + 33, 64, 77, 76, 86, 20, 68, 11, 4, 1, 13, 3, + 15, 12, 14, 25, 33, 17, 14, 18, 62, 62, 62, + 62, 10, 1, 5, 16, 65, 12, 15, 7, 64, 51, 65, + 120, 115, 62, 9, 18, 5, 7, 12, 21, 58, 33, 14, + 67, 0, 2, 23, 28, 111, 5, 5, 82, 69, 81, 3, 5, + 75, 19, 12, 11, 97, 10, 84, 79, 1, 89, 6, 4, + 1, 92, 119, 71, 87, 87, 93, 106, 103, 88, 126, + 62, 126, 99, 100, 110, 126, 112, 126, 126, + 126, 126, 107, 126, 101, 62, 120, 78, 76, 84, + 90, 91, 88, 93, 92, 92, 109, 109, 103, 105, + 106, 126, 75, 78, 102, 78, 87, 88, 95, 98, + 104, 101, 110, 104, 87, 106, 107, 98, 84, 23, + 39, 24, 10, 13, 21, 12, 8, 8, 43, 28, 34, 26, + 24, 23, 33, 26, 35, 31, 29, 22, 51, 43, 38, + 34, 41, 16, 7, 5, 6, 72, 58, 28, 65, 67, 15, + 3, 73, 64, 2, 38, 24, 2, 69, 17, 6, 6, 66, 65, + 62, 3, 11, 16, 19, 18, 12, 27, 31, 15, 28, 32, + 45, 0, 7, 70, 6, 37, 70, 73, 69, 7, 7, 68, 79, + 70, 84, 69, 72, 90, 16, 15, 36, 6, 67, 15, 9, + 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 103, 87, + 16, 91, 71, 78, 72, 9, 78, 81, 4, 4, 99, 75, + 106, 10, 13, 20, 69, 80, 78, 81, 87, 91, 101, + 104, 104, 119, 111, 109, 126, 126, 126, 126, + 126, 126, 118, 112, 124, 107, 113, 108, 92, + 99, 82, 85, 88, 88, 110, 101, 101, 124, 106, + 115, 115, 126, 116, 120, 122, 85, 83, 126, 90, + 93, 105, 123, 109, 117, 118, 98, 117, 106, + 107, 119, 114, 117, 110, 114, 119, 69, 1, 18, + 4, 37, 47, 2, 12, 21, 25, 6, 22, 41, 4, 65, + 20, 87, 122, 126, 126, 126, 126, 126, 126, 8, + 39, 31, 28, 18, 35, 19, 11, 9, 3, 71, 66, 13, + 4, 29, 39, 3, 6, 13, 17, 6, 15, 32, 6, 64, 20, + 87, 122, 126, 126, 126, 126, 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 95, 108, + 12, 61, 10, 38, 71, 12, 26, 67, 78, 3, 85, + 116, 82, 126, 126, 126, 126, 62, 10, 0, 12, + 26, 67, 88, 15, 11, 68, 1, 66, 64, 65, 81, 77, + 90, 4, 64, 65, 4, 71, 0, 79, 1, 73, 73, 79, 7, + 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 7, 73, + 86, 61, 30, 22, 62, 62, 38, 40, 31, 41, 20, + 19, 51, 80, 73, 71, 79, 24, 65, 27, 48, 66, + 65, 1, 35, 64, 78, 77, 86, 20, 68, 12, 4, 2, + 14, 3, 16, 13, 15, 27, 35, 17, 15, 19, 62, 62, + 62, 62, 10, 1, 5, 17, 65, 12, 16, 8, 0, 53, + 65, 122, 117, 62, 9, 18, 5, 7, 12, 22, 59, 34, + 14, 67, 0, 2, 23, 29, 112, 5, 5, 83, 69, 82, + 3, 5, 75, 19, 12, 11, 98, 10, 85, 80, 1, 89, + 6, 4, 1, 94, 122, 72, 89, 89, 96, 108, 106, + 90, 126, 62, 126, 101, 102, 112, 126, 115, + 126, 126, 126, 126, 109, 126, 103, 62, 122, + 80, 78, 86, 93, 94, 90, 95, 94, 94, 111, 111, + 105, 107, 107, 126, 75, 78, 102, 79, 88, 89, + 96, 99, 105, 102, 112, 105, 88, 107, 108, 98, + 84, 25, 40, 25, 10, 13, 22, 12, 8, 8, 45, 29, + 34, 26, 25, 24, 34, 27, 36, 32, 31, 23, 51, + 43, 38, 34, 42, 17, 7, 5, 6, 72, 58, 28, 66, + 67, 15, 3, 73, 0, 2, 37, 24, 1, 70, 17, 6, 6, + 66, 65, 62, 4, 13, 17, 20, 19, 13, 29, 33, 16, + 29, 34, 47, 0, 8, 69, 7, 39, 69, 73, 69, 7, 8, + 68, 79, 70, 84, 69, 72, 91, 17, 16, 37, 6, 67, + 16, 9, 0, 8, 7, 1, 79, 1, 64, 68, 66, 20, 104, + 88, 16, 92, 72, 79, 72, 9, 79, 82, 4, 4, 100, + 75, 107, 9, 12, 19, 70, 82, 80, 83, 89, 94, + 103, 107, 107, 122, 113, 111, 126, 126, 126, + 126, 126, 126, 120, 114, 126, 109, 115, 110, + 93, 100, 84, 88, 90, 91, 113, 103, 103, 126, + 109, 117, 118, 126, 118, 122, 123, 86, 84, + 126, 92, 95, 107, 125, 110, 119, 120, 99, 118, + 107, 108, 120, 115, 118, 111, 115, 120, 69, 2, + 18, 5, 38, 48, 2, 12, 21, 25, 6, 23, 42, 4, + 65, 19, 89, 124, 126, 126, 126, 126, 126, 126, + 8, 39, 31, 28, 18, 35, 20, 11, 9, 4, 71, 66, + 14, 5, 30, 40, 3, 7, 13, 17, 6, 15, 32, 6, 64, + 19, 89, 124, 126, 126, 126, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 47, 62, + 62, 12, 1, 99, 47, 85, 102, 6, 6, 73, 6, 23, 53, + 62, 62, 21, 97, 126, 117, 74, 85, 102, 6, 93, + 88, 19, 8, 89, 103, 116, 6, 5, 84, 96, 0, 85, + 106, 0, 75, 90, 101, 8, 79, 75, 97, 13, 3, 22, + 0, 0, 0, 83, 86, 97, 72, 22, 1, 29, 88, 126, + 126, 91, 95, 84, 86, 89, 91, 126, 76, 103, 90, + 126, 80, 76, 84, 78, 8, 2, 83, 126, 79, 104, 91, + 126, 65, 79, 72, 92, 7, 68, 71, 98, 86, 88, 82, + 72, 67, 72, 89, 69, 4, 66, 6, 71, 71, 5, 74, 19, + 69, 1, 12, 16, 21, 22, 10, 76, 78, 83, 11, 67, + 90, 67, 72, 75, 80, 83, 64, 32, 64, 94, 75, 0, + 74, 28, 36, 91, 65, 69, 77, 66, 1, 68, 81, 33, + 56, 40, 74, 66, 124, 26, 62, 62, 126, 24, 21, + 29, 34, 32, 26, 21, 23, 30, 20, 27, 16, 8, 5, 3, + 19, 19, 21, 15, 7, 11, 26, 14, 5, 15, 18, 69, + 30, 0, 62, 62, 62, 53, 62, 62, 62, 62, 46, 38, + 34, 30, 48, 43, 73, 29, 32, 19, 47, 27, 27, 35, + 42, 43, 51, 47, 21, 93, 7, 6, 25, 126, 115, 82, + 1, 10, 4, 85, 89, 94, 92, 126, 100, 6, 67, 71, + 77, 85, 88, 104, 98, 126, 82, 15, 2, 66, 70, 75, + 79, 83, 92, 108, 79, 69, 75, 5, 5, 78, 83, 81, + 99, 81, 25, 1, 5, 4, 73, 76, 86, 83, 87, 62, + 126, 126, 120, 126, 114, 117, 118, 117, 113, + 118, 120, 124, 94, 102, 99, 106, 126, 92, 6, 86, + 94, 91, 77, 71, 73, 64, 81, 64, 6, 67, 68, 67, + 68, 77, 64, 68, 78, 8, 4, 65, 9, 19, 3, 70, 76, + 86, 70, 64, 70, 8, 7, 69, 65, 74, 9, 9, 76, 82, + 77, 77, 21, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 52, 62, 62, 62, 62, 62, 62, + 48, 62, 62, 46, 25, 18, 9, 79, 62, 62, 62, 62, + 48, 48, 38, 41, 47, 45, 35, 22, 35, 16, 1, 32, + 37, 39, 40, 47, 33, 34, 22, 21, 3, 11, 3, 78, + 123, 10, 7, 2, 30, 13, 2, 78, 74, 72, 72, 75, + 71, 0, 70, 75, 72, 67, 10, 4, 11, 68, 62, 62, + 62, 62, 56, 51, 40, 25, 64, 71, 26, 19, 14, 7, + 4, 0, 67, 68, 79, 78, 74, 72, 72, 75, 71, 0, 70, + 75, 72, 67, 10, 4, 11, 68, 62, 62, 62, 62, 56, + 51, 40, 25, 64 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 46, + 62, 62, 13, 2, 97, 46, 84, 100, 6, 6, 71, 6, + 22, 52, 62, 60, 19, 97, 125, 115, 73, 84, 100, + 6, 92, 87, 20, 8, 88, 102, 114, 5, 4, 84, 96, + 0, 84, 105, 0, 75, 89, 100, 8, 78, 74, 96, 14, + 3, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 29, 87, + 125, 124, 89, 94, 82, 84, 88, 89, 125, 75, + 101, 89, 124, 80, 76, 84, 78, 9, 2, 82, 124, + 78, 103, 90, 125, 65, 78, 72, 91, 8, 68, 70, + 97, 85, 87, 81, 71, 66, 71, 88, 68, 5, 66, 6, + 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, + 76, 77, 82, 11, 67, 89, 67, 71, 74, 79, 81, 1, + 33, 1, 92, 75, 64, 73, 29, 37, 91, 65, 68, 77, + 65, 1, 67, 79, 33, 56, 41, 72, 67, 122, 25, + 62, 62, 125, 24, 21, 29, 34, 32, 26, 21, 23, + 30, 20, 27, 16, 8, 5, 3, 19, 19, 21, 15, 7, + 11, 26, 14, 4, 15, 18, 69, 29, 0, 62, 62, 62, + 52, 62, 62, 62, 62, 45, 37, 32, 29, 46, 42, + 74, 28, 31, 18, 46, 27, 27, 34, 41, 42, 50, + 46, 20, 93, 7, 6, 24, 125, 113, 80, 2, 10, 4, + 84, 88, 93, 91, 125, 98, 7, 66, 70, 76, 83, + 87, 102, 97, 124, 81, 16, 3, 65, 69, 74, 78, + 82, 91, 106, 78, 67, 74, 6, 5, 77, 82, 80, 98, + 80, 26, 2, 6, 5, 72, 75, 85, 82, 86, 62, 125, + 125, 118, 125, 112, 115, 116, 115, 111, 116, + 118, 121, 93, 101, 98, 105, 123, 91, 5, 85, + 93, 90, 76, 71, 72, 64, 80, 64, 6, 67, 68, 66, + 68, 77, 64, 68, 77, 8, 4, 65, 9, 19, 3, 70, + 75, 84, 70, 64, 69, 8, 7, 69, 65, 73, 9, 9, + 75, 81, 76, 76, 20, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 50, 62, 62, + 62, 62, 62, 62, 47, 60, 60, 45, 24, 17, 9, 79, + 62, 62, 62, 60, 46, 47, 37, 39, 46, 43, 34, + 20, 33, 15, 0, 31, 36, 37, 39, 46, 32, 33, 21, + 20, 2, 11, 3, 78, 122, 9, 6, 1, 29, 12, 1, 77, + 73, 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, + 12, 67, 62, 62, 62, 62, 54, 50, 38, 24, 65, + 70, 27, 20, 15, 8, 5, 1, 66, 67, 78, 77, 73, + 71, 71, 73, 70, 1, 69, 73, 71, 66, 11, 5, 12, + 67, 62, 62, 62, 62, 54, 50, 38, 24, 65 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 44, + 60, 62, 14, 2, 95, 44, 84, 99, 6, 6, 70, 5, + 21, 51, 60, 57, 17, 98, 123, 114, 73, 84, 99, + 6, 92, 86, 20, 8, 87, 101, 113, 4, 3, 84, 96, + 0, 84, 104, 0, 75, 89, 100, 8, 78, 74, 95, 14, + 3, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 29, 86, + 124, 122, 88, 93, 80, 82, 87, 88, 123, 74, + 100, 88, 122, 81, 76, 84, 78, 9, 2, 81, 122, + 78, 102, 89, 123, 65, 78, 72, 91, 8, 68, 70, + 96, 85, 86, 81, 71, 66, 71, 87, 67, 5, 66, 6, + 70, 70, 5, 73, 20, 68, 1, 13, 17, 22, 23, 11, + 77, 76, 81, 10, 67, 89, 67, 70, 74, 79, 80, 2, + 34, 3, 90, 76, 65, 73, 29, 37, 92, 65, 68, 78, + 64, 1, 67, 78, 33, 56, 41, 71, 68, 121, 24, + 62, 62, 124, 24, 21, 29, 33, 31, 26, 21, 23, + 29, 19, 26, 16, 8, 5, 3, 18, 18, 20, 15, 7, + 11, 25, 13, 3, 14, 17, 69, 28, 64, 62, 62, 62, + 50, 60, 62, 62, 62, 44, 35, 30, 27, 44, 40, + 75, 27, 30, 16, 45, 26, 26, 33, 39, 40, 48, + 44, 18, 93, 6, 5, 22, 124, 112, 79, 3, 10, 4, + 83, 87, 92, 90, 123, 97, 8, 65, 69, 75, 82, + 86, 101, 96, 122, 80, 16, 3, 65, 69, 73, 77, + 81, 90, 105, 78, 66, 73, 6, 5, 76, 81, 80, 97, + 79, 26, 3, 6, 5, 71, 74, 84, 81, 85, 62, 124, + 123, 116, 123, 111, 114, 114, 113, 110, 114, + 116, 119, 92, 100, 97, 104, 120, 91, 4, 85, + 92, 89, 76, 71, 72, 64, 80, 64, 5, 67, 68, 65, + 68, 77, 64, 68, 77, 8, 4, 65, 8, 18, 3, 70, + 75, 83, 71, 64, 68, 7, 7, 69, 65, 73, 9, 9, + 75, 80, 76, 76, 18, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 48, 62, 62, + 62, 62, 62, 61, 45, 58, 58, 43, 23, 16, 8, 79, + 62, 62, 62, 58, 44, 45, 35, 37, 44, 41, 32, + 18, 31, 13, 64, 30, 35, 35, 37, 44, 30, 31, + 20, 19, 1, 10, 2, 78, 121, 8, 5, 64, 28, 11, + 0, 77, 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, + 11, 6, 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, + 66, 69, 27, 20, 16, 9, 6, 1, 65, 67, 77, 77, + 73, 70, 70, 72, 69, 2, 69, 72, 70, 65, 11, 6, + 13, 66, 62, 62, 62, 60, 52, 48, 36, 22, 66 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 42, 59, + 61, 14, 2, 93, 43, 84, 97, 6, 5, 69, 4, 20, + 50, 58, 53, 15, 99, 121, 112, 73, 84, 97, 6, + 91, 85, 21, 8, 86, 100, 112, 3, 2, 84, 97, 0, + 84, 103, 0, 76, 89, 100, 8, 78, 74, 94, 15, 3, + 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 28, 86, + 123, 120, 87, 92, 79, 81, 86, 87, 121, 73, 99, + 87, 120, 82, 76, 84, 78, 10, 2, 80, 120, 78, + 101, 88, 121, 65, 78, 72, 91, 9, 68, 69, 95, + 85, 85, 81, 71, 66, 70, 86, 67, 5, 66, 6, 70, + 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 77, + 76, 80, 10, 67, 89, 67, 69, 74, 78, 79, 3, 35, + 4, 88, 76, 66, 72, 29, 37, 93, 65, 67, 78, 64, + 1, 67, 77, 33, 56, 41, 70, 69, 119, 23, 62, + 62, 122, 24, 21, 28, 32, 31, 25, 20, 23, 29, + 18, 25, 16, 8, 5, 2, 18, 17, 19, 14, 7, 11, + 24, 13, 2, 14, 16, 69, 27, 64, 62, 62, 61, 49, + 58, 62, 62, 62, 43, 33, 28, 26, 42, 38, 77, + 26, 29, 14, 44, 25, 25, 32, 38, 38, 46, 42, + 17, 93, 5, 4, 21, 122, 110, 77, 3, 10, 4, 82, + 86, 91, 89, 121, 96, 9, 64, 68, 75, 81, 85, + 99, 95, 120, 80, 17, 4, 64, 68, 72, 77, 81, + 89, 104, 78, 64, 72, 6, 5, 75, 81, 80, 96, 78, + 27, 4, 7, 5, 70, 74, 83, 81, 85, 62, 122, 122, + 115, 121, 110, 112, 113, 112, 108, 112, 114, + 117, 92, 99, 97, 103, 117, 91, 3, 85, 91, 88, + 76, 71, 72, 64, 79, 64, 4, 67, 68, 65, 68, 77, + 64, 68, 77, 7, 4, 65, 7, 17, 3, 70, 75, 82, + 72, 64, 67, 6, 7, 69, 65, 72, 9, 8, 74, 79, + 76, 76, 17, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 46, 62, 62, 62, 62, + 62, 59, 43, 56, 55, 41, 22, 15, 7, 79, 62, 62, + 62, 56, 42, 43, 34, 35, 42, 39, 30, 16, 29, + 11, 65, 29, 34, 33, 36, 42, 29, 29, 18, 17, 0, + 9, 1, 78, 120, 7, 3, 65, 27, 10, 64, 77, 72, + 70, 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, + 65, 62, 62, 62, 58, 50, 46, 34, 20, 67, 69, + 28, 21, 17, 9, 7, 2, 65, 66, 77, 77, 72, 70, + 70, 71, 68, 3, 69, 71, 69, 64, 12, 7, 13, 65, + 62, 62, 62, 58, 50, 46, 34, 20, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 40, 57, + 60, 15, 2, 92, 41, 84, 96, 5, 5, 68, 3, 18, + 48, 56, 50, 12, 100, 119, 111, 73, 84, 96, 5, + 91, 84, 21, 7, 86, 99, 110, 2, 0, 85, 97, 0, + 83, 102, 64, 76, 89, 100, 8, 78, 74, 94, 15, + 3, 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 28, 85, + 122, 118, 86, 91, 77, 79, 86, 86, 119, 72, 98, + 86, 117, 82, 77, 84, 79, 10, 1, 79, 117, 77, + 101, 88, 119, 65, 78, 72, 91, 9, 68, 69, 94, + 85, 85, 80, 71, 66, 70, 85, 66, 5, 67, 5, 70, + 70, 5, 73, 20, 68, 1, 14, 17, 23, 23, 12, 78, + 75, 80, 9, 67, 88, 67, 68, 73, 78, 77, 5, 36, + 6, 86, 77, 67, 72, 30, 37, 94, 65, 67, 79, 0, + 1, 67, 76, 33, 56, 41, 68, 70, 118, 22, 62, + 62, 121, 23, 21, 28, 32, 30, 25, 20, 23, 28, + 17, 24, 15, 8, 5, 2, 17, 17, 18, 14, 6, 10, + 23, 12, 1, 13, 15, 69, 25, 65, 62, 62, 59, 47, + 57, 62, 62, 62, 42, 31, 25, 24, 40, 36, 78, + 24, 28, 13, 43, 24, 24, 30, 36, 36, 44, 41, + 15, 93, 4, 3, 19, 121, 109, 76, 4, 10, 4, 81, + 85, 90, 89, 119, 94, 10, 64, 68, 74, 79, 84, + 98, 94, 117, 79, 17, 4, 64, 68, 71, 76, 80, + 89, 103, 78, 0, 71, 6, 5, 74, 80, 80, 95, 77, + 27, 5, 7, 5, 69, 73, 82, 80, 84, 62, 121, 120, + 113, 120, 109, 111, 111, 110, 107, 111, 112, + 114, 91, 98, 96, 102, 114, 90, 2, 84, 90, 88, + 76, 71, 72, 65, 79, 65, 3, 67, 68, 64, 68, 77, + 64, 68, 76, 7, 3, 65, 6, 16, 2, 70, 75, 81, + 73, 65, 67, 6, 6, 69, 65, 72, 8, 8, 74, 79, + 76, 76, 15, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 44, 62, 62, 62, 62, + 62, 57, 41, 54, 53, 39, 20, 14, 6, 79, 62, 62, + 62, 54, 40, 41, 32, 33, 40, 37, 28, 14, 26, + 10, 67, 28, 33, 30, 34, 41, 27, 27, 17, 16, + 64, 8, 0, 78, 119, 5, 2, 67, 25, 9, 65, 77, + 72, 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, + 14, 65, 62, 62, 60, 56, 48, 44, 31, 18, 69, + 68, 28, 21, 17, 10, 7, 2, 64, 66, 76, 77, 72, + 69, 69, 70, 68, 3, 68, 70, 68, 0, 12, 8, 14, + 65, 62, 62, 60, 56, 48, 44, 31, 18, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 38, 56, + 59, 16, 2, 90, 39, 83, 94, 5, 5, 67, 2, 17, + 47, 54, 47, 10, 100, 117, 110, 73, 83, 94, 5, + 91, 83, 21, 7, 85, 98, 109, 1, 64, 85, 97, 0, + 83, 101, 64, 76, 89, 100, 8, 77, 74, 93, 16, + 3, 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 27, 85, + 120, 115, 85, 90, 76, 78, 85, 85, 117, 71, 97, + 85, 115, 83, 77, 84, 79, 10, 1, 78, 115, 77, + 100, 87, 117, 65, 78, 72, 90, 9, 68, 68, 93, + 84, 84, 80, 71, 65, 69, 84, 66, 5, 67, 5, 69, + 70, 5, 73, 21, 68, 1, 15, 18, 23, 23, 12, 78, + 75, 79, 9, 67, 88, 67, 67, 73, 77, 76, 6, 37, + 7, 84, 77, 68, 71, 30, 37, 95, 65, 66, 79, 1, + 1, 67, 74, 33, 56, 41, 67, 71, 116, 21, 62, + 62, 120, 23, 21, 27, 31, 30, 25, 19, 23, 28, + 16, 23, 15, 8, 5, 2, 17, 16, 17, 13, 6, 10, + 22, 12, 0, 12, 15, 69, 24, 65, 62, 62, 58, 46, + 55, 62, 62, 62, 41, 29, 23, 23, 38, 34, 79, + 23, 27, 11, 42, 23, 23, 29, 35, 34, 42, 39, + 14, 93, 3, 2, 17, 119, 107, 75, 4, 10, 4, 80, + 84, 89, 88, 117, 93, 11, 0, 67, 73, 78, 83, + 96, 93, 115, 78, 18, 5, 0, 67, 70, 75, 80, 88, + 102, 77, 1, 70, 6, 5, 73, 80, 79, 94, 76, 27, + 6, 7, 5, 68, 72, 81, 80, 83, 62, 120, 119, + 112, 118, 108, 109, 110, 108, 105, 109, 110, + 112, 90, 97, 95, 101, 111, 90, 1, 84, 89, 87, + 76, 71, 72, 65, 78, 65, 2, 67, 68, 0, 68, 77, + 64, 68, 76, 6, 3, 65, 5, 15, 2, 70, 75, 80, + 73, 65, 66, 5, 6, 69, 65, 72, 8, 7, 74, 78, + 76, 76, 14, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 42, 62, 62, 62, 62, + 62, 55, 40, 52, 50, 37, 19, 13, 5, 79, 62, 62, + 62, 52, 38, 39, 31, 31, 38, 35, 26, 12, 24, 8, + 68, 27, 32, 28, 33, 39, 26, 25, 16, 15, 65, 7, + 64, 78, 118, 4, 1, 68, 24, 8, 66, 77, 71, 69, + 68, 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, + 62, 62, 58, 54, 46, 42, 29, 16, 70, 68, 29, + 22, 18, 11, 8, 3, 64, 66, 75, 77, 71, 69, 68, + 69, 67, 4, 68, 69, 67, 1, 13, 9, 14, 64, 62, + 62, 58, 54, 46, 42, 29, 16, 70 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 37, 54, + 58, 16, 3, 88, 38, 83, 93, 5, 4, 66, 1, 16, + 46, 53, 43, 8, 101, 115, 108, 73, 83, 93, 5, + 90, 82, 22, 7, 84, 97, 108, 64, 65, 85, 98, 0, + 83, 101, 64, 77, 88, 100, 7, 77, 74, 92, 16, + 3, 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 27, 84, + 119, 113, 84, 89, 74, 76, 84, 84, 115, 70, 96, + 85, 113, 84, 77, 84, 79, 11, 1, 77, 113, 77, + 99, 86, 115, 65, 78, 72, 90, 10, 69, 68, 93, + 84, 83, 80, 70, 65, 69, 83, 65, 5, 67, 5, 69, + 70, 5, 73, 21, 68, 1, 15, 18, 24, 24, 13, 79, + 74, 78, 8, 67, 88, 67, 66, 73, 77, 75, 7, 37, + 9, 83, 78, 69, 71, 30, 37, 95, 66, 66, 80, 1, + 0, 66, 73, 33, 56, 42, 66, 72, 115, 20, 62, + 62, 118, 23, 21, 27, 30, 29, 24, 19, 22, 27, + 16, 23, 15, 7, 5, 1, 16, 15, 16, 13, 6, 10, + 22, 11, 65, 12, 14, 69, 23, 66, 62, 62, 56, + 44, 53, 62, 62, 62, 39, 27, 21, 21, 36, 32, + 81, 22, 25, 9, 40, 22, 22, 28, 33, 32, 40, 37, + 12, 93, 2, 1, 16, 118, 106, 73, 5, 10, 4, 79, + 84, 89, 87, 116, 92, 12, 1, 66, 73, 77, 82, + 95, 92, 113, 78, 18, 5, 0, 67, 69, 75, 79, 87, + 101, 77, 3, 69, 6, 5, 73, 79, 79, 94, 76, 28, + 6, 8, 5, 67, 72, 81, 79, 83, 62, 118, 117, + 110, 116, 106, 108, 108, 107, 104, 107, 108, + 110, 90, 96, 95, 101, 108, 90, 0, 84, 89, 86, + 76, 71, 72, 65, 78, 65, 1, 67, 68, 0, 68, 77, + 64, 68, 76, 6, 3, 65, 4, 14, 2, 70, 75, 79, + 74, 65, 65, 4, 6, 69, 65, 71, 8, 7, 73, 77, + 76, 76, 12, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 40, 62, 62, 62, 62, + 62, 52, 38, 50, 48, 35, 18, 12, 4, 79, 62, 62, + 62, 50, 36, 38, 29, 29, 36, 32, 24, 10, 22, 6, + 69, 26, 30, 26, 31, 37, 24, 23, 14, 13, 66, 6, + 65, 79, 117, 3, 64, 70, 23, 6, 67, 76, 71, 68, + 68, 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, + 62, 62, 56, 52, 44, 40, 27, 14, 71, 67, 29, + 22, 19, 11, 9, 3, 0, 65, 75, 76, 71, 68, 68, + 68, 66, 5, 68, 68, 66, 2, 13, 10, 15, 0, 62, + 62, 56, 52, 44, 40, 27, 14, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 35, 53, + 57, 17, 3, 87, 36, 83, 91, 4, 4, 65, 0, 15, + 45, 51, 40, 5, 102, 113, 107, 73, 83, 91, 4, + 90, 81, 22, 7, 84, 96, 106, 65, 66, 85, 98, 0, + 82, 100, 65, 77, 88, 100, 7, 77, 74, 91, 17, + 3, 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 26, 84, + 118, 111, 83, 88, 73, 75, 83, 83, 113, 69, 95, + 84, 110, 84, 78, 84, 80, 11, 1, 76, 110, 76, + 99, 86, 113, 65, 78, 72, 90, 10, 69, 67, 92, + 84, 82, 79, 70, 65, 68, 82, 65, 5, 68, 5, 69, + 70, 5, 73, 21, 68, 1, 16, 18, 24, 24, 13, 79, + 74, 78, 8, 67, 87, 67, 65, 72, 76, 73, 9, 38, + 10, 81, 78, 70, 70, 31, 37, 96, 66, 65, 80, 2, + 0, 66, 72, 33, 56, 42, 64, 73, 113, 19, 62, + 62, 117, 23, 21, 26, 30, 29, 24, 18, 22, 27, + 15, 22, 15, 7, 5, 1, 16, 15, 15, 12, 6, 10, + 21, 11, 66, 11, 13, 69, 22, 66, 62, 62, 54, + 43, 52, 62, 62, 62, 38, 25, 19, 20, 34, 30, + 82, 21, 24, 8, 39, 21, 21, 26, 32, 30, 38, 36, + 11, 93, 1, 0, 14, 116, 104, 72, 5, 10, 4, 78, + 83, 88, 87, 114, 90, 13, 2, 66, 72, 75, 81, + 93, 91, 110, 77, 19, 6, 1, 66, 68, 74, 79, 86, + 100, 77, 4, 68, 6, 5, 72, 79, 79, 93, 75, 28, + 7, 8, 5, 66, 71, 80, 79, 82, 62, 117, 116, + 109, 115, 105, 106, 107, 105, 102, 105, 106, + 107, 89, 95, 94, 100, 105, 89, 64, 83, 88, 85, + 76, 71, 72, 65, 77, 66, 0, 67, 68, 1, 68, 77, + 64, 68, 75, 5, 2, 65, 3, 13, 1, 70, 75, 78, + 75, 66, 64, 4, 5, 69, 65, 71, 7, 6, 73, 77, + 76, 76, 11, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 38, 62, 62, 62, 62, + 62, 50, 36, 48, 45, 33, 17, 11, 3, 79, 62, 61, + 62, 48, 34, 36, 28, 27, 34, 30, 22, 8, 20, 5, + 71, 25, 29, 24, 30, 36, 23, 21, 13, 12, 67, 5, + 66, 79, 116, 1, 65, 71, 21, 5, 68, 76, 70, 68, + 67, 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, + 62, 60, 54, 50, 42, 38, 24, 12, 72, 67, 30, + 23, 19, 12, 10, 4, 0, 65, 74, 76, 70, 68, 67, + 67, 65, 5, 67, 67, 65, 3, 14, 11, 15, 0, 62, + 60, 54, 50, 42, 38, 24, 12, 72 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 33, 51, + 56, 17, 3, 85, 34, 83, 90, 4, 3, 64, 64, 13, + 43, 49, 36, 3, 103, 111, 106, 73, 83, 90, 4, + 90, 81, 22, 6, 83, 95, 105, 66, 68, 86, 99, 0, + 82, 99, 65, 78, 88, 100, 7, 77, 74, 91, 17, 3, + 22, 0, 0, 0, 78, 88, 97, 68, 16, 0, 26, 83, + 117, 109, 82, 88, 71, 73, 83, 82, 111, 69, 94, + 83, 108, 85, 78, 85, 80, 11, 0, 76, 108, 76, + 98, 85, 112, 65, 78, 72, 90, 10, 69, 67, 91, + 84, 82, 79, 70, 65, 68, 81, 64, 5, 68, 4, 69, + 70, 4, 73, 21, 68, 1, 16, 18, 24, 24, 13, 80, + 73, 77, 7, 67, 87, 67, 64, 72, 76, 72, 10, 39, + 12, 79, 79, 71, 70, 31, 37, 97, 66, 65, 81, 2, + 0, 66, 71, 33, 56, 42, 0, 74, 112, 18, 59, 62, + 116, 22, 21, 26, 29, 28, 23, 18, 22, 26, 14, + 21, 14, 7, 4, 0, 15, 14, 14, 12, 5, 9, 20, 10, + 67, 10, 12, 69, 20, 67, 62, 62, 52, 41, 50, + 60, 62, 62, 37, 23, 16, 18, 31, 28, 84, 19, + 23, 6, 38, 20, 20, 25, 30, 28, 36, 34, 9, 93, + 0, 64, 12, 115, 103, 71, 6, 10, 4, 78, 82, 87, + 86, 112, 89, 13, 2, 65, 72, 74, 80, 92, 90, + 108, 77, 19, 6, 1, 66, 68, 74, 78, 86, 99, 77, + 5, 67, 6, 5, 71, 78, 79, 92, 74, 28, 8, 8, 5, + 65, 71, 79, 78, 82, 62, 116, 114, 107, 113, + 104, 105, 105, 104, 101, 104, 104, 105, 89, + 94, 94, 99, 102, 89, 65, 83, 87, 85, 76, 71, + 72, 66, 77, 66, 64, 67, 68, 1, 68, 77, 65, 68, + 75, 5, 2, 66, 2, 12, 1, 71, 75, 77, 76, 66, + 64, 3, 5, 69, 66, 71, 7, 6, 73, 76, 76, 76, 9, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 61, 36, 62, 62, 62, 62, 61, 48, 34, + 45, 43, 31, 15, 9, 2, 79, 61, 59, 62, 46, 31, + 34, 26, 24, 32, 28, 20, 6, 17, 3, 72, 23, 28, + 21, 28, 34, 21, 19, 11, 10, 68, 4, 67, 79, + 115, 0, 67, 73, 20, 4, 69, 76, 70, 67, 67, 66, + 65, 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, + 52, 48, 40, 36, 22, 10, 74, 66, 30, 23, 20, + 12, 10, 4, 1, 65, 74, 76, 70, 67, 67, 66, 65, + 6, 67, 66, 65, 4, 14, 11, 16, 1, 61, 58, 52, + 48, 40, 36, 22, 10, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 31, 49, + 56, 18, 3, 83, 33, 82, 88, 4, 3, 0, 64, 12, + 42, 47, 33, 1, 103, 109, 104, 72, 82, 88, 4, + 89, 80, 23, 6, 82, 94, 104, 67, 69, 86, 99, 0, + 82, 98, 65, 78, 88, 100, 7, 76, 73, 90, 17, 3, + 22, 0, 0, 0, 77, 88, 97, 68, 15, 0, 26, 82, + 115, 106, 81, 87, 69, 71, 82, 81, 109, 68, 92, + 82, 106, 86, 78, 85, 80, 12, 0, 75, 106, 76, + 97, 84, 110, 65, 77, 72, 89, 11, 69, 66, 90, + 83, 81, 79, 70, 64, 67, 80, 0, 5, 68, 4, 68, + 69, 4, 73, 22, 68, 1, 16, 19, 25, 24, 14, 80, + 72, 76, 6, 67, 87, 67, 0, 72, 75, 71, 11, 40, + 14, 77, 80, 72, 69, 31, 38, 98, 66, 65, 81, 3, + 0, 66, 69, 33, 56, 42, 1, 75, 111, 17, 57, 62, + 114, 22, 21, 26, 28, 28, 23, 18, 22, 26, 13, + 20, 14, 7, 4, 0, 15, 13, 14, 12, 5, 9, 19, 9, + 68, 10, 12, 69, 19, 67, 62, 62, 51, 40, 48, + 58, 62, 62, 36, 21, 14, 17, 29, 27, 85, 18, + 22, 4, 37, 19, 19, 24, 28, 27, 34, 32, 8, 93, + 0, 65, 11, 113, 101, 69, 7, 10, 4, 77, 81, 86, + 85, 110, 88, 14, 3, 64, 71, 73, 79, 91, 89, + 106, 76, 20, 7, 2, 66, 67, 73, 77, 85, 97, 76, + 7, 66, 7, 5, 70, 77, 78, 91, 73, 29, 9, 9, 6, + 64, 70, 78, 77, 81, 62, 114, 112, 105, 111, + 103, 104, 103, 102, 99, 102, 102, 103, 88, 93, + 93, 98, 98, 89, 66, 83, 86, 84, 75, 71, 72, + 66, 77, 66, 65, 67, 68, 2, 68, 77, 65, 68, 75, + 5, 2, 66, 2, 11, 1, 71, 74, 75, 76, 66, 0, 2, + 5, 69, 66, 70, 7, 6, 72, 75, 75, 75, 7, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 58, 34, 62, 62, 62, 62, 58, 46, 33, 43, + 41, 30, 14, 8, 1, 79, 59, 57, 60, 44, 29, 32, + 25, 22, 30, 26, 18, 4, 15, 1, 73, 22, 27, 19, + 27, 32, 20, 17, 10, 9, 69, 3, 67, 79, 114, 64, + 68, 75, 19, 3, 70, 76, 69, 66, 66, 64, 64, 7, + 67, 65, 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, + 38, 34, 20, 8, 75, 65, 30, 24, 21, 13, 11, 5, + 2, 64, 73, 76, 69, 66, 66, 64, 64, 7, 67, 65, + 64, 5, 15, 12, 17, 2, 60, 57, 50, 46, 38, 34, + 20, 8, 75 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 29, 48, + 55, 19, 3, 82, 31, 82, 87, 3, 3, 1, 65, 11, + 41, 45, 30, 65, 104, 107, 103, 72, 82, 87, 3, + 89, 79, 23, 6, 82, 93, 102, 68, 70, 86, 99, 0, + 81, 97, 66, 78, 88, 100, 7, 76, 73, 89, 18, 3, + 22, 0, 0, 0, 77, 88, 97, 67, 14, 0, 25, 82, + 114, 104, 80, 86, 68, 70, 81, 80, 107, 67, 91, + 81, 103, 86, 79, 85, 81, 12, 0, 74, 103, 75, + 97, 84, 108, 65, 77, 72, 89, 11, 69, 66, 89, + 83, 80, 78, 70, 64, 67, 79, 0, 5, 69, 4, 68, + 69, 4, 73, 22, 68, 1, 17, 19, 25, 24, 14, 81, + 72, 76, 6, 67, 86, 67, 1, 71, 75, 69, 13, 41, + 15, 75, 80, 73, 69, 32, 38, 99, 66, 64, 82, 4, + 0, 66, 68, 33, 56, 42, 3, 76, 109, 16, 54, 62, + 113, 22, 21, 25, 28, 27, 23, 17, 22, 25, 12, + 19, 14, 7, 4, 0, 14, 13, 13, 11, 5, 9, 18, 9, + 69, 9, 11, 69, 18, 68, 60, 62, 49, 38, 47, 56, + 62, 62, 35, 19, 12, 15, 27, 25, 86, 17, 21, 3, + 36, 18, 18, 22, 27, 25, 32, 31, 6, 93, 64, 66, + 9, 112, 100, 68, 7, 10, 4, 76, 80, 85, 85, + 108, 86, 15, 4, 64, 70, 71, 78, 89, 88, 103, + 75, 20, 7, 2, 65, 66, 72, 77, 84, 96, 76, 8, + 65, 7, 5, 69, 77, 78, 90, 72, 29, 10, 9, 6, 0, + 69, 77, 77, 80, 62, 113, 111, 104, 110, 102, + 102, 102, 100, 98, 100, 100, 100, 87, 92, 92, + 97, 95, 88, 67, 82, 85, 83, 75, 71, 72, 66, + 76, 67, 66, 67, 68, 3, 68, 77, 65, 68, 74, 4, + 1, 66, 1, 10, 0, 71, 74, 74, 77, 67, 1, 2, 4, + 69, 66, 70, 6, 5, 72, 75, 75, 75, 6, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 56, 32, 62, 62, 62, 62, 55, 44, 31, 41, 38, + 28, 13, 7, 0, 79, 57, 54, 57, 42, 27, 30, 23, + 20, 28, 24, 16, 2, 13, 0, 75, 21, 26, 17, 25, + 31, 18, 15, 9, 8, 70, 2, 68, 79, 113, 66, 69, + 76, 17, 2, 71, 76, 69, 66, 65, 0, 0, 7, 66, + 64, 0, 6, 15, 13, 17, 2, 60, 55, 48, 44, 36, + 32, 17, 6, 76, 65, 31, 24, 21, 14, 12, 5, 2, + 64, 72, 76, 69, 66, 65, 0, 0, 7, 66, 64, 0, 6, + 15, 13, 17, 2, 60, 55, 48, 44, 36, 32, 17, 6, + 76 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 28, 46, + 54, 19, 4, 80, 30, 82, 85, 3, 2, 2, 66, 10, + 40, 44, 26, 67, 105, 105, 101, 72, 82, 85, 3, + 88, 78, 24, 6, 81, 92, 101, 70, 71, 86, 100, + 0, 81, 97, 66, 79, 87, 100, 6, 76, 73, 88, 18, + 3, 22, 0, 0, 0, 76, 88, 97, 67, 14, 64, 25, + 81, 113, 102, 79, 85, 66, 68, 80, 79, 105, 66, + 90, 81, 101, 87, 79, 85, 81, 13, 0, 73, 101, + 75, 96, 83, 106, 65, 77, 72, 89, 12, 70, 65, + 89, 83, 79, 78, 69, 64, 66, 78, 1, 5, 69, 4, + 68, 69, 4, 73, 22, 68, 1, 17, 19, 26, 25, 15, + 81, 71, 75, 5, 67, 86, 67, 2, 71, 74, 68, 14, + 41, 17, 74, 81, 74, 68, 32, 38, 99, 67, 64, + 82, 4, 64, 65, 67, 33, 56, 43, 4, 77, 108, 15, + 51, 62, 111, 22, 21, 25, 27, 27, 22, 17, 21, + 25, 12, 19, 14, 6, 4, 64, 14, 12, 12, 11, 5, + 9, 18, 8, 71, 9, 10, 69, 17, 68, 57, 62, 47, + 37, 45, 54, 62, 61, 33, 17, 10, 14, 25, 23, + 88, 16, 19, 1, 34, 17, 17, 21, 25, 23, 30, 29, + 5, 93, 65, 67, 8, 110, 98, 66, 8, 10, 4, 75, + 80, 85, 84, 107, 85, 16, 5, 0, 70, 70, 77, 88, + 87, 101, 75, 21, 8, 3, 65, 65, 72, 76, 83, 95, + 76, 10, 64, 7, 5, 69, 76, 78, 90, 72, 30, 10, + 10, 6, 1, 69, 77, 76, 80, 62, 111, 109, 102, + 108, 100, 101, 100, 99, 96, 98, 98, 98, 87, + 91, 92, 97, 92, 88, 68, 82, 85, 82, 75, 71, + 72, 66, 76, 67, 67, 67, 68, 3, 68, 77, 65, 68, + 74, 4, 1, 66, 0, 9, 0, 71, 74, 73, 78, 67, 2, + 1, 4, 69, 66, 69, 6, 5, 71, 74, 75, 75, 4, 62, + 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 53, 30, 62, 62, 62, 62, 53, 41, 29, 39, + 36, 26, 12, 6, 64, 79, 55, 52, 55, 40, 25, 29, + 22, 18, 26, 21, 14, 0, 11, 65, 76, 20, 24, 15, + 24, 29, 17, 13, 7, 6, 71, 1, 69, 80, 112, 67, + 71, 78, 16, 0, 72, 75, 68, 65, 65, 1, 1, 8, + 66, 0, 1, 7, 16, 14, 18, 3, 59, 53, 46, 42, + 34, 30, 15, 4, 77, 64, 31, 25, 22, 14, 13, 6, + 3, 0, 72, 75, 68, 65, 65, 1, 1, 8, 66, 0, 1, + 7, 16, 14, 18, 3, 59, 53, 46, 42, 34, 30, 15, + 4, 77 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 26, 45, + 53, 20, 4, 78, 28, 82, 84, 3, 2, 3, 67, 8, 38, + 42, 23, 69, 106, 103, 100, 72, 82, 84, 3, 88, + 77, 24, 5, 80, 91, 100, 71, 73, 87, 100, 0, + 81, 96, 66, 79, 87, 100, 6, 76, 73, 88, 19, 3, + 22, 0, 0, 0, 76, 89, 97, 66, 13, 64, 24, 81, + 112, 100, 78, 84, 65, 67, 80, 78, 103, 65, 89, + 80, 99, 88, 79, 85, 81, 13, 64, 72, 99, 75, + 95, 82, 104, 65, 77, 72, 89, 12, 70, 65, 88, + 83, 79, 78, 69, 64, 66, 77, 1, 5, 69, 3, 68, + 69, 4, 73, 22, 68, 1, 18, 19, 26, 25, 15, 82, + 71, 74, 5, 67, 86, 67, 3, 71, 74, 67, 15, 42, + 18, 72, 81, 75, 68, 32, 38, 100, 67, 0, 83, 5, + 64, 65, 66, 33, 56, 43, 5, 78, 106, 14, 48, + 60, 110, 21, 21, 24, 26, 26, 22, 16, 21, 24, + 11, 18, 13, 6, 4, 64, 13, 11, 11, 10, 4, 8, + 17, 8, 72, 8, 9, 69, 15, 69, 55, 62, 45, 35, + 43, 52, 62, 58, 32, 15, 7, 12, 23, 21, 89, 14, + 18, 64, 33, 16, 16, 20, 24, 21, 28, 27, 3, 93, + 66, 68, 6, 109, 97, 65, 8, 10, 4, 74, 79, 84, + 83, 105, 84, 17, 5, 1, 69, 69, 76, 86, 86, 99, + 74, 21, 8, 3, 64, 64, 71, 76, 83, 94, 76, 11, + 0, 7, 5, 68, 76, 78, 89, 71, 30, 11, 10, 6, 2, + 68, 76, 76, 79, 62, 110, 108, 101, 106, 99, + 99, 99, 97, 95, 97, 96, 96, 86, 90, 91, 96, + 89, 88, 69, 82, 84, 82, 75, 71, 72, 67, 75, + 67, 68, 67, 68, 4, 68, 77, 65, 68, 74, 3, 1, + 66, 64, 8, 0, 71, 74, 72, 79, 67, 2, 0, 4, 69, + 66, 69, 6, 4, 71, 73, 75, 75, 3, 62, 60, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 50, + 28, 62, 62, 62, 62, 50, 39, 27, 37, 33, 24, + 10, 5, 65, 79, 52, 50, 53, 38, 23, 27, 20, 16, + 24, 19, 12, 65, 8, 67, 77, 19, 23, 12, 22, 27, + 15, 11, 6, 5, 72, 0, 70, 80, 111, 68, 72, 79, + 15, 64, 73, 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, + 8, 16, 15, 18, 4, 59, 51, 44, 40, 32, 28, 13, + 2, 79, 64, 32, 25, 23, 15, 13, 6, 3, 0, 71, + 75, 68, 65, 64, 2, 1, 9, 66, 1, 2, 8, 16, 15, + 18, 4, 59, 51, 44, 40, 32, 28, 13, 2, 79 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 24, 43, + 52, 21, 4, 77, 26, 81, 82, 2, 2, 4, 68, 7, 37, + 40, 20, 72, 106, 101, 99, 72, 81, 82, 2, 88, + 76, 24, 5, 80, 90, 98, 72, 74, 87, 100, 0, 80, + 95, 67, 79, 87, 100, 6, 75, 73, 87, 19, 3, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 24, 80, 110, + 97, 77, 83, 0, 65, 79, 77, 101, 64, 88, 79, + 96, 88, 80, 85, 82, 13, 64, 71, 96, 74, 95, + 82, 102, 65, 77, 72, 88, 12, 70, 64, 87, 82, + 78, 77, 69, 0, 65, 76, 2, 5, 70, 3, 67, 69, 4, + 73, 23, 68, 1, 18, 20, 26, 25, 15, 82, 70, 74, + 4, 67, 85, 67, 4, 70, 73, 65, 17, 43, 20, 70, + 82, 76, 67, 33, 38, 101, 67, 0, 83, 6, 64, 65, + 64, 33, 56, 43, 7, 79, 105, 13, 46, 57, 109, + 21, 21, 24, 26, 26, 22, 16, 21, 24, 10, 17, + 13, 6, 4, 64, 13, 11, 10, 10, 4, 8, 16, 7, 73, + 7, 9, 69, 14, 69, 53, 62, 44, 34, 42, 50, 62, + 56, 31, 13, 5, 11, 21, 19, 90, 13, 17, 65, 32, + 15, 15, 18, 22, 19, 26, 26, 2, 93, 67, 69, 4, + 107, 95, 64, 9, 10, 4, 73, 78, 83, 83, 103, + 82, 18, 6, 1, 68, 67, 75, 85, 85, 96, 73, 22, + 9, 4, 64, 0, 70, 75, 82, 93, 75, 12, 1, 7, 5, + 67, 75, 77, 88, 70, 30, 12, 10, 6, 3, 67, 75, + 75, 78, 62, 109, 106, 99, 105, 98, 98, 97, 95, + 93, 95, 94, 93, 85, 89, 90, 95, 86, 87, 70, + 81, 83, 81, 75, 71, 72, 67, 75, 68, 69, 67, + 68, 5, 68, 77, 65, 68, 73, 3, 0, 66, 65, 7, + 64, 71, 74, 71, 79, 68, 3, 0, 3, 69, 66, 69, + 5, 4, 71, 73, 75, 75, 1, 62, 59, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 48, 26, 62, + 62, 62, 62, 47, 37, 26, 35, 31, 22, 9, 4, 66, + 79, 50, 47, 50, 36, 21, 25, 19, 14, 22, 17, + 10, 67, 6, 68, 79, 18, 22, 10, 21, 26, 14, 9, + 5, 4, 73, 64, 71, 80, 110, 70, 73, 81, 13, 65, + 74, 75, 67, 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, + 16, 19, 4, 58, 49, 42, 38, 30, 26, 10, 0, 80, + 0, 32, 26, 23, 16, 14, 7, 4, 0, 70, 75, 67, + 64, 0, 3, 2, 9, 65, 2, 3, 9, 17, 16, 19, 4, + 58, 49, 42, 38, 30, 26, 10, 0, 80 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 22, 42, + 51, 21, 4, 75, 25, 81, 81, 2, 1, 5, 69, 6, 36, + 38, 16, 74, 107, 99, 97, 72, 81, 81, 2, 87, + 75, 25, 5, 79, 89, 97, 73, 75, 87, 101, 0, 80, + 94, 67, 80, 87, 100, 6, 75, 73, 86, 20, 3, 22, + 0, 0, 0, 75, 89, 97, 65, 11, 64, 23, 80, 109, + 95, 76, 82, 1, 64, 78, 76, 99, 0, 87, 78, 94, + 89, 80, 85, 82, 14, 64, 70, 94, 74, 94, 81, + 100, 65, 77, 72, 88, 13, 70, 64, 86, 82, 77, + 77, 69, 0, 65, 75, 2, 5, 70, 3, 67, 69, 4, 73, + 23, 68, 1, 19, 20, 27, 25, 16, 83, 70, 73, 4, + 67, 85, 67, 5, 70, 73, 64, 18, 44, 21, 68, 82, + 77, 67, 33, 38, 102, 67, 1, 84, 6, 64, 65, 0, + 33, 56, 43, 8, 80, 103, 12, 43, 54, 107, 21, + 21, 23, 25, 25, 21, 15, 21, 23, 9, 16, 13, 6, + 4, 65, 12, 10, 9, 9, 4, 8, 15, 7, 74, 7, 8, + 69, 13, 70, 51, 60, 42, 32, 40, 48, 62, 53, + 30, 11, 3, 9, 19, 17, 92, 12, 16, 67, 31, 14, + 14, 17, 21, 17, 24, 24, 0, 93, 68, 70, 3, 106, + 94, 1, 9, 10, 4, 72, 77, 82, 82, 101, 81, 19, + 7, 2, 68, 66, 74, 83, 84, 94, 73, 22, 9, 4, 0, + 1, 70, 75, 81, 92, 75, 14, 2, 7, 5, 66, 75, + 77, 87, 69, 31, 13, 11, 6, 4, 67, 74, 75, 78, + 62, 107, 105, 98, 103, 97, 96, 96, 94, 92, 93, + 92, 91, 85, 88, 90, 94, 83, 87, 71, 81, 82, + 80, 75, 71, 72, 67, 74, 68, 70, 67, 68, 5, 68, + 77, 65, 68, 73, 2, 0, 66, 66, 6, 64, 71, 74, + 70, 80, 68, 4, 64, 3, 69, 66, 68, 5, 3, 70, + 72, 75, 75, 0, 62, 58, 61, 61, 61, 62, 62, 62, + 61, 62, 62, 62, 57, 45, 24, 62, 60, 59, 60, + 44, 35, 24, 33, 28, 20, 8, 3, 67, 79, 48, 45, + 48, 34, 19, 23, 17, 12, 20, 15, 8, 69, 4, 70, + 80, 17, 21, 8, 19, 24, 12, 7, 3, 2, 74, 65, + 72, 80, 109, 71, 75, 82, 12, 66, 75, 75, 67, + 64, 0, 4, 3, 10, 65, 3, 4, 10, 17, 17, 19, 5, + 58, 47, 40, 36, 28, 24, 8, 65, 81, 0, 33, 26, + 24, 16, 15, 7, 4, 1, 70, 75, 67, 64, 0, 4, 3, + 10, 65, 3, 4, 10, 17, 17, 19, 5, 58, 47, 40, + 36, 28, 24, 8, 65, 81 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 20, 40, + 50, 22, 4, 73, 23, 81, 79, 2, 1, 6, 70, 5, 35, + 36, 13, 76, 108, 97, 96, 72, 81, 79, 2, 87, + 74, 25, 5, 78, 88, 96, 74, 76, 87, 101, 0, 80, + 93, 67, 80, 87, 100, 6, 75, 73, 85, 20, 3, 22, + 0, 0, 0, 74, 89, 97, 65, 10, 64, 23, 79, 108, + 93, 75, 81, 3, 1, 77, 75, 97, 1, 86, 77, 92, + 90, 80, 85, 82, 14, 64, 69, 92, 74, 93, 80, + 98, 65, 77, 72, 88, 13, 70, 0, 85, 82, 76, 77, + 69, 0, 64, 74, 3, 5, 70, 3, 67, 69, 4, 73, 23, + 68, 1, 19, 20, 27, 25, 16, 83, 69, 72, 3, 67, + 85, 67, 6, 70, 72, 0, 19, 45, 23, 66, 83, 78, + 66, 33, 38, 103, 67, 1, 84, 7, 64, 65, 1, 33, + 56, 43, 9, 81, 102, 11, 40, 51, 106, 21, 21, + 23, 24, 25, 21, 15, 21, 23, 8, 15, 13, 6, 4, + 65, 12, 9, 8, 9, 4, 8, 14, 6, 75, 6, 7, 69, + 12, 70, 49, 58, 40, 31, 38, 46, 59, 51, 29, 9, + 1, 8, 17, 15, 93, 11, 15, 69, 30, 13, 13, 16, + 19, 15, 22, 22, 64, 93, 69, 71, 1, 104, 92, 2, + 10, 10, 4, 71, 76, 81, 81, 99, 80, 20, 8, 3, + 67, 65, 73, 82, 83, 92, 72, 23, 10, 5, 0, 2, + 69, 74, 80, 91, 75, 15, 3, 7, 5, 65, 74, 77, + 86, 68, 31, 14, 11, 6, 5, 66, 73, 74, 77, 62, + 106, 103, 96, 101, 96, 95, 94, 92, 90, 91, 90, + 89, 84, 87, 89, 93, 80, 87, 72, 81, 81, 79, + 75, 71, 72, 67, 74, 68, 71, 67, 68, 6, 68, 77, + 65, 68, 73, 2, 0, 66, 67, 5, 64, 71, 74, 69, + 81, 68, 5, 65, 3, 69, 66, 68, 5, 3, 70, 71, + 75, 75, 65, 61, 57, 60, 59, 59, 62, 62, 62, + 59, 60, 62, 61, 54, 42, 22, 61, 57, 55, 55, + 41, 33, 22, 31, 26, 18, 7, 2, 68, 79, 46, 43, + 46, 32, 17, 21, 16, 10, 18, 13, 6, 71, 2, 72, + 81, 16, 20, 6, 18, 22, 11, 5, 2, 1, 75, 66, + 73, 80, 108, 72, 76, 84, 11, 67, 76, 75, 66, + 0, 1, 5, 4, 11, 65, 4, 5, 11, 18, 18, 20, 6, + 57, 45, 38, 34, 26, 22, 6, 67, 82, 1, 33, 27, + 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 5, 4, + 11, 65, 4, 5, 11, 18, 18, 20, 6, 57, 45, 38, + 34, 26, 22, 6, 67, 82 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 18, 38, + 49, 22, 4, 72, 21, 81, 78, 1, 0, 7, 71, 3, 33, + 34, 9, 79, 109, 95, 95, 72, 81, 78, 1, 87, 74, + 25, 4, 78, 88, 95, 76, 78, 88, 102, 64, 80, + 93, 68, 81, 87, 100, 5, 75, 73, 85, 20, 2, 22, + 0, 0, 0, 74, 90, 97, 65, 9, 65, 22, 79, 107, + 91, 74, 81, 4, 2, 77, 74, 96, 1, 85, 77, 90, + 91, 81, 86, 83, 14, 65, 69, 90, 74, 93, 80, + 97, 65, 77, 72, 88, 13, 71, 0, 85, 82, 76, 77, + 69, 0, 64, 73, 3, 5, 71, 2, 67, 69, 3, 73, 23, + 68, 1, 19, 20, 27, 25, 16, 84, 69, 72, 2, 67, + 85, 68, 6, 70, 72, 1, 20, 45, 24, 65, 84, 80, + 66, 33, 38, 104, 68, 1, 85, 7, 65, 65, 2, 33, + 55, 43, 10, 82, 101, 9, 37, 47, 105, 20, 21, + 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, + 66, 11, 8, 7, 8, 3, 7, 13, 5, 77, 5, 6, 69, + 10, 71, 46, 55, 38, 29, 36, 43, 55, 48, 27, 7, + 65, 6, 14, 13, 95, 9, 13, 71, 28, 12, 12, 14, + 17, 13, 20, 20, 66, 93, 70, 72, 64, 103, 91, + 3, 10, 10, 4, 71, 76, 81, 81, 98, 79, 20, 8, + 3, 67, 64, 72, 81, 83, 90, 72, 23, 10, 5, 0, + 2, 69, 74, 80, 90, 75, 16, 4, 7, 4, 65, 74, + 77, 86, 68, 31, 14, 11, 6, 6, 66, 73, 74, 77, + 62, 105, 102, 95, 100, 95, 94, 93, 91, 89, 90, + 89, 87, 84, 87, 89, 93, 77, 87, 74, 81, 81, + 79, 75, 71, 72, 68, 74, 69, 72, 68, 68, 6, 69, + 77, 66, 68, 73, 1, 64, 67, 68, 4, 65, 72, 74, + 68, 82, 69, 5, 66, 2, 69, 67, 68, 4, 2, 70, + 71, 75, 75, 67, 59, 56, 58, 57, 56, 62, 62, + 62, 56, 57, 62, 58, 50, 39, 20, 57, 53, 51, + 49, 38, 30, 20, 28, 23, 16, 5, 0, 69, 79, 43, + 40, 43, 30, 14, 19, 14, 7, 16, 10, 4, 74, 64, + 74, 83, 14, 18, 3, 16, 20, 9, 3, 0, 64, 76, + 67, 74, 81, 107, 74, 78, 86, 9, 69, 78, 75, + 66, 0, 1, 6, 4, 11, 65, 5, 5, 12, 18, 18, 20, + 6, 56, 43, 36, 31, 23, 20, 3, 69, 84, 1, 33, + 27, 25, 17, 16, 8, 5, 1, 69, 75, 66, 0, 1, 6, + 4, 11, 65, 5, 5, 12, 18, 18, 20, 6, 56, 43, + 36, 31, 23, 20, 3, 69, 84 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 17, 37, + 49, 23, 5, 70, 20, 80, 76, 1, 0, 9, 71, 2, 32, + 33, 6, 81, 109, 93, 93, 71, 80, 76, 1, 86, 73, + 26, 4, 77, 87, 93, 77, 79, 88, 102, 64, 79, + 92, 68, 81, 86, 99, 5, 74, 72, 84, 21, 2, 22, + 0, 0, 0, 73, 90, 97, 64, 9, 65, 22, 78, 105, + 88, 72, 80, 6, 4, 76, 72, 94, 2, 83, 76, 87, + 91, 81, 86, 83, 15, 65, 68, 87, 73, 92, 79, + 95, 65, 76, 72, 87, 14, 71, 1, 84, 81, 75, 76, + 68, 1, 0, 72, 4, 6, 71, 2, 66, 68, 3, 72, 24, + 67, 1, 20, 21, 28, 26, 17, 84, 68, 71, 2, 67, + 84, 68, 7, 69, 71, 3, 22, 46, 26, 0, 84, 81, + 65, 34, 39, 104, 68, 2, 85, 8, 65, 64, 4, 33, + 55, 44, 12, 83, 99, 8, 35, 44, 103, 20, 21, + 22, 23, 24, 20, 14, 20, 22, 7, 14, 12, 5, 3, + 66, 11, 8, 7, 8, 3, 7, 13, 5, 78, 5, 6, 69, 9, + 71, 44, 53, 37, 28, 35, 41, 52, 46, 26, 6, 67, + 5, 12, 12, 96, 8, 12, 72, 27, 12, 12, 13, 16, + 12, 19, 19, 67, 93, 70, 72, 65, 101, 89, 5, + 11, 10, 4, 70, 75, 80, 80, 96, 77, 21, 9, 4, + 66, 1, 71, 79, 82, 87, 71, 24, 11, 6, 1, 3, + 68, 73, 79, 88, 74, 18, 5, 8, 4, 64, 73, 76, + 85, 67, 32, 15, 12, 7, 7, 65, 72, 73, 76, 62, + 103, 100, 93, 98, 93, 92, 91, 89, 87, 88, 87, + 84, 83, 86, 88, 92, 73, 86, 75, 80, 80, 78, + 74, 71, 71, 68, 73, 69, 72, 68, 68, 7, 69, 77, + 66, 68, 72, 1, 64, 67, 68, 4, 65, 72, 73, 66, + 82, 69, 6, 66, 2, 69, 67, 67, 4, 2, 69, 70, + 74, 74, 68, 58, 55, 57, 56, 54, 60, 60, 59, + 54, 55, 59, 56, 47, 37, 18, 54, 50, 48, 44, + 36, 28, 19, 26, 21, 15, 4, 64, 69, 79, 41, 38, + 41, 28, 12, 18, 13, 5, 15, 8, 3, 76, 66, 75, + 84, 13, 17, 1, 15, 19, 8, 2, 64, 65, 77, 67, + 74, 81, 106, 75, 79, 87, 8, 70, 79, 74, 65, 1, + 2, 8, 5, 12, 64, 7, 6, 13, 19, 19, 21, 7, 56, + 42, 35, 29, 21, 19, 1, 70, 85, 2, 34, 28, 26, + 18, 17, 9, 6, 2, 68, 74, 65, 1, 2, 8, 5, 12, + 64, 7, 6, 13, 19, 19, 21, 7, 56, 42, 35, 29, + 21, 19, 1, 70, 85 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 15, 35, + 48, 24, 5, 68, 18, 80, 75, 1, 0, 10, 72, 1, + 31, 31, 3, 83, 110, 91, 92, 71, 80, 75, 1, 86, + 72, 26, 4, 76, 86, 92, 78, 80, 88, 102, 64, + 79, 91, 68, 81, 86, 99, 5, 74, 72, 83, 21, 2, + 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 22, 77, + 104, 86, 71, 79, 8, 6, 75, 71, 92, 3, 82, 75, + 85, 92, 81, 86, 83, 15, 65, 67, 85, 73, 91, + 78, 93, 65, 76, 72, 87, 14, 71, 1, 83, 81, 74, + 76, 68, 1, 0, 71, 5, 6, 71, 2, 66, 68, 3, 72, + 24, 67, 1, 20, 21, 28, 26, 17, 85, 67, 70, 1, + 67, 84, 68, 8, 69, 71, 4, 23, 47, 28, 2, 85, + 82, 65, 34, 39, 105, 68, 2, 86, 9, 65, 64, 5, + 33, 55, 44, 13, 84, 98, 7, 32, 41, 102, 20, + 21, 22, 22, 23, 20, 14, 20, 21, 6, 13, 12, 5, + 3, 66, 10, 7, 6, 8, 3, 7, 12, 4, 79, 4, 5, 69, + 8, 72, 42, 51, 35, 26, 33, 39, 49, 44, 25, 4, + 69, 3, 10, 10, 97, 7, 11, 74, 26, 11, 11, 12, + 14, 10, 17, 17, 69, 93, 71, 73, 67, 100, 88, + 6, 12, 10, 4, 69, 74, 79, 79, 94, 76, 22, 10, + 5, 65, 2, 70, 78, 81, 85, 70, 24, 11, 6, 1, 4, + 67, 72, 78, 87, 74, 19, 6, 8, 4, 0, 72, 76, + 84, 66, 32, 16, 12, 7, 8, 64, 71, 72, 75, 62, + 102, 98, 91, 96, 92, 91, 89, 87, 86, 86, 85, + 82, 82, 85, 87, 91, 70, 86, 76, 80, 79, 77, + 74, 71, 71, 68, 73, 69, 73, 68, 68, 8, 69, 77, + 66, 68, 72, 1, 64, 67, 69, 3, 65, 72, 73, 65, + 83, 69, 7, 67, 2, 69, 67, 67, 4, 2, 69, 69, + 74, 74, 70, 57, 54, 56, 54, 52, 57, 57, 56, + 52, 52, 56, 53, 44, 34, 16, 50, 46, 44, 39, + 33, 26, 17, 24, 19, 13, 3, 65, 70, 79, 39, 36, + 39, 26, 10, 16, 11, 3, 13, 6, 1, 78, 68, 77, + 85, 12, 16, 64, 13, 17, 6, 0, 65, 66, 78, 68, + 75, 81, 105, 76, 80, 89, 7, 71, 80, 74, 65, 2, + 3, 9, 6, 13, 64, 8, 7, 14, 19, 20, 22, 8, 55, + 40, 33, 27, 19, 17, 64, 72, 86, 3, 34, 28, 27, + 19, 18, 9, 7, 2, 67, 74, 65, 2, 3, 9, 6, 13, + 64, 8, 7, 14, 19, 20, 22, 8, 55, 40, 33, 27, + 19, 17, 64, 72, 86 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 13, 34, + 47, 24, 5, 66, 17, 80, 73, 1, 64, 11, 73, 0, + 30, 29, 64, 85, 111, 89, 90, 71, 80, 73, 1, + 85, 71, 27, 4, 75, 85, 91, 79, 81, 88, 103, + 64, 79, 90, 68, 82, 86, 99, 5, 74, 72, 82, 22, + 2, 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 21, 77, + 103, 84, 70, 78, 9, 7, 74, 70, 90, 4, 81, 74, + 83, 93, 81, 86, 83, 16, 65, 66, 83, 73, 90, + 77, 91, 65, 76, 72, 87, 15, 71, 2, 82, 81, 73, + 76, 68, 1, 1, 70, 5, 6, 71, 2, 66, 68, 3, 72, + 24, 67, 1, 21, 21, 29, 26, 18, 85, 67, 69, 1, + 67, 84, 68, 9, 69, 70, 5, 24, 48, 29, 4, 85, + 83, 64, 34, 39, 106, 68, 3, 86, 9, 65, 64, 6, + 33, 55, 44, 14, 85, 96, 6, 29, 38, 100, 20, + 21, 21, 21, 23, 19, 13, 20, 21, 5, 12, 12, 5, + 3, 67, 10, 6, 5, 7, 3, 7, 11, 4, 80, 4, 4, 69, + 7, 72, 40, 49, 33, 25, 31, 37, 46, 41, 24, 2, + 71, 2, 8, 8, 99, 6, 10, 76, 25, 10, 10, 11, + 13, 8, 15, 15, 70, 93, 72, 74, 68, 98, 86, 8, + 12, 10, 4, 68, 73, 78, 78, 92, 75, 23, 11, 6, + 65, 3, 69, 76, 80, 83, 70, 25, 12, 7, 2, 5, + 67, 72, 77, 86, 74, 21, 7, 8, 4, 1, 72, 76, + 83, 65, 33, 17, 13, 7, 9, 64, 70, 72, 75, 62, + 100, 97, 90, 94, 91, 89, 88, 86, 84, 84, 83, + 80, 82, 84, 87, 90, 67, 86, 77, 80, 78, 76, + 74, 71, 71, 68, 72, 69, 74, 68, 68, 8, 69, 77, + 66, 68, 72, 0, 64, 67, 70, 2, 65, 72, 73, 64, + 84, 69, 8, 68, 2, 69, 67, 66, 4, 1, 68, 68, + 74, 74, 71, 56, 53, 55, 52, 50, 55, 55, 53, + 49, 49, 53, 50, 41, 31, 14, 46, 43, 40, 34, + 30, 24, 15, 22, 16, 11, 2, 66, 71, 79, 37, 34, + 37, 24, 8, 14, 10, 1, 11, 4, 64, 80, 70, 79, + 86, 11, 15, 66, 12, 15, 5, 65, 67, 68, 79, 69, + 76, 81, 104, 77, 82, 90, 6, 72, 81, 74, 64, 2, + 3, 10, 7, 14, 64, 9, 8, 15, 20, 21, 22, 9, 55, + 38, 31, 25, 17, 15, 66, 74, 87, 3, 35, 29, 28, + 19, 19, 10, 7, 3, 67, 74, 64, 2, 3, 10, 7, 14, + 64, 9, 8, 15, 20, 21, 22, 9, 55, 38, 31, 25, + 17, 15, 66, 74, 87 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 11, 32, + 46, 25, 5, 65, 15, 80, 72, 0, 64, 12, 74, 65, + 28, 27, 67, 88, 112, 87, 89, 71, 80, 72, 0, + 85, 70, 27, 3, 75, 84, 89, 80, 83, 89, 103, + 64, 78, 89, 69, 82, 86, 99, 5, 74, 72, 82, 22, + 2, 22, 0, 0, 0, 71, 91, 97, 0, 6, 65, 21, 76, + 102, 82, 69, 77, 11, 9, 74, 69, 88, 5, 80, 73, + 80, 93, 82, 86, 84, 16, 66, 65, 80, 72, 90, + 77, 89, 65, 76, 72, 87, 15, 71, 2, 81, 81, 73, + 75, 68, 1, 1, 69, 6, 6, 72, 1, 66, 68, 3, 72, + 24, 67, 1, 21, 21, 29, 26, 18, 86, 66, 69, 0, + 67, 83, 68, 10, 68, 70, 7, 26, 49, 31, 6, 86, + 84, 64, 35, 39, 107, 68, 3, 87, 10, 65, 64, 7, + 33, 55, 44, 16, 86, 95, 5, 26, 35, 99, 19, 21, + 21, 21, 22, 19, 13, 20, 20, 4, 11, 11, 5, 3, + 67, 9, 6, 4, 7, 2, 6, 10, 3, 81, 3, 3, 69, 5, + 73, 38, 47, 31, 23, 30, 35, 42, 39, 23, 0, 74, + 0, 6, 6, 100, 4, 9, 77, 24, 9, 9, 9, 11, 6, + 13, 14, 72, 93, 73, 75, 70, 97, 85, 9, 13, 10, + 4, 67, 72, 77, 78, 90, 73, 24, 11, 6, 64, 5, + 68, 75, 79, 80, 69, 25, 12, 7, 2, 6, 66, 71, + 77, 85, 74, 22, 8, 8, 4, 2, 71, 76, 82, 64, + 33, 18, 13, 7, 10, 0, 69, 71, 74, 62, 99, 95, + 88, 93, 90, 88, 86, 84, 83, 83, 81, 77, 81, + 83, 86, 89, 64, 85, 78, 79, 77, 76, 74, 71, + 71, 69, 72, 70, 75, 68, 68, 9, 69, 77, 66, 68, + 71, 0, 65, 67, 71, 1, 66, 72, 73, 0, 85, 70, + 8, 68, 1, 69, 67, 66, 3, 1, 68, 68, 74, 74, + 73, 55, 52, 54, 51, 47, 52, 52, 50, 47, 46, + 49, 47, 37, 29, 12, 42, 39, 36, 29, 27, 22, + 13, 20, 14, 9, 0, 67, 72, 79, 34, 31, 34, 22, + 6, 12, 8, 64, 9, 2, 66, 82, 73, 80, 88, 10, + 14, 69, 10, 14, 3, 67, 68, 69, 80, 70, 77, 81, + 103, 79, 83, 92, 4, 73, 82, 74, 64, 3, 4, 11, + 7, 14, 0, 10, 9, 16, 20, 22, 23, 9, 54, 36, + 29, 23, 15, 13, 69, 76, 89, 4, 35, 29, 28, 20, + 19, 10, 8, 3, 66, 74, 64, 3, 4, 11, 7, 14, 0, + 10, 9, 16, 20, 22, 23, 9, 54, 36, 29, 23, 15, + 13, 69, 76, 89 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 9, 31, + 45, 26, 5, 0, 13, 79, 70, 0, 64, 13, 75, 66, + 27, 25, 70, 90, 112, 85, 88, 71, 79, 70, 0, + 85, 69, 27, 3, 74, 83, 88, 81, 84, 89, 103, + 64, 78, 88, 69, 82, 86, 99, 5, 73, 72, 81, 23, + 2, 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 20, 76, + 100, 79, 68, 76, 12, 10, 73, 68, 86, 6, 79, + 72, 78, 94, 82, 86, 84, 16, 66, 64, 78, 72, + 89, 76, 87, 65, 76, 72, 86, 15, 71, 3, 80, 80, + 72, 75, 68, 2, 2, 68, 6, 6, 72, 1, 65, 68, 3, + 72, 25, 67, 1, 22, 22, 29, 26, 18, 86, 66, 68, + 0, 67, 83, 68, 11, 68, 69, 8, 27, 50, 32, 8, + 86, 85, 0, 35, 39, 108, 68, 4, 87, 11, 65, 64, + 9, 33, 55, 44, 17, 87, 93, 4, 24, 32, 98, 19, + 21, 20, 20, 22, 19, 12, 20, 20, 3, 10, 11, 5, + 3, 67, 9, 5, 3, 6, 2, 6, 9, 3, 82, 2, 3, 69, + 4, 73, 36, 45, 30, 22, 28, 33, 39, 36, 22, 65, + 76, 64, 4, 4, 101, 3, 8, 79, 23, 8, 8, 8, 10, + 4, 11, 12, 73, 93, 74, 76, 72, 95, 83, 10, 13, + 10, 4, 66, 71, 76, 77, 88, 72, 25, 12, 7, 0, + 6, 67, 73, 78, 78, 68, 26, 13, 8, 3, 7, 65, + 71, 76, 84, 73, 23, 9, 8, 4, 3, 71, 75, 81, 0, + 33, 19, 13, 7, 11, 1, 68, 71, 73, 62, 98, 94, + 87, 91, 89, 86, 85, 82, 81, 81, 79, 75, 80, + 82, 85, 88, 2, 85, 79, 79, 76, 75, 74, 71, 71, + 69, 71, 70, 76, 68, 68, 10, 69, 77, 66, 68, + 71, 64, 65, 67, 72, 0, 66, 72, 73, 1, 85, 70, + 9, 69, 1, 69, 67, 66, 3, 0, 68, 67, 74, 74, + 74, 54, 51, 53, 49, 45, 50, 49, 47, 44, 43, + 46, 44, 34, 26, 10, 38, 36, 32, 24, 24, 20, + 12, 18, 11, 7, 64, 68, 73, 79, 32, 29, 32, 20, + 4, 10, 7, 66, 7, 0, 68, 84, 75, 82, 89, 9, 13, + 71, 9, 12, 2, 69, 69, 70, 81, 71, 78, 81, 102, + 80, 84, 93, 3, 74, 83, 74, 0, 3, 5, 12, 8, 15, + 0, 11, 10, 17, 21, 23, 23, 10, 54, 34, 27, 21, + 13, 11, 71, 78, 90, 4, 36, 30, 29, 21, 20, 11, + 8, 3, 65, 74, 0, 3, 5, 12, 8, 15, 0, 11, 10, + 17, 21, 23, 23, 10, 54, 34, 27, 21, 13, 11, + 71, 78, 90 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 8, 29, + 44, 26, 6, 2, 12, 79, 69, 0, 65, 14, 76, 67, + 26, 24, 74, 92, 113, 83, 86, 71, 79, 69, 0, + 84, 68, 28, 3, 73, 82, 87, 83, 85, 89, 104, + 64, 78, 88, 69, 83, 85, 99, 4, 73, 72, 80, 23, + 2, 22, 0, 0, 0, 70, 91, 97, 1, 5, 66, 20, 75, + 99, 77, 67, 75, 14, 12, 72, 67, 84, 7, 78, 72, + 76, 95, 82, 86, 84, 17, 66, 0, 76, 72, 88, 75, + 85, 65, 76, 72, 86, 16, 72, 3, 80, 80, 71, 75, + 67, 2, 2, 67, 7, 6, 72, 1, 65, 68, 3, 72, 25, + 67, 1, 22, 22, 30, 27, 19, 87, 65, 67, 64, 67, + 83, 68, 12, 68, 69, 9, 28, 50, 34, 9, 87, 86, + 0, 35, 39, 108, 69, 4, 88, 11, 66, 0, 10, 33, + 55, 45, 18, 88, 92, 3, 21, 29, 96, 19, 21, 20, + 19, 21, 18, 12, 19, 19, 3, 10, 11, 4, 3, 68, + 8, 4, 2, 6, 2, 6, 9, 2, 84, 2, 2, 69, 3, 74, + 33, 43, 28, 20, 26, 31, 36, 34, 20, 67, 78, + 66, 2, 2, 103, 2, 6, 81, 21, 7, 7, 7, 8, 2, 9, + 10, 75, 93, 75, 77, 73, 94, 82, 12, 14, 10, 4, + 65, 71, 76, 76, 87, 71, 26, 13, 8, 0, 7, 66, + 72, 77, 76, 68, 26, 13, 8, 3, 8, 65, 70, 75, + 83, 73, 25, 10, 8, 4, 3, 70, 75, 81, 0, 34, + 19, 14, 7, 12, 1, 68, 70, 73, 62, 96, 92, 85, + 89, 87, 85, 83, 81, 80, 79, 77, 73, 80, 81, + 85, 88, 5, 85, 80, 79, 76, 74, 74, 71, 71, 69, + 71, 70, 77, 68, 68, 10, 69, 77, 66, 68, 71, + 64, 65, 67, 73, 64, 66, 72, 73, 2, 86, 70, 10, + 70, 1, 69, 67, 65, 3, 0, 67, 66, 74, 74, 76, + 53, 50, 52, 47, 43, 47, 47, 44, 42, 40, 43, + 41, 31, 23, 8, 35, 32, 28, 19, 22, 17, 10, 16, + 9, 5, 65, 69, 74, 79, 30, 27, 30, 18, 2, 9, 5, + 68, 5, 66, 70, 86, 77, 84, 90, 8, 11, 73, 7, + 10, 0, 71, 71, 72, 82, 72, 79, 82, 101, 81, + 86, 95, 2, 76, 84, 73, 0, 4, 5, 13, 9, 16, 0, + 12, 11, 18, 21, 24, 24, 11, 53, 32, 25, 19, + 11, 9, 73, 80, 91, 5, 36, 30, 30, 21, 21, 11, + 9, 4, 65, 73, 0, 4, 5, 13, 9, 16, 0, 12, 11, + 18, 21, 24, 24, 11, 53, 32, 25, 19, 11, 9, 73, + 80, 91 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 6, 28, + 43, 27, 6, 3, 10, 79, 67, 64, 65, 15, 77, 68, + 25, 22, 77, 95, 114, 81, 85, 71, 79, 67, 64, + 84, 67, 28, 3, 73, 81, 85, 84, 86, 89, 104, + 64, 77, 87, 70, 83, 85, 99, 4, 73, 72, 79, 24, + 2, 22, 0, 0, 0, 70, 91, 97, 2, 4, 66, 19, 75, + 98, 75, 66, 74, 15, 13, 71, 66, 82, 8, 77, 71, + 73, 95, 83, 86, 85, 17, 66, 1, 73, 71, 88, 75, + 83, 65, 76, 72, 86, 16, 72, 4, 79, 80, 70, 74, + 67, 2, 3, 66, 7, 6, 73, 1, 65, 68, 3, 72, 25, + 67, 1, 23, 22, 30, 27, 19, 87, 65, 67, 64, 67, + 82, 68, 13, 67, 68, 11, 30, 51, 35, 11, 87, + 87, 1, 36, 39, 109, 69, 5, 88, 12, 66, 0, 11, + 33, 55, 45, 20, 89, 90, 2, 18, 26, 95, 19, 21, + 19, 19, 21, 18, 11, 19, 19, 2, 9, 11, 4, 3, + 68, 8, 4, 1, 5, 2, 6, 8, 2, 85, 1, 1, 69, 2, + 74, 31, 41, 26, 19, 25, 29, 33, 31, 19, 69, + 80, 67, 0, 0, 104, 1, 5, 82, 20, 6, 6, 5, 7, + 0, 7, 9, 76, 93, 76, 78, 75, 92, 80, 13, 14, + 10, 4, 64, 70, 75, 76, 85, 69, 27, 14, 8, 1, + 9, 65, 70, 76, 73, 67, 27, 14, 9, 4, 9, 64, + 70, 74, 82, 73, 26, 11, 8, 4, 4, 70, 75, 80, + 1, 34, 20, 14, 7, 13, 2, 67, 70, 72, 62, 95, + 91, 84, 88, 86, 83, 82, 79, 78, 77, 75, 70, + 79, 80, 84, 87, 8, 84, 81, 78, 75, 73, 74, 71, + 71, 69, 70, 71, 78, 68, 68, 11, 69, 77, 66, + 68, 70, 65, 66, 67, 74, 65, 67, 72, 73, 3, 87, + 71, 11, 70, 0, 69, 67, 65, 2, 64, 67, 66, 74, + 74, 77, 52, 49, 51, 46, 40, 45, 44, 41, 39, + 37, 40, 38, 28, 21, 6, 31, 29, 24, 14, 19, 15, + 8, 14, 6, 3, 66, 70, 75, 79, 28, 24, 27, 16, + 0, 7, 4, 70, 3, 68, 72, 88, 79, 85, 92, 7, 10, + 75, 6, 9, 64, 73, 72, 73, 83, 73, 80, 82, 100, + 83, 87, 96, 0, 77, 85, 73, 1, 4, 6, 14, 10, + 16, 1, 13, 12, 19, 22, 25, 24, 11, 53, 30, 23, + 17, 9, 7, 76, 82, 92, 5, 37, 31, 30, 22, 22, + 12, 9, 4, 64, 73, 1, 4, 6, 14, 10, 16, 1, 13, + 12, 19, 22, 25, 24, 11, 53, 30, 23, 17, 9, 7, + 76, 82, 92 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 4, 26, + 42, 27, 6, 5, 8, 79, 66, 64, 66, 16, 78, 70, + 23, 20, 81, 97, 115, 79, 84, 71, 79, 66, 64, + 84, 67, 28, 2, 72, 80, 84, 85, 88, 90, 105, + 64, 77, 86, 70, 84, 85, 99, 4, 73, 72, 79, 24, + 2, 22, 0, 0, 0, 69, 92, 97, 2, 3, 66, 19, 74, + 97, 73, 65, 74, 17, 15, 71, 65, 80, 8, 76, 70, + 71, 96, 83, 87, 85, 17, 67, 1, 71, 71, 87, 74, + 82, 65, 76, 72, 86, 16, 72, 4, 78, 80, 70, 74, + 67, 2, 3, 65, 8, 6, 73, 0, 65, 68, 2, 72, 25, + 67, 1, 23, 22, 30, 27, 19, 88, 64, 66, 65, 67, + 82, 68, 14, 67, 68, 12, 31, 52, 37, 13, 88, + 88, 1, 36, 39, 110, 69, 5, 89, 12, 66, 0, 12, + 33, 55, 45, 21, 90, 89, 1, 15, 22, 94, 18, 21, + 19, 18, 20, 17, 11, 19, 18, 1, 8, 10, 4, 2, + 69, 7, 3, 0, 5, 1, 5, 7, 1, 86, 0, 0, 69, 0, + 75, 29, 39, 24, 17, 23, 26, 29, 29, 18, 71, + 83, 69, 66, 65, 106, 64, 4, 84, 19, 5, 5, 4, + 5, 65, 5, 7, 78, 93, 77, 79, 77, 91, 79, 14, + 15, 10, 4, 64, 69, 74, 75, 83, 68, 27, 14, 9, + 1, 10, 64, 69, 75, 71, 67, 27, 14, 9, 4, 9, + 64, 69, 74, 81, 73, 27, 12, 8, 4, 5, 69, 75, + 79, 2, 34, 21, 14, 7, 14, 2, 66, 69, 72, 62, + 94, 89, 82, 86, 85, 82, 80, 78, 77, 76, 73, + 68, 79, 79, 84, 86, 11, 84, 82, 78, 74, 73, + 74, 71, 71, 70, 70, 71, 79, 68, 68, 11, 69, + 77, 67, 68, 70, 65, 66, 68, 75, 66, 67, 73, + 73, 4, 88, 71, 11, 71, 0, 69, 68, 65, 2, 64, + 67, 65, 74, 74, 79, 51, 48, 50, 44, 38, 42, + 41, 38, 37, 34, 36, 35, 24, 18, 4, 27, 25, 20, + 9, 16, 13, 6, 11, 4, 1, 68, 72, 76, 79, 25, + 22, 25, 14, 66, 5, 2, 73, 1, 70, 74, 90, 82, + 87, 93, 5, 9, 78, 4, 7, 66, 75, 74, 75, 84, + 74, 81, 82, 99, 84, 89, 98, 64, 78, 86, 73, 1, + 5, 6, 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, + 12, 52, 28, 21, 15, 7, 5, 78, 84, 94, 6, 37, + 31, 31, 22, 22, 12, 10, 4, 64, 73, 1, 5, 6, + 15, 10, 17, 1, 14, 12, 20, 22, 25, 25, 12, 52, + 28, 21, 15, 7, 5, 78, 84, 94 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 2, 24, + 42, 28, 6, 7, 7, 78, 64, 64, 66, 17, 78, 71, + 22, 18, 84, 99, 115, 77, 82, 70, 78, 64, 64, + 83, 66, 29, 2, 71, 79, 83, 86, 89, 90, 105, + 64, 77, 85, 70, 84, 85, 99, 4, 72, 71, 78, 24, + 2, 22, 0, 0, 0, 68, 92, 97, 2, 2, 66, 19, 73, + 95, 70, 64, 73, 19, 17, 70, 64, 78, 9, 74, 69, + 69, 97, 83, 87, 85, 18, 67, 2, 69, 71, 86, 73, + 80, 65, 75, 72, 85, 17, 72, 5, 77, 79, 69, 74, + 67, 3, 4, 64, 9, 6, 73, 0, 64, 67, 2, 72, 26, + 67, 1, 23, 23, 31, 27, 20, 88, 0, 65, 66, 67, + 82, 68, 15, 67, 67, 13, 32, 53, 39, 15, 89, + 89, 2, 36, 40, 111, 69, 5, 89, 13, 66, 0, 14, + 33, 55, 45, 22, 91, 88, 0, 13, 19, 92, 18, 21, + 19, 17, 20, 17, 11, 19, 18, 0, 7, 10, 4, 2, + 69, 7, 2, 0, 5, 1, 5, 6, 0, 87, 0, 0, 69, 64, + 75, 27, 37, 23, 16, 21, 24, 26, 27, 17, 73, + 85, 70, 68, 66, 107, 65, 3, 86, 18, 4, 4, 3, + 3, 66, 3, 5, 79, 93, 77, 80, 78, 89, 77, 16, + 16, 10, 4, 0, 68, 73, 74, 81, 67, 28, 15, 10, + 2, 11, 0, 68, 74, 69, 66, 28, 15, 10, 4, 10, + 0, 68, 73, 79, 72, 29, 13, 9, 4, 6, 68, 74, + 78, 3, 35, 22, 15, 8, 15, 3, 65, 68, 71, 62, + 92, 87, 80, 84, 84, 81, 78, 76, 75, 74, 71, + 66, 78, 78, 83, 85, 15, 84, 83, 78, 73, 72, + 73, 71, 71, 70, 70, 71, 80, 68, 68, 12, 69, + 77, 67, 68, 70, 65, 66, 68, 75, 67, 67, 73, + 72, 6, 88, 71, 12, 72, 0, 69, 68, 64, 2, 64, + 66, 64, 73, 73, 81, 50, 47, 49, 42, 36, 39, + 39, 35, 35, 32, 33, 33, 21, 15, 2, 23, 22, 17, + 4, 13, 11, 5, 9, 2, 0, 69, 73, 77, 79, 23, 20, + 23, 12, 68, 3, 1, 75, 64, 72, 76, 92, 84, 89, + 94, 4, 8, 80, 3, 5, 67, 77, 75, 76, 85, 75, + 81, 82, 98, 85, 90, 100, 65, 79, 87, 73, 2, 6, + 7, 17, 11, 18, 1, 15, 13, 21, 23, 26, 26, 13, + 51, 27, 19, 13, 5, 3, 80, 86, 95, 7, 37, 32, + 32, 23, 23, 13, 11, 5, 0, 73, 2, 6, 7, 17, 11, + 18, 1, 15, 13, 21, 23, 26, 26, 13, 51, 27, 19, + 13, 5, 3, 80, 86, 95 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 0, 23, + 41, 29, 6, 8, 5, 78, 0, 65, 66, 18, 79, 72, + 21, 16, 87, 102, 116, 75, 81, 70, 78, 0, 65, + 83, 65, 29, 2, 71, 78, 81, 87, 90, 90, 105, + 64, 76, 84, 71, 84, 85, 99, 4, 72, 71, 77, 25, + 2, 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 18, 73, + 94, 68, 0, 72, 20, 18, 69, 0, 76, 10, 73, 68, + 66, 97, 84, 87, 86, 18, 67, 3, 66, 70, 86, 73, + 78, 65, 75, 72, 85, 17, 72, 5, 76, 79, 68, 73, + 67, 3, 4, 0, 9, 6, 74, 0, 64, 67, 2, 72, 26, + 67, 1, 24, 23, 31, 27, 20, 89, 0, 65, 66, 67, + 81, 68, 16, 66, 67, 15, 34, 54, 40, 17, 89, + 90, 2, 37, 40, 112, 69, 6, 90, 14, 66, 0, 15, + 33, 55, 45, 24, 92, 86, 64, 10, 16, 91, 18, + 21, 18, 17, 19, 17, 10, 19, 17, 64, 6, 10, 4, + 2, 69, 6, 2, 64, 4, 1, 5, 5, 0, 88, 64, 64, + 69, 65, 76, 25, 35, 21, 14, 20, 22, 23, 24, + 16, 75, 87, 72, 70, 68, 108, 66, 2, 87, 17, 3, + 3, 1, 2, 68, 1, 4, 81, 93, 78, 81, 80, 88, 76, + 17, 16, 10, 4, 1, 67, 72, 74, 79, 65, 29, 16, + 10, 3, 13, 1, 66, 73, 66, 65, 28, 15, 10, 5, + 11, 1, 68, 72, 78, 72, 30, 14, 9, 4, 7, 68, + 74, 77, 4, 35, 23, 15, 8, 16, 4, 64, 68, 70, + 62, 91, 86, 79, 83, 83, 79, 77, 74, 74, 72, + 69, 0, 77, 77, 82, 84, 18, 83, 84, 77, 72, 71, + 73, 71, 71, 70, 69, 72, 81, 68, 68, 13, 69, + 77, 67, 68, 69, 66, 67, 68, 76, 68, 68, 73, + 72, 7, 89, 72, 13, 72, 64, 69, 68, 64, 1, 65, + 66, 64, 73, 73, 82, 49, 46, 48, 41, 33, 37, + 36, 32, 32, 29, 30, 30, 18, 13, 0, 19, 18, 13, + 64, 10, 9, 3, 7, 64, 65, 70, 74, 78, 79, 21, + 17, 20, 10, 70, 1, 64, 77, 66, 74, 78, 94, 86, + 90, 96, 3, 7, 82, 1, 4, 69, 79, 76, 77, 86, + 76, 82, 82, 97, 87, 91, 101, 67, 80, 88, 73, + 2, 6, 8, 18, 12, 18, 2, 16, 14, 22, 23, 27, + 26, 13, 51, 25, 17, 11, 3, 1, 83, 88, 96, 7, + 38, 32, 32, 24, 24, 13, 11, 5, 1, 73, 2, 6, 8, + 18, 12, 18, 2, 16, 14, 22, 23, 27, 26, 13, 51, + 25, 17, 11, 3, 1, 83, 88, 96 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 64, 21, + 40, 29, 7, 10, 4, 78, 2, 65, 67, 19, 80, 73, + 20, 15, 91, 104, 117, 73, 79, 70, 78, 2, 65, + 82, 64, 30, 2, 70, 77, 80, 89, 91, 90, 106, + 64, 76, 84, 71, 85, 84, 99, 3, 72, 71, 76, 25, + 2, 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 18, 72, + 93, 66, 1, 71, 22, 20, 68, 1, 74, 11, 72, 68, + 64, 98, 84, 87, 86, 19, 67, 4, 64, 70, 85, 72, + 76, 65, 75, 72, 85, 18, 73, 6, 76, 79, 67, 73, + 66, 3, 5, 1, 10, 6, 74, 0, 64, 67, 2, 72, 26, + 67, 1, 24, 23, 32, 28, 21, 89, 1, 64, 67, 67, + 81, 68, 17, 66, 66, 16, 35, 54, 42, 18, 90, + 91, 3, 37, 40, 112, 70, 6, 90, 14, 67, 1, 16, + 33, 55, 46, 25, 93, 85, 65, 7, 13, 89, 18, 21, + 18, 16, 19, 16, 10, 18, 17, 64, 6, 10, 3, 2, + 70, 6, 1, 65, 4, 1, 5, 5, 64, 90, 64, 65, 69, + 66, 76, 22, 33, 19, 13, 18, 20, 20, 22, 14, + 77, 89, 73, 72, 70, 110, 67, 0, 89, 15, 2, 2, + 0, 0, 70, 64, 2, 82, 93, 79, 82, 81, 86, 74, + 19, 17, 10, 4, 2, 67, 72, 73, 78, 64, 30, 17, + 11, 3, 14, 2, 65, 72, 64, 65, 29, 16, 11, 5, + 12, 1, 67, 71, 77, 72, 32, 15, 9, 4, 7, 67, + 74, 77, 4, 36, 23, 16, 8, 17, 4, 64, 67, 70, + 62, 89, 84, 77, 81, 81, 78, 75, 73, 72, 70, + 67, 2, 77, 76, 82, 84, 21, 83, 85, 77, 72, 70, + 73, 71, 71, 70, 69, 72, 82, 68, 68, 13, 69, + 77, 67, 68, 69, 66, 67, 68, 77, 69, 68, 73, + 72, 8, 90, 72, 14, 73, 64, 69, 68, 0, 1, 65, + 65, 0, 73, 73, 84, 48, 45, 47, 39, 31, 34, 34, + 29, 30, 26, 27, 27, 15, 10, 65, 16, 15, 9, 69, + 8, 6, 1, 5, 66, 67, 71, 75, 79, 79, 19, 15, + 18, 8, 72, 0, 65, 79, 68, 77, 80, 96, 88, 92, + 97, 2, 5, 84, 0, 2, 70, 81, 78, 79, 87, 77, + 83, 83, 96, 88, 93, 103, 68, 82, 89, 72, 3, 7, + 8, 19, 13, 19, 2, 17, 15, 23, 24, 28, 27, 14, + 50, 23, 15, 9, 1, 64, 85, 90, 97, 8, 38, 33, + 33, 24, 25, 14, 12, 6, 1, 72, 3, 7, 8, 19, 13, + 19, 2, 17, 15, 23, 24, 28, 27, 14, 50, 23, 15, + 9, 1, 64, 85, 90, 97 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 66, 20, + 39, 30, 7, 12, 2, 78, 3, 65, 67, 20, 81, 75, + 18, 13, 94, 106, 118, 71, 78, 70, 78, 3, 65, + 82, 0, 30, 1, 69, 76, 79, 90, 93, 91, 106, 64, + 76, 83, 71, 85, 84, 99, 3, 72, 71, 76, 26, 2, + 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 17, 72, 92, + 64, 2, 70, 23, 21, 68, 2, 72, 12, 71, 67, 1, + 99, 84, 87, 86, 19, 68, 5, 1, 70, 84, 71, 74, + 65, 75, 72, 85, 18, 73, 6, 75, 79, 67, 73, 66, + 3, 5, 2, 10, 6, 74, 64, 64, 67, 2, 72, 26, 67, + 1, 25, 23, 32, 28, 21, 90, 1, 0, 67, 67, 81, + 68, 18, 66, 66, 17, 36, 55, 43, 20, 90, 92, 3, + 37, 40, 113, 70, 7, 91, 15, 67, 1, 17, 33, 55, + 46, 26, 94, 83, 66, 4, 10, 88, 17, 21, 17, 15, + 18, 16, 9, 18, 16, 65, 5, 9, 3, 2, 70, 5, 0, + 66, 3, 0, 4, 4, 64, 91, 65, 66, 69, 68, 77, + 20, 31, 17, 11, 16, 18, 16, 19, 13, 79, 92, + 75, 74, 72, 111, 69, 64, 91, 14, 1, 1, 64, 64, + 72, 66, 0, 84, 93, 80, 83, 83, 85, 73, 20, 17, + 10, 4, 3, 66, 71, 72, 76, 0, 31, 17, 12, 4, + 15, 3, 0, 71, 1, 64, 29, 16, 11, 6, 13, 2, 67, + 71, 76, 72, 33, 16, 9, 4, 8, 67, 74, 76, 5, + 36, 24, 16, 8, 18, 5, 0, 67, 69, 62, 88, 83, + 76, 79, 80, 76, 74, 71, 71, 69, 65, 4, 76, 75, + 81, 83, 24, 83, 86, 77, 71, 70, 73, 71, 71, + 71, 68, 72, 83, 68, 68, 14, 69, 77, 67, 68, + 69, 67, 67, 68, 78, 70, 68, 73, 72, 9, 91, 72, + 14, 74, 64, 69, 68, 0, 1, 66, 65, 1, 73, 73, + 85, 47, 44, 46, 37, 29, 32, 31, 26, 27, 23, + 23, 24, 11, 7, 67, 12, 11, 5, 74, 5, 4, 64, 3, + 69, 69, 73, 76, 80, 79, 16, 13, 16, 6, 74, 65, + 67, 81, 70, 79, 82, 98, 91, 94, 98, 1, 4, 87, + 65, 0, 72, 83, 79, 80, 88, 78, 84, 83, 95, 89, + 94, 104, 69, 83, 90, 72, 3, 7, 9, 20, 13, 20, + 2, 18, 16, 24, 24, 29, 27, 15, 50, 21, 13, 7, + 64, 66, 87, 92, 99, 8, 39, 33, 34, 25, 25, 14, + 12, 6, 2, 72, 3, 7, 9, 20, 13, 20, 2, 18, 16, + 24, 24, 29, 27, 15, 50, 21, 13, 7, 64, 66, 87, + 92, 99 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 68, 18, + 38, 31, 7, 13, 0, 77, 5, 66, 67, 21, 82, 76, + 17, 11, 97, 109, 118, 69, 77, 70, 77, 5, 66, + 82, 1, 30, 1, 69, 75, 77, 91, 94, 91, 106, 64, + 75, 82, 72, 85, 84, 99, 3, 71, 71, 75, 26, 2, + 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 17, 71, + 90, 2, 3, 69, 25, 23, 67, 3, 70, 13, 70, 66, + 4, 99, 85, 87, 87, 19, 68, 6, 4, 69, 84, 71, + 72, 65, 75, 72, 84, 18, 73, 7, 74, 78, 66, 72, + 66, 4, 6, 3, 11, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 25, 24, 32, 28, 21, 90, 2, 0, 68, 67, + 80, 68, 19, 65, 65, 19, 38, 56, 45, 22, 91, + 93, 4, 38, 40, 114, 70, 7, 91, 16, 67, 1, 19, + 33, 55, 46, 28, 95, 82, 67, 2, 7, 87, 17, 21, + 17, 15, 18, 16, 9, 18, 16, 66, 4, 9, 3, 2, 70, + 5, 0, 67, 3, 0, 4, 3, 65, 92, 66, 66, 69, 69, + 77, 18, 29, 16, 10, 15, 16, 13, 17, 12, 81, + 94, 76, 76, 74, 112, 70, 65, 92, 13, 0, 0, 66, + 66, 74, 68, 64, 85, 93, 81, 84, 85, 83, 71, + 21, 18, 10, 4, 4, 65, 70, 72, 74, 2, 32, 18, + 12, 5, 17, 4, 1, 70, 4, 0, 30, 17, 12, 6, 14, + 3, 66, 70, 75, 71, 34, 17, 9, 4, 9, 66, 73, + 75, 6, 36, 25, 16, 8, 19, 6, 1, 66, 68, 62, + 87, 81, 74, 78, 79, 75, 72, 69, 69, 67, 0, 7, + 75, 74, 80, 82, 27, 82, 87, 76, 70, 69, 73, + 71, 71, 71, 68, 73, 84, 68, 68, 15, 69, 77, + 67, 68, 68, 67, 68, 68, 79, 71, 69, 73, 72, + 10, 91, 73, 15, 74, 65, 69, 68, 0, 0, 66, 65, + 1, 73, 73, 87, 46, 43, 45, 36, 26, 29, 28, 23, + 25, 20, 20, 21, 8, 5, 69, 8, 8, 1, 79, 2, 2, + 65, 1, 71, 71, 74, 77, 81, 79, 14, 10, 13, 4, + 76, 67, 68, 83, 72, 81, 84, 100, 93, 95, 100, + 0, 3, 89, 66, 64, 73, 85, 80, 81, 89, 79, 85, + 83, 94, 91, 95, 106, 71, 84, 91, 72, 4, 8, 10, + 21, 14, 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, + 19, 11, 5, 66, 68, 90, 94, 100, 9, 39, 34, 34, + 26, 26, 15, 13, 6, 3, 72, 4, 8, 10, 21, 14, + 20, 3, 19, 17, 25, 25, 30, 28, 15, 49, 19, 11, + 5, 66, 68, 90, 94, 100 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 70, 17, + 37, 31, 7, 15, 64, 77, 6, 66, 68, 22, 83, 77, + 16, 9, 101, 111, 119, 67, 75, 70, 77, 6, 66, + 81, 2, 31, 1, 68, 74, 76, 92, 95, 91, 107, 64, + 75, 81, 72, 86, 84, 99, 3, 71, 71, 74, 27, 2, + 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 16, 71, + 89, 4, 4, 68, 26, 24, 66, 4, 68, 14, 69, 65, + 6, 100, 85, 87, 87, 20, 68, 7, 6, 69, 83, 70, + 70, 65, 75, 72, 84, 19, 73, 7, 73, 78, 65, 72, + 66, 4, 6, 4, 11, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 26, 24, 33, 28, 22, 91, 2, 1, 68, 67, + 80, 68, 20, 65, 65, 20, 39, 57, 46, 24, 91, + 94, 4, 38, 40, 115, 70, 8, 92, 16, 67, 1, 20, + 33, 55, 46, 29, 96, 80, 68, 64, 4, 85, 17, 21, + 16, 14, 17, 15, 8, 18, 15, 67, 3, 9, 3, 2, 71, + 4, 64, 68, 2, 0, 4, 2, 65, 93, 66, 67, 69, 70, + 78, 16, 27, 14, 8, 13, 14, 10, 14, 11, 83, 96, + 78, 78, 76, 114, 71, 66, 94, 12, 64, 64, 67, + 67, 76, 70, 66, 87, 93, 82, 85, 86, 82, 70, + 23, 18, 10, 4, 5, 64, 69, 71, 72, 3, 33, 19, + 13, 5, 18, 5, 3, 69, 6, 0, 30, 17, 12, 7, 15, + 3, 66, 69, 74, 71, 36, 18, 9, 4, 10, 66, 73, + 74, 7, 37, 26, 17, 8, 20, 6, 2, 66, 68, 62, + 85, 80, 73, 76, 78, 73, 71, 68, 68, 65, 2, 9, + 75, 73, 80, 81, 30, 82, 88, 76, 69, 68, 73, + 71, 71, 71, 67, 73, 85, 68, 68, 15, 69, 77, + 67, 68, 68, 68, 68, 68, 80, 72, 69, 73, 72, + 11, 92, 73, 16, 75, 65, 69, 68, 1, 0, 67, 64, + 2, 73, 73, 88, 45, 42, 44, 34, 24, 27, 26, 20, + 22, 17, 17, 18, 5, 2, 71, 4, 4, 66, 84, 64, 0, + 67, 64, 74, 73, 75, 78, 82, 79, 12, 8, 11, 2, + 78, 69, 70, 85, 74, 83, 86, 102, 95, 97, 101, + 64, 2, 91, 68, 66, 75, 87, 82, 83, 90, 80, 86, + 83, 93, 92, 97, 107, 72, 85, 92, 72, 4, 8, 10, + 22, 15, 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, + 17, 9, 3, 68, 70, 92, 96, 101, 9, 40, 34, 35, + 26, 27, 15, 13, 7, 3, 72, 4, 8, 10, 22, 15, + 21, 3, 20, 18, 26, 25, 31, 28, 16, 49, 17, 9, + 3, 68, 70, 92, 96, 101 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 72, 15, + 36, 32, 7, 17, 66, 77, 8, 66, 68, 23, 84, 78, + 15, 7, 104, 113, 120, 65, 74, 70, 77, 8, 66, + 81, 3, 31, 1, 67, 73, 75, 93, 96, 91, 107, 64, + 75, 80, 72, 86, 84, 99, 3, 71, 71, 73, 27, 2, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 16, 70, + 88, 6, 5, 67, 28, 26, 65, 5, 66, 15, 68, 64, + 8, 101, 85, 87, 87, 20, 68, 8, 8, 69, 82, 69, + 68, 65, 75, 72, 84, 19, 73, 8, 72, 78, 64, 72, + 66, 4, 7, 5, 12, 6, 75, 64, 0, 67, 2, 72, 27, + 67, 1, 26, 24, 33, 28, 22, 91, 3, 2, 69, 67, + 80, 68, 21, 65, 64, 21, 40, 58, 48, 26, 92, + 95, 5, 38, 40, 116, 70, 8, 92, 17, 67, 1, 21, + 33, 55, 46, 30, 97, 79, 69, 67, 1, 84, 17, 21, + 16, 13, 17, 15, 8, 18, 15, 68, 2, 9, 3, 2, 71, + 4, 65, 69, 2, 0, 4, 1, 66, 94, 67, 68, 69, 71, + 78, 14, 25, 12, 7, 11, 12, 7, 12, 10, 85, 98, + 79, 80, 78, 115, 72, 67, 96, 11, 65, 65, 68, + 69, 78, 72, 68, 88, 93, 83, 86, 88, 80, 68, + 24, 19, 10, 4, 6, 0, 68, 70, 70, 4, 34, 20, + 14, 6, 19, 6, 4, 68, 8, 1, 31, 18, 13, 7, 16, + 4, 65, 68, 73, 71, 37, 19, 9, 4, 11, 65, 73, + 73, 8, 37, 27, 17, 8, 21, 7, 3, 65, 67, 62, + 84, 78, 71, 74, 77, 72, 69, 66, 66, 0, 4, 11, + 74, 72, 79, 80, 33, 82, 89, 76, 68, 67, 73, + 71, 71, 71, 67, 73, 86, 68, 68, 16, 69, 77, + 67, 68, 68, 68, 68, 68, 81, 73, 69, 73, 72, + 12, 93, 73, 17, 76, 65, 69, 68, 1, 0, 67, 64, + 3, 73, 73, 90, 44, 41, 43, 32, 22, 24, 23, 17, + 20, 14, 14, 15, 2, 64, 73, 0, 1, 70, 89, 67, + 65, 69, 66, 76, 75, 76, 79, 83, 79, 10, 6, 9, + 0, 80, 71, 71, 87, 76, 85, 88, 104, 97, 99, + 102, 65, 1, 93, 69, 68, 76, 89, 83, 84, 91, + 81, 87, 83, 92, 93, 98, 109, 73, 86, 93, 72, + 5, 9, 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, + 29, 17, 48, 15, 7, 1, 70, 72, 94, 98, 102, 10, + 40, 35, 36, 27, 28, 16, 14, 7, 4, 72, 5, 9, + 11, 23, 16, 22, 3, 21, 19, 27, 26, 32, 29, 17, + 48, 15, 7, 1, 70, 72, 94, 98, 102 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 74, 13, + 35, 32, 7, 18, 68, 77, 9, 67, 69, 24, 85, 80, + 13, 5, 108, 116, 121, 0, 73, 70, 77, 9, 67, + 81, 3, 31, 0, 67, 73, 74, 95, 98, 92, 108, 65, + 75, 80, 73, 87, 84, 99, 2, 71, 71, 73, 27, 1, + 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 15, 70, + 87, 8, 6, 67, 29, 27, 65, 6, 65, 15, 67, 64, + 10, 102, 86, 88, 88, 20, 69, 8, 10, 69, 82, + 69, 67, 65, 75, 72, 84, 19, 74, 8, 72, 78, 64, + 72, 66, 4, 7, 6, 12, 6, 76, 65, 0, 67, 1, 72, + 27, 67, 1, 26, 24, 33, 28, 22, 92, 3, 2, 70, + 67, 80, 69, 21, 65, 64, 22, 41, 58, 49, 27, + 93, 97, 5, 38, 40, 117, 71, 8, 93, 17, 68, 1, + 22, 33, 54, 46, 31, 98, 78, 71, 70, 66, 83, + 16, 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, + 2, 1, 72, 3, 66, 70, 1, 64, 3, 0, 67, 96, 68, + 69, 69, 73, 79, 11, 22, 10, 5, 9, 9, 3, 9, 8, + 87, 101, 81, 83, 80, 117, 74, 69, 98, 9, 66, + 66, 70, 71, 80, 74, 70, 90, 93, 84, 87, 90, + 79, 67, 25, 19, 10, 4, 6, 0, 68, 70, 69, 5, + 34, 20, 14, 6, 20, 7, 5, 68, 10, 1, 31, 18, + 13, 7, 16, 4, 65, 68, 72, 71, 38, 20, 9, 3, + 11, 65, 73, 73, 8, 37, 27, 17, 8, 22, 7, 3, + 65, 67, 62, 83, 77, 70, 73, 76, 71, 68, 65, + 65, 1, 5, 13, 74, 72, 79, 80, 36, 82, 91, 76, + 68, 67, 73, 71, 71, 72, 67, 74, 87, 69, 68, + 16, 70, 77, 68, 68, 68, 69, 69, 69, 82, 74, + 70, 74, 72, 13, 94, 74, 17, 77, 66, 69, 69, 1, + 64, 68, 64, 3, 73, 73, 92, 42, 40, 41, 30, 19, + 21, 20, 14, 17, 11, 10, 12, 65, 67, 75, 67, + 66, 74, 95, 70, 68, 71, 69, 79, 77, 78, 81, + 84, 79, 7, 3, 6, 65, 83, 73, 73, 90, 78, 88, + 90, 107, 100, 101, 104, 67, 64, 96, 71, 70, + 78, 91, 85, 86, 92, 82, 88, 84, 91, 95, 100, + 111, 75, 88, 95, 72, 5, 9, 11, 24, 16, 22, 3, + 22, 19, 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, + 74, 97, 100, 104, 10, 40, 35, 36, 27, 28, 16, + 14, 7, 4, 72, 5, 9, 11, 24, 16, 22, 3, 22, 19, + 28, 26, 32, 29, 17, 47, 13, 5, 65, 73, 74, 97, + 100, 104 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 75, 12, + 35, 33, 8, 20, 69, 76, 11, 67, 69, 26, 85, 81, + 12, 4, 111, 118, 121, 2, 71, 69, 76, 11, 67, + 80, 4, 32, 0, 66, 72, 72, 96, 99, 92, 108, 65, + 74, 79, 73, 87, 83, 98, 2, 70, 70, 72, 28, 1, + 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 15, 69, + 85, 11, 8, 66, 31, 29, 64, 8, 0, 16, 65, 0, + 13, 102, 86, 88, 88, 21, 69, 9, 13, 68, 81, + 68, 65, 65, 74, 72, 83, 20, 74, 9, 71, 77, 0, + 71, 65, 5, 8, 7, 13, 7, 76, 65, 1, 66, 1, 71, + 28, 66, 1, 27, 25, 34, 29, 23, 92, 4, 3, 70, + 67, 79, 69, 22, 64, 0, 24, 43, 59, 51, 29, 93, + 98, 6, 39, 41, 117, 71, 9, 93, 18, 68, 2, 24, + 33, 54, 47, 33, 99, 76, 72, 72, 69, 81, 16, + 21, 15, 12, 16, 14, 7, 17, 14, 69, 1, 8, 2, 1, + 72, 3, 66, 70, 1, 64, 3, 0, 67, 97, 68, 69, + 69, 74, 79, 9, 20, 9, 4, 8, 7, 0, 7, 7, 88, + 103, 82, 85, 81, 118, 75, 70, 99, 8, 66, 66, + 71, 72, 81, 75, 71, 91, 93, 84, 87, 91, 77, + 65, 27, 20, 10, 4, 7, 1, 67, 69, 67, 7, 35, + 21, 15, 7, 22, 8, 7, 67, 13, 2, 32, 19, 14, 8, + 17, 5, 64, 67, 70, 70, 40, 21, 10, 3, 12, 64, + 72, 72, 9, 38, 28, 18, 9, 23, 8, 4, 64, 66, + 62, 81, 75, 68, 71, 74, 69, 66, 0, 0, 3, 7, + 16, 73, 71, 78, 79, 40, 81, 92, 75, 67, 66, + 72, 71, 70, 72, 66, 74, 87, 69, 68, 17, 70, + 77, 68, 68, 67, 69, 69, 69, 82, 74, 70, 74, + 71, 15, 94, 74, 18, 77, 66, 69, 69, 2, 64, 68, + 0, 4, 72, 72, 93, 41, 39, 40, 29, 17, 19, 18, + 11, 15, 9, 7, 10, 68, 69, 77, 70, 69, 77, 100, + 72, 70, 72, 71, 81, 78, 79, 82, 84, 79, 5, 1, + 4, 67, 85, 74, 74, 92, 79, 90, 91, 109, 102, + 102, 105, 68, 65, 98, 72, 71, 79, 92, 86, 87, + 93, 82, 88, 84, 90, 96, 101, 112, 76, 89, 96, + 71, 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, + 33, 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, + 105, 11, 41, 36, 37, 28, 29, 17, 15, 8, 5, 71, + 6, 10, 12, 26, 17, 23, 4, 24, 20, 29, 27, 33, + 30, 18, 47, 12, 4, 67, 75, 75, 99, 101, 105 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 77, 10, + 34, 34, 8, 22, 71, 76, 12, 67, 69, 27, 86, 82, + 11, 2, 114, 120, 122, 4, 70, 69, 76, 12, 67, + 80, 5, 32, 0, 65, 71, 71, 97, 100, 92, 108, + 65, 74, 78, 73, 87, 83, 98, 2, 70, 70, 71, 28, + 1, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 15, 68, + 84, 13, 9, 65, 33, 31, 0, 9, 2, 17, 64, 1, 15, + 103, 86, 88, 88, 21, 69, 10, 15, 68, 80, 67, + 0, 65, 74, 72, 83, 20, 74, 9, 70, 77, 1, 71, + 65, 5, 8, 8, 14, 7, 76, 65, 1, 66, 1, 71, 28, + 66, 1, 27, 25, 34, 29, 23, 93, 5, 4, 71, 67, + 79, 69, 23, 64, 0, 25, 44, 60, 53, 31, 94, 99, + 6, 39, 41, 118, 71, 9, 94, 19, 68, 2, 25, 33, + 54, 47, 34, 100, 75, 73, 75, 72, 80, 16, 21, + 15, 11, 15, 14, 7, 17, 13, 70, 0, 8, 2, 1, 72, + 2, 67, 71, 1, 64, 3, 64, 68, 98, 69, 70, 69, + 75, 80, 7, 18, 7, 2, 6, 5, 66, 5, 6, 90, 105, + 84, 87, 83, 119, 76, 71, 101, 7, 67, 67, 72, + 74, 83, 77, 73, 93, 93, 85, 88, 93, 76, 64, + 28, 21, 10, 4, 8, 2, 66, 68, 65, 8, 36, 22, + 16, 8, 23, 9, 8, 66, 15, 3, 32, 19, 14, 8, 18, + 6, 0, 66, 69, 70, 41, 22, 10, 3, 13, 0, 72, + 71, 10, 38, 29, 18, 9, 24, 9, 5, 0, 65, 62, + 80, 73, 66, 69, 73, 68, 64, 2, 1, 5, 9, 18, + 72, 70, 77, 78, 43, 81, 93, 75, 66, 65, 72, + 71, 70, 72, 66, 74, 88, 69, 68, 18, 70, 77, + 68, 68, 67, 69, 69, 69, 83, 75, 70, 74, 71, + 16, 95, 74, 19, 78, 66, 69, 69, 2, 64, 68, 0, + 5, 72, 72, 95, 40, 38, 39, 27, 15, 16, 15, 8, + 13, 6, 4, 7, 71, 72, 79, 74, 73, 81, 105, 75, + 72, 74, 73, 83, 80, 80, 83, 85, 79, 3, 64, 2, + 69, 87, 76, 76, 94, 81, 92, 93, 111, 104, 104, + 106, 69, 66, 100, 74, 73, 81, 94, 87, 88, 94, + 83, 89, 84, 89, 97, 102, 114, 77, 90, 97, 71, + 6, 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, + 31, 19, 46, 10, 2, 69, 77, 77, 101, 103, 106, + 12, 41, 36, 38, 29, 30, 17, 16, 8, 6, 71, 6, + 11, 13, 27, 18, 24, 4, 25, 21, 30, 27, 34, 31, + 19, 46, 10, 2, 69, 77, 77, 101, 103, 106 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 79, 9, + 33, 34, 8, 24, 72, 76, 14, 67, 70, 28, 87, 83, + 10, 0, 118, 122, 123, 6, 68, 69, 76, 14, 67, + 79, 6, 33, 0, 64, 70, 70, 98, 101, 92, 109, + 65, 74, 77, 73, 88, 83, 98, 2, 70, 70, 70, 29, + 1, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 14, 68, + 83, 15, 10, 64, 34, 32, 1, 10, 4, 18, 0, 2, + 17, 104, 86, 88, 88, 22, 69, 11, 17, 68, 79, + 66, 2, 65, 74, 72, 83, 21, 74, 10, 69, 77, 2, + 71, 65, 5, 9, 9, 14, 7, 76, 65, 1, 66, 1, 71, + 28, 66, 1, 28, 25, 35, 29, 24, 93, 5, 5, 71, + 67, 79, 69, 24, 64, 1, 26, 45, 61, 54, 33, 94, + 100, 7, 39, 41, 119, 71, 10, 94, 19, 68, 2, + 26, 33, 54, 47, 35, 101, 73, 74, 78, 75, 78, + 16, 21, 14, 10, 15, 13, 6, 17, 13, 71, 64, 8, + 2, 1, 73, 2, 68, 72, 0, 64, 3, 65, 68, 99, 69, + 71, 69, 76, 80, 5, 16, 5, 1, 4, 3, 69, 2, 5, + 92, 107, 85, 89, 85, 121, 77, 72, 103, 6, 68, + 68, 73, 75, 85, 79, 75, 94, 93, 86, 89, 94, + 74, 1, 30, 21, 10, 4, 9, 3, 65, 67, 0, 9, 37, + 23, 17, 8, 24, 10, 10, 65, 17, 3, 33, 20, 15, + 9, 19, 6, 0, 65, 68, 70, 43, 23, 10, 3, 14, 0, + 72, 70, 11, 39, 30, 19, 9, 25, 9, 6, 0, 65, + 62, 78, 72, 65, 67, 72, 66, 0, 3, 3, 7, 11, + 20, 72, 69, 77, 77, 46, 81, 94, 75, 65, 64, + 72, 71, 70, 72, 65, 74, 89, 69, 68, 18, 70, + 77, 68, 68, 67, 70, 69, 69, 84, 76, 70, 74, + 71, 17, 96, 74, 20, 79, 66, 69, 69, 3, 64, 69, + 1, 6, 72, 72, 96, 39, 37, 38, 25, 13, 14, 13, + 5, 10, 3, 1, 4, 74, 75, 81, 78, 76, 85, 110, + 78, 74, 76, 75, 86, 82, 81, 84, 86, 79, 1, 66, + 0, 71, 89, 78, 77, 96, 83, 94, 95, 113, 106, + 106, 107, 70, 67, 102, 75, 75, 82, 96, 89, 90, + 95, 84, 90, 84, 88, 98, 104, 115, 78, 91, 98, + 71, 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, + 35, 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, + 107, 12, 42, 37, 39, 29, 31, 18, 16, 9, 6, 71, + 7, 11, 13, 28, 19, 25, 4, 26, 22, 31, 28, 35, + 31, 20, 46, 8, 0, 71, 79, 79, 103, 105, 107 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 81, 7, + 32, 35, 8, 25, 74, 76, 15, 68, 70, 29, 88, 85, + 8, 65, 121, 125, 124, 8, 67, 69, 76, 15, 68, + 79, 7, 33, 64, 64, 69, 68, 99, 103, 93, 109, + 65, 73, 76, 74, 88, 83, 98, 2, 70, 70, 70, 29, + 1, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 14, 67, + 82, 17, 11, 0, 36, 34, 1, 11, 6, 19, 1, 3, 20, + 104, 87, 88, 89, 22, 70, 12, 20, 67, 79, 66, + 4, 65, 74, 72, 83, 21, 74, 10, 68, 77, 2, 70, + 65, 5, 9, 10, 15, 7, 77, 66, 1, 66, 1, 71, 28, + 66, 1, 28, 25, 35, 29, 24, 94, 6, 5, 72, 67, + 78, 69, 25, 0, 1, 28, 47, 62, 56, 35, 95, 101, + 7, 40, 41, 120, 71, 10, 95, 20, 68, 2, 27, 33, + 54, 47, 37, 102, 72, 75, 81, 78, 77, 15, 21, + 14, 10, 14, 13, 6, 17, 12, 72, 65, 7, 2, 1, + 73, 1, 68, 73, 0, 65, 2, 66, 69, 100, 70, 72, + 69, 78, 81, 3, 14, 3, 64, 3, 1, 73, 0, 4, 94, + 110, 87, 91, 87, 122, 79, 73, 104, 5, 69, 69, + 75, 77, 87, 81, 76, 96, 93, 87, 90, 96, 73, 2, + 31, 22, 10, 4, 10, 4, 64, 67, 2, 11, 38, 23, + 17, 9, 26, 11, 11, 64, 20, 4, 33, 20, 15, 9, + 20, 7, 1, 65, 67, 70, 44, 24, 10, 3, 15, 1, + 72, 69, 12, 39, 31, 19, 9, 26, 10, 7, 1, 64, + 62, 77, 70, 0, 66, 71, 65, 2, 5, 4, 8, 13, 23, + 71, 68, 76, 76, 49, 80, 95, 74, 64, 64, 72, + 71, 70, 73, 65, 75, 90, 69, 68, 19, 70, 77, + 68, 68, 66, 70, 70, 69, 85, 77, 71, 74, 71, + 18, 97, 75, 20, 79, 67, 69, 69, 3, 65, 69, 1, + 6, 72, 72, 98, 38, 36, 37, 24, 10, 11, 10, 2, + 8, 0, 66, 1, 78, 77, 83, 82, 80, 89, 115, 81, + 76, 78, 77, 88, 84, 83, 85, 87, 79, 65, 69, + 66, 73, 91, 80, 79, 98, 85, 96, 97, 115, 109, + 107, 109, 71, 68, 105, 77, 76, 84, 98, 90, 91, + 96, 85, 91, 84, 87, 100, 105, 117, 80, 92, 99, + 71, 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, + 36, 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, + 109, 13, 42, 37, 39, 30, 31, 18, 17, 9, 7, 71, + 7, 12, 14, 29, 19, 25, 5, 27, 23, 32, 28, 36, + 32, 20, 45, 6, 65, 73, 81, 81, 106, 107, 109 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 83, 6, + 31, 36, 8, 27, 76, 75, 17, 68, 70, 30, 89, 86, + 7, 67, 124, 126, 124, 10, 66, 69, 75, 17, 68, + 79, 8, 33, 64, 0, 68, 67, 100, 104, 93, 109, + 65, 73, 75, 74, 88, 83, 98, 2, 69, 70, 69, 30, + 1, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 13, 67, + 80, 20, 12, 1, 37, 35, 2, 12, 8, 20, 2, 4, 22, + 105, 87, 88, 89, 22, 70, 13, 22, 67, 78, 65, + 6, 65, 74, 72, 82, 21, 74, 11, 67, 76, 3, 70, + 65, 6, 10, 11, 15, 7, 77, 66, 2, 66, 1, 71, + 29, 66, 1, 29, 26, 35, 29, 24, 94, 6, 6, 72, + 67, 78, 69, 26, 0, 2, 29, 48, 62, 57, 37, 95, + 102, 8, 40, 41, 121, 71, 11, 95, 21, 68, 2, + 29, 33, 54, 47, 38, 103, 70, 76, 83, 81, 76, + 15, 21, 13, 9, 14, 13, 5, 17, 12, 73, 66, 7, + 2, 1, 73, 1, 69, 74, 64, 65, 2, 67, 69, 101, + 71, 72, 69, 79, 81, 1, 12, 2, 65, 1, 64, 76, + 66, 3, 96, 112, 88, 93, 89, 123, 80, 74, 106, + 4, 70, 70, 76, 78, 89, 83, 78, 97, 93, 88, 91, + 98, 71, 4, 32, 22, 10, 4, 11, 5, 0, 66, 4, 12, + 39, 24, 18, 10, 27, 12, 13, 0, 22, 5, 34, 21, + 16, 10, 21, 8, 1, 64, 66, 69, 45, 25, 10, 3, + 16, 1, 71, 68, 13, 39, 32, 19, 9, 27, 11, 8, + 1, 0, 62, 76, 69, 1, 64, 70, 0, 3, 7, 6, 10, + 15, 25, 70, 67, 75, 75, 52, 80, 96, 74, 0, 0, + 72, 71, 70, 73, 64, 75, 91, 69, 68, 20, 70, + 77, 68, 68, 66, 71, 70, 69, 86, 78, 71, 74, + 71, 19, 97, 75, 21, 80, 67, 69, 69, 3, 65, 70, + 1, 7, 72, 72, 99, 37, 35, 36, 22, 8, 9, 7, 64, + 5, 66, 69, 65, 81, 80, 85, 86, 83, 93, 120, + 84, 78, 79, 79, 91, 86, 84, 86, 88, 79, 67, + 71, 68, 75, 93, 82, 80, 100, 87, 98, 99, 117, + 111, 109, 110, 72, 69, 107, 78, 78, 85, 100, + 91, 92, 97, 86, 92, 84, 86, 101, 106, 118, 81, + 93, 100, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, + 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, + 108, 109, 110, 13, 43, 38, 40, 31, 32, 19, 17, + 9, 8, 71, 8, 12, 15, 30, 20, 26, 5, 28, 24, + 33, 29, 37, 32, 21, 45, 4, 67, 75, 83, 83, + 108, 109, 110 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 84, 4, + 30, 36, 9, 29, 77, 75, 18, 68, 71, 31, 90, 87, + 6, 68, 126, 126, 125, 12, 64, 69, 75, 18, 68, + 78, 9, 34, 64, 1, 67, 66, 102, 105, 93, 110, + 65, 73, 75, 74, 89, 82, 98, 1, 69, 70, 68, 30, + 1, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 13, 66, + 79, 22, 13, 2, 39, 37, 3, 13, 10, 21, 3, 4, + 24, 106, 87, 88, 89, 23, 70, 14, 24, 67, 77, + 64, 8, 65, 74, 72, 82, 22, 75, 11, 67, 76, 4, + 70, 64, 6, 10, 12, 16, 7, 77, 66, 2, 66, 1, + 71, 29, 66, 1, 29, 26, 36, 30, 25, 95, 7, 7, + 73, 67, 78, 69, 27, 0, 2, 30, 49, 62, 59, 38, + 96, 103, 8, 40, 41, 121, 72, 11, 96, 21, 69, + 3, 30, 33, 54, 48, 39, 104, 69, 77, 86, 84, + 74, 15, 21, 13, 8, 13, 12, 5, 16, 11, 73, 66, + 7, 1, 1, 74, 0, 70, 75, 64, 65, 2, 67, 70, + 103, 71, 73, 69, 80, 82, 65, 10, 0, 67, 64, + 66, 79, 68, 1, 98, 114, 90, 95, 91, 125, 81, + 76, 108, 2, 71, 71, 77, 80, 91, 85, 80, 99, + 93, 89, 92, 99, 70, 5, 34, 23, 10, 4, 12, 5, + 0, 65, 5, 13, 40, 25, 19, 10, 28, 13, 14, 1, + 24, 5, 34, 21, 16, 10, 22, 8, 2, 0, 65, 69, + 47, 26, 10, 3, 16, 2, 71, 68, 13, 40, 32, 20, + 9, 28, 11, 8, 2, 0, 62, 74, 67, 3, 1, 68, 1, + 5, 8, 7, 12, 17, 27, 70, 66, 75, 75, 55, 80, + 97, 74, 0, 1, 72, 71, 70, 73, 64, 75, 92, 69, + 68, 20, 70, 77, 68, 68, 66, 71, 70, 69, 87, + 79, 71, 74, 71, 20, 98, 75, 22, 81, 67, 69, + 69, 4, 65, 70, 2, 8, 72, 72, 101, 36, 34, 35, + 20, 6, 6, 5, 67, 3, 69, 72, 68, 84, 83, 87, + 89, 87, 97, 125, 86, 81, 81, 81, 93, 88, 85, + 87, 89, 79, 69, 73, 70, 77, 95, 83, 82, 102, + 89, 101, 101, 119, 113, 111, 111, 73, 71, 109, + 80, 80, 87, 102, 93, 94, 98, 87, 93, 85, 85, + 102, 108, 120, 82, 95, 101, 70, 8, 13, 15, 31, + 21, 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, + 69, 77, 85, 85, 110, 111, 111, 14, 43, 38, 41, + 31, 33, 19, 18, 10, 8, 70, 8, 13, 15, 31, 21, + 27, 5, 29, 25, 34, 29, 38, 33, 22, 44, 2, 69, + 77, 85, 85, 110, 111, 111 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 86, 3, + 29, 37, 9, 30, 79, 75, 20, 69, 71, 32, 91, 88, + 5, 70, 126, 126, 126, 14, 0, 69, 75, 20, 69, + 78, 10, 34, 64, 1, 66, 64, 103, 106, 93, 110, + 65, 72, 74, 75, 89, 82, 98, 1, 69, 70, 67, 31, + 1, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 12, 66, + 78, 24, 14, 3, 40, 38, 4, 14, 12, 22, 4, 5, + 27, 106, 88, 88, 90, 23, 70, 15, 27, 66, 77, + 64, 10, 65, 74, 72, 82, 22, 75, 12, 66, 76, 5, + 69, 64, 6, 11, 13, 16, 7, 78, 66, 2, 66, 1, + 71, 29, 66, 1, 30, 26, 36, 30, 25, 95, 7, 7, + 73, 67, 77, 69, 28, 1, 3, 32, 51, 62, 60, 40, + 96, 104, 9, 41, 41, 122, 72, 12, 96, 22, 69, + 3, 31, 33, 54, 48, 41, 105, 67, 78, 89, 87, + 73, 15, 21, 12, 8, 13, 12, 4, 16, 11, 74, 67, + 7, 1, 1, 74, 0, 70, 76, 65, 65, 2, 68, 70, + 104, 72, 74, 69, 81, 82, 67, 8, 65, 68, 65, + 68, 82, 71, 0, 100, 116, 91, 97, 93, 126, 82, + 77, 109, 1, 72, 72, 79, 81, 93, 87, 81, 100, + 93, 90, 93, 101, 68, 7, 35, 23, 10, 4, 13, 6, + 1, 65, 7, 15, 41, 26, 19, 11, 30, 14, 16, 2, + 27, 6, 35, 22, 17, 11, 23, 9, 2, 1, 64, 69, + 48, 27, 10, 3, 17, 2, 71, 67, 14, 40, 33, 20, + 9, 29, 12, 9, 2, 1, 62, 73, 66, 4, 2, 67, 3, + 6, 10, 9, 14, 19, 30, 69, 65, 74, 74, 58, 79, + 98, 73, 1, 2, 72, 71, 70, 73, 0, 76, 93, 69, + 68, 21, 70, 77, 68, 68, 65, 72, 71, 69, 88, + 80, 72, 74, 71, 21, 99, 76, 23, 81, 68, 69, + 69, 4, 66, 71, 2, 8, 72, 72, 102, 35, 33, 34, + 19, 3, 4, 2, 70, 0, 72, 75, 71, 87, 85, 89, + 93, 90, 101, 126, 89, 83, 83, 83, 96, 90, 86, + 88, 90, 79, 71, 76, 73, 79, 97, 85, 83, 104, + 91, 103, 103, 121, 115, 112, 113, 74, 72, 111, + 81, 81, 88, 104, 94, 95, 99, 88, 94, 85, 84, + 104, 109, 121, 84, 96, 102, 70, 9, 13, 16, 32, + 22, 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, + 71, 79, 87, 87, 113, 113, 112, 14, 44, 39, 41, + 32, 34, 20, 18, 10, 9, 70, 9, 13, 16, 32, 22, + 27, 6, 30, 26, 35, 30, 39, 33, 22, 44, 0, 71, + 79, 87, 87, 113, 113, 112 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 88, 1, + 28, 37, 9, 32, 81, 75, 21, 69, 72, 33, 92, 90, + 3, 72, 126, 126, 126, 16, 1, 69, 75, 21, 69, + 78, 10, 34, 65, 2, 65, 0, 104, 108, 94, 111, + 65, 72, 73, 75, 90, 82, 98, 1, 69, 70, 67, 31, + 1, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 12, 65, + 77, 26, 15, 3, 42, 40, 4, 15, 14, 22, 5, 6, + 29, 107, 88, 89, 90, 23, 71, 15, 29, 66, 76, + 0, 11, 65, 74, 72, 82, 22, 75, 12, 65, 76, 5, + 69, 64, 6, 11, 14, 17, 7, 78, 67, 2, 66, 0, + 71, 29, 66, 1, 30, 26, 36, 30, 25, 96, 8, 8, + 74, 67, 77, 69, 29, 1, 3, 33, 52, 62, 62, 42, + 97, 105, 9, 41, 41, 123, 72, 12, 97, 22, 69, + 3, 32, 33, 54, 48, 42, 106, 66, 79, 92, 91, + 72, 14, 21, 12, 7, 12, 11, 4, 16, 10, 75, 68, + 6, 1, 0, 75, 64, 71, 77, 65, 66, 1, 69, 71, + 105, 73, 75, 69, 83, 83, 69, 6, 67, 70, 67, + 71, 86, 73, 64, 102, 119, 93, 100, 95, 126, + 84, 78, 111, 0, 73, 73, 80, 83, 95, 89, 83, + 102, 93, 91, 94, 103, 67, 8, 36, 24, 10, 4, + 13, 7, 2, 64, 9, 16, 41, 26, 20, 11, 31, 15, + 17, 3, 29, 6, 35, 22, 17, 11, 23, 9, 3, 1, 0, + 69, 49, 28, 10, 3, 18, 3, 71, 66, 15, 40, 34, + 20, 9, 30, 12, 10, 3, 1, 62, 72, 64, 6, 4, 66, + 4, 8, 11, 10, 15, 21, 32, 69, 64, 74, 73, 61, + 79, 99, 73, 2, 2, 72, 71, 70, 74, 0, 76, 94, + 69, 68, 21, 70, 77, 69, 68, 65, 72, 71, 70, + 89, 81, 72, 75, 71, 22, 100, 76, 23, 82, 68, + 69, 70, 4, 66, 71, 2, 9, 72, 72, 104, 34, 32, + 33, 17, 1, 1, 64, 73, 65, 75, 79, 74, 91, 88, + 91, 97, 94, 105, 126, 92, 85, 85, 86, 98, 92, + 88, 90, 91, 79, 74, 78, 75, 81, 100, 87, 85, + 107, 93, 105, 105, 123, 118, 114, 114, 76, 73, + 114, 83, 83, 90, 106, 96, 97, 100, 89, 95, 85, + 83, 105, 111, 123, 85, 97, 103, 70, 9, 14, 16, + 33, 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, + 65, 73, 81, 89, 89, 115, 115, 114, 15, 44, 39, + 42, 32, 34, 20, 19, 10, 9, 70, 9, 14, 16, 33, + 22, 28, 6, 31, 26, 36, 30, 39, 34, 23, 43, 65, + 73, 81, 89, 89, 115, 115, 114 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 90, 64, + 28, 38, 9, 34, 82, 74, 23, 69, 72, 34, 92, 91, + 2, 74, 126, 126, 126, 18, 3, 68, 74, 23, 69, + 77, 11, 35, 65, 3, 64, 1, 105, 109, 94, 111, + 65, 72, 72, 75, 90, 82, 98, 1, 68, 69, 66, 31, + 1, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 12, 64, + 75, 29, 16, 4, 44, 42, 5, 16, 16, 23, 7, 7, + 31, 108, 88, 89, 90, 24, 71, 16, 31, 66, 75, + 1, 13, 65, 73, 72, 81, 23, 75, 13, 64, 75, 6, + 69, 64, 7, 12, 15, 18, 7, 78, 67, 3, 65, 0, + 71, 30, 66, 1, 30, 27, 37, 30, 26, 96, 9, 9, + 75, 67, 77, 69, 30, 1, 4, 34, 53, 62, 62, 44, + 98, 106, 10, 41, 42, 124, 72, 12, 97, 23, 69, + 3, 34, 33, 54, 48, 43, 107, 65, 80, 94, 94, + 70, 14, 21, 12, 6, 12, 11, 4, 16, 10, 76, 69, + 6, 1, 0, 75, 64, 72, 77, 65, 66, 1, 70, 72, + 106, 73, 75, 69, 84, 83, 71, 4, 68, 71, 69, + 73, 89, 75, 65, 104, 121, 94, 102, 96, 126, + 85, 79, 113, 64, 74, 74, 81, 85, 96, 91, 85, + 103, 93, 91, 95, 104, 65, 10, 38, 25, 10, 4, + 14, 8, 3, 0, 11, 17, 42, 27, 21, 12, 32, 16, + 18, 4, 31, 7, 36, 23, 18, 11, 24, 10, 4, 2, 2, + 68, 51, 29, 11, 3, 19, 4, 70, 65, 16, 41, 35, + 21, 10, 31, 13, 11, 4, 2, 62, 70, 1, 8, 6, 65, + 5, 10, 13, 12, 17, 23, 34, 68, 0, 73, 72, 62, + 79, 100, 73, 3, 3, 71, 71, 70, 74, 0, 76, 95, + 69, 68, 22, 70, 77, 69, 68, 65, 72, 71, 70, + 89, 82, 72, 75, 70, 24, 100, 76, 24, 83, 68, + 69, 70, 5, 66, 71, 3, 10, 71, 71, 106, 33, 31, + 32, 15, 64, 65, 66, 76, 67, 77, 82, 76, 94, + 91, 93, 101, 97, 108, 126, 95, 87, 86, 88, + 100, 93, 89, 91, 92, 79, 76, 80, 77, 83, 102, + 89, 86, 109, 95, 107, 107, 125, 120, 116, 115, + 77, 74, 116, 84, 85, 91, 108, 97, 98, 101, 90, + 95, 85, 82, 106, 112, 125, 86, 98, 104, 70, + 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, + 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115, + 16, 44, 40, 43, 33, 35, 21, 20, 11, 10, 70, + 10, 15, 17, 35, 23, 29, 6, 32, 27, 37, 31, 40, + 35, 24, 42, 66, 75, 83, 91, 91, 117, 117, 115 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 92, 65, + 27, 39, 9, 35, 84, 74, 24, 70, 72, 35, 93, 92, + 1, 76, 126, 126, 126, 20, 4, 68, 74, 24, 70, + 77, 12, 35, 65, 3, 0, 3, 106, 110, 94, 111, + 65, 71, 71, 76, 90, 82, 98, 1, 68, 69, 65, 32, + 1, 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 11, 64, + 74, 31, 17, 5, 45, 43, 6, 17, 18, 24, 8, 8, + 34, 108, 89, 89, 91, 24, 71, 17, 34, 65, 75, + 1, 15, 65, 73, 72, 81, 23, 75, 13, 0, 75, 7, + 68, 64, 7, 12, 16, 18, 7, 79, 67, 3, 65, 0, + 71, 30, 66, 1, 31, 27, 37, 30, 26, 97, 9, 9, + 75, 67, 76, 69, 31, 2, 4, 36, 55, 62, 62, 46, + 98, 107, 10, 42, 42, 125, 72, 13, 98, 24, 69, + 3, 35, 33, 54, 48, 45, 108, 0, 81, 97, 97, 69, + 14, 21, 11, 6, 11, 11, 3, 16, 9, 77, 70, 6, 1, + 0, 75, 65, 72, 78, 66, 66, 1, 71, 72, 107, 74, + 76, 69, 85, 84, 73, 2, 70, 73, 70, 75, 92, 78, + 66, 106, 123, 96, 104, 98, 126, 86, 80, 114, + 65, 75, 75, 83, 86, 98, 93, 86, 105, 93, 92, + 96, 106, 64, 11, 39, 25, 10, 4, 15, 9, 4, 0, + 13, 19, 43, 28, 21, 13, 34, 17, 20, 5, 34, 8, + 36, 23, 18, 12, 25, 11, 4, 3, 3, 68, 52, 30, + 11, 3, 20, 4, 70, 64, 17, 41, 36, 21, 10, 32, + 14, 12, 4, 3, 62, 69, 2, 9, 7, 64, 7, 11, 15, + 13, 19, 25, 37, 67, 1, 72, 71, 62, 78, 101, + 72, 4, 4, 71, 71, 70, 74, 1, 77, 96, 69, 68, + 23, 70, 77, 69, 68, 64, 73, 72, 70, 90, 83, + 73, 75, 70, 25, 101, 77, 25, 83, 69, 69, 70, + 5, 67, 72, 3, 10, 71, 71, 107, 32, 30, 31, 14, + 67, 67, 69, 79, 70, 80, 85, 79, 97, 93, 95, + 105, 101, 112, 126, 98, 89, 88, 90, 103, 95, + 90, 92, 93, 79, 78, 83, 80, 85, 104, 91, 88, + 111, 97, 109, 109, 126, 122, 117, 117, 78, 75, + 118, 86, 86, 93, 110, 98, 99, 102, 91, 96, 85, + 81, 108, 113, 126, 88, 99, 105, 70, 10, 15, + 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, + 42, 68, 77, 85, 93, 93, 120, 119, 116, 16, 45, + 40, 43, 34, 36, 21, 20, 11, 11, 70, 10, 15, + 18, 36, 24, 29, 7, 33, 28, 38, 31, 41, 35, 24, + 42, 68, 77, 85, 93, 93, 120, 119, 116 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 93, 67, + 26, 39, 10, 37, 85, 74, 26, 70, 73, 36, 94, + 93, 0, 77, 126, 126, 126, 22, 6, 68, 74, 26, + 70, 76, 13, 36, 65, 4, 1, 4, 108, 111, 94, + 112, 65, 71, 71, 76, 91, 81, 98, 0, 68, 69, + 64, 32, 1, 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, + 11, 0, 73, 33, 18, 6, 47, 45, 7, 18, 20, 25, + 9, 8, 36, 109, 89, 89, 91, 25, 71, 18, 36, 65, + 74, 2, 17, 65, 73, 72, 81, 24, 76, 14, 0, 75, + 8, 68, 0, 7, 13, 17, 19, 7, 79, 67, 3, 65, 0, + 71, 30, 66, 1, 31, 27, 38, 31, 27, 97, 10, 10, + 76, 67, 76, 69, 32, 2, 5, 37, 56, 62, 62, 47, + 99, 108, 11, 42, 42, 125, 73, 13, 98, 24, 70, + 4, 36, 33, 54, 49, 46, 109, 1, 82, 100, 100, + 67, 14, 21, 11, 5, 11, 10, 3, 15, 9, 77, 70, + 6, 0, 0, 76, 65, 73, 79, 66, 66, 1, 71, 73, + 109, 74, 77, 69, 86, 84, 76, 0, 72, 74, 72, + 77, 95, 80, 68, 108, 125, 97, 106, 100, 126, + 87, 82, 116, 67, 76, 76, 84, 88, 100, 95, 88, + 106, 93, 93, 97, 107, 1, 13, 41, 26, 10, 4, + 16, 9, 4, 1, 14, 20, 44, 29, 22, 13, 35, 18, + 21, 6, 36, 8, 37, 24, 19, 12, 26, 11, 5, 4, 4, + 68, 54, 31, 11, 3, 20, 5, 70, 64, 17, 42, 36, + 22, 10, 33, 14, 12, 5, 3, 62, 67, 4, 11, 9, 1, + 8, 13, 16, 15, 21, 27, 39, 67, 2, 72, 71, 62, + 78, 102, 72, 4, 5, 71, 71, 70, 74, 1, 77, 97, + 69, 68, 23, 70, 77, 69, 68, 64, 73, 72, 70, + 91, 84, 73, 75, 70, 26, 102, 77, 26, 84, 69, + 69, 70, 6, 67, 72, 4, 11, 71, 71, 109, 31, 29, + 30, 12, 69, 70, 71, 82, 72, 83, 88, 82, 100, + 96, 97, 108, 104, 116, 126, 100, 92, 90, 92, + 105, 97, 91, 93, 94, 79, 80, 85, 82, 87, 106, + 92, 89, 113, 99, 112, 111, 126, 124, 119, 118, + 79, 77, 120, 87, 88, 94, 112, 100, 101, 103, + 92, 97, 86, 80, 109, 115, 126, 89, 101, 106, + 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, + 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, + 117, 17, 45, 41, 44, 34, 37, 22, 21, 12, 11, + 69, 11, 16, 18, 37, 25, 30, 7, 34, 29, 39, 32, + 42, 36, 25, 41, 70, 79, 87, 95, 95, 122, 121, + 117 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 95, 68, + 25, 40, 10, 39, 87, 74, 27, 70, 73, 37, 95, + 95, 65, 79, 126, 126, 126, 24, 7, 68, 74, 27, + 70, 76, 14, 36, 66, 5, 2, 5, 109, 113, 95, + 112, 65, 71, 70, 76, 91, 81, 98, 0, 68, 69, + 64, 33, 1, 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, + 10, 0, 72, 35, 19, 7, 48, 46, 7, 19, 22, 26, + 10, 9, 38, 110, 89, 89, 91, 25, 72, 19, 38, + 65, 73, 3, 19, 65, 73, 72, 81, 24, 76, 14, 1, + 75, 8, 68, 0, 7, 13, 18, 19, 7, 79, 68, 3, 65, + 0, 71, 30, 66, 1, 32, 27, 38, 31, 27, 98, 10, + 11, 76, 67, 76, 69, 33, 2, 5, 38, 57, 62, 62, + 49, 99, 109, 11, 42, 42, 126, 73, 14, 99, 25, + 70, 4, 37, 33, 54, 49, 47, 110, 3, 83, 103, + 103, 66, 13, 21, 10, 4, 10, 10, 2, 15, 8, 78, + 71, 5, 0, 0, 76, 66, 74, 80, 67, 67, 0, 72, + 73, 110, 75, 78, 69, 88, 85, 78, 65, 74, 76, + 74, 79, 99, 83, 69, 110, 126, 99, 108, 102, + 126, 89, 83, 118, 68, 77, 77, 85, 89, 102, 97, + 90, 108, 93, 94, 98, 109, 2, 14, 42, 26, 10, + 4, 17, 10, 5, 2, 16, 21, 45, 29, 23, 14, 36, + 19, 23, 7, 38, 9, 37, 24, 19, 13, 27, 12, 5, + 4, 5, 68, 55, 32, 11, 3, 21, 5, 70, 0, 18, 42, + 37, 22, 10, 34, 15, 13, 5, 4, 62, 66, 5, 12, + 11, 2, 10, 14, 18, 16, 22, 29, 41, 66, 3, 71, + 70, 62, 78, 103, 72, 5, 5, 71, 71, 70, 75, 2, + 77, 98, 69, 68, 24, 70, 77, 69, 68, 64, 74, + 72, 70, 92, 85, 73, 75, 70, 27, 103, 77, 26, + 85, 69, 69, 70, 6, 67, 73, 4, 12, 71, 71, 110, + 30, 28, 29, 10, 71, 72, 74, 85, 75, 86, 92, + 85, 104, 99, 99, 112, 108, 120, 126, 103, 94, + 92, 94, 108, 99, 93, 94, 95, 79, 83, 87, 84, + 89, 108, 94, 91, 115, 101, 114, 113, 126, 126, + 121, 119, 80, 78, 123, 89, 90, 96, 114, 101, + 102, 104, 93, 98, 86, 79, 110, 116, 126, 90, + 102, 107, 69, 11, 16, 19, 38, 25, 31, 7, 35, + 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, + 97, 124, 123, 119, 17, 46, 41, 45, 35, 37, 22, + 21, 12, 12, 69, 11, 16, 19, 38, 25, 31, 7, 35, + 30, 40, 32, 43, 36, 26, 41, 72, 81, 89, 97, + 97, 124, 123, 119 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 70, + 24, 41, 10, 40, 89, 73, 29, 71, 73, 38, 96, + 96, 66, 81, 126, 126, 126, 26, 8, 68, 73, 29, + 71, 76, 15, 36, 66, 5, 3, 7, 110, 114, 95, + 112, 65, 70, 69, 77, 91, 81, 98, 0, 67, 69, 0, + 33, 1, 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 10, + 1, 70, 38, 20, 8, 50, 48, 8, 20, 24, 27, 11, + 10, 41, 110, 90, 89, 92, 25, 72, 20, 41, 64, + 73, 3, 21, 65, 73, 72, 80, 24, 76, 15, 2, 74, + 9, 67, 0, 8, 14, 19, 20, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 32, 28, 38, 31, 27, 98, 11, 11, + 77, 67, 75, 69, 34, 3, 6, 40, 59, 62, 62, 51, + 100, 110, 12, 43, 42, 126, 73, 14, 99, 26, 70, + 4, 39, 33, 54, 49, 49, 111, 4, 84, 105, 106, + 65, 13, 21, 10, 4, 10, 10, 2, 15, 8, 79, 72, + 5, 0, 0, 76, 66, 74, 81, 67, 67, 0, 73, 74, + 111, 76, 78, 69, 89, 85, 80, 67, 75, 77, 75, + 81, 102, 85, 70, 112, 126, 100, 110, 104, 126, + 90, 84, 119, 69, 78, 78, 87, 91, 104, 99, 91, + 109, 93, 95, 99, 111, 4, 16, 43, 27, 10, 4, + 18, 11, 6, 2, 18, 23, 46, 30, 23, 15, 38, 20, + 24, 8, 41, 10, 38, 25, 20, 13, 28, 13, 6, 5, + 6, 67, 56, 33, 11, 3, 22, 6, 69, 1, 19, 42, + 38, 22, 10, 35, 16, 14, 6, 5, 62, 65, 7, 14, + 12, 3, 11, 16, 20, 18, 24, 31, 44, 65, 4, 70, + 69, 62, 77, 104, 71, 6, 6, 71, 71, 70, 75, 2, + 78, 99, 69, 68, 25, 70, 77, 69, 68, 0, 74, 73, + 70, 93, 86, 74, 75, 70, 28, 103, 78, 27, 85, + 70, 69, 70, 6, 68, 73, 4, 12, 71, 71, 112, 29, + 27, 28, 9, 74, 75, 77, 88, 77, 89, 95, 88, + 107, 101, 101, 116, 111, 124, 126, 106, 96, + 93, 96, 110, 101, 94, 95, 96, 79, 85, 90, 87, + 91, 110, 96, 92, 117, 103, 116, 115, 126, 126, + 122, 121, 81, 79, 125, 90, 91, 97, 116, 102, + 103, 105, 94, 99, 86, 78, 112, 117, 126, 92, + 103, 108, 69, 12, 17, 20, 39, 26, 31, 8, 36, + 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, + 99, 126, 125, 120, 18, 46, 42, 45, 36, 38, 23, + 22, 12, 13, 69, 12, 17, 20, 39, 26, 31, 8, 36, + 31, 41, 33, 44, 37, 26, 40, 74, 83, 91, 99, + 99, 126, 125, 120 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 71, + 23, 41, 10, 42, 90, 73, 30, 71, 74, 39, 97, + 97, 67, 83, 126, 126, 126, 28, 10, 68, 73, 30, + 71, 75, 16, 37, 66, 6, 4, 8, 111, 115, 95, + 113, 65, 70, 68, 77, 92, 81, 98, 0, 67, 69, 1, + 34, 1, 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 9, + 1, 69, 40, 21, 9, 51, 49, 9, 21, 26, 28, 12, + 11, 43, 111, 90, 89, 92, 26, 72, 21, 43, 64, + 72, 4, 23, 65, 73, 72, 80, 25, 76, 15, 3, 74, + 10, 67, 0, 8, 14, 20, 20, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 11, 12, + 77, 67, 75, 69, 35, 3, 6, 41, 60, 62, 62, 53, + 100, 111, 12, 43, 42, 126, 73, 15, 100, 26, + 70, 4, 40, 33, 54, 49, 50, 112, 6, 85, 108, + 109, 0, 13, 21, 9, 3, 9, 9, 1, 15, 7, 80, 73, + 5, 0, 0, 77, 67, 75, 82, 68, 67, 0, 74, 74, + 112, 76, 79, 69, 90, 86, 82, 69, 77, 79, 77, + 83, 105, 88, 71, 114, 126, 102, 112, 106, 126, + 91, 85, 121, 70, 79, 79, 88, 92, 106, 101, 93, + 111, 93, 96, 100, 112, 5, 17, 45, 27, 10, 4, + 19, 12, 7, 3, 20, 24, 47, 31, 24, 15, 39, 21, + 26, 9, 43, 10, 38, 25, 20, 14, 29, 13, 6, 6, + 7, 67, 58, 34, 11, 3, 23, 6, 69, 2, 20, 43, + 39, 23, 10, 36, 16, 15, 6, 5, 62, 0, 8, 15, + 14, 4, 13, 17, 21, 19, 26, 33, 46, 65, 5, 70, + 68, 62, 77, 105, 71, 7, 7, 71, 71, 70, 75, 3, + 78, 100, 69, 68, 25, 70, 77, 69, 68, 0, 75, + 73, 70, 94, 87, 74, 75, 70, 29, 104, 78, 28, + 86, 70, 69, 70, 7, 68, 74, 5, 13, 71, 71, 113, + 28, 26, 27, 7, 76, 77, 79, 91, 80, 92, 98, 91, + 110, 104, 103, 120, 115, 126, 126, 109, 98, + 95, 98, 113, 103, 95, 96, 97, 79, 87, 92, 89, + 93, 112, 98, 94, 119, 105, 118, 117, 126, 126, + 124, 122, 82, 80, 126, 92, 93, 99, 118, 104, + 105, 106, 95, 100, 86, 77, 113, 119, 126, 93, + 104, 109, 69, 12, 17, 20, 40, 27, 32, 8, 37, + 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, 101, + 101, 126, 126, 121, 18, 47, 42, 46, 36, 39, + 23, 22, 13, 13, 69, 12, 17, 20, 40, 27, 32, 8, + 37, 32, 42, 33, 45, 37, 27, 40, 76, 85, 93, + 101, 101, 126, 126, 121 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 101, 73, + 22, 42, 10, 44, 92, 73, 32, 71, 74, 40, 98, + 98, 68, 85, 126, 126, 126, 30, 11, 68, 73, 32, + 71, 75, 17, 37, 66, 7, 5, 9, 112, 116, 95, + 113, 65, 70, 67, 77, 92, 81, 98, 0, 67, 69, 2, + 34, 1, 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 9, + 2, 68, 42, 22, 10, 53, 51, 10, 22, 28, 29, 13, + 12, 45, 112, 90, 89, 92, 26, 72, 22, 45, 64, + 71, 5, 25, 65, 73, 72, 80, 25, 76, 16, 4, 74, + 11, 67, 0, 8, 15, 21, 21, 7, 80, 68, 4, 65, 0, + 71, 31, 66, 1, 33, 28, 39, 31, 28, 99, 12, 13, + 78, 67, 75, 69, 36, 3, 7, 42, 61, 62, 62, 55, + 101, 112, 13, 43, 42, 126, 73, 15, 100, 27, + 70, 4, 41, 33, 54, 49, 51, 113, 7, 86, 111, + 112, 1, 13, 21, 9, 2, 9, 9, 1, 15, 7, 81, 74, + 5, 0, 0, 77, 67, 76, 83, 68, 67, 0, 75, 75, + 113, 77, 80, 69, 91, 86, 84, 71, 79, 80, 79, + 85, 108, 90, 72, 116, 126, 103, 114, 108, 126, + 92, 86, 123, 71, 80, 80, 89, 94, 108, 103, 95, + 112, 93, 97, 101, 114, 7, 19, 46, 28, 10, 4, + 20, 13, 8, 4, 22, 25, 48, 32, 25, 16, 40, 22, + 27, 10, 45, 11, 39, 26, 21, 14, 30, 14, 7, 7, + 8, 67, 59, 35, 11, 3, 24, 7, 69, 3, 21, 43, + 40, 23, 10, 37, 17, 16, 7, 6, 62, 1, 10, 17, + 16, 5, 14, 19, 23, 21, 28, 35, 48, 64, 6, 69, + 67, 62, 77, 106, 71, 8, 8, 71, 71, 70, 75, 3, + 78, 101, 69, 68, 26, 70, 77, 69, 68, 0, 75, + 73, 70, 95, 88, 74, 75, 70, 30, 105, 78, 29, + 87, 70, 69, 70, 7, 68, 74, 5, 14, 71, 71, 115, + 27, 25, 26, 5, 78, 80, 82, 94, 82, 95, 101, + 94, 113, 107, 105, 124, 118, 126, 126, 112, + 100, 97, 100, 115, 105, 96, 97, 98, 79, 89, + 94, 91, 95, 114, 100, 95, 121, 107, 120, 119, + 126, 126, 126, 123, 83, 81, 126, 93, 95, 100, + 120, 105, 106, 107, 96, 101, 86, 76, 114, 120, + 126, 94, 105, 110, 69, 13, 18, 21, 41, 28, 33, + 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, 95, + 103, 103, 126, 126, 122, 19, 47, 43, 47, 37, + 40, 24, 23, 13, 14, 69, 13, 18, 21, 41, 28, + 33, 8, 38, 33, 43, 34, 46, 38, 28, 39, 78, 87, + 95, 103, 103, 126, 126, 122 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 103, 75, + 21, 42, 10, 45, 94, 73, 33, 72, 75, 41, 99, + 100, 70, 87, 126, 126, 126, 32, 12, 68, 73, + 33, 72, 75, 17, 37, 67, 7, 5, 10, 114, 118, + 96, 114, 66, 70, 67, 78, 93, 81, 98, 64, 67, + 69, 2, 34, 0, 22, 0, 0, 0, 7, 98, 97, 12, 80, + 71, 8, 2, 67, 44, 23, 10, 54, 52, 10, 23, 29, + 29, 14, 12, 47, 113, 91, 90, 93, 26, 73, 22, + 47, 64, 71, 5, 26, 65, 73, 72, 80, 25, 77, 16, + 4, 74, 11, 67, 0, 8, 15, 22, 21, 7, 81, 69, 4, + 65, 64, 71, 31, 66, 1, 33, 28, 39, 31, 28, + 100, 12, 13, 79, 67, 75, 70, 36, 3, 7, 43, 62, + 62, 62, 56, 102, 114, 13, 43, 42, 126, 74, 15, + 101, 27, 71, 4, 42, 33, 53, 49, 52, 114, 8, + 88, 114, 116, 2, 12, 21, 8, 1, 8, 8, 0, 14, 6, + 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, + 76, 76, 115, 78, 81, 69, 93, 87, 87, 74, 81, + 82, 81, 88, 112, 93, 74, 118, 126, 105, 117, + 110, 126, 94, 88, 125, 73, 81, 81, 91, 96, + 110, 105, 97, 114, 93, 98, 102, 116, 8, 20, + 47, 28, 10, 4, 20, 13, 8, 4, 23, 26, 48, 32, + 25, 16, 41, 23, 28, 10, 47, 11, 39, 26, 21, + 14, 30, 14, 7, 7, 9, 67, 60, 36, 11, 2, 24, 7, + 69, 3, 21, 43, 40, 23, 10, 38, 17, 16, 7, 6, + 62, 2, 11, 18, 17, 6, 15, 20, 24, 22, 29, 36, + 50, 64, 6, 69, 67, 62, 77, 108, 71, 8, 8, 71, + 71, 70, 76, 3, 79, 102, 70, 68, 26, 71, 77, + 70, 68, 0, 76, 74, 71, 96, 89, 75, 76, 70, 31, + 106, 79, 29, 88, 71, 69, 71, 7, 69, 75, 5, 14, + 71, 71, 117, 25, 24, 24, 3, 81, 83, 85, 97, + 85, 98, 105, 97, 117, 110, 107, 126, 122, 126, + 126, 115, 103, 99, 103, 118, 107, 98, 99, 99, + 79, 92, 97, 94, 97, 117, 102, 97, 124, 109, + 123, 121, 126, 126, 126, 125, 85, 83, 126, 95, + 97, 102, 122, 107, 108, 108, 97, 102, 87, 75, + 116, 122, 126, 96, 107, 112, 69, 13, 18, 21, + 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, 38, + 80, 89, 98, 106, 105, 126, 126, 124, 19, 47, + 43, 47, 37, 40, 24, 23, 13, 14, 69, 13, 18, + 21, 42, 28, 33, 8, 39, 33, 44, 34, 46, 38, 28, + 38, 80, 89, 98, 106, 105, 126, 126, 124 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 104, 76, + 21, 43, 11, 47, 95, 72, 35, 72, 75, 43, 99, + 101, 71, 88, 126, 126, 126, 34, 14, 67, 72, + 35, 72, 74, 18, 38, 67, 8, 6, 12, 115, 119, + 96, 114, 66, 69, 66, 78, 93, 80, 97, 64, 66, + 68, 3, 35, 0, 22, 0, 0, 0, 8, 98, 97, 13, 80, + 71, 8, 3, 65, 47, 25, 11, 56, 54, 11, 25, 31, + 30, 16, 13, 50, 113, 91, 90, 93, 27, 73, 23, + 50, 0, 70, 6, 28, 65, 72, 72, 79, 26, 77, 17, + 5, 73, 12, 66, 1, 9, 16, 23, 22, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, + 100, 13, 14, 79, 67, 74, 70, 37, 4, 8, 45, 62, + 62, 62, 58, 102, 115, 14, 44, 43, 126, 74, 16, + 101, 28, 71, 5, 44, 33, 53, 50, 54, 115, 10, + 89, 116, 119, 4, 12, 21, 8, 1, 8, 8, 0, 14, 6, + 82, 75, 4, 64, 64, 78, 68, 77, 84, 69, 68, 64, + 76, 76, 116, 78, 81, 69, 94, 87, 89, 76, 82, + 83, 82, 90, 115, 95, 75, 119, 126, 106, 119, + 111, 126, 95, 89, 126, 74, 81, 81, 92, 97, + 111, 106, 98, 115, 93, 98, 102, 117, 10, 22, + 49, 29, 10, 4, 21, 14, 9, 5, 25, 28, 49, 33, + 26, 17, 43, 24, 30, 11, 50, 12, 40, 27, 22, + 15, 31, 15, 8, 8, 11, 66, 62, 37, 12, 2, 25, + 8, 68, 4, 22, 44, 41, 24, 11, 39, 18, 17, 8, + 7, 62, 4, 13, 20, 19, 8, 17, 22, 26, 24, 31, + 38, 53, 0, 7, 68, 66, 62, 76, 109, 70, 9, 9, + 70, 71, 69, 76, 4, 79, 102, 70, 68, 27, 71, + 77, 70, 68, 1, 76, 74, 71, 96, 89, 75, 76, 69, + 33, 106, 79, 30, 88, 71, 69, 71, 8, 69, 75, 6, + 15, 70, 70, 118, 24, 23, 23, 2, 83, 85, 87, + 100, 87, 100, 108, 99, 120, 112, 109, 126, + 125, 126, 126, 117, 105, 100, 105, 120, 108, + 99, 100, 99, 79, 94, 99, 96, 99, 119, 103, 98, + 126, 110, 125, 122, 126, 126, 126, 126, 86, + 84, 126, 96, 98, 103, 123, 108, 109, 109, 97, + 102, 87, 74, 117, 123, 126, 97, 108, 113, 68, + 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, 47, + 39, 29, 38, 81, 90, 100, 108, 106, 126, 126, + 125, 20, 48, 44, 48, 38, 41, 25, 24, 14, 15, + 68, 14, 19, 22, 44, 29, 34, 9, 41, 34, 45, 35, + 47, 39, 29, 38, 81, 90, 100, 108, 106, 126, + 126, 125 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 106, 78, + 20, 44, 11, 49, 97, 72, 36, 72, 75, 44, 100, + 102, 72, 90, 126, 126, 126, 36, 15, 67, 72, + 36, 72, 74, 19, 38, 67, 9, 7, 13, 116, 120, + 96, 114, 66, 69, 65, 78, 93, 80, 97, 64, 66, + 68, 4, 35, 0, 22, 0, 0, 0, 9, 98, 97, 13, 81, + 71, 8, 4, 64, 49, 26, 12, 58, 56, 12, 26, 33, + 31, 17, 14, 52, 114, 91, 90, 93, 27, 73, 24, + 52, 0, 69, 7, 30, 65, 72, 72, 79, 26, 77, 17, + 6, 73, 13, 66, 1, 9, 16, 24, 23, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 34, 29, 40, 32, 29, + 101, 14, 15, 80, 67, 74, 70, 38, 4, 8, 46, 62, + 62, 62, 60, 103, 116, 14, 44, 43, 126, 74, 16, + 102, 29, 71, 5, 45, 33, 53, 50, 55, 116, 11, + 90, 119, 122, 5, 12, 21, 8, 0, 7, 8, 0, 14, 5, + 83, 76, 4, 64, 64, 78, 69, 78, 85, 69, 68, 64, + 77, 77, 117, 79, 82, 69, 95, 88, 91, 78, 84, + 85, 84, 92, 118, 97, 76, 121, 126, 108, 121, + 113, 126, 96, 90, 126, 75, 82, 82, 93, 99, + 113, 108, 100, 117, 93, 99, 103, 119, 11, 23, + 50, 30, 10, 4, 22, 15, 10, 6, 27, 29, 50, 34, + 27, 18, 44, 25, 31, 12, 52, 13, 40, 27, 22, + 15, 32, 16, 9, 9, 12, 66, 62, 38, 12, 2, 26, + 9, 68, 5, 23, 44, 42, 24, 11, 40, 19, 18, 9, + 8, 62, 5, 15, 22, 21, 9, 18, 24, 28, 25, 33, + 40, 55, 1, 8, 67, 65, 62, 76, 110, 70, 10, 10, + 70, 71, 69, 76, 4, 79, 103, 70, 68, 28, 71, + 77, 70, 68, 1, 76, 74, 71, 97, 90, 75, 76, 69, + 34, 107, 79, 31, 89, 71, 69, 71, 8, 69, 75, 6, + 16, 70, 70, 120, 23, 22, 22, 0, 85, 88, 90, + 103, 89, 103, 111, 102, 123, 115, 111, 126, + 126, 126, 126, 120, 107, 102, 107, 122, 110, + 100, 101, 100, 79, 96, 101, 98, 101, 121, 105, + 100, 126, 112, 126, 124, 126, 126, 126, 126, + 87, 85, 126, 98, 100, 105, 125, 109, 110, 110, + 98, 103, 87, 73, 118, 124, 126, 98, 109, 114, + 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, 35, + 48, 40, 30, 37, 83, 92, 102, 110, 108, 126, + 126, 126, 21, 48, 44, 49, 39, 42, 25, 25, 14, + 16, 68, 14, 20, 23, 45, 30, 35, 9, 42, 35, 46, + 35, 48, 40, 30, 37, 83, 92, 102, 110, 108, + 126, 126, 126 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 108, 79, + 19, 44, 11, 51, 98, 72, 38, 72, 76, 45, 101, + 103, 73, 92, 126, 126, 126, 38, 17, 67, 72, + 38, 72, 73, 20, 39, 67, 10, 8, 14, 117, 121, + 96, 115, 66, 69, 64, 78, 94, 80, 97, 64, 66, + 68, 5, 36, 0, 22, 0, 0, 0, 9, 98, 97, 14, 82, + 71, 7, 4, 0, 51, 27, 13, 59, 57, 13, 27, 35, + 32, 18, 15, 54, 115, 91, 90, 93, 28, 73, 25, + 54, 0, 68, 8, 32, 65, 72, 72, 79, 27, 77, 18, + 7, 73, 14, 66, 1, 9, 17, 25, 23, 8, 81, 69, 5, + 64, 64, 70, 32, 65, 1, 35, 29, 41, 32, 30, + 101, 14, 16, 80, 67, 74, 70, 39, 4, 9, 47, 62, + 62, 62, 62, 103, 117, 15, 44, 43, 126, 74, 17, + 102, 29, 71, 5, 46, 33, 53, 50, 56, 117, 13, + 91, 122, 125, 7, 12, 21, 7, 64, 7, 7, 64, 14, + 5, 84, 77, 4, 64, 64, 79, 69, 79, 86, 70, 68, + 64, 78, 77, 118, 79, 83, 69, 96, 88, 93, 80, + 86, 86, 86, 94, 121, 100, 77, 123, 126, 109, + 123, 115, 126, 97, 91, 126, 76, 83, 83, 94, + 100, 115, 110, 102, 118, 93, 100, 104, 120, + 13, 25, 52, 30, 10, 4, 23, 16, 11, 7, 29, 30, + 51, 35, 28, 18, 45, 26, 33, 13, 54, 13, 41, + 28, 23, 16, 33, 16, 9, 10, 13, 66, 62, 39, 12, + 2, 27, 9, 68, 6, 24, 45, 43, 25, 11, 41, 19, + 19, 9, 8, 62, 7, 16, 23, 23, 10, 20, 25, 29, + 27, 35, 42, 57, 1, 9, 67, 64, 62, 76, 111, 70, + 11, 11, 70, 71, 69, 76, 5, 79, 104, 70, 68, + 28, 71, 77, 70, 68, 1, 77, 74, 71, 98, 91, 75, + 76, 69, 35, 108, 79, 32, 90, 71, 69, 71, 9, + 69, 76, 7, 17, 70, 70, 121, 22, 21, 21, 65, + 87, 90, 92, 106, 92, 106, 114, 105, 126, 118, + 113, 126, 126, 126, 126, 123, 109, 104, 109, + 125, 112, 101, 102, 101, 79, 98, 103, 100, + 103, 123, 107, 101, 126, 114, 126, 126, 126, + 126, 126, 126, 88, 86, 126, 99, 102, 106, 126, + 111, 112, 111, 99, 104, 87, 72, 119, 126, 126, + 99, 110, 115, 68, 15, 20, 23, 46, 31, 36, 9, + 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, 104, + 112, 110, 126, 126, 126, 21, 49, 45, 50, 39, + 43, 26, 25, 15, 16, 68, 15, 20, 23, 46, 31, + 36, 9, 43, 36, 47, 36, 49, 40, 31, 37, 85, 94, + 104, 112, 110, 126, 126, 126 }, + + }, + + { + + { + + 62, + 9, 74, 62, 9, 74, 126, 104, 10, 9, 12, 30, 61, + 62, 54, 14, 118, 6, 78, 65, 1, 14, 73, 13, 64, + 20, 62, 67, 90, 104, 126, 104, 67, 78, 65, 1, + 86, 95, 2, 18, 69, 81, 96, 8, 67, 86, 88, 5, 76, + 94, 9, 69, 81, 88, 67, 74, 74, 80, 72, 5, 22, 0, + 0, 0, 83, 86, 97, 72, 22, 1, 52, 8, 69, 126, + 102, 82, 74, 107, 126, 126, 126, 95, 126, 114, + 126, 123, 115, 122, 115, 0, 68, 84, 104, 70, 93, + 90, 126, 74, 97, 91, 126, 7, 82, 76, 125, 93, + 87, 77, 71, 0, 68, 84, 1, 65, 2, 7, 66, 64, 2, + 78, 13, 11, 28, 19, 25, 18, 17, 19, 46, 12, 13, + 44, 30, 1, 108, 100, 101, 91, 94, 88, 84, 86, + 83, 87, 94, 70, 72, 74, 4, 102, 100, 95, 75, 72, + 75, 71, 17, 69, 1, 65, 26, 72, 6, 9, 1, 72, 62, + 54, 38, 45, 54, 44, 26, 45, 34, 30, 33, 18, 5, + 1, 2, 25, 18, 24, 21, 19, 18, 22, 14, 29, 21, 8, + 12, 17, 89, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 46, 62, 60, 41, 62, 62, 62, + 62, 60, 58, 62, 47, 41, 15, 26, 3, 68, 97, 71, + 21, 13, 9, 1, 5, 0, 72, 74, 91, 67, 36, 24, 19, + 17, 64, 68, 78, 77, 86, 92, 8, 3, 1, 65, 73, 76, + 80, 88, 110, 97, 84, 79, 73, 74, 86, 96, 97, + 117, 78, 30, 15, 10, 1, 71, 79, 86, 90, 97, 62, + 93, 84, 79, 66, 71, 1, 3, 4, 75, 1, 5, 66, 79, + 71, 68, 19, 1, 27, 23, 36, 34, 19, 27, 31, 21, + 15, 1, 17, 64, 104, 97, 96, 88, 85, 85, 85, 88, + 66, 77, 76, 76, 5, 76, 83, 99, 95, 95, 76, 74, + 70, 75, 68, 65, 73, 1, 1, 68, 75, 8, 64, 70, 57, + 44, 47, 49, 50, 52, 48, 47, 40, 40, 43, 37, 19, + 23, 16, 46, 42, 41, 36, 34, 28, 13, 6, 0, 77, + 82, 94, 69, 109, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 61, 50, 28, 5, 62, 62, 33, 62, 62, + 62, 60, 62, 58, 52, 58, 51, 52, 34, 37, 24, 66, + 42, 32, 13, 120, 112, 114, 85, 92, 89, 71, 81, + 80, 68, 70, 7, 68, 13, 74, 62, 62, 62, 62, 60, + 57, 29, 9, 82, 75, 40, 29, 20, 9, 8, 2, 64, 68, + 92, 106, 97, 90, 90, 88, 73, 79, 86, 73, 70, 69, + 66, 64, 5, 4, 62, 62, 62, 62, 60, 54, 43, 27, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 125, 102, 11, 10, 12, 29, + 60, 62, 54, 14, 115, 6, 77, 64, 1, 14, 72, 12, + 65, 20, 62, 68, 91, 104, 124, 102, 67, 77, 64, + 1, 85, 93, 3, 18, 68, 80, 95, 8, 67, 85, 88, + 5, 75, 93, 9, 69, 80, 88, 66, 73, 73, 79, 71, + 5, 22, 0, 0, 0, 82, 86, 97, 71, 22, 1, 52, 8, + 69, 125, 101, 82, 73, 105, 125, 125, 125, 93, + 125, 112, 125, 121, 114, 121, 114, 1, 67, 83, + 103, 69, 92, 89, 125, 73, 96, 90, 125, 8, 81, + 75, 123, 92, 86, 76, 70, 1, 67, 83, 2, 64, 2, + 7, 65, 64, 2, 77, 13, 11, 28, 19, 25, 18, 17, + 19, 45, 12, 13, 43, 29, 1, 107, 99, 100, 90, + 93, 87, 83, 85, 82, 86, 92, 70, 72, 73, 3, + 101, 99, 95, 74, 72, 74, 70, 17, 68, 1, 65, + 25, 71, 6, 8, 1, 72, 62, 54, 38, 45, 54, 44, + 26, 45, 34, 29, 33, 18, 5, 1, 2, 25, 18, 24, + 21, 19, 17, 22, 14, 28, 20, 8, 11, 16, 89, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 60, 44, 62, 59, 40, 62, 62, 62, 62, 58, + 56, 61, 45, 39, 15, 25, 2, 68, 97, 70, 22, 14, + 10, 2, 5, 0, 71, 73, 90, 66, 37, 25, 20, 17, + 0, 67, 77, 76, 85, 91, 9, 4, 2, 64, 72, 75, + 79, 87, 108, 96, 82, 78, 72, 73, 85, 95, 96, + 115, 77, 31, 16, 11, 2, 70, 78, 85, 89, 96, + 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 65, + 78, 71, 68, 19, 2, 27, 23, 35, 34, 19, 26, 30, + 21, 15, 1, 16, 64, 103, 96, 95, 87, 84, 84, + 84, 87, 66, 76, 75, 75, 5, 75, 82, 98, 94, 95, + 76, 73, 70, 74, 68, 65, 72, 1, 1, 67, 74, 8, + 64, 70, 57, 44, 47, 49, 49, 52, 48, 47, 40, + 40, 43, 37, 19, 22, 15, 45, 41, 40, 35, 33, + 27, 13, 6, 0, 76, 81, 93, 69, 108, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 61, 59, 48, 27, 5, + 62, 62, 32, 62, 62, 62, 58, 62, 56, 50, 56, + 49, 50, 33, 35, 23, 67, 41, 31, 12, 118, 110, + 112, 84, 91, 88, 69, 80, 79, 68, 69, 9, 66, + 15, 73, 62, 62, 62, 62, 58, 55, 27, 7, 83, 74, + 41, 29, 20, 9, 9, 2, 64, 68, 91, 105, 96, 89, + 89, 86, 72, 78, 85, 72, 69, 68, 65, 0, 6, 4, + 62, 62, 62, 62, 59, 53, 41, 26, 67 }, + + { + + 62, + 9, 74, 62, 9, 74, 123, 101, 11, 10, 12, 28, + 59, 61, 54, 14, 113, 6, 76, 0, 1, 13, 72, 11, + 66, 19, 60, 70, 92, 105, 121, 101, 67, 76, 0, + 1, 85, 92, 3, 17, 68, 80, 94, 8, 67, 85, 88, + 5, 75, 92, 9, 69, 80, 88, 66, 73, 73, 79, 71, + 5, 22, 0, 0, 0, 81, 86, 97, 71, 21, 1, 52, 8, + 69, 124, 100, 82, 73, 104, 123, 123, 124, 92, + 123, 111, 123, 120, 113, 120, 113, 2, 67, 82, + 102, 69, 92, 88, 123, 73, 96, 90, 124, 8, 81, + 75, 122, 92, 85, 76, 70, 1, 67, 82, 2, 64, 1, + 7, 65, 64, 2, 77, 13, 11, 27, 19, 24, 18, 17, + 19, 43, 12, 13, 41, 28, 0, 106, 98, 99, 89, + 92, 86, 82, 84, 82, 85, 91, 70, 72, 73, 2, + 101, 98, 95, 74, 72, 73, 70, 16, 67, 1, 65, + 24, 70, 5, 7, 1, 73, 60, 53, 37, 44, 53, 43, + 25, 44, 34, 28, 32, 18, 5, 1, 2, 24, 17, 23, + 20, 18, 16, 21, 13, 26, 19, 7, 10, 15, 89, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 58, 41, 62, 57, 38, 62, 62, 62, 62, 56, + 54, 58, 43, 37, 14, 23, 1, 69, 97, 70, 22, 14, + 10, 2, 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, + 1, 67, 76, 76, 84, 90, 10, 5, 2, 64, 71, 75, + 79, 86, 107, 95, 81, 77, 72, 73, 84, 94, 95, + 114, 77, 31, 16, 11, 2, 69, 77, 84, 88, 95, + 62, 92, 83, 78, 66, 70, 1, 4, 5, 74, 2, 6, 64, + 78, 71, 68, 18, 2, 26, 22, 34, 33, 19, 25, 29, + 21, 15, 0, 15, 65, 102, 95, 94, 87, 84, 84, + 83, 86, 66, 76, 75, 75, 4, 75, 82, 98, 93, 95, + 76, 73, 70, 73, 68, 65, 71, 1, 1, 67, 73, 7, + 64, 71, 56, 44, 47, 48, 48, 51, 47, 46, 39, + 39, 42, 36, 18, 21, 14, 43, 40, 38, 33, 32, + 26, 12, 5, 0, 76, 81, 93, 70, 107, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 59, 57, 46, 26, 4, + 62, 60, 31, 62, 62, 62, 56, 60, 54, 48, 54, + 47, 48, 31, 33, 21, 68, 39, 29, 10, 117, 109, + 111, 83, 90, 87, 67, 79, 78, 68, 68, 10, 65, + 16, 72, 62, 62, 62, 62, 55, 52, 24, 5, 84, 74, + 41, 29, 20, 9, 9, 2, 64, 68, 90, 104, 95, 88, + 88, 85, 71, 77, 84, 71, 68, 67, 65, 1, 6, 4, + 62, 62, 62, 61, 57, 51, 39, 24, 68 }, + + { + + 62, + 9, 74, 62, 9, 74, 121, 99, 12, 10, 11, 26, 57, + 60, 54, 14, 111, 6, 75, 1, 1, 12, 72, 10, 67, + 19, 58, 71, 93, 105, 118, 100, 67, 75, 1, 1, + 84, 91, 4, 17, 68, 79, 93, 7, 68, 85, 88, 5, + 75, 92, 9, 69, 80, 88, 65, 73, 73, 79, 70, 5, + 22, 0, 0, 0, 81, 86, 97, 70, 20, 1, 52, 8, 69, + 123, 99, 82, 72, 103, 121, 121, 122, 91, 121, + 110, 121, 119, 112, 119, 112, 3, 67, 81, 101, + 69, 91, 88, 121, 73, 95, 89, 123, 8, 81, 74, + 120, 91, 84, 76, 70, 1, 67, 81, 3, 0, 1, 7, + 65, 64, 2, 77, 13, 10, 27, 19, 23, 18, 17, 19, + 41, 12, 12, 39, 27, 64, 105, 97, 98, 88, 91, + 86, 81, 84, 81, 84, 90, 70, 72, 73, 1, 100, + 97, 95, 74, 72, 72, 70, 15, 66, 1, 65, 23, 69, + 5, 6, 1, 74, 59, 52, 37, 43, 52, 42, 25, 43, + 33, 27, 31, 18, 5, 1, 1, 23, 16, 22, 19, 17, + 15, 20, 13, 24, 18, 7, 9, 14, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 55, + 39, 62, 55, 37, 62, 61, 62, 59, 54, 51, 56, + 41, 34, 13, 21, 0, 70, 97, 70, 23, 14, 10, 2, + 5, 0, 71, 73, 89, 66, 37, 25, 20, 17, 2, 66, + 76, 75, 84, 89, 11, 5, 3, 64, 70, 74, 78, 86, + 106, 94, 80, 76, 71, 73, 83, 93, 94, 113, 76, + 31, 16, 11, 2, 68, 77, 83, 87, 94, 62, 91, 82, + 77, 66, 70, 1, 4, 5, 74, 2, 6, 64, 78, 71, 68, + 18, 3, 25, 21, 33, 32, 19, 24, 28, 21, 15, 0, + 14, 65, 101, 94, 93, 86, 83, 83, 83, 85, 66, + 76, 75, 74, 4, 75, 82, 97, 92, 95, 76, 73, 70, + 72, 68, 65, 70, 1, 1, 67, 72, 6, 64, 72, 55, + 43, 46, 47, 47, 50, 46, 45, 38, 38, 41, 35, + 17, 20, 13, 42, 39, 37, 31, 30, 25, 11, 5, 64, + 76, 81, 93, 70, 106, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 57, 54, 44, 24, 3, 61, 59, 29, + 62, 62, 60, 54, 58, 52, 46, 52, 45, 45, 29, + 31, 19, 69, 37, 27, 9, 116, 108, 110, 82, 89, + 86, 66, 78, 77, 68, 67, 12, 0, 18, 71, 62, 62, + 62, 62, 52, 49, 21, 3, 85, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 90, 103, 94, 87, 87, 84, 71, 77, + 83, 71, 68, 67, 65, 1, 6, 4, 62, 62, 62, 59, + 55, 49, 37, 22, 69 }, + + { + + 62, + 9, 74, 62, 9, 74, 120, 98, 12, 10, 11, 25, 56, + 58, 54, 14, 108, 5, 74, 1, 1, 11, 72, 9, 68, + 18, 56, 73, 94, 106, 115, 99, 67, 74, 1, 1, + 84, 90, 4, 16, 68, 79, 93, 7, 68, 84, 88, 5, + 75, 91, 8, 70, 80, 88, 65, 72, 73, 78, 70, 5, + 22, 0, 0, 0, 80, 87, 97, 70, 19, 1, 52, 8, 69, + 122, 98, 82, 72, 101, 120, 119, 121, 90, 120, + 108, 119, 118, 112, 118, 112, 3, 67, 80, 100, + 69, 91, 87, 119, 73, 95, 89, 122, 8, 80, 74, + 119, 91, 84, 76, 69, 1, 67, 81, 3, 0, 0, 6, + 65, 64, 2, 77, 13, 10, 26, 19, 23, 18, 17, 18, + 39, 12, 12, 37, 26, 65, 104, 96, 97, 87, 91, + 85, 80, 83, 81, 83, 89, 70, 72, 72, 0, 100, + 96, 95, 74, 72, 72, 70, 14, 65, 1, 65, 21, 68, + 4, 5, 1, 75, 57, 51, 36, 42, 51, 41, 24, 42, + 33, 25, 30, 17, 5, 1, 1, 22, 16, 21, 19, 16, + 14, 19, 12, 22, 17, 6, 8, 13, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 59, 53, + 36, 62, 54, 35, 62, 59, 62, 57, 51, 49, 53, + 39, 32, 12, 20, 65, 71, 97, 70, 23, 15, 10, 2, + 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 3, 66, + 75, 75, 83, 89, 12, 6, 3, 64, 70, 74, 78, 85, + 105, 94, 79, 76, 71, 73, 82, 92, 94, 112, 76, + 32, 16, 11, 2, 67, 76, 83, 86, 93, 62, 91, 82, + 77, 66, 70, 1, 4, 5, 73, 2, 6, 0, 78, 71, 68, + 17, 3, 24, 20, 32, 31, 19, 22, 27, 20, 15, 64, + 13, 66, 101, 94, 92, 86, 83, 83, 82, 84, 67, + 76, 75, 74, 3, 75, 82, 97, 91, 95, 76, 72, 70, + 72, 68, 65, 69, 1, 0, 67, 71, 6, 65, 73, 54, + 43, 46, 46, 46, 49, 45, 44, 37, 37, 40, 34, + 16, 19, 12, 40, 37, 35, 29, 29, 24, 10, 4, 64, + 76, 81, 93, 71, 106, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 60, 55, 52, 42, 23, 2, 59, 57, 28, + 62, 62, 58, 52, 55, 50, 44, 50, 43, 43, 27, + 29, 17, 70, 35, 25, 7, 115, 107, 109, 82, 88, + 85, 64, 77, 76, 68, 66, 13, 1, 19, 71, 62, 62, + 62, 62, 49, 46, 18, 1, 86, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 89, 102, 93, 86, 87, 83, 70, 76, + 82, 70, 67, 66, 64, 2, 7, 4, 62, 62, 62, 57, + 53, 47, 35, 20, 70 }, + + { + + 62, + 9, 74, 62, 9, 74, 118, 96, 12, 10, 10, 23, 54, + 57, 54, 14, 106, 5, 73, 2, 1, 11, 71, 8, 69, + 18, 54, 75, 95, 106, 112, 97, 67, 73, 2, 1, + 84, 89, 4, 16, 68, 79, 92, 7, 69, 84, 88, 5, + 75, 90, 8, 70, 80, 88, 64, 72, 72, 78, 69, 5, + 22, 0, 0, 0, 80, 87, 97, 69, 18, 1, 52, 8, 69, + 121, 97, 82, 71, 100, 118, 117, 119, 89, 118, + 107, 117, 117, 111, 117, 111, 4, 67, 79, 99, + 69, 90, 86, 117, 73, 95, 88, 120, 9, 80, 73, + 118, 90, 83, 76, 69, 2, 66, 80, 4, 1, 0, 6, + 65, 64, 2, 77, 13, 9, 25, 19, 22, 18, 17, 18, + 37, 12, 11, 36, 25, 66, 103, 95, 96, 86, 90, + 84, 79, 82, 80, 82, 88, 70, 72, 72, 64, 99, + 95, 95, 73, 72, 71, 70, 13, 64, 1, 65, 20, 67, + 4, 4, 1, 75, 56, 50, 36, 41, 50, 40, 23, 42, + 33, 24, 29, 17, 5, 1, 0, 22, 15, 20, 18, 15, + 13, 19, 11, 20, 16, 5, 7, 12, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 57, 51, + 34, 60, 52, 33, 62, 57, 60, 55, 49, 47, 50, + 37, 29, 11, 18, 66, 71, 97, 70, 23, 15, 10, 2, + 5, 0, 71, 73, 88, 65, 38, 25, 20, 17, 4, 65, + 74, 75, 82, 88, 13, 7, 3, 0, 69, 73, 77, 85, + 104, 93, 77, 75, 71, 72, 81, 91, 93, 111, 75, + 32, 17, 11, 2, 66, 75, 82, 85, 92, 62, 91, 82, + 76, 66, 70, 1, 4, 5, 73, 2, 7, 0, 78, 71, 68, + 16, 4, 23, 19, 31, 31, 19, 21, 26, 20, 15, 65, + 12, 66, 100, 93, 91, 85, 82, 82, 82, 83, 67, + 76, 75, 74, 2, 75, 82, 96, 90, 95, 76, 72, 70, + 71, 68, 65, 68, 1, 0, 67, 70, 5, 65, 73, 53, + 43, 45, 46, 45, 48, 44, 43, 37, 36, 39, 33, + 15, 18, 11, 39, 36, 34, 27, 28, 23, 9, 3, 65, + 76, 80, 93, 71, 105, 62, 62, 62, 62, 62, 62, + 62, 62, 60, 58, 53, 50, 40, 21, 1, 57, 55, 27, + 61, 62, 56, 50, 53, 48, 42, 48, 41, 40, 25, + 27, 15, 71, 33, 23, 6, 114, 105, 108, 81, 87, + 84, 1, 76, 75, 68, 65, 15, 3, 21, 70, 62, 62, + 62, 62, 47, 43, 16, 64, 87, 74, 41, 29, 20, 9, + 9, 2, 64, 68, 89, 101, 92, 85, 86, 82, 69, 76, + 81, 69, 66, 65, 64, 2, 7, 4, 62, 62, 62, 56, + 51, 45, 33, 18, 71 }, + + { + + 62, + 9, 75, 62, 9, 75, 116, 95, 13, 10, 10, 22, 53, + 56, 54, 14, 104, 5, 73, 3, 1, 10, 71, 7, 70, + 17, 53, 76, 96, 107, 109, 96, 67, 73, 3, 1, + 83, 88, 5, 15, 67, 78, 91, 6, 69, 84, 88, 5, + 74, 90, 8, 70, 79, 88, 64, 72, 72, 78, 69, 5, + 22, 0, 0, 0, 79, 87, 97, 69, 18, 0, 52, 8, 69, + 120, 97, 82, 71, 99, 116, 115, 118, 88, 116, + 106, 115, 116, 110, 116, 110, 5, 67, 78, 99, + 68, 90, 86, 115, 73, 94, 88, 119, 9, 80, 73, + 116, 90, 82, 75, 69, 2, 66, 79, 4, 1, 64, 6, + 65, 64, 2, 77, 13, 9, 25, 19, 21, 18, 17, 18, + 35, 12, 11, 34, 24, 67, 103, 94, 96, 86, 89, + 84, 78, 82, 80, 82, 86, 70, 72, 72, 65, 99, + 94, 95, 73, 72, 70, 69, 12, 64, 1, 65, 19, 66, + 3, 3, 1, 76, 54, 49, 35, 41, 49, 40, 23, 41, + 32, 23, 28, 17, 5, 1, 0, 21, 14, 19, 17, 15, + 12, 18, 11, 18, 15, 5, 6, 11, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 54, 48, + 31, 58, 50, 32, 62, 54, 57, 52, 47, 44, 48, + 34, 27, 10, 16, 67, 72, 97, 69, 24, 15, 11, 2, + 5, 0, 71, 73, 87, 65, 38, 26, 20, 17, 5, 65, + 74, 74, 82, 87, 14, 7, 4, 0, 68, 73, 77, 84, + 103, 92, 76, 74, 70, 72, 81, 91, 92, 109, 75, + 32, 17, 11, 3, 66, 75, 81, 85, 91, 62, 90, 81, + 76, 66, 70, 1, 4, 5, 73, 3, 7, 1, 78, 71, 69, + 16, 4, 22, 18, 30, 30, 19, 20, 25, 20, 15, 65, + 11, 67, 99, 92, 90, 85, 82, 82, 81, 83, 67, + 75, 74, 73, 2, 75, 82, 96, 89, 95, 76, 72, 70, + 70, 68, 65, 67, 0, 0, 67, 70, 4, 65, 74, 52, + 42, 45, 45, 44, 48, 44, 42, 36, 36, 38, 32, + 14, 17, 10, 37, 35, 32, 25, 26, 21, 8, 3, 65, + 76, 80, 92, 72, 104, 62, 62, 62, 62, 62, 62, + 62, 62, 58, 55, 51, 47, 38, 20, 1, 56, 54, 25, + 59, 62, 54, 48, 51, 46, 40, 45, 39, 38, 23, + 25, 14, 73, 31, 21, 4, 113, 104, 107, 80, 86, + 83, 2, 75, 74, 68, 64, 16, 4, 22, 69, 62, 62, + 62, 59, 44, 41, 13, 66, 89, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 88, 100, 92, 84, 85, 81, 69, 75, + 80, 69, 66, 65, 64, 3, 7, 4, 62, 62, 61, 54, + 50, 44, 30, 17, 72 }, + + { + + 62, + 9, 75, 62, 9, 75, 114, 93, 13, 10, 9, 20, 51, + 54, 54, 14, 101, 4, 72, 3, 1, 9, 71, 6, 71, + 17, 51, 78, 97, 107, 106, 95, 67, 72, 3, 1, + 83, 87, 5, 15, 67, 78, 91, 6, 70, 83, 88, 5, + 74, 89, 7, 70, 79, 88, 0, 71, 72, 77, 68, 5, + 22, 0, 0, 0, 79, 87, 97, 68, 17, 0, 52, 8, 69, + 119, 96, 82, 70, 97, 115, 113, 116, 87, 115, + 104, 113, 115, 109, 115, 110, 6, 67, 77, 98, + 68, 89, 85, 113, 73, 94, 87, 118, 9, 79, 72, + 115, 89, 82, 75, 68, 2, 66, 78, 5, 2, 64, 5, + 65, 64, 2, 77, 13, 8, 24, 19, 21, 18, 17, 17, + 33, 12, 10, 32, 23, 68, 102, 93, 95, 85, 88, + 83, 77, 81, 79, 81, 85, 70, 72, 71, 66, 98, + 93, 95, 73, 72, 70, 69, 11, 0, 1, 65, 17, 65, + 3, 2, 1, 77, 53, 48, 35, 40, 48, 39, 22, 40, + 32, 22, 27, 17, 5, 1, 64, 20, 14, 18, 17, 14, + 11, 17, 10, 16, 14, 4, 5, 10, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 60, 61, 52, 46, + 29, 56, 49, 30, 62, 52, 55, 50, 44, 42, 45, + 32, 24, 9, 15, 69, 73, 97, 69, 24, 16, 11, 2, + 5, 0, 71, 73, 87, 64, 39, 26, 20, 17, 6, 64, + 73, 74, 81, 86, 15, 8, 4, 0, 67, 72, 76, 84, + 102, 92, 75, 74, 70, 72, 80, 90, 92, 108, 74, + 33, 17, 11, 3, 65, 74, 80, 84, 90, 62, 90, 81, + 75, 66, 70, 1, 4, 5, 72, 3, 7, 1, 78, 71, 69, + 15, 5, 21, 17, 29, 29, 19, 19, 24, 19, 15, 66, + 10, 67, 98, 92, 89, 84, 81, 81, 81, 82, 67, + 75, 74, 73, 1, 75, 82, 95, 88, 95, 76, 71, 70, + 70, 68, 65, 66, 0, 0, 67, 69, 4, 66, 75, 51, + 42, 44, 44, 43, 47, 43, 41, 35, 35, 37, 31, + 13, 16, 9, 36, 33, 31, 23, 25, 20, 7, 2, 66, + 76, 80, 92, 72, 103, 62, 62, 62, 62, 62, 62, + 62, 61, 56, 53, 49, 45, 36, 18, 0, 54, 52, 24, + 57, 62, 52, 46, 49, 44, 38, 43, 37, 35, 21, + 23, 12, 74, 29, 19, 3, 112, 103, 106, 80, 85, + 82, 4, 74, 73, 68, 0, 18, 6, 24, 69, 62, 62, + 61, 56, 41, 38, 10, 68, 90, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 88, 99, 91, 83, 84, 80, 68, 75, + 79, 68, 65, 64, 0, 3, 8, 4, 62, 62, 59, 52, + 48, 42, 28, 15, 73 }, + + { + + 62, + 8, 75, 62, 8, 75, 113, 92, 13, 10, 9, 19, 50, + 53, 54, 14, 99, 4, 71, 4, 1, 8, 71, 5, 73, 16, + 49, 80, 98, 108, 104, 94, 67, 71, 4, 1, 83, + 86, 5, 14, 67, 78, 90, 5, 70, 83, 89, 5, 74, + 89, 7, 71, 79, 88, 0, 71, 72, 77, 68, 5, 22, + 0, 0, 0, 78, 88, 97, 68, 16, 0, 52, 8, 69, + 118, 95, 82, 70, 96, 113, 111, 115, 86, 113, + 103, 112, 114, 109, 114, 109, 6, 67, 76, 97, + 68, 89, 85, 112, 73, 94, 87, 117, 9, 79, 72, + 114, 89, 81, 75, 68, 2, 66, 78, 5, 2, 65, 5, + 65, 64, 2, 77, 13, 8, 23, 19, 20, 18, 17, 17, + 31, 12, 10, 30, 22, 69, 101, 92, 94, 84, 88, + 83, 76, 81, 79, 80, 84, 70, 72, 71, 68, 98, + 92, 95, 73, 73, 69, 69, 10, 1, 1, 65, 16, 64, + 2, 1, 1, 78, 51, 47, 34, 39, 47, 38, 21, 39, + 31, 20, 26, 16, 5, 1, 64, 19, 13, 17, 16, 13, + 10, 16, 9, 14, 12, 3, 4, 9, 89, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 61, 58, 58, 49, 43, + 26, 54, 47, 28, 61, 50, 52, 47, 42, 39, 42, + 30, 22, 8, 13, 70, 74, 98, 69, 24, 16, 11, 2, + 5, 0, 71, 73, 86, 64, 39, 26, 20, 17, 7, 64, + 73, 74, 81, 86, 16, 8, 4, 0, 67, 72, 76, 83, + 101, 91, 74, 73, 70, 72, 79, 89, 91, 107, 74, + 33, 17, 11, 3, 64, 74, 80, 83, 90, 62, 90, 81, + 75, 66, 70, 1, 4, 5, 72, 3, 7, 2, 78, 71, 69, + 14, 5, 20, 16, 28, 28, 19, 17, 22, 19, 15, 67, + 9, 68, 98, 91, 88, 84, 81, 81, 80, 81, 68, 75, + 74, 73, 0, 75, 82, 95, 88, 96, 76, 71, 70, 69, + 68, 65, 66, 0, 64, 67, 68, 3, 66, 76, 50, 41, + 44, 43, 41, 46, 42, 40, 34, 34, 36, 30, 12, + 15, 8, 34, 32, 29, 21, 23, 19, 6, 1, 66, 76, + 80, 92, 73, 103, 62, 62, 62, 62, 62, 62, 61, + 58, 54, 51, 47, 42, 34, 17, 64, 52, 50, 22, + 55, 61, 49, 43, 46, 41, 36, 41, 34, 33, 19, + 20, 10, 75, 27, 17, 1, 111, 102, 105, 79, 84, + 82, 5, 73, 73, 68, 0, 19, 7, 25, 68, 62, 62, + 58, 53, 38, 35, 7, 70, 91, 73, 41, 29, 20, 9, + 9, 2, 64, 68, 87, 99, 90, 82, 84, 79, 68, 74, + 79, 68, 65, 64, 0, 4, 8, 3, 62, 62, 57, 50, + 46, 40, 26, 13, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 111, 91, 14, 10, 9, 18, 49, + 52, 54, 14, 97, 4, 70, 5, 1, 8, 70, 4, 74, 15, + 47, 81, 99, 109, 101, 92, 67, 70, 5, 1, 82, + 85, 6, 13, 67, 77, 89, 5, 70, 83, 89, 5, 74, + 88, 7, 71, 79, 88, 0, 71, 71, 77, 68, 5, 22, + 0, 0, 0, 77, 88, 97, 68, 15, 0, 52, 8, 69, + 117, 94, 82, 70, 95, 111, 109, 113, 84, 111, + 102, 110, 113, 108, 113, 108, 7, 66, 75, 96, + 68, 88, 84, 110, 73, 93, 87, 115, 10, 79, 72, + 112, 89, 80, 75, 68, 3, 65, 77, 5, 2, 65, 5, + 64, 64, 2, 76, 13, 8, 23, 19, 19, 18, 17, 17, + 29, 12, 10, 29, 21, 69, 100, 91, 93, 83, 87, + 82, 75, 80, 79, 79, 83, 70, 72, 71, 69, 97, + 91, 95, 72, 73, 68, 69, 9, 2, 1, 65, 15, 0, 1, + 0, 1, 78, 50, 46, 34, 38, 46, 37, 21, 39, 31, + 19, 25, 16, 5, 1, 64, 19, 12, 16, 15, 12, 9, + 16, 9, 13, 11, 3, 3, 8, 89, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 59, 56, 56, 46, 41, 23, + 53, 45, 27, 59, 48, 50, 45, 40, 37, 40, 28, + 20, 8, 11, 71, 74, 98, 69, 25, 16, 11, 3, 5, + 0, 70, 73, 85, 64, 39, 26, 21, 17, 8, 0, 72, + 73, 80, 85, 17, 9, 5, 1, 66, 71, 76, 82, 100, + 90, 72, 72, 69, 71, 78, 88, 90, 106, 73, 33, + 18, 12, 3, 0, 73, 79, 82, 89, 62, 89, 80, 74, + 66, 70, 1, 5, 6, 72, 3, 8, 3, 78, 71, 69, 14, + 5, 19, 16, 27, 28, 19, 16, 21, 19, 15, 67, 8, + 69, 97, 90, 87, 84, 80, 81, 79, 80, 68, 75, + 74, 72, 0, 75, 82, 95, 87, 96, 76, 71, 70, 68, + 68, 65, 65, 0, 64, 67, 67, 2, 66, 76, 49, 41, + 44, 43, 40, 45, 41, 39, 34, 33, 35, 30, 12, + 14, 7, 33, 31, 27, 19, 22, 18, 6, 1, 66, 75, + 79, 92, 74, 102, 62, 62, 62, 62, 62, 62, 59, + 56, 52, 49, 45, 40, 32, 16, 65, 50, 49, 21, + 53, 59, 47, 41, 44, 39, 34, 39, 32, 31, 18, + 18, 8, 76, 25, 15, 64, 110, 100, 103, 78, 83, + 81, 7, 72, 72, 68, 1, 21, 8, 27, 67, 62, 62, + 56, 50, 36, 32, 5, 72, 92, 73, 41, 29, 20, 9, + 10, 2, 64, 68, 86, 98, 89, 81, 83, 77, 67, 73, + 78, 67, 64, 0, 0, 5, 8, 3, 62, 61, 56, 49, 44, + 38, 24, 11, 74 }, + + { + + 62, + 8, 75, 62, 8, 75, 109, 89, 14, 10, 8, 16, 47, + 50, 54, 14, 94, 3, 69, 5, 1, 7, 70, 3, 75, 15, + 45, 83, 100, 109, 98, 91, 67, 69, 5, 1, 82, + 84, 6, 13, 67, 77, 89, 5, 71, 82, 89, 5, 74, + 87, 6, 71, 79, 88, 1, 70, 71, 76, 67, 5, 22, + 0, 0, 0, 77, 88, 97, 67, 14, 0, 52, 8, 69, + 116, 93, 82, 69, 93, 110, 107, 112, 83, 110, + 100, 108, 112, 107, 112, 108, 8, 66, 74, 95, + 68, 88, 83, 108, 73, 93, 86, 114, 10, 78, 71, + 111, 88, 80, 75, 67, 3, 65, 76, 6, 3, 66, 4, + 64, 64, 2, 76, 13, 7, 22, 19, 19, 18, 17, 16, + 27, 12, 9, 27, 20, 70, 99, 90, 92, 82, 86, 81, + 74, 79, 78, 78, 82, 70, 72, 70, 70, 97, 90, + 95, 72, 73, 68, 69, 8, 3, 1, 65, 13, 1, 1, 64, + 1, 79, 48, 45, 33, 37, 45, 36, 20, 38, 31, 18, + 24, 16, 5, 1, 65, 18, 12, 15, 15, 11, 8, 15, + 8, 11, 10, 2, 2, 7, 89, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 57, 54, 53, 44, 39, 21, 51, + 44, 25, 56, 46, 48, 43, 37, 35, 37, 26, 17, 7, + 10, 73, 75, 98, 69, 25, 17, 11, 3, 5, 0, 70, + 73, 85, 0, 40, 26, 21, 17, 9, 0, 71, 73, 79, + 84, 18, 10, 5, 1, 65, 71, 75, 82, 99, 90, 71, + 72, 69, 71, 77, 87, 90, 105, 73, 34, 18, 12, + 3, 1, 72, 78, 81, 88, 62, 89, 80, 74, 66, 70, + 1, 5, 6, 71, 3, 8, 3, 78, 71, 69, 13, 6, 18, + 15, 26, 27, 19, 15, 20, 18, 15, 68, 7, 69, 96, + 90, 86, 83, 80, 80, 79, 79, 68, 75, 74, 72, + 64, 75, 82, 94, 86, 96, 76, 70, 70, 68, 68, + 65, 64, 0, 64, 67, 66, 2, 67, 77, 48, 41, 43, + 42, 39, 44, 40, 38, 33, 32, 34, 29, 11, 13, 6, + 31, 29, 26, 17, 21, 17, 5, 0, 67, 75, 79, 92, + 74, 101, 62, 62, 62, 62, 62, 60, 57, 53, 50, + 47, 43, 38, 30, 14, 66, 48, 47, 20, 51, 57, + 45, 39, 42, 37, 32, 37, 30, 28, 16, 16, 6, 77, + 23, 13, 65, 109, 99, 102, 78, 82, 80, 9, 71, + 71, 68, 2, 22, 10, 28, 67, 62, 60, 53, 47, 33, + 29, 2, 74, 93, 73, 41, 29, 20, 9, 10, 2, 64, + 68, 86, 97, 88, 80, 82, 76, 66, 73, 77, 66, 0, + 1, 1, 5, 9, 3, 60, 59, 54, 47, 42, 36, 22, 9, + 75 }, + + { + + 62, + 8, 76, 62, 8, 76, 107, 88, 15, 10, 8, 15, 46, + 49, 54, 14, 92, 3, 69, 6, 1, 6, 70, 2, 76, 14, + 44, 84, 101, 110, 95, 90, 67, 69, 6, 1, 81, + 83, 7, 12, 66, 76, 88, 4, 71, 82, 89, 5, 73, + 87, 6, 71, 78, 88, 1, 70, 71, 76, 67, 5, 22, + 0, 0, 0, 76, 88, 97, 67, 14, 64, 52, 8, 69, + 115, 93, 82, 69, 92, 108, 105, 110, 82, 108, + 99, 106, 111, 106, 111, 107, 9, 66, 73, 95, + 67, 87, 83, 106, 73, 92, 86, 113, 10, 78, 71, + 109, 88, 79, 74, 67, 3, 65, 75, 6, 3, 66, 4, + 64, 64, 2, 76, 13, 7, 22, 19, 18, 18, 17, 16, + 25, 12, 9, 25, 19, 71, 99, 89, 92, 82, 85, 81, + 73, 79, 78, 78, 80, 70, 72, 70, 71, 96, 89, + 95, 72, 73, 67, 68, 7, 3, 1, 65, 12, 2, 0, 65, + 1, 80, 47, 44, 33, 37, 44, 36, 20, 37, 30, 17, + 23, 16, 5, 1, 65, 17, 11, 14, 14, 11, 7, 14, + 8, 9, 9, 2, 1, 6, 89, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 54, 52, 51, 41, 36, 18, 49, 42, + 24, 54, 43, 45, 40, 35, 32, 35, 23, 15, 6, 8, + 74, 76, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, + 84, 0, 40, 27, 21, 17, 10, 1, 71, 72, 79, 83, + 19, 10, 6, 1, 64, 70, 75, 81, 98, 89, 70, 71, + 68, 71, 77, 87, 89, 103, 72, 34, 18, 12, 4, 1, + 72, 77, 81, 87, 62, 88, 79, 73, 66, 70, 1, 5, + 6, 71, 4, 8, 4, 78, 71, 70, 13, 6, 17, 14, 25, + 26, 19, 14, 19, 18, 15, 68, 6, 70, 95, 89, 85, + 83, 79, 80, 78, 79, 68, 74, 73, 71, 64, 75, + 82, 94, 85, 96, 76, 70, 70, 67, 68, 65, 0, 64, + 64, 67, 66, 1, 67, 78, 47, 40, 43, 41, 38, 44, + 40, 37, 32, 32, 33, 28, 10, 12, 5, 30, 28, 24, + 15, 19, 15, 4, 0, 67, 75, 79, 91, 75, 100, 62, + 62, 62, 62, 62, 58, 55, 51, 48, 44, 41, 35, + 28, 13, 66, 47, 46, 18, 49, 54, 43, 37, 40, + 35, 30, 34, 28, 26, 14, 14, 5, 79, 21, 11, 67, + 108, 98, 101, 77, 81, 79, 10, 70, 70, 68, 3, + 24, 11, 30, 66, 61, 59, 51, 44, 30, 27, 64, + 76, 95, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, + 96, 88, 79, 81, 75, 66, 72, 76, 66, 0, 1, 1, + 6, 9, 3, 59, 58, 52, 45, 41, 35, 19, 8, 76 }, + + { + + 62, + 8, 76, 62, 8, 76, 106, 86, 15, 10, 7, 13, 44, + 48, 54, 14, 90, 3, 68, 7, 1, 5, 70, 1, 77, 14, + 42, 86, 102, 110, 92, 89, 67, 68, 7, 1, 81, + 82, 7, 12, 66, 76, 87, 4, 72, 82, 89, 5, 73, + 86, 6, 72, 78, 88, 2, 70, 71, 76, 66, 5, 22, + 0, 0, 0, 76, 89, 97, 66, 13, 64, 52, 8, 69, + 114, 92, 82, 68, 91, 106, 103, 109, 81, 106, + 98, 104, 110, 106, 110, 106, 9, 66, 72, 94, + 67, 87, 82, 104, 73, 92, 85, 112, 10, 78, 70, + 108, 87, 78, 74, 67, 3, 65, 75, 7, 4, 67, 4, + 64, 64, 2, 76, 13, 6, 21, 19, 17, 18, 17, 16, + 23, 12, 8, 23, 18, 72, 98, 88, 91, 81, 85, 80, + 72, 78, 77, 77, 79, 70, 72, 70, 72, 96, 88, + 95, 72, 73, 66, 68, 6, 4, 1, 65, 11, 3, 0, 66, + 1, 81, 45, 43, 32, 36, 43, 35, 19, 36, 30, 15, + 22, 15, 5, 1, 66, 16, 10, 13, 13, 10, 6, 13, + 7, 7, 8, 1, 0, 5, 89, 62, 62, 61, 62, 62, 62, + 62, 62, 61, 52, 50, 48, 39, 34, 16, 47, 40, + 22, 52, 41, 43, 38, 33, 30, 32, 21, 12, 5, 6, + 75, 77, 98, 68, 26, 17, 12, 3, 5, 0, 70, 73, + 84, 0, 40, 27, 21, 17, 11, 1, 70, 72, 78, 83, + 20, 11, 6, 1, 64, 70, 74, 81, 97, 88, 69, 70, + 68, 71, 76, 86, 88, 102, 72, 34, 18, 12, 4, 2, + 71, 77, 80, 86, 62, 88, 79, 73, 66, 70, 1, 5, + 6, 71, 4, 8, 4, 78, 71, 70, 12, 7, 16, 13, 24, + 25, 19, 12, 18, 18, 15, 69, 5, 70, 95, 88, 84, + 82, 79, 79, 78, 78, 69, 74, 73, 71, 65, 75, + 82, 93, 84, 96, 76, 70, 70, 66, 68, 65, 1, 64, + 65, 67, 65, 0, 67, 79, 46, 40, 42, 40, 37, 43, + 39, 36, 31, 31, 32, 27, 9, 11, 4, 28, 27, 23, + 13, 18, 14, 3, 64, 68, 75, 79, 91, 75, 100, + 62, 62, 62, 62, 62, 56, 53, 48, 46, 42, 39, + 33, 26, 11, 67, 45, 44, 17, 47, 52, 41, 35, + 37, 33, 28, 32, 26, 23, 12, 12, 3, 80, 19, 9, + 68, 107, 97, 100, 76, 80, 78, 12, 69, 69, 68, + 4, 25, 13, 31, 65, 59, 57, 48, 41, 27, 24, 67, + 78, 96, 72, 41, 29, 20, 9, 10, 2, 64, 68, 85, + 95, 87, 78, 81, 74, 65, 72, 75, 65, 1, 2, 1, + 6, 9, 3, 58, 56, 50, 43, 39, 33, 17, 6, 77 }, + + { + + 62, + 8, 76, 62, 8, 76, 104, 85, 15, 10, 7, 12, 43, + 46, 54, 14, 87, 2, 67, 7, 1, 5, 69, 0, 78, 13, + 40, 88, 103, 111, 89, 87, 67, 67, 7, 1, 81, + 81, 7, 11, 66, 76, 87, 4, 72, 81, 89, 5, 73, + 85, 5, 72, 78, 88, 2, 69, 70, 75, 66, 5, 22, + 0, 0, 0, 75, 89, 97, 66, 12, 64, 52, 8, 69, + 113, 91, 82, 68, 89, 105, 101, 107, 80, 105, + 96, 102, 109, 105, 109, 106, 10, 66, 71, 93, + 67, 86, 81, 102, 73, 92, 85, 110, 11, 77, 70, + 107, 87, 78, 74, 66, 4, 64, 74, 7, 4, 67, 3, + 64, 64, 2, 76, 13, 6, 20, 19, 17, 18, 17, 15, + 21, 12, 8, 22, 17, 73, 97, 87, 90, 80, 84, 79, + 71, 77, 77, 76, 78, 70, 72, 69, 73, 95, 87, + 95, 71, 73, 66, 68, 5, 5, 1, 65, 9, 4, 64, 67, + 1, 81, 44, 42, 32, 35, 42, 34, 18, 36, 30, 14, + 21, 15, 5, 1, 66, 16, 10, 12, 13, 9, 5, 13, 6, + 5, 7, 0, 64, 4, 89, 61, 62, 59, 62, 61, 60, + 60, 60, 59, 50, 48, 46, 36, 32, 13, 45, 39, + 20, 49, 39, 41, 36, 30, 28, 29, 19, 10, 4, 5, + 77, 77, 98, 68, 26, 18, 12, 3, 5, 0, 70, 73, + 83, 1, 41, 27, 21, 17, 12, 2, 69, 72, 77, 82, + 21, 12, 6, 2, 0, 69, 74, 80, 96, 88, 67, 70, + 68, 70, 75, 85, 88, 101, 71, 35, 19, 12, 4, 3, + 70, 76, 79, 85, 62, 88, 79, 72, 66, 70, 1, 5, + 6, 70, 4, 9, 5, 78, 71, 70, 11, 7, 15, 12, 23, + 25, 19, 11, 17, 17, 15, 70, 4, 71, 94, 88, 83, + 82, 78, 79, 77, 77, 69, 74, 73, 71, 66, 75, + 82, 93, 83, 96, 76, 69, 70, 66, 68, 65, 2, 64, + 65, 67, 64, 0, 68, 79, 45, 40, 42, 40, 36, 42, + 38, 35, 31, 30, 31, 26, 8, 10, 3, 27, 25, 21, + 11, 17, 13, 2, 65, 68, 75, 78, 91, 76, 99, 62, + 62, 62, 62, 60, 54, 51, 46, 44, 40, 37, 31, + 24, 10, 68, 43, 42, 16, 45, 50, 39, 33, 35, + 31, 26, 30, 24, 21, 10, 10, 1, 81, 17, 7, 70, + 106, 95, 99, 76, 79, 77, 14, 68, 68, 68, 5, + 27, 14, 33, 65, 58, 55, 46, 38, 25, 21, 69, + 80, 97, 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, + 94, 86, 77, 80, 73, 64, 71, 74, 64, 2, 3, 2, + 7, 10, 3, 56, 55, 49, 42, 37, 31, 15, 4, 78 }, + + { + + 61, + 8, 76, 61, 8, 76, 102, 83, 16, 10, 6, 10, 41, + 45, 54, 14, 85, 2, 66, 8, 1, 4, 69, 64, 79, + 13, 38, 89, 104, 111, 86, 86, 67, 66, 8, 1, + 80, 80, 8, 11, 66, 75, 86, 3, 73, 81, 89, 5, + 73, 85, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, + 22, 0, 0, 0, 75, 89, 97, 65, 11, 64, 52, 8, + 69, 112, 90, 82, 67, 88, 103, 99, 106, 79, + 103, 95, 100, 108, 104, 108, 105, 11, 66, 70, + 92, 67, 86, 81, 100, 73, 91, 84, 109, 11, 77, + 69, 105, 86, 77, 74, 66, 4, 64, 73, 8, 5, 68, + 3, 64, 64, 2, 76, 13, 5, 20, 19, 16, 18, 17, + 15, 19, 12, 7, 20, 16, 74, 96, 86, 89, 79, 83, + 79, 70, 77, 76, 75, 77, 70, 72, 69, 74, 95, + 86, 95, 71, 73, 65, 68, 4, 6, 1, 65, 8, 5, 64, + 68, 1, 82, 42, 41, 31, 34, 41, 33, 18, 35, 29, + 13, 20, 15, 5, 1, 67, 15, 9, 11, 12, 8, 4, 12, + 6, 3, 6, 0, 65, 3, 89, 60, 61, 58, 62, 59, 58, + 58, 58, 56, 47, 46, 43, 34, 29, 11, 43, 37, + 19, 47, 37, 38, 33, 28, 25, 27, 17, 7, 3, 3, + 78, 78, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, + 83, 1, 41, 27, 21, 17, 13, 2, 69, 71, 77, 81, + 22, 12, 7, 2, 1, 69, 73, 80, 95, 87, 66, 69, + 67, 70, 74, 84, 87, 100, 71, 35, 19, 12, 4, 4, + 70, 75, 78, 84, 62, 87, 78, 72, 66, 70, 1, 5, + 6, 70, 4, 9, 5, 78, 71, 70, 11, 8, 14, 11, 22, + 24, 19, 10, 16, 17, 15, 70, 3, 71, 93, 87, 82, + 81, 78, 78, 77, 76, 69, 74, 73, 70, 66, 75, + 82, 92, 82, 96, 76, 69, 70, 65, 68, 65, 3, 64, + 65, 67, 0, 64, 68, 80, 44, 39, 41, 39, 35, 41, + 37, 34, 30, 29, 30, 25, 7, 9, 2, 25, 24, 20, + 9, 15, 12, 1, 65, 69, 75, 78, 91, 76, 98, 62, + 62, 61, 61, 57, 52, 49, 43, 42, 38, 35, 28, + 22, 8, 69, 41, 41, 14, 43, 48, 37, 31, 33, 29, + 24, 28, 22, 18, 8, 8, 64, 82, 15, 5, 71, 105, + 94, 98, 75, 78, 76, 15, 67, 67, 68, 6, 28, 16, + 34, 64, 56, 54, 43, 35, 22, 18, 72, 82, 98, + 72, 41, 29, 20, 9, 10, 2, 64, 68, 84, 93, 85, + 76, 79, 72, 64, 71, 73, 64, 2, 3, 2, 7, 10, 3, + 55, 53, 47, 40, 35, 29, 13, 2, 79 }, + + { + + 60, + 8, 76, 60, 8, 76, 100, 82, 16, 10, 6, 9, 40, + 44, 54, 14, 83, 2, 65, 9, 1, 3, 69, 65, 80, + 12, 36, 91, 105, 112, 83, 85, 67, 65, 9, 1, + 80, 79, 8, 10, 66, 75, 85, 3, 73, 81, 89, 5, + 73, 84, 5, 72, 78, 88, 3, 69, 70, 75, 65, 5, + 22, 0, 0, 0, 74, 89, 97, 65, 10, 64, 52, 8, + 69, 111, 89, 82, 67, 87, 101, 97, 104, 78, + 101, 94, 98, 107, 103, 107, 104, 12, 66, 69, + 91, 67, 85, 80, 98, 73, 91, 84, 108, 11, 77, + 69, 104, 86, 76, 74, 66, 4, 64, 72, 8, 5, 68, + 3, 64, 64, 2, 76, 13, 5, 19, 19, 15, 18, 17, + 15, 17, 12, 7, 18, 15, 75, 95, 85, 88, 78, 82, + 78, 69, 76, 76, 74, 76, 70, 72, 69, 75, 94, + 85, 95, 71, 73, 64, 68, 3, 7, 1, 65, 7, 6, 65, + 69, 1, 83, 41, 40, 31, 33, 40, 32, 17, 34, 29, + 12, 19, 15, 5, 1, 67, 14, 8, 10, 11, 7, 3, 11, + 5, 1, 5, 64, 66, 2, 89, 58, 60, 56, 60, 57, + 56, 56, 56, 54, 45, 44, 41, 31, 27, 8, 41, 35, + 17, 45, 35, 36, 31, 26, 23, 24, 15, 5, 2, 1, + 79, 79, 98, 68, 27, 18, 12, 3, 5, 0, 70, 73, + 82, 1, 41, 27, 21, 17, 14, 3, 68, 71, 76, 80, + 23, 13, 7, 2, 2, 68, 73, 79, 94, 86, 65, 68, + 67, 70, 73, 83, 86, 99, 70, 35, 19, 12, 4, 5, + 69, 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, + 6, 70, 4, 9, 6, 78, 71, 70, 10, 8, 13, 10, 21, + 23, 19, 9, 15, 17, 15, 71, 2, 72, 92, 86, 81, + 81, 77, 78, 76, 75, 69, 74, 73, 70, 67, 75, + 82, 92, 81, 96, 76, 69, 70, 64, 68, 65, 4, 64, + 65, 67, 1, 65, 68, 81, 43, 39, 41, 38, 34, 40, + 36, 33, 29, 28, 29, 24, 6, 8, 1, 24, 23, 18, + 7, 14, 11, 0, 66, 69, 75, 78, 91, 77, 97, 62, + 62, 59, 59, 54, 50, 47, 41, 40, 36, 33, 26, + 20, 7, 70, 39, 39, 13, 41, 46, 35, 29, 31, 27, + 22, 26, 20, 16, 6, 6, 66, 83, 13, 3, 73, 104, + 93, 97, 74, 77, 75, 17, 66, 66, 68, 7, 30, 17, + 36, 0, 55, 52, 41, 32, 19, 15, 75, 84, 99, 72, + 41, 29, 20, 9, 10, 2, 64, 68, 83, 92, 84, 75, + 78, 71, 0, 70, 72, 0, 3, 4, 2, 8, 10, 3, 54, + 52, 45, 38, 33, 27, 11, 0, 80 }, + + { + + 58, + 7, 77, 58, 7, 77, 99, 81, 16, 10, 5, 7, 38, + 42, 53, 14, 81, 1, 65, 9, 0, 2, 69, 67, 82, + 11, 34, 93, 106, 113, 81, 84, 68, 65, 9, 0, + 80, 78, 8, 9, 66, 75, 85, 2, 74, 81, 90, 5, + 73, 84, 4, 73, 78, 88, 3, 69, 70, 75, 65, 4, + 22, 0, 0, 0, 74, 90, 97, 65, 9, 65, 52, 7, 69, + 110, 89, 82, 67, 86, 100, 96, 103, 77, 100, + 93, 97, 106, 103, 106, 104, 12, 66, 69, 91, + 67, 85, 80, 97, 73, 91, 84, 107, 11, 77, 69, + 103, 86, 76, 74, 66, 4, 64, 72, 8, 5, 69, 2, + 64, 65, 2, 76, 12, 4, 18, 19, 14, 17, 17, 14, + 15, 11, 6, 16, 14, 76, 95, 85, 88, 78, 82, 78, + 68, 76, 76, 74, 75, 71, 72, 69, 77, 94, 85, + 95, 71, 74, 64, 68, 2, 7, 1, 65, 5, 6, 66, 70, + 1, 84, 39, 39, 30, 32, 39, 31, 16, 33, 28, 10, + 18, 14, 4, 1, 68, 13, 7, 9, 10, 6, 2, 10, 4, + 64, 3, 65, 68, 0, 89, 56, 58, 54, 58, 55, 53, + 53, 53, 51, 42, 41, 38, 28, 24, 5, 39, 33, 15, + 42, 32, 33, 28, 23, 20, 21, 12, 2, 1, 64, 81, + 80, 99, 68, 27, 18, 12, 3, 5, 64, 70, 73, 82, + 1, 41, 27, 21, 17, 15, 3, 68, 71, 76, 80, 23, + 13, 7, 2, 2, 68, 73, 79, 93, 86, 64, 68, 67, + 70, 73, 83, 86, 98, 70, 35, 19, 12, 4, 5, 69, + 74, 77, 83, 62, 87, 78, 71, 66, 70, 1, 5, 6, + 70, 4, 9, 6, 78, 71, 71, 9, 8, 12, 9, 20, 22, + 18, 7, 13, 16, 14, 72, 0, 73, 92, 86, 80, 81, + 77, 78, 76, 75, 70, 74, 73, 70, 68, 75, 82, + 92, 81, 97, 76, 69, 70, 64, 69, 65, 4, 65, 66, + 67, 1, 66, 69, 82, 42, 38, 40, 37, 32, 39, 35, + 32, 28, 27, 28, 23, 5, 6, 64, 22, 21, 16, 5, + 12, 9, 64, 67, 70, 75, 78, 91, 78, 97, 62, 61, + 57, 56, 51, 47, 44, 38, 37, 33, 30, 23, 17, 5, + 71, 37, 37, 11, 39, 43, 32, 26, 28, 24, 20, + 23, 17, 13, 4, 3, 68, 85, 11, 1, 75, 103, 92, + 96, 74, 77, 75, 18, 66, 66, 68, 7, 31, 18, 37, + 0, 53, 50, 38, 28, 16, 12, 78, 87, 101, 72, + 41, 28, 19, 9, 10, 2, 65, 68, 83, 92, 84, 75, + 78, 70, 0, 70, 72, 0, 3, 4, 2, 8, 10, 2, 52, + 50, 43, 36, 31, 25, 8, 65, 81 }, + + { + + 57, + 7, 77, 57, 7, 77, 97, 79, 17, 11, 5, 6, 37, + 41, 53, 14, 78, 1, 64, 10, 0, 2, 68, 68, 83, + 11, 33, 94, 107, 113, 78, 82, 68, 64, 10, 0, + 79, 76, 9, 9, 65, 74, 84, 2, 74, 80, 90, 5, + 72, 83, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, + 22, 0, 0, 0, 73, 90, 97, 64, 9, 65, 52, 7, 69, + 108, 88, 82, 66, 84, 98, 94, 101, 75, 98, 91, + 95, 104, 102, 105, 103, 13, 65, 68, 90, 66, + 84, 79, 95, 72, 90, 83, 105, 12, 76, 68, 101, + 85, 75, 73, 65, 5, 0, 71, 9, 6, 69, 2, 0, 65, + 2, 75, 12, 4, 18, 19, 14, 17, 17, 14, 14, 11, + 6, 15, 13, 76, 94, 84, 87, 77, 81, 77, 67, 75, + 75, 73, 73, 71, 72, 68, 78, 93, 84, 95, 70, + 74, 0, 67, 2, 8, 1, 65, 4, 7, 66, 71, 1, 84, + 38, 39, 30, 32, 39, 31, 16, 33, 28, 9, 18, 14, + 4, 1, 68, 13, 7, 9, 10, 6, 1, 10, 4, 65, 2, + 65, 69, 64, 89, 55, 57, 53, 57, 54, 51, 51, + 51, 49, 40, 39, 36, 26, 22, 3, 38, 32, 14, 40, + 30, 31, 26, 21, 18, 19, 10, 0, 1, 65, 82, 80, + 99, 67, 28, 19, 13, 4, 5, 64, 69, 72, 81, 2, + 42, 28, 22, 17, 16, 4, 67, 70, 75, 79, 24, 14, + 8, 3, 3, 67, 72, 78, 91, 85, 1, 67, 66, 69, + 72, 82, 85, 96, 69, 36, 20, 13, 5, 6, 68, 73, + 76, 82, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, + 5, 10, 7, 77, 71, 71, 9, 9, 12, 9, 19, 22, 18, + 6, 12, 16, 14, 72, 64, 73, 91, 85, 79, 80, 76, + 77, 75, 74, 70, 73, 72, 69, 68, 74, 81, 91, + 80, 97, 76, 68, 70, 0, 69, 65, 5, 65, 66, 66, + 2, 66, 69, 82, 42, 38, 40, 37, 31, 39, 35, 32, + 28, 27, 28, 23, 5, 5, 65, 21, 20, 15, 4, 11, + 8, 64, 67, 70, 74, 77, 90, 78, 96, 60, 59, 55, + 54, 49, 45, 42, 36, 35, 31, 28, 21, 15, 4, 71, + 36, 36, 10, 38, 41, 30, 24, 26, 22, 18, 21, + 15, 11, 3, 1, 69, 86, 10, 0, 76, 101, 90, 94, + 73, 76, 74, 20, 65, 65, 68, 8, 33, 20, 39, 1, + 52, 49, 36, 25, 14, 10, 80, 89, 102, 71, 42, + 28, 19, 9, 11, 2, 65, 68, 82, 91, 83, 74, 77, + 68, 1, 69, 71, 1, 4, 5, 3, 9, 11, 2, 51, 49, + 42, 35, 30, 24, 6, 66, 81 }, + + { + + 56, + 7, 77, 56, 7, 77, 95, 78, 17, 11, 5, 5, 36, + 40, 53, 14, 76, 1, 0, 11, 0, 1, 68, 69, 84, + 10, 31, 96, 108, 114, 75, 81, 68, 0, 11, 0, + 79, 75, 9, 8, 65, 74, 83, 2, 74, 80, 90, 5, + 72, 82, 4, 73, 77, 88, 4, 68, 69, 74, 64, 4, + 22, 0, 0, 0, 72, 90, 97, 64, 8, 65, 52, 7, 69, + 107, 87, 82, 66, 83, 96, 92, 100, 74, 96, 90, + 93, 103, 101, 104, 102, 14, 65, 67, 89, 66, + 84, 78, 93, 72, 90, 83, 104, 12, 76, 68, 100, + 85, 74, 73, 65, 5, 0, 70, 9, 6, 70, 2, 0, 65, + 2, 75, 12, 4, 17, 19, 13, 17, 17, 14, 12, 11, + 6, 13, 12, 77, 93, 83, 86, 76, 80, 76, 66, 74, + 75, 72, 72, 71, 72, 68, 79, 93, 83, 95, 70, + 74, 1, 67, 1, 9, 1, 65, 3, 8, 67, 72, 1, 85, + 36, 38, 29, 31, 38, 30, 15, 32, 28, 8, 17, 14, + 4, 1, 68, 12, 6, 8, 9, 5, 0, 9, 3, 67, 1, 66, + 70, 65, 89, 53, 56, 51, 55, 52, 49, 49, 49, + 46, 38, 37, 33, 23, 20, 0, 36, 30, 12, 38, 28, + 29, 24, 19, 16, 16, 8, 65, 0, 67, 83, 81, 99, + 67, 28, 19, 13, 4, 5, 64, 69, 72, 80, 2, 42, + 28, 22, 17, 17, 4, 66, 70, 74, 78, 25, 15, 8, + 3, 4, 67, 72, 77, 90, 84, 2, 66, 66, 69, 71, + 81, 84, 95, 69, 36, 20, 13, 5, 7, 67, 72, 75, + 81, 62, 86, 77, 70, 66, 69, 1, 6, 7, 69, 5, + 10, 8, 77, 71, 71, 8, 9, 11, 8, 18, 21, 18, 5, + 11, 16, 14, 73, 65, 74, 90, 84, 78, 80, 76, + 77, 74, 73, 70, 73, 72, 69, 69, 74, 81, 91, + 79, 97, 76, 68, 70, 1, 69, 65, 6, 65, 66, 66, + 3, 67, 69, 83, 41, 38, 40, 36, 30, 38, 34, 31, + 27, 26, 27, 22, 4, 4, 66, 19, 19, 13, 2, 10, + 7, 65, 68, 70, 74, 77, 90, 79, 95, 58, 57, 53, + 52, 46, 43, 40, 33, 33, 29, 26, 19, 13, 3, 72, + 34, 34, 9, 36, 39, 28, 22, 24, 20, 16, 19, 13, + 9, 1, 64, 71, 87, 8, 65, 78, 100, 89, 93, 72, + 75, 73, 22, 64, 64, 68, 9, 34, 21, 40, 2, 51, + 47, 33, 22, 11, 7, 83, 91, 103, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 81, 90, 82, 73, 76, 67, + 2, 68, 70, 2, 5, 6, 3, 10, 11, 2, 50, 47, 40, + 33, 28, 22, 4, 68, 82 }, + + { + + 55, + 7, 77, 55, 7, 77, 93, 76, 18, 11, 4, 3, 34, + 39, 53, 14, 74, 1, 1, 12, 0, 0, 68, 70, 85, + 10, 29, 97, 109, 114, 72, 80, 68, 1, 12, 0, + 78, 74, 10, 8, 65, 73, 82, 1, 75, 80, 90, 5, + 72, 82, 4, 73, 77, 88, 5, 68, 69, 74, 0, 4, + 22, 0, 0, 0, 72, 90, 97, 0, 7, 65, 52, 7, 69, + 106, 86, 82, 65, 82, 94, 90, 98, 73, 94, 89, + 91, 102, 100, 103, 101, 15, 65, 66, 88, 66, + 83, 78, 91, 72, 89, 82, 103, 12, 76, 67, 98, + 84, 73, 73, 65, 5, 0, 69, 10, 7, 70, 2, 0, 65, + 2, 75, 12, 3, 17, 19, 12, 17, 17, 14, 10, 11, + 5, 11, 11, 78, 92, 82, 85, 75, 79, 76, 65, 74, + 74, 71, 71, 71, 72, 68, 80, 92, 82, 95, 70, + 74, 2, 67, 0, 10, 1, 65, 2, 9, 67, 73, 1, 86, + 35, 37, 29, 30, 37, 29, 15, 31, 27, 7, 16, 14, + 4, 1, 69, 11, 5, 7, 8, 4, 64, 8, 3, 69, 0, 66, + 71, 66, 89, 52, 54, 50, 53, 50, 47, 47, 47, + 44, 35, 35, 31, 21, 17, 65, 34, 28, 11, 36, + 26, 26, 21, 17, 13, 14, 6, 68, 64, 69, 84, 82, + 99, 67, 29, 19, 13, 4, 5, 64, 69, 72, 80, 2, + 42, 28, 22, 17, 18, 5, 66, 69, 74, 77, 26, 15, + 9, 3, 5, 66, 71, 77, 89, 83, 3, 65, 65, 69, + 70, 80, 83, 94, 68, 36, 20, 13, 5, 8, 67, 71, + 74, 80, 62, 85, 76, 69, 66, 69, 1, 6, 7, 69, + 5, 10, 8, 77, 71, 71, 8, 10, 10, 7, 17, 20, + 18, 4, 10, 16, 14, 73, 66, 74, 89, 83, 77, 79, + 75, 76, 74, 72, 70, 73, 72, 68, 69, 74, 81, + 90, 78, 97, 76, 68, 70, 2, 69, 65, 7, 65, 66, + 66, 4, 68, 69, 84, 40, 37, 39, 35, 29, 37, 33, + 30, 26, 25, 26, 21, 3, 3, 67, 18, 18, 12, 0, + 8, 6, 66, 68, 71, 74, 77, 90, 79, 94, 56, 55, + 51, 50, 43, 41, 38, 31, 31, 27, 24, 16, 11, 1, + 73, 32, 33, 7, 34, 37, 26, 20, 22, 18, 14, 17, + 11, 6, 64, 66, 73, 88, 6, 67, 79, 99, 88, 92, + 71, 74, 72, 23, 0, 0, 68, 10, 36, 23, 42, 3, + 49, 46, 31, 19, 8, 4, 86, 93, 104, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 81, 89, 81, 72, 75, 66, + 2, 68, 69, 2, 5, 6, 3, 10, 11, 2, 49, 46, 38, + 31, 26, 20, 2, 70, 83 }, + + { + + 53, + 7, 77, 53, 7, 77, 92, 75, 18, 11, 4, 2, 33, + 37, 53, 14, 71, 0, 2, 12, 0, 64, 68, 71, 86, + 9, 27, 99, 110, 115, 69, 79, 68, 2, 12, 0, 78, + 73, 10, 7, 65, 73, 82, 1, 75, 79, 90, 5, 72, + 81, 3, 74, 77, 88, 5, 67, 69, 73, 0, 4, 22, 0, + 0, 0, 71, 91, 97, 0, 6, 65, 52, 7, 69, 105, + 85, 82, 65, 80, 93, 88, 97, 72, 93, 87, 89, + 101, 100, 102, 101, 15, 65, 65, 87, 66, 83, + 77, 89, 72, 89, 82, 102, 12, 75, 67, 97, 84, + 73, 73, 64, 5, 0, 69, 10, 7, 71, 1, 0, 65, 2, + 75, 12, 3, 16, 19, 12, 17, 17, 13, 8, 11, 5, + 9, 10, 79, 91, 81, 84, 74, 79, 75, 64, 73, 74, + 70, 70, 71, 72, 67, 81, 92, 81, 95, 70, 74, 2, + 67, 64, 11, 1, 65, 0, 10, 68, 74, 1, 87, 33, + 36, 28, 29, 36, 28, 14, 30, 27, 5, 15, 13, 4, + 1, 69, 10, 5, 6, 8, 3, 65, 7, 2, 71, 64, 67, + 72, 67, 89, 50, 53, 48, 51, 48, 45, 44, 45, + 41, 33, 33, 28, 18, 15, 68, 32, 27, 9, 33, 24, + 24, 19, 14, 11, 11, 4, 70, 65, 70, 86, 83, 99, + 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, + 28, 22, 17, 19, 5, 65, 69, 73, 77, 27, 16, 9, + 3, 5, 66, 71, 76, 88, 83, 4, 65, 65, 69, 69, + 79, 83, 93, 68, 37, 20, 13, 5, 9, 66, 71, 73, + 79, 62, 85, 76, 69, 66, 69, 1, 6, 7, 68, 5, + 10, 9, 77, 71, 71, 7, 10, 9, 6, 16, 19, 18, 2, + 9, 15, 14, 74, 67, 75, 89, 83, 76, 79, 75, 76, + 73, 71, 71, 73, 72, 68, 70, 74, 81, 90, 77, + 97, 76, 67, 70, 2, 69, 65, 8, 65, 67, 66, 5, + 68, 70, 85, 39, 37, 39, 34, 28, 36, 32, 29, + 25, 24, 25, 20, 2, 2, 68, 16, 16, 10, 65, 7, + 5, 67, 69, 71, 74, 77, 90, 80, 94, 53, 52, 49, + 47, 40, 39, 36, 28, 29, 25, 22, 14, 9, 0, 74, + 30, 31, 6, 32, 35, 24, 18, 19, 16, 12, 15, 9, + 4, 66, 68, 75, 89, 4, 69, 81, 98, 87, 91, 71, + 73, 71, 25, 1, 1, 68, 11, 37, 24, 43, 3, 48, + 44, 28, 16, 5, 1, 89, 95, 105, 71, 42, 28, 19, + 9, 11, 2, 65, 68, 80, 88, 80, 71, 75, 65, 3, + 67, 68, 3, 6, 7, 4, 11, 12, 2, 47, 44, 36, 29, + 24, 18, 0, 72, 84 }, + + { + + 52, + 7, 77, 52, 7, 77, 90, 73, 18, 11, 3, 0, 31, + 36, 53, 14, 69, 0, 3, 13, 0, 64, 67, 72, 87, + 9, 25, 101, 111, 115, 66, 77, 68, 3, 13, 0, + 78, 72, 10, 7, 65, 73, 81, 1, 76, 79, 90, 5, + 72, 80, 3, 74, 77, 88, 6, 67, 68, 73, 1, 4, + 22, 0, 0, 0, 71, 91, 97, 1, 5, 65, 52, 7, 69, + 104, 84, 82, 64, 79, 91, 86, 95, 71, 91, 86, + 87, 100, 99, 101, 100, 16, 65, 64, 86, 66, 82, + 76, 87, 72, 89, 81, 100, 13, 75, 66, 96, 83, + 72, 73, 64, 6, 1, 68, 11, 8, 71, 1, 0, 65, 2, + 75, 12, 2, 15, 19, 11, 17, 17, 13, 6, 11, 4, + 8, 9, 80, 90, 80, 83, 73, 78, 74, 0, 72, 73, + 69, 69, 71, 72, 67, 82, 91, 80, 95, 69, 74, 3, + 67, 65, 12, 1, 65, 64, 11, 68, 75, 1, 87, 32, + 35, 28, 28, 35, 27, 13, 30, 27, 4, 14, 13, 4, + 1, 70, 10, 4, 5, 7, 2, 66, 7, 1, 73, 65, 68, + 73, 68, 89, 48, 52, 46, 49, 47, 43, 42, 43, + 39, 31, 31, 26, 16, 13, 70, 30, 25, 7, 31, 22, + 22, 17, 12, 9, 8, 2, 73, 66, 72, 87, 83, 99, + 67, 29, 20, 13, 4, 5, 64, 69, 72, 79, 3, 43, + 28, 22, 17, 20, 6, 64, 69, 72, 76, 28, 17, 9, + 4, 6, 65, 70, 76, 87, 82, 6, 64, 65, 68, 68, + 78, 82, 92, 67, 37, 21, 13, 5, 10, 65, 70, 72, + 78, 62, 85, 76, 68, 66, 69, 1, 6, 7, 68, 5, + 11, 9, 77, 71, 71, 6, 11, 8, 5, 15, 19, 18, 1, + 8, 15, 14, 75, 68, 75, 88, 82, 75, 78, 74, 75, + 73, 70, 71, 73, 72, 68, 71, 74, 81, 89, 76, + 97, 76, 67, 70, 3, 69, 65, 9, 65, 67, 66, 6, + 69, 70, 85, 38, 37, 38, 34, 27, 35, 31, 28, + 25, 23, 24, 19, 1, 1, 69, 15, 15, 9, 67, 6, 4, + 68, 70, 72, 74, 76, 90, 80, 93, 51, 50, 47, + 45, 38, 37, 34, 26, 27, 23, 20, 12, 7, 65, 75, + 28, 29, 5, 30, 33, 22, 16, 17, 14, 10, 13, 7, + 1, 68, 70, 77, 90, 2, 71, 82, 97, 85, 90, 70, + 72, 70, 27, 2, 2, 68, 12, 39, 26, 45, 4, 46, + 42, 26, 13, 3, 65, 91, 97, 106, 71, 42, 28, + 19, 9, 11, 2, 65, 68, 80, 87, 79, 70, 74, 64, + 4, 67, 67, 4, 7, 8, 4, 11, 12, 2, 46, 43, 35, + 28, 22, 16, 65, 74, 85 }, + + { + + 51, + 7, 78, 51, 7, 78, 88, 72, 19, 11, 3, 64, 30, + 35, 53, 14, 67, 0, 3, 14, 0, 65, 67, 73, 88, + 8, 24, 102, 112, 116, 0, 76, 68, 3, 14, 0, 77, + 71, 11, 6, 64, 72, 80, 0, 76, 79, 90, 5, 71, + 80, 3, 74, 76, 88, 6, 67, 68, 73, 1, 4, 22, 0, + 0, 0, 70, 91, 97, 1, 5, 66, 52, 7, 69, 103, + 84, 82, 64, 78, 89, 84, 94, 70, 89, 85, 85, + 99, 98, 100, 99, 17, 65, 0, 86, 65, 82, 76, + 85, 72, 88, 81, 99, 13, 75, 66, 94, 83, 71, + 72, 64, 6, 1, 67, 11, 8, 72, 1, 0, 65, 2, 75, + 12, 2, 15, 19, 10, 17, 17, 13, 4, 11, 4, 6, 8, + 81, 90, 79, 83, 73, 77, 74, 1, 72, 73, 69, 67, + 71, 72, 67, 83, 91, 79, 95, 69, 74, 4, 66, 66, + 12, 1, 65, 65, 12, 69, 76, 1, 88, 30, 34, 27, + 28, 34, 27, 13, 29, 26, 3, 13, 13, 4, 1, 70, + 9, 3, 4, 6, 2, 67, 6, 1, 75, 66, 68, 74, 69, + 89, 47, 50, 45, 47, 45, 41, 40, 41, 36, 28, + 29, 23, 13, 10, 73, 28, 23, 6, 29, 19, 19, 14, + 10, 6, 6, 64, 75, 67, 74, 88, 84, 99, 66, 30, + 20, 14, 4, 5, 64, 69, 72, 78, 3, 43, 29, 22, + 17, 21, 6, 64, 68, 72, 75, 29, 17, 10, 4, 7, + 65, 70, 75, 86, 81, 7, 0, 64, 68, 68, 78, 81, + 90, 67, 37, 21, 13, 6, 10, 65, 69, 72, 77, 62, + 84, 75, 68, 66, 69, 1, 6, 7, 68, 6, 11, 10, + 77, 71, 72, 6, 11, 7, 4, 14, 18, 18, 0, 7, 15, + 14, 75, 69, 76, 87, 81, 74, 78, 74, 75, 72, + 70, 71, 72, 71, 67, 71, 74, 81, 89, 75, 97, + 76, 67, 70, 4, 69, 65, 10, 66, 67, 66, 6, 70, + 70, 86, 37, 36, 38, 33, 26, 35, 31, 27, 24, + 23, 23, 18, 0, 0, 70, 13, 14, 7, 69, 4, 2, 69, + 70, 72, 74, 76, 89, 81, 92, 49, 48, 45, 43, + 35, 35, 32, 23, 25, 20, 18, 9, 5, 66, 75, 27, + 28, 3, 28, 30, 20, 14, 15, 12, 8, 10, 5, 64, + 70, 72, 78, 92, 0, 73, 84, 96, 84, 89, 69, 71, + 69, 28, 3, 3, 68, 13, 40, 27, 46, 5, 45, 41, + 23, 10, 0, 67, 94, 99, 108, 70, 42, 28, 19, 9, + 11, 2, 65, 68, 79, 86, 79, 69, 73, 0, 4, 66, + 66, 4, 7, 8, 4, 12, 12, 2, 45, 41, 33, 26, 21, + 15, 68, 75, 86 }, + + { + + 50, + 7, 78, 50, 7, 78, 86, 70, 19, 11, 2, 66, 28, + 33, 53, 14, 64, 64, 4, 14, 0, 66, 67, 74, 89, + 8, 22, 104, 113, 116, 3, 75, 68, 4, 14, 0, 77, + 70, 11, 6, 64, 72, 80, 0, 77, 78, 90, 5, 71, + 79, 2, 74, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, + 0, 0, 70, 91, 97, 2, 4, 66, 52, 7, 69, 102, + 83, 82, 0, 76, 88, 82, 92, 69, 88, 83, 83, 98, + 97, 99, 99, 18, 65, 1, 85, 65, 81, 75, 83, 72, + 88, 80, 98, 13, 74, 65, 93, 82, 71, 72, 0, 6, + 1, 66, 12, 9, 72, 0, 0, 65, 2, 75, 12, 1, 14, + 19, 10, 17, 17, 12, 2, 11, 3, 4, 7, 82, 89, + 78, 82, 72, 76, 73, 2, 71, 72, 68, 66, 71, 72, + 66, 84, 90, 78, 95, 69, 74, 4, 66, 67, 13, 1, + 65, 67, 13, 69, 77, 1, 89, 29, 33, 27, 27, 33, + 26, 12, 28, 26, 2, 12, 13, 4, 1, 71, 8, 3, 3, + 6, 1, 68, 5, 0, 77, 67, 69, 75, 70, 89, 45, + 49, 43, 45, 43, 39, 37, 39, 34, 26, 27, 21, + 11, 8, 75, 26, 22, 4, 26, 17, 17, 12, 7, 4, 3, + 66, 78, 68, 75, 90, 85, 99, 66, 30, 21, 14, 4, + 5, 64, 69, 72, 78, 4, 44, 29, 22, 17, 22, 7, + 0, 68, 71, 74, 30, 18, 10, 4, 8, 64, 69, 75, + 85, 81, 8, 0, 64, 68, 67, 77, 81, 89, 66, 38, + 21, 13, 6, 11, 64, 68, 71, 76, 62, 84, 75, 67, + 66, 69, 1, 6, 7, 67, 6, 11, 10, 77, 71, 72, 5, + 12, 6, 3, 13, 17, 18, 64, 6, 14, 14, 76, 70, + 76, 86, 81, 73, 77, 73, 74, 72, 69, 71, 72, + 71, 67, 72, 74, 81, 88, 74, 97, 76, 66, 70, 4, + 69, 65, 11, 66, 67, 66, 7, 70, 71, 87, 36, 36, + 37, 32, 25, 34, 30, 26, 23, 22, 22, 17, 64, + 64, 71, 12, 12, 6, 71, 3, 1, 70, 71, 73, 74, + 76, 89, 81, 91, 47, 46, 43, 40, 32, 33, 30, + 21, 23, 18, 16, 7, 3, 68, 76, 25, 26, 2, 26, + 28, 18, 12, 13, 10, 6, 8, 3, 67, 72, 74, 80, + 93, 65, 75, 85, 95, 83, 88, 69, 70, 68, 30, 4, + 4, 68, 14, 42, 29, 48, 5, 43, 39, 21, 7, 66, + 70, 97, 101, 109, 70, 42, 28, 19, 9, 11, 2, + 65, 68, 79, 85, 78, 68, 72, 1, 5, 66, 65, 5, + 8, 9, 5, 12, 13, 2, 43, 40, 31, 24, 19, 13, + 70, 77, 87 }, + + { + + 48, + 6, 78, 48, 6, 78, 85, 69, 19, 11, 2, 67, 27, + 32, 53, 14, 1, 64, 5, 15, 0, 67, 67, 75, 91, + 7, 20, 106, 114, 117, 5, 74, 68, 5, 15, 0, 77, + 69, 11, 5, 64, 72, 79, 64, 77, 78, 91, 5, 71, + 79, 2, 75, 76, 88, 7, 66, 68, 72, 2, 4, 22, 0, + 0, 0, 69, 92, 97, 2, 3, 66, 52, 7, 69, 101, + 82, 82, 0, 75, 86, 80, 91, 68, 86, 82, 82, 97, + 97, 98, 98, 18, 65, 2, 84, 65, 81, 75, 82, 72, + 88, 80, 97, 13, 74, 65, 92, 82, 70, 72, 0, 6, + 1, 66, 12, 9, 73, 0, 0, 65, 2, 75, 12, 1, 13, + 19, 9, 17, 17, 12, 0, 11, 3, 2, 6, 83, 88, 77, + 81, 71, 76, 73, 3, 71, 72, 67, 65, 71, 72, 66, + 86, 90, 77, 95, 69, 75, 5, 66, 68, 14, 1, 65, + 68, 14, 70, 78, 1, 90, 27, 32, 26, 26, 32, 25, + 11, 27, 25, 0, 11, 12, 4, 1, 71, 7, 2, 2, 5, + 0, 69, 4, 64, 79, 69, 70, 76, 71, 89, 43, 47, + 41, 43, 41, 37, 35, 37, 31, 23, 25, 18, 8, 5, + 78, 24, 20, 2, 24, 15, 14, 9, 5, 1, 0, 68, 80, + 69, 77, 91, 86, 100, 66, 30, 21, 14, 4, 5, 64, + 69, 72, 77, 4, 44, 29, 22, 17, 23, 7, 0, 68, + 71, 74, 31, 18, 10, 4, 8, 64, 69, 74, 84, 80, + 9, 1, 64, 68, 66, 76, 80, 88, 66, 38, 21, 13, + 6, 12, 64, 68, 70, 76, 62, 84, 75, 67, 66, 69, + 1, 6, 7, 67, 6, 11, 11, 77, 71, 72, 4, 12, 5, + 2, 12, 16, 18, 66, 4, 14, 14, 77, 71, 77, 86, + 80, 72, 77, 73, 74, 71, 68, 72, 72, 71, 67, + 73, 74, 81, 88, 74, 98, 76, 66, 70, 5, 69, 65, + 11, 66, 68, 66, 8, 71, 71, 88, 35, 35, 37, 31, + 23, 33, 29, 25, 22, 21, 21, 16, 65, 65, 72, + 10, 11, 4, 73, 1, 0, 71, 72, 73, 74, 76, 89, + 82, 91, 44, 43, 41, 38, 29, 30, 27, 18, 21, + 16, 14, 4, 1, 69, 77, 23, 24, 0, 24, 26, 15, + 9, 10, 7, 4, 6, 0, 69, 74, 77, 82, 94, 67, 77, + 87, 94, 82, 87, 68, 69, 68, 31, 5, 4, 68, 14, + 43, 30, 49, 6, 42, 37, 18, 4, 69, 73, 100, + 103, 110, 70, 42, 28, 19, 9, 11, 2, 65, 68, + 78, 85, 77, 67, 72, 2, 5, 65, 65, 5, 8, 9, 5, + 13, 13, 1, 42, 38, 29, 22, 17, 11, 72, 79, 88 }, + + { + + 47, + 6, 78, 47, 6, 78, 83, 68, 20, 11, 2, 68, 26, + 31, 53, 14, 3, 64, 6, 16, 0, 67, 66, 76, 92, + 6, 18, 107, 115, 118, 8, 72, 68, 6, 16, 0, 76, + 68, 12, 4, 64, 71, 78, 64, 77, 78, 91, 5, 71, + 78, 2, 75, 76, 88, 7, 66, 67, 72, 2, 4, 22, 0, + 0, 0, 68, 92, 97, 2, 2, 66, 52, 7, 69, 100, + 81, 82, 0, 74, 84, 78, 89, 66, 84, 81, 80, 96, + 96, 97, 97, 19, 64, 3, 83, 65, 80, 74, 80, 72, + 87, 80, 95, 14, 74, 65, 90, 82, 69, 72, 0, 7, + 2, 65, 12, 9, 73, 0, 1, 65, 2, 74, 12, 1, 13, + 19, 8, 17, 17, 12, 65, 11, 3, 1, 5, 83, 87, + 76, 80, 70, 75, 72, 4, 70, 72, 66, 64, 71, 72, + 66, 87, 89, 76, 95, 68, 75, 6, 66, 69, 15, 1, + 65, 69, 15, 71, 79, 1, 90, 26, 31, 26, 25, 31, + 24, 11, 27, 25, 64, 10, 12, 4, 1, 71, 7, 1, 1, + 4, 64, 70, 4, 64, 80, 70, 70, 77, 72, 89, 42, + 46, 40, 42, 40, 35, 33, 35, 29, 21, 23, 16, 5, + 3, 81, 23, 18, 1, 22, 13, 12, 7, 3, 64, 65, + 70, 82, 69, 79, 92, 86, 100, 66, 31, 21, 14, + 5, 5, 64, 68, 72, 76, 4, 44, 29, 23, 17, 24, + 8, 1, 67, 70, 73, 32, 19, 11, 5, 9, 0, 69, 73, + 83, 79, 11, 2, 0, 67, 65, 75, 79, 87, 65, 38, + 22, 14, 6, 13, 0, 67, 69, 75, 62, 83, 74, 66, + 66, 69, 1, 7, 8, 67, 6, 12, 12, 77, 71, 72, 4, + 12, 4, 2, 11, 16, 18, 67, 3, 14, 14, 77, 72, + 78, 85, 79, 71, 77, 72, 74, 70, 67, 72, 72, + 71, 66, 73, 74, 81, 88, 73, 98, 76, 66, 70, 6, + 69, 65, 12, 66, 68, 66, 9, 72, 71, 88, 34, 35, + 37, 31, 22, 32, 28, 24, 22, 20, 20, 16, 65, + 66, 73, 9, 10, 2, 75, 0, 64, 71, 72, 73, 73, + 75, 89, 83, 90, 42, 41, 39, 36, 27, 28, 25, + 16, 19, 14, 12, 2, 64, 70, 78, 21, 23, 64, 22, + 24, 13, 7, 8, 5, 2, 4, 65, 71, 75, 79, 84, 95, + 69, 79, 89, 93, 80, 85, 67, 68, 67, 33, 6, 5, + 68, 15, 45, 31, 51, 7, 41, 36, 16, 1, 71, 76, + 102, 105, 111, 70, 42, 28, 19, 9, 12, 2, 65, + 68, 77, 84, 76, 66, 71, 4, 6, 64, 64, 6, 9, + 10, 5, 14, 13, 1, 41, 37, 28, 21, 15, 9, 74, + 81, 88 }, + + { + + 46, + 6, 78, 46, 6, 78, 81, 66, 20, 11, 1, 70, 24, + 29, 53, 14, 6, 65, 7, 16, 0, 68, 66, 77, 93, + 6, 16, 109, 116, 118, 11, 71, 68, 7, 16, 0, + 76, 67, 12, 4, 64, 71, 78, 64, 78, 77, 91, 5, + 71, 77, 1, 75, 76, 88, 8, 65, 67, 71, 3, 4, + 22, 0, 0, 0, 68, 92, 97, 3, 1, 66, 52, 7, 69, + 99, 80, 82, 1, 72, 83, 76, 88, 65, 83, 79, 78, + 95, 95, 96, 97, 20, 64, 4, 82, 65, 80, 73, 78, + 72, 87, 79, 94, 14, 73, 64, 89, 81, 69, 72, 1, + 7, 2, 64, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, + 12, 19, 8, 17, 17, 11, 67, 11, 2, 64, 4, 84, + 86, 75, 79, 69, 74, 71, 5, 69, 71, 65, 0, 71, + 72, 65, 88, 89, 75, 95, 68, 75, 6, 66, 70, 16, + 1, 65, 71, 16, 71, 80, 1, 91, 24, 30, 25, 24, + 30, 23, 10, 26, 25, 65, 9, 12, 4, 1, 72, 6, 1, + 0, 4, 65, 71, 3, 65, 82, 71, 71, 78, 73, 89, + 40, 45, 38, 40, 38, 33, 30, 33, 26, 19, 21, + 13, 3, 1, 83, 21, 17, 64, 19, 11, 10, 5, 0, + 66, 68, 72, 85, 70, 80, 94, 87, 100, 66, 31, + 22, 14, 5, 5, 64, 68, 72, 76, 5, 45, 29, 23, + 17, 25, 8, 2, 67, 69, 72, 33, 20, 11, 5, 10, + 0, 68, 73, 82, 79, 12, 2, 0, 67, 64, 74, 79, + 86, 65, 39, 22, 14, 6, 14, 1, 66, 68, 74, 62, + 83, 74, 66, 66, 69, 1, 7, 8, 66, 6, 12, 12, + 77, 71, 72, 3, 13, 3, 1, 10, 15, 18, 68, 2, + 13, 14, 78, 73, 78, 84, 79, 70, 76, 72, 73, + 70, 66, 72, 72, 71, 66, 74, 74, 81, 87, 72, + 98, 76, 65, 70, 6, 69, 65, 13, 66, 68, 66, 10, + 72, 72, 89, 33, 35, 36, 30, 21, 31, 27, 23, + 21, 19, 19, 15, 66, 67, 74, 7, 8, 1, 77, 64, + 65, 72, 73, 74, 73, 75, 89, 83, 89, 40, 39, + 37, 33, 24, 26, 23, 13, 17, 12, 10, 0, 66, 72, + 79, 19, 21, 65, 20, 22, 11, 5, 6, 3, 0, 2, 67, + 74, 77, 81, 86, 96, 71, 81, 90, 92, 79, 84, + 67, 67, 66, 35, 7, 6, 68, 16, 46, 33, 52, 7, + 39, 34, 13, 65, 74, 79, 105, 107, 112, 70, 42, + 28, 19, 9, 12, 2, 65, 68, 77, 83, 75, 65, 70, + 5, 7, 64, 0, 7, 10, 11, 6, 14, 14, 1, 39, 35, + 26, 19, 13, 7, 76, 83, 89 }, + + { + + 45, + 6, 79, 45, 6, 79, 79, 65, 21, 11, 1, 71, 23, + 28, 53, 14, 8, 65, 7, 17, 0, 69, 66, 78, 94, + 5, 15, 110, 117, 119, 14, 70, 68, 7, 17, 0, + 75, 66, 13, 3, 0, 70, 77, 65, 78, 77, 91, 5, + 70, 77, 1, 75, 75, 88, 8, 65, 67, 71, 3, 4, + 22, 0, 0, 0, 67, 92, 97, 3, 1, 67, 52, 7, 69, + 98, 80, 82, 1, 71, 81, 74, 86, 64, 81, 78, 76, + 94, 94, 95, 96, 21, 64, 5, 82, 64, 79, 73, 76, + 72, 86, 79, 93, 14, 73, 64, 87, 81, 68, 71, 1, + 7, 2, 0, 13, 10, 74, 64, 1, 65, 2, 74, 12, 0, + 12, 19, 7, 17, 17, 11, 69, 11, 2, 66, 3, 85, + 86, 74, 79, 69, 73, 71, 6, 69, 71, 65, 2, 71, + 72, 65, 89, 88, 74, 95, 68, 75, 7, 65, 71, 16, + 1, 65, 72, 17, 72, 81, 1, 92, 23, 29, 25, 24, + 29, 23, 10, 25, 24, 66, 8, 12, 4, 1, 72, 5, 0, + 64, 3, 65, 72, 2, 65, 84, 72, 71, 79, 74, 89, + 39, 43, 37, 38, 36, 31, 28, 31, 24, 16, 19, + 11, 0, 65, 86, 19, 15, 65, 17, 8, 7, 2, 65, + 69, 70, 75, 87, 71, 82, 95, 88, 100, 65, 32, + 22, 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, + 17, 26, 9, 2, 66, 69, 71, 34, 20, 12, 5, 11, + 1, 68, 72, 81, 78, 13, 3, 1, 67, 64, 74, 78, + 84, 64, 39, 22, 14, 7, 14, 1, 65, 68, 73, 62, + 82, 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, + 77, 71, 73, 3, 13, 2, 0, 9, 14, 18, 69, 1, 13, + 14, 78, 74, 79, 83, 78, 69, 76, 71, 73, 69, + 66, 72, 71, 70, 65, 74, 74, 81, 87, 71, 98, + 76, 65, 70, 7, 69, 65, 14, 67, 68, 66, 10, 73, + 72, 90, 32, 34, 36, 29, 20, 31, 27, 22, 20, + 19, 18, 14, 67, 68, 75, 6, 7, 64, 79, 66, 67, + 73, 73, 74, 73, 75, 88, 84, 88, 38, 37, 35, + 31, 21, 24, 21, 11, 15, 9, 8, 66, 68, 73, 79, + 18, 20, 67, 18, 19, 9, 3, 4, 1, 65, 64, 69, + 76, 79, 83, 87, 98, 73, 83, 92, 91, 78, 83, + 66, 66, 65, 36, 8, 7, 68, 17, 48, 34, 54, 8, + 38, 33, 11, 68, 77, 81, 108, 109, 114, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 76, 82, 75, 64, 69, + 6, 7, 0, 1, 7, 10, 11, 6, 15, 14, 1, 38, 34, + 24, 17, 12, 6, 79, 84, 90 }, + + { + + 43, + 6, 79, 43, 6, 79, 78, 0, 21, 11, 0, 73, 21, + 27, 53, 14, 10, 65, 8, 18, 0, 70, 66, 79, 95, + 5, 13, 112, 118, 119, 17, 69, 68, 8, 18, 0, + 75, 65, 13, 3, 0, 70, 76, 65, 79, 77, 91, 5, + 70, 76, 1, 76, 75, 88, 9, 65, 67, 71, 4, 4, + 22, 0, 0, 0, 67, 93, 97, 4, 0, 67, 52, 7, 69, + 97, 79, 82, 2, 70, 79, 72, 85, 0, 79, 77, 74, + 93, 94, 94, 95, 21, 64, 6, 81, 64, 79, 72, 74, + 72, 86, 78, 92, 14, 73, 0, 86, 80, 67, 71, 1, + 7, 2, 0, 14, 11, 75, 64, 1, 65, 2, 74, 12, 64, + 11, 19, 6, 17, 17, 11, 71, 11, 1, 68, 2, 86, + 85, 73, 78, 68, 73, 70, 7, 68, 70, 64, 3, 71, + 72, 65, 90, 88, 73, 95, 68, 75, 8, 65, 72, 17, + 1, 65, 73, 18, 72, 82, 1, 93, 21, 28, 24, 23, + 28, 22, 9, 24, 24, 68, 7, 11, 4, 1, 73, 4, 64, + 65, 2, 66, 73, 1, 66, 86, 73, 72, 80, 75, 89, + 37, 42, 35, 36, 34, 29, 26, 29, 21, 14, 17, 8, + 65, 67, 88, 17, 13, 67, 15, 6, 5, 0, 67, 71, + 73, 77, 90, 72, 84, 96, 89, 100, 65, 32, 22, + 15, 5, 5, 64, 68, 72, 75, 5, 45, 30, 23, 17, + 27, 9, 3, 66, 68, 71, 35, 21, 12, 5, 11, 1, + 67, 72, 80, 77, 14, 4, 1, 67, 0, 73, 77, 83, + 64, 39, 22, 14, 7, 15, 2, 65, 67, 72, 62, 82, + 73, 65, 66, 69, 1, 7, 8, 66, 7, 12, 13, 77, + 71, 73, 2, 14, 1, 64, 8, 13, 18, 71, 0, 13, + 14, 79, 75, 79, 83, 77, 68, 75, 71, 72, 69, + 65, 73, 71, 70, 65, 75, 74, 81, 86, 70, 98, + 76, 65, 70, 8, 69, 65, 15, 67, 69, 66, 11, 74, + 72, 91, 31, 34, 35, 28, 19, 30, 26, 21, 19, + 18, 17, 13, 68, 69, 76, 4, 6, 65, 81, 67, 68, + 74, 74, 75, 73, 75, 88, 84, 88, 35, 34, 33, + 29, 18, 22, 19, 8, 13, 7, 6, 68, 70, 75, 80, + 16, 18, 68, 16, 17, 7, 1, 1, 64, 67, 66, 71, + 79, 81, 85, 89, 99, 75, 85, 93, 90, 77, 82, + 65, 65, 64, 38, 9, 8, 68, 18, 49, 36, 55, 9, + 36, 31, 8, 71, 80, 84, 111, 111, 115, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 76, 81, 74, 0, 69, + 7, 8, 0, 2, 8, 11, 12, 6, 15, 14, 1, 37, 32, + 22, 15, 10, 4, 81, 86, 91 }, + + { + + 42, + 6, 79, 42, 6, 79, 76, 1, 21, 11, 0, 74, 20, + 25, 53, 14, 13, 66, 9, 18, 0, 70, 65, 80, 96, + 4, 11, 114, 119, 120, 20, 67, 68, 9, 18, 0, + 75, 64, 13, 2, 0, 70, 76, 65, 79, 76, 91, 5, + 70, 75, 0, 76, 75, 88, 9, 64, 66, 70, 4, 4, + 22, 0, 0, 0, 66, 93, 97, 4, 64, 67, 52, 7, 69, + 96, 78, 82, 2, 68, 78, 70, 83, 1, 78, 75, 72, + 92, 93, 93, 95, 22, 64, 7, 80, 64, 78, 71, 72, + 72, 86, 78, 90, 15, 72, 0, 85, 80, 67, 71, 2, + 8, 3, 1, 14, 11, 75, 65, 1, 65, 2, 74, 12, 64, + 10, 19, 6, 17, 17, 10, 73, 11, 1, 69, 1, 87, + 84, 72, 77, 67, 72, 69, 8, 67, 70, 0, 4, 71, + 72, 64, 91, 87, 72, 95, 67, 75, 8, 65, 73, 18, + 1, 65, 75, 19, 73, 83, 1, 93, 20, 27, 24, 22, + 27, 21, 8, 24, 24, 69, 6, 11, 4, 1, 73, 4, 64, + 66, 2, 67, 74, 1, 67, 88, 74, 73, 81, 76, 89, + 35, 41, 33, 34, 33, 27, 23, 27, 19, 12, 15, 6, + 68, 69, 91, 15, 12, 69, 12, 4, 3, 65, 70, 73, + 76, 79, 92, 73, 85, 98, 89, 100, 65, 32, 23, + 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, + 28, 10, 4, 66, 67, 70, 36, 22, 12, 6, 12, 2, + 67, 71, 79, 77, 16, 4, 1, 66, 1, 72, 77, 82, + 0, 40, 23, 14, 7, 16, 3, 64, 66, 71, 62, 82, + 73, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, + 71, 73, 1, 14, 0, 65, 7, 13, 18, 72, 64, 12, + 14, 80, 76, 80, 82, 77, 67, 75, 70, 72, 68, + 64, 73, 71, 70, 65, 76, 74, 81, 86, 69, 98, + 76, 64, 70, 8, 69, 65, 16, 67, 69, 66, 12, 74, + 73, 91, 30, 34, 35, 28, 18, 29, 25, 20, 19, + 17, 16, 12, 69, 70, 77, 3, 4, 67, 83, 68, 69, + 75, 75, 75, 73, 74, 88, 85, 87, 33, 32, 31, + 26, 16, 20, 17, 6, 11, 5, 4, 70, 72, 76, 81, + 14, 16, 69, 14, 15, 5, 64, 64, 66, 69, 68, 73, + 81, 83, 87, 91, 100, 77, 87, 95, 89, 75, 81, + 65, 64, 0, 40, 10, 9, 68, 19, 51, 37, 57, 9, + 35, 29, 6, 74, 82, 87, 113, 113, 116, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 75, 80, 73, 1, 68, + 8, 9, 1, 3, 9, 12, 13, 7, 16, 15, 1, 35, 31, + 21, 14, 8, 2, 83, 88, 92 }, + + { + + 41, + 6, 79, 41, 6, 79, 74, 3, 22, 11, 64, 76, 18, + 24, 53, 14, 15, 66, 10, 19, 0, 71, 65, 81, 97, + 4, 9, 115, 120, 120, 23, 66, 68, 10, 19, 0, + 74, 0, 14, 2, 0, 69, 75, 66, 80, 76, 91, 5, + 70, 75, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, + 22, 0, 0, 0, 66, 93, 97, 5, 65, 67, 52, 7, 69, + 95, 77, 82, 3, 67, 76, 68, 82, 2, 76, 74, 70, + 91, 92, 92, 94, 23, 64, 8, 79, 64, 78, 71, 70, + 72, 85, 77, 89, 15, 72, 1, 83, 79, 66, 71, 2, + 8, 3, 2, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, + 10, 19, 5, 17, 17, 10, 75, 11, 0, 71, 0, 88, + 83, 71, 76, 66, 71, 69, 9, 67, 69, 1, 5, 71, + 72, 64, 92, 87, 71, 95, 67, 75, 9, 65, 74, 19, + 1, 65, 76, 20, 73, 84, 1, 94, 18, 26, 23, 21, + 26, 20, 8, 23, 23, 70, 5, 11, 4, 1, 74, 3, 65, + 67, 1, 68, 75, 0, 67, 90, 75, 73, 82, 77, 89, + 34, 39, 32, 32, 31, 25, 21, 25, 16, 9, 13, 3, + 70, 72, 93, 13, 10, 70, 10, 2, 0, 68, 72, 76, + 78, 81, 95, 74, 87, 99, 90, 100, 65, 33, 23, + 15, 5, 5, 64, 68, 72, 74, 6, 46, 30, 23, 17, + 29, 10, 4, 65, 67, 69, 37, 22, 13, 6, 13, 2, + 66, 71, 78, 76, 17, 5, 2, 66, 2, 71, 76, 81, + 0, 40, 23, 14, 7, 17, 3, 0, 65, 70, 62, 81, + 72, 64, 66, 69, 1, 7, 8, 65, 7, 13, 14, 77, + 71, 73, 1, 15, 64, 66, 6, 12, 18, 73, 65, 12, + 14, 80, 77, 80, 81, 76, 66, 74, 70, 71, 68, 0, + 73, 71, 70, 64, 76, 74, 81, 85, 68, 98, 76, + 64, 70, 9, 69, 65, 17, 67, 69, 66, 13, 75, 73, + 92, 29, 33, 34, 27, 17, 28, 24, 19, 18, 16, + 15, 11, 70, 71, 78, 1, 3, 68, 85, 70, 70, 76, + 75, 76, 73, 74, 88, 85, 86, 31, 30, 29, 24, + 13, 18, 15, 3, 9, 3, 2, 73, 74, 78, 82, 12, + 15, 71, 12, 13, 3, 66, 66, 68, 71, 70, 75, 84, + 85, 89, 93, 101, 79, 89, 96, 88, 74, 80, 64, + 0, 1, 41, 11, 10, 68, 20, 52, 39, 58, 10, 33, + 28, 3, 77, 85, 90, 116, 115, 117, 69, 42, 28, + 19, 9, 12, 2, 65, 68, 75, 79, 72, 2, 67, 9, 9, + 1, 4, 9, 12, 13, 7, 16, 15, 1, 34, 29, 19, 12, + 6, 0, 85, 90, 93 }, + + { + + 40, + 6, 79, 40, 6, 79, 72, 4, 22, 11, 64, 77, 17, + 23, 53, 14, 17, 66, 11, 20, 0, 72, 65, 82, 98, + 3, 7, 117, 121, 121, 26, 65, 68, 11, 20, 0, + 74, 1, 14, 1, 0, 69, 74, 66, 80, 76, 91, 5, + 70, 74, 0, 76, 75, 88, 10, 64, 66, 70, 5, 4, + 22, 0, 0, 0, 65, 93, 97, 5, 66, 67, 52, 7, 69, + 94, 76, 82, 3, 66, 74, 66, 80, 3, 74, 73, 68, + 90, 91, 91, 93, 24, 64, 9, 78, 64, 77, 70, 68, + 72, 85, 77, 88, 15, 72, 1, 82, 79, 65, 71, 2, + 8, 3, 3, 15, 12, 76, 65, 1, 65, 2, 74, 12, 65, + 9, 19, 4, 17, 17, 10, 77, 11, 0, 73, 64, 89, + 82, 70, 75, 65, 70, 68, 10, 66, 69, 2, 6, 71, + 72, 64, 93, 86, 70, 95, 67, 75, 10, 65, 75, + 20, 1, 65, 77, 21, 74, 85, 1, 95, 17, 25, 23, + 20, 25, 19, 7, 22, 23, 71, 4, 11, 4, 1, 74, 2, + 66, 68, 0, 69, 76, 64, 68, 92, 76, 74, 83, 78, + 89, 32, 38, 30, 30, 29, 23, 19, 23, 14, 7, 11, + 1, 73, 74, 96, 11, 8, 72, 8, 0, 65, 70, 74, + 78, 81, 83, 97, 75, 89, 100, 91, 100, 65, 33, + 23, 15, 5, 5, 64, 68, 72, 73, 6, 46, 30, 23, + 17, 30, 11, 5, 65, 66, 68, 38, 23, 13, 6, 14, + 3, 66, 70, 77, 75, 18, 6, 2, 66, 3, 70, 75, + 80, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, 62, + 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, 77, + 71, 73, 0, 15, 65, 67, 5, 11, 18, 74, 66, 12, + 14, 81, 78, 81, 80, 75, 65, 74, 69, 71, 67, 1, + 73, 71, 70, 64, 77, 74, 81, 85, 67, 98, 76, + 64, 70, 10, 69, 65, 18, 67, 69, 66, 14, 76, + 73, 93, 28, 33, 34, 26, 16, 27, 23, 18, 17, + 15, 14, 10, 71, 72, 79, 0, 2, 70, 87, 71, 71, + 77, 76, 76, 73, 74, 88, 86, 85, 29, 28, 27, + 22, 10, 16, 13, 1, 7, 1, 0, 75, 76, 79, 83, + 10, 13, 72, 10, 11, 1, 68, 68, 70, 73, 72, 77, + 86, 87, 91, 95, 102, 81, 91, 98, 87, 73, 79, + 0, 1, 2, 43, 12, 11, 68, 21, 54, 40, 60, 11, + 32, 26, 1, 80, 88, 93, 119, 117, 118, 69, 42, + 28, 19, 9, 12, 2, 65, 68, 74, 78, 71, 3, 66, + 10, 10, 2, 5, 10, 13, 14, 7, 17, 15, 1, 33, + 28, 17, 10, 4, 65, 87, 92, 94 }, + + { + + 38, + 5, 80, 38, 5, 80, 71, 5, 22, 11, 65, 79, 15, + 21, 52, 14, 19, 67, 11, 20, 64, 73, 65, 84, + 100, 2, 5, 119, 122, 122, 28, 64, 69, 11, 20, + 64, 74, 2, 14, 0, 0, 69, 74, 67, 81, 76, 92, + 5, 70, 74, 64, 77, 75, 88, 10, 64, 66, 70, 5, + 3, 22, 0, 0, 0, 65, 94, 97, 5, 67, 68, 52, 6, + 69, 93, 76, 82, 3, 65, 73, 65, 79, 4, 73, 72, + 67, 89, 91, 90, 93, 24, 64, 9, 78, 64, 77, 70, + 67, 72, 85, 77, 87, 15, 72, 1, 81, 79, 65, 71, + 2, 8, 3, 3, 15, 12, 77, 66, 1, 66, 2, 74, 11, + 66, 8, 19, 3, 16, 17, 9, 79, 10, 64, 75, 65, + 90, 82, 70, 75, 65, 70, 68, 11, 66, 69, 2, 7, + 72, 72, 64, 95, 86, 70, 95, 67, 76, 10, 65, + 76, 20, 1, 65, 79, 21, 75, 86, 1, 96, 15, 24, + 22, 19, 24, 18, 6, 21, 22, 73, 3, 10, 3, 1, + 75, 1, 67, 69, 64, 70, 77, 65, 69, 94, 78, 75, + 85, 80, 89, 30, 36, 28, 28, 27, 20, 16, 20, + 11, 4, 8, 65, 76, 77, 99, 9, 6, 74, 5, 66, 68, + 73, 77, 81, 84, 86, 100, 76, 91, 102, 92, 101, + 65, 33, 23, 15, 5, 5, 65, 68, 72, 73, 6, 46, + 30, 23, 17, 31, 11, 5, 65, 66, 68, 38, 23, 13, + 6, 14, 3, 66, 70, 76, 75, 19, 6, 2, 66, 3, 70, + 75, 79, 1, 40, 23, 14, 7, 18, 4, 1, 64, 69, + 62, 81, 72, 0, 66, 69, 1, 7, 8, 65, 7, 13, 15, + 77, 71, 74, 64, 15, 66, 68, 4, 10, 17, 76, 68, + 11, 13, 82, 80, 82, 80, 75, 64, 74, 69, 71, + 67, 1, 74, 71, 70, 64, 78, 74, 81, 85, 67, 99, + 76, 64, 70, 10, 70, 65, 18, 68, 70, 66, 14, + 77, 74, 94, 27, 32, 33, 25, 14, 26, 22, 17, + 16, 14, 13, 9, 72, 74, 81, 65, 0, 72, 89, 73, + 73, 78, 77, 77, 73, 74, 88, 87, 85, 26, 25, + 25, 19, 7, 13, 10, 65, 4, 65, 66, 78, 79, 81, + 84, 8, 11, 74, 8, 8, 65, 71, 71, 73, 75, 75, + 80, 89, 89, 94, 97, 104, 83, 93, 100, 86, 72, + 78, 0, 1, 2, 44, 12, 11, 68, 21, 55, 41, 61, + 11, 30, 24, 65, 84, 91, 96, 122, 120, 120, 69, + 42, 27, 18, 9, 12, 2, 66, 68, 74, 78, 71, 3, + 66, 11, 10, 2, 5, 10, 13, 14, 7, 17, 15, 0, + 31, 26, 15, 8, 2, 67, 90, 94, 95 }, + + { + + 37, + 5, 80, 37, 5, 80, 69, 7, 23, 12, 65, 80, 14, + 20, 52, 14, 22, 67, 12, 21, 64, 73, 64, 85, + 101, 2, 4, 120, 123, 122, 31, 1, 69, 12, 21, + 64, 73, 4, 15, 0, 1, 68, 73, 67, 81, 75, 92, + 5, 69, 73, 64, 77, 74, 88, 11, 0, 65, 69, 6, + 3, 22, 0, 0, 0, 64, 94, 97, 6, 67, 68, 52, 6, + 69, 91, 75, 82, 4, 0, 71, 0, 77, 6, 71, 70, + 65, 87, 90, 89, 92, 25, 0, 10, 77, 0, 76, 69, + 65, 71, 84, 76, 85, 16, 71, 2, 79, 78, 64, 70, + 3, 9, 4, 4, 16, 13, 77, 66, 2, 66, 2, 73, 11, + 66, 8, 19, 3, 16, 17, 9, 80, 10, 64, 76, 66, + 90, 81, 69, 74, 64, 69, 67, 12, 65, 68, 3, 9, + 72, 72, 0, 96, 85, 69, 95, 66, 76, 11, 64, 76, + 21, 1, 65, 80, 22, 75, 87, 1, 96, 14, 24, 22, + 19, 24, 18, 6, 21, 22, 74, 3, 10, 3, 1, 75, 1, + 67, 69, 64, 70, 78, 65, 69, 95, 79, 75, 86, + 81, 89, 29, 35, 27, 27, 26, 18, 14, 18, 9, 2, + 6, 67, 78, 79, 101, 8, 5, 75, 3, 68, 70, 75, + 79, 83, 86, 88, 102, 76, 92, 103, 92, 101, 64, + 34, 24, 16, 6, 5, 65, 67, 71, 72, 7, 47, 31, + 24, 17, 32, 12, 6, 64, 65, 67, 39, 24, 14, 7, + 15, 4, 65, 69, 74, 74, 21, 7, 3, 65, 4, 69, + 74, 77, 2, 41, 24, 15, 8, 19, 5, 2, 0, 68, 62, + 80, 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 16, 76, + 71, 74, 64, 16, 66, 68, 3, 10, 17, 77, 69, 11, + 13, 82, 81, 82, 79, 74, 0, 73, 68, 70, 66, 2, + 74, 70, 69, 0, 78, 73, 80, 84, 66, 99, 76, 0, + 70, 11, 70, 65, 19, 68, 70, 65, 15, 77, 74, + 94, 27, 32, 33, 25, 13, 26, 22, 17, 16, 14, + 13, 9, 72, 75, 82, 66, 64, 73, 90, 74, 74, 78, + 77, 77, 72, 73, 87, 87, 84, 24, 23, 23, 17, 5, + 11, 8, 67, 2, 67, 68, 80, 81, 82, 84, 7, 10, + 75, 7, 6, 67, 73, 73, 75, 77, 77, 82, 91, 90, + 96, 98, 105, 84, 94, 101, 84, 70, 76, 1, 2, 3, + 46, 13, 12, 68, 22, 57, 43, 62, 12, 29, 23, + 67, 87, 93, 98, 124, 122, 121, 68, 43, 27, 18, + 9, 13, 2, 66, 68, 73, 77, 70, 4, 65, 13, 11, + 3, 6, 11, 14, 15, 8, 18, 16, 0, 30, 25, 14, 7, + 1, 68, 92, 95, 95 }, + + { + + 36, + 5, 80, 36, 5, 80, 67, 8, 23, 12, 65, 81, 13, + 19, 52, 14, 24, 67, 13, 22, 64, 74, 64, 86, + 102, 1, 2, 122, 124, 123, 34, 2, 69, 13, 22, + 64, 73, 5, 15, 64, 1, 68, 72, 67, 81, 75, 92, + 5, 69, 72, 64, 77, 74, 88, 11, 0, 65, 69, 6, + 3, 22, 0, 0, 0, 0, 94, 97, 6, 68, 68, 52, 6, + 69, 90, 74, 82, 4, 1, 69, 2, 76, 7, 69, 69, 0, + 86, 89, 88, 91, 26, 0, 11, 76, 0, 76, 68, 0, + 71, 84, 76, 84, 16, 71, 2, 78, 78, 0, 70, 3, + 9, 4, 5, 16, 13, 78, 66, 2, 66, 2, 73, 11, 66, + 7, 19, 2, 16, 17, 9, 82, 10, 64, 78, 67, 91, + 80, 68, 73, 0, 68, 66, 13, 64, 68, 4, 10, 72, + 72, 0, 97, 85, 68, 95, 66, 76, 12, 64, 77, 22, + 1, 65, 81, 23, 76, 88, 1, 97, 12, 23, 21, 18, + 23, 17, 5, 20, 22, 75, 2, 10, 3, 1, 75, 0, 68, + 70, 65, 71, 79, 66, 70, 97, 80, 76, 87, 82, + 89, 27, 34, 25, 25, 24, 16, 12, 16, 6, 0, 4, + 70, 81, 81, 104, 6, 3, 77, 1, 70, 72, 77, 81, + 85, 89, 90, 104, 77, 94, 104, 93, 101, 64, 34, + 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, 24, + 17, 33, 12, 7, 64, 64, 66, 40, 25, 14, 7, 16, + 4, 65, 68, 73, 73, 22, 8, 3, 65, 5, 68, 73, + 76, 2, 41, 24, 15, 8, 20, 6, 3, 1, 67, 62, 80, + 71, 1, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, 71, + 74, 65, 16, 67, 69, 2, 9, 17, 78, 70, 11, 13, + 83, 82, 83, 78, 73, 1, 73, 68, 70, 65, 3, 74, + 70, 69, 0, 79, 73, 80, 84, 65, 99, 76, 0, 70, + 12, 70, 65, 20, 68, 70, 65, 16, 78, 74, 95, + 26, 32, 33, 24, 12, 25, 21, 16, 15, 13, 12, 8, + 73, 76, 83, 68, 65, 75, 92, 75, 75, 79, 78, + 77, 72, 73, 87, 88, 83, 22, 21, 21, 15, 2, 9, + 6, 70, 0, 69, 70, 82, 83, 83, 85, 5, 8, 76, 5, + 4, 69, 75, 75, 77, 79, 79, 84, 93, 92, 98, + 100, 106, 86, 96, 103, 83, 69, 75, 2, 3, 4, + 48, 14, 13, 68, 23, 58, 44, 62, 13, 28, 21, + 70, 90, 96, 101, 126, 124, 122, 68, 43, 27, + 18, 9, 13, 2, 66, 68, 72, 76, 69, 5, 64, 14, + 12, 4, 7, 12, 15, 16, 8, 19, 16, 0, 29, 23, + 12, 5, 64, 70, 94, 97, 96 }, + + { + + 35, + 5, 80, 35, 5, 80, 65, 10, 24, 12, 66, 83, 11, + 18, 52, 14, 26, 67, 14, 23, 64, 75, 64, 87, + 103, 1, 0, 123, 125, 123, 37, 3, 69, 14, 23, + 64, 72, 6, 16, 64, 1, 67, 71, 68, 82, 75, 92, + 5, 69, 72, 64, 77, 74, 88, 12, 0, 65, 69, 7, + 3, 22, 0, 0, 0, 0, 94, 97, 7, 69, 68, 52, 6, + 69, 89, 73, 82, 5, 2, 67, 4, 74, 8, 67, 68, 2, + 85, 88, 87, 90, 27, 0, 12, 75, 0, 75, 68, 2, + 71, 83, 75, 83, 16, 71, 3, 76, 77, 1, 70, 3, + 9, 4, 6, 17, 14, 78, 66, 2, 66, 2, 73, 11, 67, + 7, 19, 1, 16, 17, 9, 84, 10, 65, 80, 68, 92, + 79, 67, 72, 1, 67, 66, 14, 64, 67, 5, 11, 72, + 72, 0, 98, 84, 67, 95, 66, 76, 13, 64, 78, 23, + 1, 65, 82, 24, 76, 89, 1, 98, 11, 22, 21, 17, + 22, 16, 5, 19, 21, 76, 1, 10, 3, 1, 76, 64, + 69, 71, 66, 72, 80, 67, 70, 99, 81, 76, 88, + 83, 89, 26, 32, 24, 23, 22, 14, 10, 14, 4, 66, + 2, 72, 83, 84, 106, 4, 1, 78, 64, 72, 75, 80, + 83, 88, 91, 92, 107, 78, 96, 105, 94, 101, 64, + 35, 24, 16, 6, 5, 65, 67, 71, 71, 7, 47, 31, + 24, 17, 34, 13, 7, 0, 64, 65, 41, 25, 15, 7, + 17, 5, 64, 68, 72, 72, 23, 9, 4, 65, 6, 67, + 72, 75, 3, 41, 24, 15, 8, 21, 6, 4, 2, 66, 62, + 79, 70, 2, 66, 68, 1, 8, 9, 64, 8, 14, 17, 76, + 71, 74, 65, 17, 68, 70, 1, 8, 17, 79, 71, 11, + 13, 83, 83, 83, 77, 72, 2, 72, 67, 69, 65, 4, + 74, 70, 69, 1, 79, 73, 80, 83, 64, 99, 76, 0, + 70, 13, 70, 65, 21, 68, 70, 65, 17, 79, 74, + 96, 25, 31, 32, 23, 11, 24, 20, 15, 14, 12, + 11, 7, 74, 77, 84, 69, 66, 76, 94, 77, 76, 80, + 78, 78, 72, 73, 87, 88, 82, 20, 19, 19, 13, + 64, 7, 4, 72, 65, 71, 72, 85, 85, 85, 86, 3, + 7, 78, 3, 2, 71, 77, 77, 79, 81, 81, 86, 96, + 94, 100, 102, 107, 88, 98, 104, 82, 68, 74, 3, + 4, 5, 49, 15, 14, 68, 24, 60, 46, 62, 14, 26, + 20, 72, 93, 99, 104, 126, 126, 123, 68, 43, + 27, 18, 9, 13, 2, 66, 68, 72, 75, 68, 6, 0, + 15, 12, 4, 8, 12, 15, 16, 8, 19, 16, 0, 28, + 22, 10, 3, 66, 72, 96, 99, 97 }, + + { + + 33, + 5, 80, 33, 5, 80, 64, 11, 24, 12, 66, 84, 10, + 16, 52, 14, 29, 68, 15, 23, 64, 76, 64, 88, + 104, 0, 65, 125, 126, 124, 40, 4, 69, 15, 23, + 64, 72, 7, 16, 65, 1, 67, 71, 68, 82, 74, 92, + 5, 69, 71, 65, 78, 74, 88, 12, 1, 65, 68, 7, + 3, 22, 0, 0, 0, 1, 95, 97, 7, 70, 68, 52, 6, + 69, 88, 72, 82, 5, 4, 66, 6, 73, 9, 66, 66, 4, + 84, 88, 86, 90, 27, 0, 13, 74, 0, 75, 67, 4, + 71, 83, 75, 82, 16, 70, 3, 75, 77, 1, 70, 4, + 9, 4, 6, 17, 14, 79, 67, 2, 66, 2, 73, 11, 67, + 6, 19, 1, 16, 17, 8, 86, 10, 65, 82, 69, 93, + 78, 66, 71, 2, 67, 65, 15, 0, 67, 6, 12, 72, + 72, 1, 99, 84, 66, 95, 66, 76, 13, 64, 79, 24, + 1, 65, 84, 25, 77, 90, 1, 99, 9, 21, 20, 16, + 21, 15, 4, 18, 21, 78, 0, 9, 3, 1, 76, 65, 69, + 72, 66, 73, 81, 68, 71, 101, 82, 77, 89, 84, + 89, 24, 31, 22, 21, 20, 12, 7, 12, 1, 68, 0, + 75, 86, 86, 109, 2, 0, 80, 67, 74, 77, 82, 86, + 90, 94, 94, 109, 79, 97, 107, 95, 101, 64, 35, + 25, 16, 6, 5, 65, 67, 71, 70, 8, 48, 31, 24, + 17, 35, 13, 8, 0, 0, 65, 42, 26, 15, 7, 17, 5, + 64, 67, 71, 72, 24, 9, 4, 65, 7, 66, 72, 74, + 3, 42, 24, 15, 8, 22, 7, 4, 3, 65, 62, 79, 70, + 2, 66, 68, 1, 8, 9, 0, 8, 14, 18, 76, 71, 74, + 66, 17, 69, 71, 0, 7, 17, 81, 72, 10, 13, 84, + 84, 84, 77, 72, 3, 72, 67, 69, 64, 5, 75, 70, + 69, 1, 80, 73, 80, 83, 0, 99, 76, 1, 70, 13, + 70, 65, 22, 68, 71, 65, 18, 79, 75, 97, 24, + 31, 32, 22, 10, 23, 19, 14, 13, 11, 10, 6, 75, + 78, 85, 71, 68, 78, 96, 78, 77, 81, 79, 78, + 72, 73, 87, 89, 82, 17, 16, 17, 10, 67, 5, 2, + 75, 67, 73, 74, 87, 87, 86, 87, 1, 5, 79, 1, + 0, 73, 79, 80, 81, 83, 83, 88, 98, 96, 102, + 104, 108, 90, 100, 106, 81, 67, 73, 3, 5, 6, + 51, 16, 15, 68, 25, 61, 47, 62, 14, 25, 18, + 75, 96, 102, 107, 126, 126, 124, 68, 43, 27, + 18, 9, 13, 2, 66, 68, 71, 74, 67, 7, 0, 16, + 13, 5, 9, 13, 16, 17, 9, 20, 17, 0, 26, 20, 8, + 1, 68, 74, 98, 101, 98 }, + + { + + 32, + 5, 80, 32, 5, 80, 1, 13, 24, 12, 67, 86, 8, + 15, 52, 14, 31, 68, 16, 24, 64, 76, 0, 89, + 105, 0, 67, 126, 126, 124, 43, 6, 69, 16, 24, + 64, 72, 8, 16, 65, 1, 67, 70, 68, 83, 74, 92, + 5, 69, 70, 65, 78, 74, 88, 13, 1, 64, 68, 8, + 3, 22, 0, 0, 0, 1, 95, 97, 8, 71, 68, 52, 6, + 69, 87, 71, 82, 6, 5, 64, 8, 71, 10, 64, 65, + 6, 83, 87, 85, 89, 28, 0, 14, 73, 0, 74, 66, + 6, 71, 83, 74, 80, 17, 70, 4, 74, 76, 2, 70, + 4, 10, 5, 7, 18, 15, 79, 67, 2, 66, 2, 73, 11, + 68, 5, 19, 0, 16, 17, 8, 88, 10, 66, 83, 70, + 94, 77, 65, 70, 3, 66, 64, 16, 1, 66, 7, 13, + 72, 72, 1, 100, 83, 65, 95, 65, 76, 14, 64, + 80, 25, 1, 65, 85, 26, 77, 91, 1, 99, 8, 20, + 20, 15, 20, 14, 3, 18, 21, 79, 64, 9, 3, 1, + 77, 65, 70, 73, 67, 74, 82, 68, 72, 103, 83, + 78, 90, 85, 89, 22, 30, 20, 19, 19, 10, 5, 10, + 64, 70, 65, 77, 88, 88, 111, 0, 65, 82, 69, + 76, 79, 84, 88, 92, 97, 96, 112, 80, 99, 108, + 95, 101, 64, 35, 25, 16, 6, 5, 65, 67, 71, 70, + 8, 48, 31, 24, 17, 36, 14, 9, 0, 1, 64, 43, + 27, 15, 8, 18, 6, 0, 67, 70, 71, 26, 10, 4, + 64, 8, 65, 71, 73, 4, 42, 25, 15, 8, 23, 8, 5, + 4, 64, 62, 79, 70, 3, 66, 68, 1, 8, 9, 0, 8, + 15, 18, 76, 71, 74, 67, 18, 70, 72, 64, 7, 17, + 82, 73, 10, 13, 85, 85, 84, 76, 71, 4, 71, 66, + 68, 64, 6, 75, 70, 69, 1, 81, 73, 80, 82, 1, + 99, 76, 1, 70, 14, 70, 65, 23, 68, 71, 65, 19, + 80, 75, 97, 23, 31, 31, 22, 9, 22, 18, 13, 13, + 10, 9, 5, 76, 79, 86, 72, 69, 79, 98, 79, 78, + 82, 80, 79, 72, 72, 87, 89, 81, 15, 14, 15, 8, + 69, 3, 0, 77, 69, 75, 76, 89, 89, 88, 88, 64, + 3, 80, 64, 65, 75, 81, 82, 83, 85, 85, 90, + 101, 98, 104, 106, 109, 92, 102, 107, 80, 65, + 72, 4, 6, 7, 53, 17, 16, 68, 26, 62, 49, 62, + 15, 23, 16, 77, 99, 104, 110, 126, 126, 125, + 68, 43, 27, 18, 9, 13, 2, 66, 68, 71, 73, 66, + 8, 1, 17, 14, 5, 10, 14, 17, 18, 9, 20, 17, 0, + 25, 19, 7, 0, 70, 76, 100, 103, 99 }, + + { + + 31, + 5, 81, 31, 5, 81, 3, 14, 25, 12, 67, 87, 7, + 14, 52, 14, 33, 68, 16, 25, 64, 77, 0, 90, + 106, 64, 68, 126, 126, 125, 46, 7, 69, 16, 25, + 64, 71, 9, 17, 66, 2, 66, 69, 69, 83, 74, 92, + 5, 68, 70, 65, 78, 73, 88, 13, 1, 64, 68, 8, + 3, 22, 0, 0, 0, 2, 95, 97, 8, 71, 69, 52, 6, + 69, 86, 71, 82, 6, 6, 1, 10, 70, 11, 1, 64, 8, + 82, 86, 84, 88, 29, 0, 15, 73, 1, 74, 66, 8, + 71, 82, 74, 79, 17, 70, 4, 72, 76, 3, 69, 4, + 10, 5, 8, 18, 15, 80, 67, 2, 66, 2, 73, 11, + 68, 5, 19, 64, 16, 17, 8, 90, 10, 66, 85, 71, + 95, 77, 64, 70, 3, 65, 64, 17, 1, 66, 7, 15, + 72, 72, 1, 101, 83, 64, 95, 65, 76, 15, 0, 81, + 25, 1, 65, 86, 27, 78, 92, 1, 100, 6, 19, 19, + 15, 19, 14, 3, 17, 20, 80, 65, 9, 3, 1, 77, + 66, 71, 74, 68, 74, 83, 69, 72, 105, 84, 78, + 91, 86, 89, 21, 28, 19, 17, 17, 8, 3, 8, 67, + 73, 67, 80, 91, 91, 114, 65, 67, 83, 71, 79, + 82, 87, 90, 95, 99, 99, 114, 81, 101, 109, 96, + 101, 0, 36, 25, 17, 6, 5, 65, 67, 71, 69, 8, + 48, 32, 24, 17, 37, 14, 9, 1, 1, 0, 44, 27, + 16, 8, 19, 6, 0, 66, 69, 70, 27, 11, 5, 64, 8, + 65, 70, 71, 4, 42, 25, 15, 9, 23, 8, 6, 4, 0, + 62, 78, 69, 3, 66, 68, 1, 8, 9, 0, 9, 15, 19, + 76, 71, 75, 67, 18, 71, 73, 65, 6, 17, 83, 74, + 10, 13, 85, 86, 85, 75, 70, 5, 71, 66, 68, 0, + 6, 75, 69, 68, 2, 81, 73, 80, 82, 2, 99, 76, + 1, 70, 15, 70, 65, 24, 69, 71, 65, 19, 81, 75, + 98, 22, 30, 31, 21, 8, 22, 18, 12, 12, 10, 8, + 4, 77, 80, 87, 74, 70, 81, 100, 81, 80, 83, + 80, 79, 72, 72, 86, 90, 80, 13, 12, 13, 6, 72, + 1, 65, 80, 71, 78, 78, 92, 91, 89, 88, 65, 2, + 82, 66, 68, 77, 83, 84, 85, 87, 88, 92, 103, + 100, 106, 107, 111, 94, 104, 109, 79, 64, 71, + 5, 7, 8, 54, 18, 17, 68, 27, 62, 50, 62, 16, + 22, 15, 80, 102, 107, 112, 126, 126, 126, 67, + 43, 27, 18, 9, 13, 2, 66, 68, 70, 72, 66, 9, + 2, 18, 14, 6, 11, 14, 17, 18, 9, 21, 17, 0, + 24, 17, 5, 65, 71, 77, 103, 104, 100 }, + + { + + 30, + 5, 81, 30, 5, 81, 5, 16, 25, 12, 68, 89, 5, + 12, 52, 14, 36, 69, 17, 25, 64, 78, 0, 91, + 107, 64, 70, 126, 126, 125, 49, 8, 69, 17, 25, + 64, 71, 10, 17, 66, 2, 66, 69, 69, 84, 73, 92, + 5, 68, 69, 66, 78, 73, 88, 14, 2, 64, 67, 9, + 3, 22, 0, 0, 0, 2, 95, 97, 9, 72, 69, 52, 6, + 69, 85, 70, 82, 7, 8, 2, 12, 68, 12, 2, 1, 10, + 81, 85, 83, 88, 30, 0, 16, 72, 1, 73, 65, 10, + 71, 82, 73, 78, 17, 69, 5, 71, 75, 3, 69, 5, + 10, 5, 9, 19, 16, 80, 68, 2, 66, 2, 73, 11, + 69, 4, 19, 64, 16, 17, 7, 92, 10, 67, 87, 72, + 96, 76, 0, 69, 4, 64, 0, 18, 2, 65, 8, 16, 72, + 72, 2, 102, 82, 0, 95, 65, 76, 15, 0, 82, 26, + 1, 65, 88, 28, 78, 93, 1, 101, 5, 18, 19, 14, + 18, 13, 2, 16, 20, 81, 66, 9, 3, 1, 78, 67, + 71, 75, 68, 75, 84, 70, 73, 107, 85, 79, 92, + 87, 89, 19, 27, 17, 15, 15, 6, 0, 6, 69, 75, + 69, 82, 93, 93, 116, 67, 68, 85, 74, 81, 84, + 89, 93, 97, 102, 101, 117, 82, 102, 111, 97, + 101, 0, 36, 26, 17, 6, 5, 65, 67, 71, 69, 9, + 49, 32, 24, 17, 38, 15, 10, 1, 2, 1, 45, 28, + 16, 8, 20, 7, 1, 66, 68, 70, 28, 11, 5, 64, 9, + 64, 70, 70, 5, 43, 25, 15, 9, 24, 9, 7, 5, 1, + 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, 19, + 76, 71, 75, 68, 19, 72, 74, 66, 5, 17, 84, 75, + 9, 13, 86, 87, 85, 74, 70, 6, 70, 65, 67, 0, + 7, 75, 69, 68, 2, 82, 73, 80, 81, 3, 99, 76, + 2, 70, 15, 70, 65, 25, 69, 71, 65, 20, 81, 76, + 99, 21, 30, 30, 20, 7, 21, 17, 11, 11, 9, 7, + 3, 78, 81, 88, 75, 72, 82, 102, 82, 81, 84, + 81, 80, 72, 72, 86, 90, 79, 11, 10, 11, 3, 75, + 64, 67, 82, 73, 80, 80, 94, 93, 91, 89, 67, 0, + 83, 68, 70, 79, 85, 86, 87, 89, 90, 94, 106, + 102, 108, 109, 112, 96, 106, 110, 78, 0, 70, + 5, 8, 9, 56, 19, 18, 68, 28, 62, 52, 62, 16, + 20, 13, 82, 105, 110, 115, 126, 126, 126, 67, + 43, 27, 18, 9, 13, 2, 66, 68, 70, 71, 65, 10, + 3, 19, 15, 6, 12, 15, 18, 19, 10, 21, 18, 0, + 22, 16, 3, 67, 73, 79, 105, 106, 101 }, + + { + + 28, + 4, 81, 28, 4, 81, 6, 17, 25, 12, 68, 90, 4, + 11, 52, 14, 38, 69, 18, 26, 64, 79, 0, 92, + 109, 65, 72, 126, 126, 126, 51, 9, 69, 18, 26, + 64, 71, 11, 17, 67, 2, 66, 68, 70, 84, 73, 93, + 5, 68, 69, 66, 79, 73, 88, 14, 2, 64, 67, 9, + 3, 22, 0, 0, 0, 3, 96, 97, 9, 73, 69, 52, 6, + 69, 84, 69, 82, 7, 9, 4, 14, 67, 13, 4, 2, 11, + 80, 85, 82, 87, 30, 0, 17, 71, 1, 73, 65, 11, + 71, 82, 73, 77, 17, 69, 5, 70, 75, 4, 69, 5, + 10, 5, 9, 19, 16, 81, 68, 2, 66, 2, 73, 11, + 69, 3, 19, 65, 16, 17, 7, 94, 10, 67, 89, 73, + 97, 75, 1, 68, 5, 64, 0, 19, 2, 65, 9, 17, 72, + 72, 2, 104, 82, 1, 95, 65, 77, 16, 0, 83, 27, + 1, 65, 89, 29, 79, 94, 1, 102, 3, 17, 18, 13, + 17, 12, 1, 15, 19, 83, 67, 8, 3, 1, 78, 68, + 72, 76, 69, 76, 85, 71, 74, 109, 87, 80, 93, + 88, 89, 17, 25, 15, 13, 13, 4, 65, 4, 72, 78, + 71, 85, 96, 96, 119, 69, 70, 87, 76, 83, 87, + 92, 95, 100, 105, 103, 119, 83, 104, 112, 98, + 102, 0, 36, 26, 17, 6, 5, 65, 67, 71, 68, 9, + 49, 32, 24, 17, 39, 15, 10, 1, 2, 1, 46, 28, + 16, 8, 20, 7, 1, 65, 67, 69, 29, 12, 5, 64, + 10, 0, 69, 69, 5, 43, 25, 15, 9, 25, 9, 7, 6, + 1, 62, 78, 69, 4, 66, 68, 1, 8, 9, 1, 9, 15, + 20, 76, 71, 75, 69, 19, 73, 75, 67, 4, 17, 86, + 77, 9, 13, 87, 88, 86, 74, 69, 7, 70, 65, 67, + 1, 8, 76, 69, 68, 2, 83, 73, 80, 81, 3, 100, + 76, 2, 70, 16, 70, 65, 25, 69, 72, 65, 21, 82, + 76, 100, 20, 29, 30, 19, 5, 20, 16, 10, 10, 8, + 6, 2, 79, 82, 89, 77, 73, 84, 104, 84, 82, 85, + 82, 80, 72, 72, 86, 91, 79, 8, 7, 9, 1, 78, + 67, 70, 85, 75, 82, 82, 97, 95, 92, 90, 69, + 65, 85, 70, 72, 82, 88, 89, 90, 91, 92, 97, + 108, 104, 111, 111, 113, 98, 108, 112, 77, 1, + 69, 6, 9, 9, 57, 20, 18, 68, 28, 62, 53, 62, + 17, 19, 11, 85, 108, 113, 118, 126, 126, 126, + 67, 43, 27, 18, 9, 13, 2, 66, 68, 69, 71, 64, + 11, 3, 20, 15, 7, 12, 15, 18, 19, 10, 22, 18, + 64, 21, 14, 1, 69, 75, 81, 107, 108, 102 }, + + { + + 27, + 4, 81, 27, 4, 81, 8, 18, 26, 12, 68, 91, 3, + 10, 52, 14, 40, 69, 19, 27, 64, 79, 1, 93, + 110, 66, 74, 126, 126, 126, 54, 11, 69, 19, + 27, 64, 70, 12, 18, 68, 2, 65, 67, 70, 84, 73, + 93, 5, 68, 68, 66, 79, 73, 88, 14, 2, 0, 67, + 9, 3, 22, 0, 0, 0, 4, 96, 97, 9, 74, 69, 52, + 6, 69, 83, 68, 82, 7, 10, 6, 16, 65, 15, 6, 3, + 13, 79, 84, 81, 86, 31, 1, 18, 70, 1, 72, 64, + 13, 71, 81, 73, 75, 18, 69, 5, 68, 75, 5, 69, + 5, 11, 6, 10, 19, 16, 81, 68, 3, 66, 2, 72, + 11, 69, 3, 19, 66, 16, 17, 7, 96, 10, 67, 90, + 74, 97, 74, 2, 67, 6, 0, 1, 20, 3, 65, 10, 18, + 72, 72, 2, 105, 81, 2, 95, 64, 77, 17, 0, 84, + 28, 1, 65, 90, 30, 80, 95, 1, 102, 2, 16, 18, + 12, 16, 11, 1, 15, 19, 84, 68, 8, 3, 1, 78, + 68, 73, 77, 70, 77, 86, 71, 74, 110, 88, 80, + 94, 89, 89, 16, 24, 14, 12, 12, 2, 67, 2, 74, + 80, 73, 87, 99, 98, 122, 70, 72, 88, 78, 85, + 89, 94, 97, 102, 107, 105, 121, 83, 106, 113, + 98, 102, 0, 37, 26, 17, 7, 5, 65, 66, 71, 67, + 9, 49, 32, 25, 17, 40, 16, 11, 2, 3, 2, 47, + 29, 17, 9, 21, 8, 1, 64, 66, 68, 31, 13, 6, 0, + 11, 1, 68, 68, 6, 43, 26, 16, 9, 26, 10, 8, 7, + 2, 62, 77, 68, 5, 66, 68, 1, 9, 10, 1, 9, 16, + 21, 76, 71, 75, 69, 19, 74, 75, 68, 4, 17, 87, + 78, 9, 13, 87, 89, 87, 73, 68, 8, 70, 64, 67, + 2, 9, 76, 69, 68, 3, 83, 73, 80, 81, 4, 100, + 76, 2, 70, 17, 70, 65, 26, 69, 72, 65, 22, 83, + 76, 100, 19, 29, 30, 19, 4, 19, 15, 9, 10, 7, + 5, 2, 79, 83, 90, 78, 74, 86, 106, 85, 83, 85, + 82, 80, 71, 71, 86, 92, 78, 6, 5, 7, 64, 80, + 69, 72, 87, 77, 84, 84, 99, 97, 93, 91, 71, + 66, 86, 72, 74, 84, 90, 91, 92, 93, 94, 99, + 110, 105, 113, 113, 114, 100, 110, 114, 76, 3, + 67, 7, 10, 10, 59, 21, 19, 68, 29, 62, 54, 62, + 18, 18, 10, 87, 111, 115, 121, 126, 126, 126, + 67, 43, 27, 18, 9, 14, 2, 66, 68, 68, 70, 0, + 12, 4, 22, 16, 8, 13, 16, 19, 20, 10, 23, 18, + 64, 20, 13, 0, 70, 77, 83, 109, 110, 102 }, + + { + + 26, + 4, 81, 26, 4, 81, 10, 20, 26, 12, 69, 93, 1, + 8, 52, 14, 43, 70, 20, 27, 64, 80, 1, 94, 111, + 66, 76, 126, 126, 126, 57, 12, 69, 20, 27, 64, + 70, 13, 18, 68, 2, 65, 67, 70, 85, 72, 93, 5, + 68, 67, 67, 79, 73, 88, 15, 3, 0, 66, 10, 3, + 22, 0, 0, 0, 4, 96, 97, 10, 75, 69, 52, 6, 69, + 82, 67, 82, 8, 12, 7, 18, 64, 16, 7, 5, 15, + 78, 83, 80, 86, 32, 1, 19, 69, 1, 72, 0, 15, + 71, 81, 72, 74, 18, 68, 6, 67, 74, 5, 69, 6, + 11, 6, 11, 20, 17, 82, 69, 3, 66, 2, 72, 11, + 70, 2, 19, 66, 16, 17, 6, 98, 10, 68, 92, 75, + 98, 73, 3, 66, 7, 1, 2, 21, 4, 64, 11, 19, 72, + 72, 3, 106, 81, 3, 95, 64, 77, 17, 0, 85, 29, + 1, 65, 92, 31, 80, 96, 1, 103, 0, 15, 17, 11, + 15, 10, 0, 14, 19, 85, 69, 8, 3, 1, 79, 69, + 73, 78, 70, 78, 87, 72, 75, 112, 89, 81, 95, + 90, 89, 14, 23, 12, 10, 10, 0, 70, 0, 77, 82, + 75, 90, 101, 100, 124, 72, 73, 90, 81, 87, 91, + 96, 100, 104, 110, 107, 124, 84, 107, 115, 99, + 102, 0, 37, 27, 17, 7, 5, 65, 66, 71, 67, 10, + 50, 32, 25, 17, 41, 16, 12, 2, 4, 3, 48, 30, + 17, 9, 22, 8, 2, 64, 65, 68, 32, 13, 6, 0, 12, + 2, 68, 67, 6, 44, 26, 16, 9, 27, 11, 9, 8, 3, + 62, 77, 68, 5, 66, 68, 1, 9, 10, 2, 9, 16, 21, + 76, 71, 75, 70, 20, 75, 76, 69, 3, 17, 88, 79, + 8, 13, 88, 90, 87, 72, 68, 9, 69, 64, 66, 2, + 10, 76, 69, 68, 3, 84, 73, 80, 80, 5, 100, 76, + 3, 70, 17, 70, 65, 27, 69, 72, 65, 23, 83, 77, + 101, 18, 29, 29, 18, 3, 18, 14, 8, 9, 6, 4, 1, + 80, 84, 91, 80, 76, 87, 108, 86, 84, 86, 83, + 81, 71, 71, 86, 92, 77, 4, 3, 5, 67, 83, 71, + 74, 90, 79, 86, 86, 101, 99, 95, 92, 73, 68, + 87, 74, 76, 86, 92, 93, 94, 95, 96, 101, 113, + 107, 115, 115, 115, 102, 112, 115, 75, 4, 66, + 7, 11, 11, 61, 22, 20, 68, 30, 62, 56, 62, 18, + 16, 8, 90, 114, 118, 124, 126, 126, 126, 67, + 43, 27, 18, 9, 14, 2, 66, 68, 68, 69, 1, 13, + 5, 23, 17, 8, 14, 17, 20, 21, 11, 23, 19, 64, + 18, 11, 65, 72, 79, 85, 111, 112, 103 }, + + { + + 25, + 4, 82, 25, 4, 82, 12, 21, 27, 12, 69, 94, 0, + 7, 52, 14, 45, 70, 20, 28, 64, 81, 1, 95, 112, + 67, 77, 126, 126, 126, 60, 13, 69, 20, 28, 64, + 69, 14, 19, 69, 3, 64, 66, 71, 85, 72, 93, 5, + 67, 67, 67, 79, 72, 88, 15, 3, 0, 66, 10, 3, + 22, 0, 0, 0, 5, 96, 97, 10, 75, 70, 52, 6, 69, + 81, 67, 82, 8, 13, 9, 20, 1, 17, 9, 6, 17, 77, + 82, 79, 85, 33, 1, 20, 69, 2, 71, 0, 17, 71, + 80, 72, 73, 18, 68, 6, 65, 74, 6, 68, 6, 11, + 6, 12, 20, 17, 82, 69, 3, 66, 2, 72, 11, 70, + 2, 19, 67, 16, 17, 6, 100, 10, 68, 94, 76, 99, + 73, 4, 66, 7, 2, 2, 22, 4, 64, 11, 21, 72, 72, + 3, 107, 80, 4, 95, 64, 77, 18, 1, 86, 29, 1, + 65, 93, 32, 81, 97, 1, 104, 64, 14, 17, 11, + 14, 10, 0, 13, 18, 86, 70, 8, 3, 1, 79, 70, + 74, 79, 71, 78, 88, 73, 75, 114, 90, 81, 96, + 91, 89, 13, 21, 11, 8, 8, 65, 72, 65, 79, 85, + 77, 92, 104, 103, 126, 74, 75, 91, 83, 90, 94, + 99, 102, 107, 112, 110, 126, 85, 109, 116, + 100, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, + 10, 50, 33, 25, 17, 42, 17, 12, 3, 4, 4, 49, + 30, 18, 9, 23, 9, 2, 0, 64, 67, 33, 14, 7, 0, + 12, 2, 67, 65, 7, 44, 26, 16, 10, 27, 11, 10, + 8, 4, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, + 16, 22, 76, 71, 76, 70, 20, 76, 77, 70, 2, 17, + 89, 80, 8, 13, 88, 91, 88, 71, 67, 10, 69, 0, + 66, 3, 10, 76, 68, 67, 4, 84, 73, 80, 80, 6, + 100, 76, 3, 70, 18, 70, 65, 28, 70, 72, 65, + 23, 84, 77, 102, 17, 28, 29, 17, 2, 18, 14, 7, + 8, 6, 3, 0, 81, 85, 92, 81, 77, 89, 110, 88, + 86, 87, 83, 81, 71, 71, 85, 93, 76, 2, 1, 3, + 69, 86, 73, 76, 92, 81, 89, 88, 104, 101, 96, + 92, 74, 69, 89, 76, 79, 88, 94, 95, 96, 97, + 99, 103, 115, 109, 117, 116, 117, 104, 114, + 117, 74, 5, 65, 8, 12, 12, 62, 23, 21, 68, 31, + 62, 57, 62, 19, 15, 7, 92, 117, 121, 126, 126, + 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, + 67, 68, 1, 14, 6, 24, 17, 9, 15, 17, 20, 21, + 11, 24, 19, 64, 17, 10, 67, 74, 80, 86, 114, + 113, 104 }, + + { + + 23, + 4, 82, 23, 4, 82, 13, 23, 27, 12, 70, 96, 65, + 6, 52, 14, 47, 70, 21, 29, 64, 82, 1, 96, 113, + 67, 79, 126, 126, 126, 62, 14, 69, 21, 29, 64, + 69, 15, 19, 69, 3, 64, 65, 71, 86, 72, 93, 5, + 67, 66, 67, 80, 72, 88, 16, 3, 0, 66, 11, 3, + 22, 0, 0, 0, 5, 97, 97, 11, 76, 70, 52, 6, 69, + 80, 66, 82, 9, 14, 11, 22, 2, 18, 11, 7, 19, + 76, 82, 78, 84, 33, 1, 21, 68, 2, 71, 1, 19, + 71, 80, 71, 72, 18, 68, 7, 64, 73, 7, 68, 6, + 11, 6, 12, 21, 18, 83, 69, 3, 66, 2, 72, 11, + 71, 1, 19, 68, 16, 17, 6, 102, 10, 69, 96, 77, + 100, 72, 5, 65, 8, 2, 3, 23, 5, 0, 12, 22, 72, + 72, 3, 108, 80, 5, 95, 64, 77, 19, 1, 87, 30, + 1, 65, 94, 33, 81, 98, 1, 105, 66, 13, 16, 10, + 13, 9, 64, 12, 18, 88, 71, 7, 3, 1, 80, 71, + 75, 80, 72, 79, 89, 74, 76, 116, 91, 82, 97, + 92, 89, 11, 20, 9, 6, 6, 67, 74, 67, 82, 87, + 79, 95, 106, 105, 126, 76, 77, 93, 85, 92, 96, + 101, 104, 109, 115, 112, 126, 86, 111, 117, + 101, 102, 1, 38, 27, 18, 7, 5, 65, 66, 71, 66, + 10, 50, 33, 25, 17, 43, 17, 13, 3, 5, 4, 50, + 31, 18, 9, 23, 9, 3, 0, 0, 66, 34, 15, 7, 0, + 13, 3, 66, 64, 7, 44, 26, 16, 10, 28, 12, 10, + 9, 5, 62, 76, 67, 6, 66, 68, 1, 9, 10, 2, 10, + 16, 22, 76, 71, 76, 71, 21, 77, 78, 71, 1, 17, + 91, 81, 8, 13, 89, 92, 88, 71, 66, 11, 68, 0, + 65, 3, 11, 77, 68, 67, 4, 85, 73, 80, 79, 7, + 100, 76, 3, 70, 19, 70, 65, 29, 70, 73, 65, + 24, 85, 77, 103, 16, 28, 28, 16, 1, 17, 13, 6, + 7, 5, 2, 64, 82, 86, 93, 83, 78, 90, 112, 89, + 87, 88, 84, 82, 71, 71, 85, 93, 76, 64, 65, 1, + 71, 89, 75, 78, 95, 83, 91, 90, 106, 103, 98, + 93, 76, 71, 90, 78, 81, 90, 96, 98, 98, 99, + 101, 105, 118, 111, 119, 118, 118, 106, 116, + 118, 73, 6, 64, 9, 13, 13, 62, 24, 22, 68, 32, + 62, 59, 62, 20, 13, 5, 95, 120, 124, 126, 126, + 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, 68, + 67, 67, 2, 15, 6, 25, 18, 9, 16, 18, 21, 22, + 11, 24, 19, 64, 16, 8, 69, 76, 82, 88, 116, + 115, 105 }, + + { + + 22, + 4, 82, 22, 4, 82, 15, 24, 27, 12, 70, 97, 66, + 4, 52, 14, 50, 71, 22, 29, 64, 82, 2, 97, 114, + 68, 81, 126, 126, 126, 62, 16, 69, 22, 29, 64, + 69, 16, 19, 70, 3, 64, 65, 71, 86, 71, 93, 5, + 67, 65, 68, 80, 72, 88, 16, 4, 1, 65, 11, 3, + 22, 0, 0, 0, 6, 97, 97, 11, 77, 70, 52, 6, 69, + 79, 65, 82, 9, 16, 12, 24, 4, 19, 12, 9, 21, + 75, 81, 77, 84, 34, 1, 22, 67, 2, 70, 2, 21, + 71, 80, 71, 70, 19, 67, 7, 0, 73, 7, 68, 7, + 12, 7, 13, 21, 18, 83, 70, 3, 66, 2, 72, 11, + 71, 0, 19, 68, 16, 17, 5, 104, 10, 69, 97, 78, + 101, 71, 6, 64, 9, 3, 4, 24, 6, 0, 13, 23, 72, + 72, 4, 109, 79, 6, 95, 0, 77, 19, 1, 88, 31, + 1, 65, 96, 34, 82, 99, 1, 105, 67, 12, 16, 9, + 12, 8, 65, 12, 18, 89, 72, 7, 3, 1, 80, 71, + 75, 81, 72, 80, 90, 74, 77, 118, 92, 83, 98, + 93, 89, 9, 19, 7, 4, 5, 69, 77, 69, 84, 89, + 81, 97, 109, 107, 126, 78, 78, 95, 88, 94, 98, + 103, 107, 111, 118, 114, 126, 87, 112, 119, + 101, 102, 1, 38, 28, 18, 7, 5, 65, 66, 71, 65, + 11, 51, 33, 25, 17, 44, 18, 14, 3, 6, 5, 51, + 32, 18, 10, 24, 10, 3, 1, 1, 66, 36, 15, 7, 1, + 14, 4, 66, 0, 8, 45, 27, 16, 10, 29, 13, 11, + 10, 6, 62, 76, 67, 7, 66, 68, 1, 9, 10, 3, 10, + 17, 23, 76, 71, 76, 72, 21, 78, 79, 72, 1, 17, + 92, 82, 7, 13, 90, 93, 89, 70, 66, 12, 68, 1, + 65, 4, 12, 77, 68, 67, 4, 86, 73, 80, 79, 8, + 100, 76, 4, 70, 19, 70, 65, 30, 70, 73, 65, + 25, 85, 78, 103, 15, 28, 28, 16, 0, 16, 12, 5, + 7, 4, 1, 65, 83, 87, 94, 84, 80, 92, 114, 90, + 88, 89, 85, 82, 71, 70, 85, 94, 75, 66, 67, + 64, 74, 91, 77, 80, 97, 85, 93, 92, 108, 105, + 99, 94, 78, 73, 91, 80, 83, 92, 98, 100, 100, + 101, 103, 107, 120, 113, 121, 120, 119, 108, + 118, 120, 72, 8, 0, 9, 14, 14, 62, 25, 23, 68, + 33, 62, 60, 62, 20, 12, 3, 97, 123, 126, 126, + 126, 126, 126, 66, 43, 27, 18, 9, 14, 2, 66, + 68, 66, 66, 3, 16, 7, 26, 19, 10, 17, 19, 22, + 23, 12, 25, 20, 64, 14, 7, 70, 77, 84, 90, + 118, 117, 106 }, + + { + + 21, + 4, 82, 21, 4, 82, 17, 26, 28, 12, 71, 99, 68, + 3, 52, 14, 52, 71, 23, 30, 64, 83, 2, 98, 115, + 68, 83, 126, 126, 126, 62, 17, 69, 23, 30, 64, + 68, 17, 20, 70, 3, 0, 64, 72, 87, 71, 93, 5, + 67, 65, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, + 22, 0, 0, 0, 6, 97, 97, 12, 78, 70, 52, 6, 69, + 78, 64, 82, 10, 17, 14, 26, 5, 20, 14, 10, 23, + 74, 80, 76, 83, 35, 1, 23, 66, 2, 70, 2, 23, + 71, 79, 70, 69, 19, 67, 8, 2, 72, 8, 68, 7, + 12, 7, 14, 22, 19, 84, 70, 3, 66, 2, 72, 11, + 72, 0, 19, 69, 16, 17, 5, 106, 10, 70, 99, 79, + 102, 70, 7, 0, 10, 4, 4, 25, 6, 1, 14, 24, 72, + 72, 4, 110, 79, 7, 95, 0, 77, 20, 1, 89, 32, + 1, 65, 97, 35, 82, 100, 1, 106, 69, 11, 15, 8, + 11, 7, 65, 11, 17, 90, 73, 7, 3, 1, 81, 72, + 76, 82, 73, 81, 91, 75, 77, 120, 93, 83, 99, + 94, 89, 8, 17, 6, 2, 3, 71, 79, 71, 87, 92, + 83, 100, 111, 110, 126, 80, 80, 96, 90, 96, + 101, 106, 109, 114, 120, 116, 126, 88, 114, + 120, 102, 102, 1, 39, 28, 18, 7, 5, 65, 66, + 71, 65, 11, 51, 33, 25, 17, 45, 18, 14, 4, 6, + 6, 52, 32, 19, 10, 25, 10, 4, 1, 2, 65, 37, + 16, 8, 1, 15, 5, 65, 1, 8, 45, 27, 16, 10, 30, + 13, 12, 11, 7, 62, 75, 66, 7, 66, 68, 1, 9, + 10, 3, 10, 17, 23, 76, 71, 76, 72, 22, 79, 80, + 73, 0, 17, 93, 83, 7, 13, 90, 94, 89, 69, 65, + 13, 67, 1, 64, 4, 13, 77, 68, 67, 5, 86, 73, + 80, 78, 9, 100, 76, 4, 70, 20, 70, 65, 31, 70, + 73, 65, 26, 86, 78, 104, 14, 27, 27, 15, 64, + 15, 11, 4, 6, 3, 0, 66, 84, 88, 95, 86, 81, + 93, 116, 92, 89, 90, 85, 83, 71, 70, 85, 94, + 74, 68, 69, 66, 76, 94, 79, 82, 100, 87, 95, + 94, 111, 107, 101, 95, 80, 74, 93, 82, 85, 94, + 100, 102, 102, 103, 105, 109, 123, 115, 123, + 122, 120, 110, 120, 121, 71, 9, 1, 10, 15, 15, + 62, 26, 24, 68, 34, 62, 62, 62, 21, 10, 2, + 100, 126, 126, 126, 126, 126, 126, 66, 43, 27, + 18, 9, 14, 2, 66, 68, 66, 65, 4, 17, 8, 27, + 19, 10, 18, 19, 22, 23, 12, 25, 20, 64, 13, 5, + 72, 79, 86, 92, 120, 119, 107 }, + + { + + 20, + 4, 82, 20, 4, 82, 19, 27, 28, 12, 71, 100, 69, + 2, 52, 14, 54, 71, 24, 31, 64, 84, 2, 99, 116, + 69, 85, 126, 126, 126, 62, 18, 69, 24, 31, 64, + 68, 18, 20, 71, 3, 0, 0, 72, 87, 71, 93, 5, + 67, 64, 68, 80, 72, 88, 17, 4, 1, 65, 12, 3, + 22, 0, 0, 0, 7, 97, 97, 12, 79, 70, 52, 6, 69, + 77, 0, 82, 10, 18, 16, 28, 7, 21, 16, 11, 25, + 73, 79, 75, 82, 36, 1, 24, 65, 2, 69, 3, 25, + 71, 79, 70, 68, 19, 67, 8, 3, 72, 9, 68, 7, + 12, 7, 15, 22, 19, 84, 70, 3, 66, 2, 72, 11, + 72, 64, 19, 70, 16, 17, 5, 108, 10, 70, 101, + 80, 103, 69, 8, 1, 11, 5, 5, 26, 7, 1, 15, 25, + 72, 72, 4, 111, 78, 8, 95, 0, 77, 21, 1, 90, + 33, 1, 65, 98, 36, 83, 101, 1, 107, 70, 10, + 15, 7, 10, 6, 66, 10, 17, 91, 74, 7, 3, 1, 81, + 73, 77, 83, 74, 82, 92, 76, 78, 122, 94, 84, + 100, 95, 89, 6, 16, 4, 0, 1, 73, 81, 73, 89, + 94, 85, 102, 114, 112, 126, 82, 82, 98, 92, + 98, 103, 108, 111, 116, 123, 118, 126, 89, + 116, 121, 103, 102, 1, 39, 28, 18, 7, 5, 65, + 66, 71, 64, 11, 51, 33, 25, 17, 46, 19, 15, 4, + 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 3, 64, 38, + 17, 8, 1, 16, 6, 64, 2, 9, 45, 27, 16, 10, 31, + 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, 1, 9, + 10, 3, 10, 17, 24, 76, 71, 76, 73, 22, 80, 81, + 74, 64, 17, 94, 84, 7, 13, 91, 95, 90, 68, 64, + 14, 67, 2, 64, 5, 14, 77, 68, 67, 5, 87, 73, + 80, 78, 10, 100, 76, 4, 70, 21, 70, 65, 32, + 70, 73, 65, 27, 87, 78, 105, 13, 27, 27, 14, + 65, 14, 10, 3, 5, 2, 64, 67, 85, 89, 96, 87, + 82, 95, 118, 93, 90, 91, 86, 83, 71, 70, 85, + 95, 73, 70, 71, 68, 78, 97, 81, 84, 102, 89, + 97, 96, 113, 109, 102, 96, 82, 76, 94, 84, 87, + 96, 102, 104, 104, 105, 107, 111, 125, 117, + 125, 124, 121, 112, 122, 123, 70, 10, 2, 11, + 16, 16, 62, 27, 25, 68, 35, 62, 62, 62, 22, 9, + 0, 102, 126, 126, 126, 126, 126, 126, 66, 43, + 27, 18, 9, 14, 2, 66, 68, 65, 64, 5, 18, 9, + 28, 20, 11, 19, 20, 23, 24, 12, 26, 20, 64, + 12, 4, 74, 81, 88, 94, 122, 121, 108 }, + + { + + 18, + 3, 83, 18, 3, 83, 20, 28, 28, 12, 72, 102, 71, + 0, 51, 14, 56, 72, 24, 31, 65, 85, 2, 101, + 118, 70, 87, 126, 126, 126, 62, 19, 70, 24, + 31, 65, 68, 19, 20, 72, 3, 0, 0, 73, 88, 71, + 94, 5, 67, 64, 69, 81, 72, 88, 17, 4, 1, 65, + 12, 2, 22, 0, 0, 0, 7, 98, 97, 12, 80, 71, 52, + 5, 69, 76, 0, 82, 10, 19, 17, 29, 8, 22, 17, + 12, 26, 72, 79, 74, 82, 36, 1, 24, 65, 2, 69, + 3, 26, 71, 79, 70, 67, 19, 67, 8, 4, 72, 9, + 68, 7, 12, 7, 15, 22, 19, 85, 71, 3, 67, 2, + 72, 10, 73, 65, 19, 71, 15, 17, 4, 110, 9, 71, + 103, 81, 104, 69, 8, 1, 11, 5, 5, 27, 7, 1, + 15, 26, 73, 72, 4, 113, 78, 8, 95, 0, 78, 21, + 1, 91, 33, 1, 65, 100, 36, 84, 102, 1, 108, + 72, 9, 14, 6, 9, 5, 67, 9, 16, 93, 75, 6, 2, + 1, 82, 74, 78, 84, 75, 83, 93, 77, 79, 124, + 96, 85, 102, 97, 89, 4, 14, 2, 65, 64, 76, 84, + 76, 92, 97, 88, 105, 117, 115, 126, 84, 84, + 100, 95, 101, 106, 111, 114, 119, 126, 121, + 126, 90, 118, 123, 104, 103, 1, 39, 28, 18, 7, + 5, 66, 66, 71, 64, 11, 51, 33, 25, 17, 47, 19, + 15, 4, 7, 7, 53, 33, 19, 10, 26, 11, 4, 2, 4, + 64, 39, 17, 8, 1, 16, 6, 64, 3, 9, 45, 27, 16, + 10, 31, 14, 13, 12, 8, 62, 75, 66, 8, 66, 68, + 1, 9, 10, 3, 10, 17, 24, 76, 71, 77, 74, 22, + 81, 82, 75, 65, 16, 96, 86, 6, 12, 92, 97, 91, + 68, 64, 15, 67, 2, 64, 5, 14, 78, 68, 67, 5, + 88, 73, 80, 78, 10, 101, 76, 4, 70, 21, 71, + 65, 32, 71, 74, 65, 27, 88, 79, 106, 12, 26, + 26, 13, 67, 13, 9, 2, 4, 1, 65, 68, 86, 91, + 98, 89, 84, 97, 120, 95, 92, 92, 87, 84, 71, + 70, 85, 96, 73, 73, 74, 70, 81, 100, 84, 87, + 105, 92, 100, 99, 116, 112, 104, 97, 84, 78, + 96, 86, 90, 99, 105, 107, 107, 107, 110, 114, + 126, 119, 126, 126, 123, 114, 124, 125, 69, + 11, 3, 11, 16, 16, 62, 27, 25, 68, 35, 62, 62, + 62, 22, 7, 65, 105, 126, 126, 126, 126, 126, + 126, 66, 43, 26, 17, 9, 14, 2, 67, 68, 65, 64, + 5, 18, 9, 29, 20, 11, 19, 20, 23, 24, 12, 26, + 20, 65, 10, 2, 76, 83, 90, 96, 125, 123, 109 }, + + { + + 17, + 3, 83, 17, 3, 83, 22, 30, 29, 13, 72, 103, 72, + 64, 51, 14, 59, 72, 25, 32, 65, 85, 3, 102, + 119, 70, 88, 126, 126, 126, 62, 21, 70, 25, + 32, 65, 67, 21, 21, 72, 4, 1, 1, 73, 88, 70, + 94, 5, 66, 0, 69, 81, 71, 88, 18, 5, 2, 64, + 13, 2, 22, 0, 0, 0, 8, 98, 97, 13, 80, 71, 52, + 5, 69, 74, 1, 82, 11, 21, 19, 31, 10, 24, 19, + 14, 28, 70, 78, 73, 81, 37, 2, 25, 64, 3, 68, + 4, 28, 70, 78, 69, 65, 20, 66, 9, 6, 71, 10, + 67, 8, 13, 8, 16, 23, 20, 85, 71, 4, 67, 2, + 71, 10, 73, 65, 19, 71, 15, 17, 4, 111, 9, 71, + 104, 82, 104, 68, 9, 2, 12, 6, 6, 28, 8, 2, + 16, 28, 73, 72, 5, 114, 77, 9, 95, 1, 78, 22, + 2, 91, 34, 1, 65, 101, 37, 84, 103, 1, 108, + 73, 9, 14, 6, 9, 5, 67, 9, 16, 94, 75, 6, 2, + 1, 82, 74, 78, 84, 75, 83, 94, 77, 79, 125, + 97, 85, 103, 98, 89, 3, 13, 1, 66, 65, 78, 86, + 78, 94, 99, 90, 107, 119, 117, 126, 85, 85, + 101, 97, 103, 108, 113, 116, 121, 126, 123, + 126, 90, 119, 124, 104, 103, 2, 40, 29, 19, 8, + 5, 66, 65, 70, 0, 12, 52, 34, 26, 17, 48, 20, + 16, 5, 8, 8, 54, 34, 20, 11, 27, 12, 5, 3, 6, + 0, 41, 18, 9, 2, 17, 7, 0, 5, 10, 46, 28, 17, + 11, 32, 15, 14, 13, 9, 62, 74, 65, 9, 66, 67, + 1, 10, 11, 4, 11, 18, 25, 75, 71, 77, 74, 23, + 81, 82, 76, 65, 16, 97, 87, 6, 12, 92, 98, 91, + 67, 0, 16, 66, 3, 0, 6, 15, 78, 67, 66, 6, 88, + 72, 79, 77, 11, 101, 76, 5, 70, 22, 71, 65, + 33, 71, 74, 64, 28, 88, 79, 106, 12, 26, 26, + 13, 68, 13, 9, 2, 4, 1, 65, 68, 86, 92, 99, + 90, 85, 98, 121, 96, 93, 92, 87, 84, 70, 69, + 84, 96, 72, 75, 76, 72, 83, 102, 86, 89, 107, + 94, 102, 101, 118, 114, 105, 97, 85, 79, 97, + 87, 92, 101, 107, 109, 109, 109, 112, 116, + 126, 120, 126, 126, 124, 115, 125, 126, 67, + 13, 5, 12, 17, 17, 62, 28, 26, 68, 36, 62, 62, + 62, 23, 6, 66, 107, 126, 126, 126, 126, 126, + 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 64, 0, + 6, 19, 10, 31, 21, 12, 20, 21, 24, 25, 13, 27, + 21, 65, 9, 1, 77, 84, 91, 97, 126, 124, 109 }, + + { + + 16, + 3, 83, 16, 3, 83, 24, 31, 29, 13, 72, 104, 73, + 65, 51, 14, 61, 72, 26, 33, 65, 86, 3, 103, + 120, 71, 90, 126, 126, 126, 62, 22, 70, 26, + 33, 65, 67, 22, 21, 73, 4, 1, 2, 73, 88, 70, + 94, 5, 66, 1, 69, 81, 71, 88, 18, 5, 2, 64, + 13, 2, 22, 0, 0, 0, 9, 98, 97, 13, 81, 71, 52, + 5, 69, 73, 2, 82, 11, 22, 21, 33, 11, 25, 21, + 15, 30, 69, 77, 72, 80, 38, 2, 26, 0, 3, 68, + 5, 30, 70, 78, 69, 64, 20, 66, 9, 7, 71, 11, + 67, 8, 13, 8, 17, 23, 20, 86, 71, 4, 67, 2, + 71, 10, 73, 66, 19, 72, 15, 17, 4, 113, 9, 71, + 106, 83, 105, 67, 10, 3, 13, 7, 7, 29, 9, 2, + 17, 29, 73, 72, 5, 115, 77, 10, 95, 1, 78, 23, + 2, 92, 35, 1, 65, 102, 38, 85, 104, 1, 109, + 75, 8, 13, 5, 8, 4, 68, 8, 16, 95, 76, 6, 2, + 1, 82, 75, 79, 85, 76, 84, 95, 78, 80, 126, + 98, 86, 104, 99, 89, 1, 12, 64, 68, 67, 80, + 88, 80, 97, 101, 92, 110, 122, 119, 126, 87, + 87, 103, 99, 105, 110, 115, 118, 123, 126, + 125, 126, 91, 121, 125, 105, 103, 2, 40, 29, + 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, + 49, 20, 17, 5, 9, 9, 55, 35, 20, 11, 28, 12, + 5, 4, 7, 1, 42, 19, 9, 2, 18, 8, 1, 6, 10, 46, + 28, 17, 11, 33, 16, 15, 14, 10, 62, 74, 65, 9, + 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, 71, 77, + 75, 23, 82, 83, 77, 66, 16, 98, 88, 6, 12, 93, + 99, 92, 66, 1, 17, 66, 3, 0, 7, 16, 78, 67, + 66, 6, 89, 72, 79, 77, 12, 101, 76, 5, 70, 23, + 71, 65, 34, 71, 74, 64, 29, 89, 79, 107, 11, + 26, 26, 12, 69, 12, 8, 1, 3, 0, 66, 69, 87, + 93, 100, 92, 86, 100, 123, 97, 94, 93, 88, 84, + 70, 69, 84, 97, 71, 77, 78, 74, 85, 105, 88, + 91, 110, 96, 104, 103, 120, 116, 106, 98, 87, + 81, 98, 89, 94, 103, 109, 111, 111, 111, 114, + 118, 126, 122, 126, 126, 125, 117, 126, 126, + 66, 14, 6, 13, 18, 18, 62, 29, 27, 68, 37, 62, + 62, 62, 24, 5, 68, 110, 126, 126, 126, 126, + 126, 126, 65, 44, 26, 17, 9, 15, 2, 67, 68, 0, + 1, 7, 20, 11, 32, 22, 13, 21, 22, 25, 26, 13, + 28, 21, 65, 8, 64, 79, 86, 93, 99, 126, 126, + 110 }, + + { + + 15, + 3, 83, 15, 3, 83, 26, 33, 30, 13, 73, 106, 75, + 66, 51, 14, 62, 72, 27, 34, 65, 87, 3, 104, + 121, 71, 92, 126, 126, 126, 62, 23, 70, 27, + 34, 65, 66, 23, 22, 73, 4, 2, 3, 74, 89, 70, + 94, 5, 66, 1, 69, 81, 71, 88, 19, 5, 2, 64, + 14, 2, 22, 0, 0, 0, 9, 98, 97, 14, 82, 71, 52, + 5, 69, 72, 3, 82, 12, 23, 23, 35, 13, 26, 23, + 16, 32, 68, 76, 71, 79, 39, 2, 27, 1, 3, 67, + 5, 32, 70, 77, 68, 0, 20, 66, 10, 9, 70, 12, + 67, 8, 13, 8, 18, 24, 21, 86, 71, 4, 67, 2, + 71, 10, 74, 66, 19, 73, 15, 17, 4, 115, 9, 72, + 108, 84, 106, 66, 11, 4, 14, 8, 7, 30, 9, 3, + 18, 30, 73, 72, 5, 116, 76, 11, 95, 1, 78, 24, + 2, 93, 36, 1, 65, 103, 39, 85, 105, 1, 110, + 76, 7, 13, 4, 7, 3, 68, 7, 15, 96, 77, 6, 2, + 1, 83, 76, 80, 86, 77, 85, 96, 79, 80, 126, + 99, 86, 105, 100, 89, 0, 10, 65, 70, 69, 82, + 90, 82, 99, 104, 94, 112, 124, 122, 126, 89, + 89, 104, 101, 107, 113, 118, 120, 126, 126, + 126, 126, 92, 123, 126, 106, 103, 2, 41, 29, + 19, 8, 5, 66, 65, 70, 1, 12, 52, 34, 26, 17, + 50, 21, 17, 6, 9, 10, 56, 35, 21, 11, 29, 13, + 6, 4, 8, 2, 43, 20, 10, 2, 19, 9, 2, 7, 11, + 46, 28, 17, 11, 34, 16, 16, 15, 11, 62, 73, + 64, 10, 66, 67, 1, 10, 11, 4, 11, 18, 26, 75, + 71, 77, 75, 24, 83, 84, 78, 67, 16, 99, 89, 6, + 12, 93, 100, 92, 65, 2, 18, 65, 4, 1, 7, 17, + 78, 67, 66, 7, 89, 72, 79, 76, 13, 101, 76, 5, + 70, 24, 71, 65, 35, 71, 74, 64, 30, 90, 79, + 108, 10, 25, 25, 11, 70, 11, 7, 0, 2, 64, 67, + 70, 88, 94, 101, 93, 87, 101, 125, 99, 95, 94, + 88, 85, 70, 69, 84, 97, 70, 79, 80, 76, 87, + 108, 90, 93, 112, 98, 106, 105, 123, 118, 108, + 99, 89, 82, 100, 91, 96, 105, 111, 113, 113, + 113, 116, 120, 126, 124, 126, 126, 126, 119, + 126, 126, 65, 15, 7, 14, 19, 19, 62, 30, 28, + 68, 38, 62, 62, 62, 25, 3, 69, 112, 126, 126, + 126, 126, 126, 126, 65, 44, 26, 17, 9, 15, 2, + 67, 68, 0, 2, 8, 21, 12, 33, 22, 13, 22, 22, + 25, 26, 13, 28, 21, 65, 7, 65, 81, 88, 95, + 101, 126, 126, 111 }, + + }, + + }; + +#endif diff --git a/decoder/ih264d_compute_bs.c b/decoder/ih264d_compute_bs.c new file mode 100755 index 0000000..4a6750a --- /dev/null +++ b/decoder/ih264d_compute_bs.c @@ -0,0 +1,2394 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_deblocking.h" +#include "string.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" + +UWORD16 ih264d_update_csbp_8x8(UWORD16 u2_luma_csbp) +{ + UWORD16 u2_mod_csbp; + + u2_mod_csbp = u2_luma_csbp; + + if(u2_mod_csbp & 0x0033) + { + u2_mod_csbp |= 0x0033; + } + + if(u2_mod_csbp & 0x00CC) + { + u2_mod_csbp |= 0x00CC; + } + + if(u2_mod_csbp & 0x3300) + { + u2_mod_csbp |= 0x3300; + } + + if(u2_mod_csbp & 0xCC00) + { + u2_mod_csbp |= 0xCC00; + } + + return u2_mod_csbp; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs2_horz_vert */ +/* */ +/* Description : This function fills boundray strength (=2) for all horz */ +/* and vert edges of current mb based on coded sub block */ +/* pattern of current, top and left mb */ +/* Inputs : */ +/* pu4_bs : Base pointer of BS table which gets updated */ +/* u4_left_mb_csbp : left mb's coded sub block pattern */ +/* u4_top_mb_csbp : top mb's coded sub block pattern */ +/* u4_cur_mb_csbp : current mb's coded sub block pattern */ +/* */ +/* Globals : <Does it use any global variables?> */ +/* Processing : */ +/* */ +/* csbp for each 4x4 block in a mb is bit packet in reverse */ +/* raster scan order for each mb as shown below: */ +/* 15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0. */ +/* */ +/* BS=2 for a 4x4 edge if any of adjacent blocks forming edge */ +/* are coded. Keeping this in mind, bs=2 for all horz and vert */ +/* edges can be derived using a lookup table for each edge */ +/* after "ORing" the csbp values as follows: */ +/* (C means current Mb, T means top mb and L means left mb) */ +/* */ +/* All Horz edges: */ +/* 15C|14C|13C|12C|11C|10C|9C|8C|7C|6C|5C|4C|3C |2C |1C |0C */ +/* (or with) 11C|10C| 9C| 8C| 7C|6C |5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */ +/* -----BS[3]-----|----BS[2]----|---BS[1]---|----BS[0]-----| */ +/* */ +/* All Vert edges: */ +/* 15C|14C|13C|12C|11C|10C|9C| 8C|7C|6C|5C|4C|3C |2C |1C |0C */ +/* (or with) 14C|13C|12C|15L|10C| 9C|8C|11L|6C|5C|4C|7L|2C |1C |0C |3L */ +/* Do 4x4 transpose of resulting pattern to get vertBS[4]-BS[7] */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +#define CSBP_LEFT_BLOCK_MASK 0x1111 +#define CSBP_RIGHT_BLOCK_MASK 0x8888 + +void ih264d_fill_bs2_horz_vert(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_left_mb_csbp, /* csbp of left mb */ + WORD32 u4_top_mb_csbp, /* csbp of top mb */ + WORD32 u4_cur_mb_csbp, /* csbp of current mb */ + const UWORD32 *pu4_packed_bs2, const UWORD16 *pu2_4x4_v2h_reorder) +{ + /*************************************************************************/ + /*u4_nbr_horz_csbp=11C|10C|9C|8C|7C|6C|5C|4C|3C|2C|1C|0C|15T|14T|13T|12T */ + /*************************************************************************/ + UWORD32 u4_nbr_horz_csbp = (u4_cur_mb_csbp << 4) | (u4_top_mb_csbp >> 12); + UWORD32 u4_horz_bs2_dec = u4_cur_mb_csbp | u4_nbr_horz_csbp; + + /*************************************************************************/ + /*u4_left_mb_masked_csbp = 15L|0|0|0|11L|0|0|0|7L|0|0|0|3L|0|0|0 */ + /*************************************************************************/ + UWORD32 u4_left_mb_masked_csbp = u4_left_mb_csbp & CSBP_RIGHT_BLOCK_MASK; + + /*************************************************************************/ + /*u4_cur_mb_masked_csbp =14C|13C|12C|x|10C|9C|8C|x|6C|5C|4C|x|2C|1C|0C|x */ + /*************************************************************************/ + UWORD32 u4_cur_mb_masked_csbp = (u4_cur_mb_csbp << 1) + & (~CSBP_LEFT_BLOCK_MASK); + + /*************************************************************************/ + /*u4_nbr_vert_csbp=14C|13C|12C|15L|10C|9C|8C|11L|6C|5C|4C|7L|2C|1C|0C|3L */ + /*************************************************************************/ + UWORD32 u4_nbr_vert_csbp = (u4_cur_mb_masked_csbp) + | (u4_left_mb_masked_csbp >> 3); + + UWORD32 u4_vert_bs2_dec = u4_cur_mb_csbp | u4_nbr_vert_csbp; + + UWORD32 u4_reordered_vert_bs2_dec, u4_temp; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + /*************************************************************************/ + /* Fill horz edges (0,1,2,3) boundary strengths 2 using look up table */ + /*************************************************************************/ + pu4_bs[0] = pu4_packed_bs2[u4_horz_bs2_dec & 0xF]; + pu4_bs[1] = pu4_packed_bs2[(u4_horz_bs2_dec >> 4) & 0xF]; + pu4_bs[2] = pu4_packed_bs2[(u4_horz_bs2_dec >> 8) & 0xF]; + pu4_bs[3] = pu4_packed_bs2[(u4_horz_bs2_dec >> 12) & 0xF]; + + /*************************************************************************/ + /* Do 4x4 tranpose of u4_vert_bs2_dec by using look up table for reorder */ + /*************************************************************************/ + u4_reordered_vert_bs2_dec = pu2_4x4_v2h_reorder[u4_vert_bs2_dec & 0xF]; + u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 4) & 0xF]; + u4_reordered_vert_bs2_dec |= (u4_temp << 1); + u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 8) & 0xF]; + u4_reordered_vert_bs2_dec |= (u4_temp << 2); + u4_temp = pu2_4x4_v2h_reorder[(u4_vert_bs2_dec >> 12) & 0xF]; + u4_reordered_vert_bs2_dec |= (u4_temp << 3); + + /*************************************************************************/ + /* Fill vert edges (4,5,6,7) boundary strengths 2 using look up table */ + /*************************************************************************/ + pu4_bs[4] = pu4_packed_bs2[u4_reordered_vert_bs2_dec & 0xF]; + pu4_bs[5] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 4) & 0xF]; + pu4_bs[6] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 8) & 0xF]; + pu4_bs[7] = pu4_packed_bs2[(u4_reordered_vert_bs2_dec >> 12) & 0xF]; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs1_16x16mb_pslice */ +/* */ +/* Description : This function fills boundray strength (=1) for those */ +/* horz and vert mb edges of 16x16mb which are set to 0 by */ +/* ih264d_fill_bs2_horz_vert. This function is used for p slices */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : If any motion vector component of adjacent 4x4 blocks */ +/* differs by more than 1 integer pel or if reference */ +/* pictures are different, Bs is set to 1. */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs1_16x16mb_pslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, /* picture address for BS calc */ + WORD32 i4_ver_mvlimit) +{ + WORD16 i2_q_mv0, i2_q_mv1; + WORD16 i2_p_mv0, i2_p_mv1; + void *pv_cur_pic_addr0, *pv_cur_pic_addr1; + void *pv_nbr_pic_addr0, *pv_nbr_pic_addr1; + void **ppv_map_ref_idx_to_poc_l0; //,*ppv_map_ref_idx_to_poc_l1; + UWORD32 i; + UWORD32 u4_bs_horz = pu4_bs_table[0]; + UWORD32 u4_bs_vert = pu4_bs_table[4]; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + ppv_map_ref_idx_to_poc_l0 = ppv_map_ref_idx_to_poc; + + i2_q_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_q_mv1 = ps_cur_mv_pred->i2_mv[1]; + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[ps_cur_mv_pred->i1_ref_frame[0]]; + pv_cur_pic_addr1 = 0; + + /*********************************/ + /* Computing Bs for the top edge */ + /*********************************/ + for(i = 0; i < 4; i++, ps_top_mv_pred++) + { + UWORD32 u4_idx = 24 - (i << 3); + + /*********************************/ + /* check if Bs is already set */ + /*********************************/ + if(!((u4_bs_horz >> u4_idx) & 0xf)) + { + /************************************************************/ + /* If Bs is not set, use left edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + UWORD32 u4_bs_temp1; + UWORD32 u4_bs; + + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + i2_p_mv0 = ps_top_mv_pred->i2_mv[0]; + i2_p_mv1 = ps_top_mv_pred->i2_mv[1]; + pv_nbr_pic_addr0 = u4_pic_addrress[i & 2]; + pv_nbr_pic_addr1 = u4_pic_addrress[1 + (i & 2)]; + + u4_bs_temp1 = ((ABS((i2_p_mv0 - i2_q_mv0)) >= 4) || + (ABS((i2_p_mv1 - i2_q_mv1)) >= i4_ver_mvlimit)); + + u4_bs = ((pv_cur_pic_addr0 != pv_nbr_pic_addr0) + || (pv_cur_pic_addr1 != pv_nbr_pic_addr1) + || u4_bs_temp1); + + u4_bs_horz |= (u4_bs << u4_idx); + } + } + pu4_bs_table[0] = u4_bs_horz; + + /***********************************/ + /* Computing Bs for the left edge */ + /***********************************/ + for(i = 0; i < 4; i++, ps_leftmost_mv_pred += 4) + { + UWORD32 u4_idx = 24 - (i << 3); + + /*********************************/ + /* check if Bs is already set */ + /*********************************/ + if(!((u4_bs_vert >> u4_idx) & 0xf)) + { + /****************************************************/ + /* If Bs is not set, evalaute conditions for Bs=1 */ + /****************************************************/ + UWORD32 u4_bs_temp1; + UWORD32 u4_bs; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + i2_p_mv0 = ps_leftmost_mv_pred->i2_mv[0]; + i2_p_mv1 = ps_leftmost_mv_pred->i2_mv[1]; + pv_nbr_pic_addr0 = ps_left_addr->u4_add[i & 2]; + pv_nbr_pic_addr1 = ps_left_addr->u4_add[1 + (i & 2)]; + + u4_bs_temp1 = + ((ABS((i2_p_mv0 - i2_q_mv0)) + >= 4) + | (ABS((i2_p_mv1 - i2_q_mv1)) + >= i4_ver_mvlimit)); + + u4_bs = ((pv_cur_pic_addr0 != pv_nbr_pic_addr0) + || (pv_cur_pic_addr1 != pv_nbr_pic_addr1) + || u4_bs_temp1); + + u4_bs_vert |= (u4_bs << u4_idx); + } + } + pu4_bs_table[4] = u4_bs_vert; + + return; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs1_non16x16mb_pslice */ +/* */ +/* Description : This function fills boundray strength (=1) for those */ +/* horz and vert edges of non16x16mb which are set to 0 by */ +/* ih264d_fill_bs2_horz_vert. This function is used for p slices */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : If any motion vector component of adjacent 4x4 blocks */ +/* differs by more than 1 integer pel or if reference */ +/* pictures are different, Bs is set to 1. */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs1_non16x16mb_pslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit) +{ + UWORD32 edge; + void **ppv_map_ref_idx_to_poc_l0; //,*ppv_map_ref_idx_to_poc_l1; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + ppv_map_ref_idx_to_poc_l0 = ppv_map_ref_idx_to_poc; + + + for(edge = 0; edge < 4; edge++, ps_top_mv_pred = ps_cur_mv_pred - 4) + { + /*********************************************************************/ + /* Each iteration of this loop fills the four BS values of one HORIZ */ + /* edge and one BS value for each of the four VERT edges. */ + /*********************************************************************/ + WORD32 i; + UWORD32 u4_vert_idx = 24 - (edge << 3); + UWORD32 u4_bs_horz = pu4_bs_table[edge]; + mv_pred_t *ps_left_mv_pred = ps_leftmost_mv_pred + (edge << 2); + + for(i = 0; i < 4; i++, ps_top_mv_pred++, ps_cur_mv_pred++) + { + WORD16 i2_cur_mv0, i2_cur_mv1; + WORD8 i1_cur_ref0; + void *pv_cur_pic_addr0, *pv_cur_pic_addr1 = 0; + void *pv_nbr_pic_addr0, *pv_nbr_pic_addr1; + + /******************************************************/ + /* Each iteration of this inner loop computes a HORIZ */ + /* and a VERT BS value for a 4x4 block */ + /******************************************************/ + UWORD32 u4_bs_vert = (pu4_bs_table[i + 4] >> u4_vert_idx) & 0xf; + UWORD32 u4_horz_idx = 24 - (i << 3); + + /*****************************************************/ + /* check if vert Bs for this block is already set */ + /*****************************************************/ + if(!u4_bs_vert) + { + WORD16 i2_left_mv0, i2_left_mv1; + /************************************************************/ + /* If Bs is not set, use left edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + i2_left_mv0 = ps_left_mv_pred->i2_mv[0]; + i2_left_mv1 = ps_left_mv_pred->i2_mv[1]; + + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + if(i) + { + WORD8 i1_left_ref0 = ps_left_mv_pred->i1_ref_frame[0]; + pv_nbr_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_left_ref0]; + pv_nbr_pic_addr1 = 0; + } + else + { + pv_nbr_pic_addr0 = ps_left_addr->u4_add[edge & 2]; + pv_nbr_pic_addr1 = ps_left_addr->u4_add[1 + (edge & 2)]; + } + + { + UWORD32 u4_bs_temp1; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + u4_bs_temp1 = + ((ABS((i2_left_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv1 + - i2_cur_mv1)) + >= i4_ver_mvlimit)); + + u4_bs_vert = ((pv_nbr_pic_addr0 != pv_cur_pic_addr0) + || (pv_nbr_pic_addr1 != pv_cur_pic_addr1) + || u4_bs_temp1); + + pu4_bs_table[i + 4] |= (u4_bs_vert << u4_vert_idx); + } + } + + /*****************************************************/ + /* check if horz Bs for this block is already set */ + /*****************************************************/ + if(!((u4_bs_horz >> u4_horz_idx) & 0xf)) + { + WORD16 i2_top_mv0, i2_top_mv1; + /************************************************************/ + /* If Bs is not set, use top edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + + i2_top_mv0 = ps_top_mv_pred->i2_mv[0]; + i2_top_mv1 = ps_top_mv_pred->i2_mv[1]; + + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + if(edge) + { + WORD8 i1_top_ref0 = ps_top_mv_pred->i1_ref_frame[0]; + pv_nbr_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_top_ref0]; + pv_nbr_pic_addr1 = 0; + } + else + { + pv_nbr_pic_addr0 = u4_pic_addrress[i & 2]; + pv_nbr_pic_addr1 = u4_pic_addrress[1 + (i & 2)]; + } + + { + UWORD32 u4_bs_temp1; + UWORD32 u4_bs; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + u4_bs_temp1 = + ((ABS((i2_top_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_top_mv1 + - i2_cur_mv1)) + >= i4_ver_mvlimit)); + + u4_bs = ((pv_nbr_pic_addr0 != pv_cur_pic_addr0) + || (pv_nbr_pic_addr1 != pv_cur_pic_addr1) + || u4_bs_temp1); + + u4_bs_horz |= (u4_bs << u4_horz_idx); + } + } + + ps_left_mv_pred = ps_cur_mv_pred; + } + + pu4_bs_table[edge] = u4_bs_horz; + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs1_16x16mb_bslice */ +/* */ +/* Description : This function fills boundray strength (=1) for those */ +/* horz and vert mb edges of 16x16mb which are set to 0 by */ +/* ih264d_fill_bs2_horz_vert. This function is used for b slices */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : If any motion vector component of adjacent 4x4 blocks */ +/* differs by more than 1 integer pel or if reference */ +/* pictures are different, Bs is set to 1. */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs1_16x16mb_bslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit) +{ + WORD16 i2_q_mv0, i2_q_mv1, i2_q_mv2, i2_q_mv3; + WORD16 i2_p_mv0, i2_p_mv1, i2_p_mv2, i2_p_mv3; + void *pv_cur_pic_addr0, *pv_cur_pic_addr1; + void *pv_nbr_pic_addr0, *pv_nbr_pic_addr1; + void **ppv_map_ref_idx_to_poc_l0, **ppv_map_ref_idx_to_poc_l1; + UWORD32 i; + UWORD32 u4_bs_horz = pu4_bs_table[0]; + UWORD32 u4_bs_vert = pu4_bs_table[4]; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + ppv_map_ref_idx_to_poc_l0 = ppv_map_ref_idx_to_poc; + ppv_map_ref_idx_to_poc_l1 = ppv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF; + i2_q_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_q_mv1 = ps_cur_mv_pred->i2_mv[1]; + i2_q_mv2 = ps_cur_mv_pred->i2_mv[2]; + i2_q_mv3 = ps_cur_mv_pred->i2_mv[3]; + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[ps_cur_mv_pred->i1_ref_frame[0]]; + pv_cur_pic_addr1 = ppv_map_ref_idx_to_poc_l1[ps_cur_mv_pred->i1_ref_frame[1]]; + + /*********************************/ + /* Computing Bs for the top edge */ + /*********************************/ + for(i = 0; i < 4; i++, ps_top_mv_pred++) + { + UWORD32 u4_idx = 24 - (i << 3); + + /*********************************/ + /* check if Bs is already set */ + /*********************************/ + if(!((u4_bs_horz >> u4_idx) & 0xf)) + { + /************************************************************/ + /* If Bs is not set, use left edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + UWORD32 u4_bs_temp1, u4_bs_temp2; + UWORD32 u4_bs; + + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + i2_p_mv0 = ps_top_mv_pred->i2_mv[0]; + i2_p_mv1 = ps_top_mv_pred->i2_mv[1]; + i2_p_mv2 = ps_top_mv_pred->i2_mv[2]; + i2_p_mv3 = ps_top_mv_pred->i2_mv[3]; + pv_nbr_pic_addr0 = u4_pic_addrress[i & 2]; + pv_nbr_pic_addr1 = u4_pic_addrress[1 + (i & 2)]; + + u4_bs_temp1 = + ((ABS((i2_p_mv0 - i2_q_mv0)) + >= 4) + | (ABS((i2_p_mv1 - i2_q_mv1)) + >= i4_ver_mvlimit) + | (ABS((i2_p_mv2 - i2_q_mv2)) + >= 4) + | (ABS((i2_p_mv3 - i2_q_mv3)) + >= i4_ver_mvlimit)); + + u4_bs_temp2 = + ((ABS((i2_p_mv0 - i2_q_mv2)) + >= 4) + | (ABS((i2_p_mv1 - i2_q_mv3)) + >= i4_ver_mvlimit) + | (ABS((i2_p_mv2 - i2_q_mv0)) + >= 4) + | (ABS((i2_p_mv3 - i2_q_mv1)) + >= i4_ver_mvlimit)); + + u4_bs = ((pv_cur_pic_addr0 != pv_nbr_pic_addr0) + || (pv_cur_pic_addr1 != pv_nbr_pic_addr1) + || u4_bs_temp1) + && ((pv_cur_pic_addr0 != pv_nbr_pic_addr1) + || (pv_cur_pic_addr1 + != pv_nbr_pic_addr0) + || u4_bs_temp2); + + u4_bs_horz |= (u4_bs << u4_idx); + } + } + pu4_bs_table[0] = u4_bs_horz; + + /***********************************/ + /* Computing Bs for the left edge */ + /***********************************/ + for(i = 0; i < 4; i++, ps_leftmost_mv_pred += 4) + { + UWORD32 u4_idx = 24 - (i << 3); + + /*********************************/ + /* check if Bs is already set */ + /*********************************/ + if(!((u4_bs_vert >> u4_idx) & 0xf)) + { + /****************************************************/ + /* If Bs is not set, evalaute conditions for Bs=1 */ + /****************************************************/ + UWORD32 u4_bs_temp1, u4_bs_temp2; + UWORD32 u4_bs; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + i2_p_mv0 = ps_leftmost_mv_pred->i2_mv[0]; + i2_p_mv1 = ps_leftmost_mv_pred->i2_mv[1]; + i2_p_mv2 = ps_leftmost_mv_pred->i2_mv[2]; + i2_p_mv3 = ps_leftmost_mv_pred->i2_mv[3]; + pv_nbr_pic_addr0 = ps_left_addr->u4_add[i & 2]; + pv_nbr_pic_addr1 = ps_left_addr->u4_add[1 + (i & 2)]; + + u4_bs_temp1 = + ((ABS((i2_p_mv0 - i2_q_mv0)) + >= 4) + | (ABS((i2_p_mv1 - i2_q_mv1)) + >= i4_ver_mvlimit) + | (ABS((i2_p_mv2 - i2_q_mv2)) + >= 4) + | (ABS((i2_p_mv3 - i2_q_mv3)) + >= i4_ver_mvlimit)); + + u4_bs_temp2 = + ((ABS((i2_p_mv0 - i2_q_mv2)) + >= 4) + | (ABS((i2_p_mv1 - i2_q_mv3)) + >= i4_ver_mvlimit) + | (ABS((i2_p_mv2 - i2_q_mv0)) + >= 4) + | (ABS((i2_p_mv3 - i2_q_mv1)) + >= i4_ver_mvlimit)); + + u4_bs = ((pv_cur_pic_addr0 != pv_nbr_pic_addr0) + || (pv_cur_pic_addr1 != pv_nbr_pic_addr1) + || u4_bs_temp1) + && ((pv_cur_pic_addr0 != pv_nbr_pic_addr1) + || (pv_cur_pic_addr1 + != pv_nbr_pic_addr0) + || u4_bs_temp2); + + u4_bs_vert |= (u4_bs << u4_idx); + } + } + pu4_bs_table[4] = u4_bs_vert; + + return; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs1_non16x16mb_bslice */ +/* */ +/* Description : This function fills boundray strength (=1) for those */ +/* horz and vert edges of non16x16mb which are set to 0 by */ +/* ih264d_fill_bs2_horz_vert. This function is used for b slices */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : If any motion vector component of adjacent 4x4 blocks */ +/* differs by more than 1 integer pel or if reference */ +/* pictures are different, Bs is set to 1. */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs1_non16x16mb_bslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit) +{ + UWORD32 edge; + void **ppv_map_ref_idx_to_poc_l0, **ppv_map_ref_idx_to_poc_l1; + ppv_map_ref_idx_to_poc_l0 = ppv_map_ref_idx_to_poc; + ppv_map_ref_idx_to_poc_l1 = ppv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + for(edge = 0; edge < 4; edge++, ps_top_mv_pred = ps_cur_mv_pred - 4) + { + /*********************************************************************/ + /* Each iteration of this loop fills the four BS values of one HORIZ */ + /* edge and one BS value for each of the four VERT edges. */ + /*********************************************************************/ + WORD32 i; + UWORD32 u4_vert_idx = 24 - (edge << 3); + UWORD32 u4_bs_horz = pu4_bs_table[edge]; + mv_pred_t *ps_left_mv_pred = ps_leftmost_mv_pred + (edge << 2); + + for(i = 0; i < 4; i++, ps_top_mv_pred++, ps_cur_mv_pred++) + { + WORD16 i2_cur_mv0, i2_cur_mv1, i16_curMv2, i16_curMv3; + WORD8 i1_cur_ref0, i1_cur_ref1; + void *pv_cur_pic_addr0, *pv_cur_pic_addr1; + void *pv_nbr_pic_addr0, *pv_nbr_pic_addr1; + + /******************************************************/ + /* Each iteration of this inner loop computes a HORIZ */ + /* and a VERT BS value for a 4x4 block */ + /******************************************************/ + UWORD32 u4_bs_vert = (pu4_bs_table[i + 4] >> u4_vert_idx) & 0xf; + UWORD32 u4_horz_idx = 24 - (i << 3); + + /*****************************************************/ + /* check if vert Bs for this block is already set */ + /*****************************************************/ + if(!u4_bs_vert) + { + WORD16 i2_left_mv0, i2_left_mv1, i2_left_mv2, i2_left_mv3; + /************************************************************/ + /* If Bs is not set, use left edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + i2_left_mv0 = ps_left_mv_pred->i2_mv[0]; + i2_left_mv1 = ps_left_mv_pred->i2_mv[1]; + i2_left_mv2 = ps_left_mv_pred->i2_mv[2]; + i2_left_mv3 = ps_left_mv_pred->i2_mv[3]; + + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + i16_curMv2 = ps_cur_mv_pred->i2_mv[2]; + i16_curMv3 = ps_cur_mv_pred->i2_mv[3]; + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + i1_cur_ref1 = ps_cur_mv_pred->i1_ref_frame[1]; + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + pv_cur_pic_addr1 = ppv_map_ref_idx_to_poc_l1[i1_cur_ref1]; + + if(i) + { + WORD8 i1_left_ref0, i1_left_ref1; + i1_left_ref0 = ps_left_mv_pred->i1_ref_frame[0]; + i1_left_ref1 = ps_left_mv_pred->i1_ref_frame[1]; + pv_nbr_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_left_ref0]; + pv_nbr_pic_addr1 = ppv_map_ref_idx_to_poc_l1[i1_left_ref1]; + } + else + { + pv_nbr_pic_addr0 = ps_left_addr->u4_add[edge & 2]; + pv_nbr_pic_addr1 = ps_left_addr->u4_add[1 + (edge & 2)]; + } + + { + UWORD32 u4_bs_temp1, u4_bs_temp2; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + u4_bs_temp1 = + ((ABS((i2_left_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv1 + - i2_cur_mv1)) + >= i4_ver_mvlimit) + | (ABS((i2_left_mv2 + - i16_curMv2)) + >= 4) + | (ABS((i2_left_mv3 + - i16_curMv3)) + >= i4_ver_mvlimit)); + + u4_bs_temp2 = + ((ABS((i2_left_mv0 - i16_curMv2)) + >= 4) + | (ABS((i2_left_mv1 + - i16_curMv3)) + >= i4_ver_mvlimit) + | (ABS((i2_left_mv2 + - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv3 + - i2_cur_mv1)) + >= i4_ver_mvlimit)); + + u4_bs_vert = + ((pv_nbr_pic_addr0 != pv_cur_pic_addr0) + || (pv_nbr_pic_addr1 + != pv_cur_pic_addr1) + || u4_bs_temp1) + && ((pv_nbr_pic_addr0 + != pv_cur_pic_addr1) + || (pv_nbr_pic_addr1 + != pv_cur_pic_addr0) + || u4_bs_temp2); + + pu4_bs_table[i + 4] |= (u4_bs_vert << u4_vert_idx); + } + } + + /*****************************************************/ + /* check if horz Bs for this block is already set */ + /*****************************************************/ + if(!((u4_bs_horz >> u4_horz_idx) & 0xf)) + { + WORD16 i2_top_mv0, i2_top_mv1, i16_topMv2, i16_topMv3; + /************************************************************/ + /* If Bs is not set, use top edge and current edge mvs and */ + /* reference pictures addresses to evaluate Bs==1 */ + /************************************************************/ + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + i16_curMv2 = ps_cur_mv_pred->i2_mv[2]; + i16_curMv3 = ps_cur_mv_pred->i2_mv[3]; + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + i1_cur_ref1 = ps_cur_mv_pred->i1_ref_frame[1]; + + i2_top_mv0 = ps_top_mv_pred->i2_mv[0]; + i2_top_mv1 = ps_top_mv_pred->i2_mv[1]; + i16_topMv2 = ps_top_mv_pred->i2_mv[2]; + i16_topMv3 = ps_top_mv_pred->i2_mv[3]; + pv_cur_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + pv_cur_pic_addr1 = ppv_map_ref_idx_to_poc_l1[i1_cur_ref1]; + if(edge) + { + WORD8 i1_top_ref0, i1_top_ref1; + i1_top_ref0 = ps_top_mv_pred->i1_ref_frame[0]; + i1_top_ref1 = ps_top_mv_pred->i1_ref_frame[1]; + pv_nbr_pic_addr0 = ppv_map_ref_idx_to_poc_l0[i1_top_ref0]; + pv_nbr_pic_addr1 = ppv_map_ref_idx_to_poc_l1[i1_top_ref1]; + } + else + { + pv_nbr_pic_addr0 = u4_pic_addrress[i & 2]; + pv_nbr_pic_addr1 = u4_pic_addrress[1 + (i & 2)]; + } + + { + UWORD32 u4_bs_temp1, u4_bs_temp2; + UWORD32 u4_bs; + /*********************************************************/ + /* If any motion vector component differs by more than 1 */ + /* integer pel or if reference pictures are different Bs */ + /* is set to 1. Note that this condition shall be met for*/ + /* both (fwd-fwd,bwd-bwd) and (fwd-bwd,bwd-fwd) direction*/ + /*********************************************************/ + + u4_bs_temp1 = + ((ABS((i2_top_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_top_mv1 + - i2_cur_mv1)) + >= i4_ver_mvlimit) + | (ABS((i16_topMv2 + - i16_curMv2)) + >= 4) + | (ABS((i16_topMv3 + - i16_curMv3)) + >= i4_ver_mvlimit)); + + u4_bs_temp2 = + ((ABS((i2_top_mv0 - i16_curMv2)) + >= 4) + | (ABS((i2_top_mv1 + - i16_curMv3)) + >= i4_ver_mvlimit) + | (ABS((i16_topMv2 + - i2_cur_mv0)) + >= 4) + | (ABS((i16_topMv3 + - i2_cur_mv1)) + >= i4_ver_mvlimit)); + + u4_bs = + ((pv_nbr_pic_addr0 != pv_cur_pic_addr0) + || (pv_nbr_pic_addr1 + != pv_cur_pic_addr1) + || u4_bs_temp1) + && ((pv_nbr_pic_addr0 + != pv_cur_pic_addr1) + || (pv_nbr_pic_addr1 + != pv_cur_pic_addr0) + || u4_bs_temp2); + + u4_bs_horz |= (u4_bs << u4_horz_idx); + } + } + + ps_left_mv_pred = ps_cur_mv_pred; + } + + pu4_bs_table[edge] = u4_bs_horz; + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs_xtra_left_edge_cur_fld */ +/* */ +/* Description : This function fills boundray strength (= 2 or 1) for */ +/* xtra left mb edge when cur mb is field and left mb is */ +/* frame. */ +/* Inputs : */ +/* */ +/* Globals : <Does it use any global variables?> */ +/* Processing : */ +/* */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs_xtra_left_edge_cur_fld(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_left_mb_t_csbp, /* left mbpair's top csbp */ + WORD32 u4_left_mb_b_csbp, /* left mbpair's bottom csbp*/ + WORD32 u4_cur_mb_csbp, /* csbp of current mb */ + UWORD32 u4_cur_mb_top /* is top or bottom mb */ + + ) +{ + const UWORD32 *pu4_packed_bs = (const UWORD32 *)gau4_ih264d_packed_bs2; + UWORD32 u4_cur, u4_left, u4_or; + UNUSED(u4_cur_mb_top); + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + u4_left_mb_t_csbp = ((u4_left_mb_t_csbp & 0x0008) >> 3) + + ((u4_left_mb_t_csbp & 0x0080) >> 6) + + ((u4_left_mb_t_csbp & 0x0800) >> 9) + + ((u4_left_mb_t_csbp & 0x8000) >> 12); + + u4_left_mb_b_csbp = ((u4_left_mb_b_csbp & 0x0008) << 1) + + ((u4_left_mb_b_csbp & 0x0080) >> 2) + + ((u4_left_mb_b_csbp & 0x0800) >> 5) + + ((u4_left_mb_b_csbp & 0x8000) >> 8); + + /*********************************************************************/ + /* u4_cur = 0|0|0|0|0|0|0|0|12C|12C|8C|8C|4C|4C|0C|0C */ + /*********************************************************************/ + u4_cur = (u4_cur_mb_csbp & 0x0001) + ((u4_cur_mb_csbp & 0x0001) << 1) + + ((u4_cur_mb_csbp & 0x0010) >> 2) + + ((u4_cur_mb_csbp & 0x0010) >> 1) + + ((u4_cur_mb_csbp & 0x0100) >> 4) + + ((u4_cur_mb_csbp & 0x0100) >> 3) + + ((u4_cur_mb_csbp & 0x1000) >> 6) + + ((u4_cur_mb_csbp & 0x1000) >> 5); + + /*********************************************************************/ + /* u4_left =0|0|0|0|0|0|0|0|15Lb|11Lb|7Lb|3Lb|15Lt|11Lt|7Lt|3Lt */ + /*********************************************************************/ + u4_left = u4_left_mb_t_csbp + u4_left_mb_b_csbp; + + u4_or = (u4_cur | u4_left); + /*********************************************************************/ + /* Fill vert edges (4,9) boundary strengths using look up table */ + /*********************************************************************/ + pu4_packed_bs += 16; + pu4_bs[4] = pu4_packed_bs[u4_or & 0xF]; + pu4_bs[9] = pu4_packed_bs[(u4_or >> 4)]; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs_xtra_left_edge_cur_frm */ +/* */ +/* Description : This function fills boundray strength (= 2 or 1) for */ +/* xtra left mb edge when cur mb is frame and left mb is */ +/* field. */ +/* Inputs : */ +/* */ +/* Globals : <Does it use any global variables?> */ +/* Processing : */ +/* */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs_xtra_left_edge_cur_frm(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_left_mb_t_csbp, /* left mbpair's top csbp */ + WORD32 u4_left_mb_b_csbp, /* left mbpair's bottom csbp*/ + WORD32 u4_cur_mb_csbp, /* csbp of current mb */ + UWORD32 u4_cur_mb_bot /* is top or bottom mb */ + + ) +{ + const UWORD32 *pu4_packed_bs = (const UWORD32 *)gau4_ih264d_packed_bs2; + UWORD32 u4_cur, u4_left, u4_or; + UWORD32 u4_right_shift = (u4_cur_mb_bot << 3); + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + u4_left_mb_t_csbp >>= u4_right_shift; + u4_left_mb_b_csbp >>= u4_right_shift; + + u4_left_mb_t_csbp = ((u4_left_mb_t_csbp & 0x08) >> 3) + + ((u4_left_mb_t_csbp & 0x08) >> 2) + + ((u4_left_mb_t_csbp & 0x80) >> 5) + + ((u4_left_mb_t_csbp & 0x80) >> 4); + + u4_left_mb_b_csbp = ((u4_left_mb_b_csbp & 0x08) << 1) + + ((u4_left_mb_b_csbp & 0x08) << 2) + + ((u4_left_mb_b_csbp & 0x80) >> 1) + + ((u4_left_mb_b_csbp & 0x80)); + + u4_cur = ((u4_cur_mb_csbp & 0x0001)) + ((u4_cur_mb_csbp & 0x0010) >> 3) + + ((u4_cur_mb_csbp & 0x0100) >> 6) + + ((u4_cur_mb_csbp & 0x1000) >> 9); + + u4_cur += (u4_cur << 4); + + u4_left = u4_left_mb_t_csbp + u4_left_mb_b_csbp; + + u4_or = (u4_cur | u4_left); + /*********************************************************************/ + /* Fill vert edges (4,9) boundary strengths using look up table */ + /*********************************************************************/ + pu4_packed_bs += 16; + pu4_bs[4] = pu4_packed_bs[u4_or & 0xF]; + pu4_bs[9] = pu4_packed_bs[(u4_or >> 4)]; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_fill_bs_xtra_top_edge */ +/* */ +/* Description : This function fills boundray strength (= 2 or 1) for */ +/* xtra top mb edge when cur mb is top mb of frame mb pair */ +/* and top mbpair is field coded. */ +/* Inputs : */ +/* */ +/* Globals : <Does it use any global variables?> */ +/* Processing : */ +/* */ +/* */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_fill_bs_xtra_top_edge(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_topmb_t_csbp, /* top mbpair's top csbp */ + WORD32 u4_topmb_b_csbp, /* top mbpair's bottom csbp*/ + WORD32 u4_cur_mb_csbp /* csbp of current mb */ + + ) +{ + const UWORD32 *pu4_packed_bs = (const UWORD32 *)gau4_ih264d_packed_bs2; + UWORD32 u4_or; + + u4_cur_mb_csbp &= 0xf; + u4_topmb_t_csbp >>= 12; + u4_topmb_b_csbp >>= 12; + + u4_or = (u4_cur_mb_csbp | u4_topmb_t_csbp); + /*********************************************************************/ + /* Fill vert edges (0,8) boundary strengths using look up table */ + /*********************************************************************/ + pu4_packed_bs += 16; + pu4_bs[8] = pu4_packed_bs[u4_or]; + + u4_or = (u4_cur_mb_csbp | u4_topmb_b_csbp); + pu4_bs[0] = pu4_packed_bs[u4_or]; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_compute_bs_non_mbaff */ +/* */ +/* Description : This function computes the pointers of left,top & current*/ +/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function for*/ +/* : Boundary Strength Calculation */ +/* Inputs : <What inputs does the function take?> */ +/* Processing : This functions calls deblock MB in the MB increment order*/ +/* */ +/* Outputs : Produces the Boundary Strength for Current Mb */ +/* Returns : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* ITTIAM */ +/*****************************************************************************/ + +void ih264d_compute_bs_non_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb) +{ + /* Mvpred and Nnz for top and Courrent */ + mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred; + /* deblk_mb_t Params */ + deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */ + deblkmb_neighbour_t *ps_deblk_top_mb; + + /* Reference Index to POC mapping*/ + void ** apv_map_ref_idx_to_poc; + UWORD32 u4_leftmbtype; + + UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp; + + /* Set of flags */ + UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld; + UWORD32 u1_cur_mb_type; + UWORD32 * pu4_bs_table; + + /* Neighbour availability */ + /* Initialization */ + const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx; + const UWORD32 u2_mby = ps_cur_mb_info->u2_mby; + const UWORD32 u1_pingpong = u2_mbx & 0x01; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx; + + + /* Pointer assignment for Current DeblkMB, Current Mv Pred */ + ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb; + ps_cur_mv_pred = ps_dec->ps_mv_cur + (u2_mbxn_mb << 4); + + apv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc + 1; + u1_cur_mb_type = ps_cur_mb_params->u1_mb_type; + u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type; + ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type; + + { + UWORD8 mb_qp_temp; + + ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp; + ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp; + ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + } + + /* if no deblocking required for current Mb then continue */ + /* Check next Mbs in Mb group */ + if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING) + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + { + /* Store Parameter for Top MvPred refernce frame Address */ + + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + + /* Store Left addresses for Next Mb */ + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add; + WORD8 * p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + + + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]]; + //} + /* Storing the leftMbtype for next Mb */ + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + } + + return; + } + + /* Flag for extra left Edge */ + ps_cur_mb_params->u1_single_call = 1; + + /* Update the Left deblk_mb_t and Left MvPred Parameters */ + if(!u2_mbx) + { + u4_leftmbtype = 0; + + /* Initialize the ps_left_mv_pred with Junk but Valid Location */ + /* to avoid invalid memory access */ + /* this is read only pointer */ + ps_left_mv_pred = ps_dec->ps_mv_cur + 3; + } + else + { + u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type; + + /* Come to Left Most Edge of the MB */ + ps_left_mv_pred = (u2_mbxn_mb) ? + ps_dec->ps_mv_cur + ((u2_mbxn_mb - 1) << 4) + 3 : + ps_dec->ps_mv_left + 3; + } + + if(!u2_mby) + u1_top_mb_typ = 0; + + /* MvPred Pointer Calculation */ + /* CHANGED CODE */ + ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 4) + 12; + + u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB; + u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB); + /* Compute BS function */ + pu4_bs_table = ps_cur_mb_params->u4_bs_table; + + u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp; + u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp; + u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp; + /* Compute BS function */ + if(ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) + { + if(ps_cur_mb_info->u1_tran_form8x8 == 1) + { + u2_cur_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_curmb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_left_mb->u1_tran_form8x8 == 1) + { + u2_left_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_left_mb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_top_mb->u1_tran_form8x8 == 1) + { + u2_top_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_top_mb->u2_luma_csbp); + } + } + if(u4_cur_mb_intra) + { + + pu4_bs_table[4] = 0x04040404; + pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404; + pu4_bs_table[1] = 0x03030303; + pu4_bs_table[2] = 0x03030303; + pu4_bs_table[3] = 0x03030303; + pu4_bs_table[5] = 0x03030303; + pu4_bs_table[6] = 0x03030303; + pu4_bs_table[7] = 0x03030303; + } + else + { + UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16); + UWORD32 u4_is_b = ps_dec->u1_B; + + ih264d_fill_bs2_horz_vert( + pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp, + (const UWORD32 *)(gau4_ih264d_packed_bs2), + (const UWORD16 *)(gau2_ih264d_4x4_v2h_reorder)); + + if(u4_leftmbtype & D_INTRA_MB) + pu4_bs_table[4] = 0x04040404; + + if(u1_top_mb_typ & D_INTRA_MB) + pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404; + + ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16]( + ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, + pu4_bs_table, ps_left_mv_pred, + &(ps_dec->ps_left_mvpred_addr[u1_pingpong][1]), + ps_cur_mb_info->ps_top_mb->u4_pic_addrress, + (4 >> u4_cur_mb_fld)); + } + + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + { + /* Store Parameter for Top MvPred refernce frame Address */ + + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + + /* Store Left addresses for Next Mb */ + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add; + WORD8 * p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]]; + + /* Storing the leftMbtype for next Mb */ + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + + } + } + + /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pu4_bs_table[1] = 0; + pu4_bs_table[3] = 0; + pu4_bs_table[5] = 0; + pu4_bs_table[7] = 0; + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_compute_bs_mbaff */ +/* */ +/* Description : This function computes the pointers of left,top & current*/ +/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function for*/ +/* : Boundary Strength Calculation */ +/* Inputs : <What inputs does the function take?> */ +/* Processing : This functions calls deblock MB in the MB increment order*/ +/* */ +/* Outputs : Produces the Boundary Strength for Current Mb */ +/* Returns : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* ITTIAM */ +/*****************************************************************************/ + +void ih264d_compute_bs_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb) +{ + /* Mvpred and Nnz for top and Courrent */ + mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred; + /* deblk_mb_t Params */ + deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */ + neighbouradd_t * ps_left_ngbr; + deblkmb_neighbour_t *ps_deblk_top_mb; + /* Reference Index to POC mapping*/ + void ** apv_map_ref_idx_to_poc; + + UWORD32 u4_leftmbtype; + + + UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp; + + /* Set of flags */ + UWORD32 u4_cur_mb_intra, u4_cur_mb_fld, u4_top_mb_fld, u1_top_mb_typ, u4_left_mb_fld; + UWORD32 u1_cur_mb_type; + UWORD32 * pu4_bs_table; + const UWORD32 u4_bot_mb = (1 - ps_cur_mb_info->u1_topmb); + /* Initialization */ + const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx; + const UWORD32 u2_mby = ps_cur_mb_info->u2_mby; + /* Load From u1_pingpong and Store in !u1_pingpong */ + const UWORD32 u1_pingpong = u2_mbx & 0x01; + + PROFILE_DISABLE_BOUNDARY_STRENGTH() + + ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + (u2_mbx << 1); + + + /************************************************/ + /* Initialize the left Mb type */ + /* Left MvPred */ + /************************************************/ + + if(!u2_mbx) + { + /************************************************************/ + /* Initialize the ps_left_mv_pred with Junk but Valid Location */ + /* to avoid invalid memory access */ + /* this is read only pointer */ + /************************************************************/ + ps_left_mv_pred = ps_dec->ps_mv_cur + 16; + } + else + { + /* Come to Left Most Edge of the MB */ + ps_left_mv_pred = (u2_mbxn_mb) ? + ps_dec->ps_mv_cur + ((u2_mbxn_mb - 1) << 5) + 3 : + ps_dec->ps_mv_left + 3; + + ps_left_mv_pred += (u4_bot_mb << 4); + } + + u4_leftmbtype = ps_dec->deblk_left_mb[u4_bot_mb].u1_mb_type; + + ps_left_ngbr = &(ps_dec->ps_left_mvpred_addr[u1_pingpong][u4_bot_mb]); + + /************************************************/ + /* Pointer Assignment for Current Mb Parameters */ + /* Pointer Assignment for Current MvPred */ + /************************************************/ + ps_cur_mb_params = ps_dec->ps_deblk_mbn + (u2_mbxn_mb << 1) + u4_bot_mb; + u1_cur_mb_type = ps_cur_mb_params->u1_mb_type; + + ps_cur_mv_pred = ps_dec->ps_mv_cur + (u2_mbxn_mb << 5); + ps_cur_mv_pred += (u4_bot_mb << 4); + + /********************************************/ + /* Pointer Assignment for Top Mb Parameters */ + /* Pointer Assignment for Top MvPred and */ + /* Pointer Assignment for Top Nnz */ + /********************************************/ + + /* CHANGED CODE */ + ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 5) + 12; + + u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB); + u4_left_mb_fld = !!(ps_dec->deblk_left_mb[0].u1_mb_type & D_FLD_MB); + + if(u4_left_mb_fld != u4_cur_mb_fld) + { + /* Flag for extra left Edge */ + ps_cur_mb_params->u1_single_call = 0; + + if(u4_bot_mb) + { + ps_left_ngbr--; + ps_left_mv_pred -= 16; + } + } + else + ps_cur_mb_params->u1_single_call = 1; + + apv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc + 1; + if(u4_cur_mb_fld) + { + if(u4_bot_mb) + { + apv_map_ref_idx_to_poc += BOT_LIST_FLD_L0; + } + else + { + apv_map_ref_idx_to_poc += TOP_LIST_FLD_L0; + } + } + + /**********************************************************/ + /* if no deblocking required for current Mb then continue */ + /**********************************************************/ + if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING) + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + + { + /* Store Parameter for Top MvPred refernce frame Address */ + + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][u4_bot_mb].u4_add; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + WORD8 * p1_refLeft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refLeft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refLeft0[1]]; + } + if(u4_bot_mb) + { + /* store The Left Mb Type*/ + ps_dec->deblk_left_mb[0].u1_mb_type = + (ps_cur_mb_params - 1)->u1_mb_type; + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + + } + ps_deblk_top_mb[u4_bot_mb].u1_mb_type = u1_cur_mb_type; + return; + } + + if(u2_mby) + { + u1_top_mb_typ = ps_deblk_top_mb[1].u1_mb_type; + u4_top_mb_fld = !!(u1_top_mb_typ & D_FLD_MB); + + if(!u4_bot_mb) + { + if(u4_top_mb_fld & u4_cur_mb_fld) + u1_top_mb_typ = ps_deblk_top_mb[0].u1_mb_type; + else + { + ps_top_mv_pred += 16; + } + } + } + else + { + u4_top_mb_fld = u4_cur_mb_fld; + u1_top_mb_typ = 0; + } + + if(u4_bot_mb & !u4_cur_mb_fld) + { + u1_top_mb_typ = ps_deblk_top_mb[0].u1_mb_type; + u4_top_mb_fld = u4_cur_mb_fld; + ps_top_mv_pred = ps_cur_mv_pred - 4; + } + + pu4_bs_table = ps_cur_mb_params->u4_bs_table; + u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB; + + u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp; + u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp; + u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp; + /* Compute BS function */ + if(ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) + { + + if(ps_cur_mb_info->u1_tran_form8x8 == 1) + { + u2_cur_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_curmb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_left_mb->u1_tran_form8x8 == 1) + { + u2_left_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_left_mb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_top_mb->u1_tran_form8x8 == 1) + { + u2_top_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_top_mb->u2_luma_csbp); + } + } + if(u4_cur_mb_intra) + { + + pu4_bs_table[4] = 0x04040404; + if((0 == u4_cur_mb_fld) && (0 == u4_top_mb_fld)) + { + pu4_bs_table[0] = 0x04040404; + } + else + { + pu4_bs_table[0] = 0x03030303; + } + + pu4_bs_table[1] = 0x03030303; + pu4_bs_table[2] = 0x03030303; + pu4_bs_table[3] = 0x03030303; + pu4_bs_table[5] = 0x03030303; + pu4_bs_table[6] = 0x03030303; + pu4_bs_table[7] = 0x03030303; + + /*********************************************************************/ + /* Fill Bs of xtra top and left edge unconditionally to avoid checks */ + /*********************************************************************/ + pu4_bs_table[8] = 0x03030303; + pu4_bs_table[9] = 0x04040404; + } + else + { + UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16); + UWORD32 u4_is_b = ps_dec->u1_B; + + ih264d_fill_bs2_horz_vert( + pu4_bs_table, u2_left_csbp, u2_top_csbp, u2_cur_csbp, + (const UWORD32 *)(gau4_ih264d_packed_bs2), + (const UWORD16 *)(gau2_ih264d_4x4_v2h_reorder)); + + if(u4_leftmbtype & D_INTRA_MB) + pu4_bs_table[4] = 0x04040404; + + if(u1_top_mb_typ & D_INTRA_MB) + pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404; + else if(u4_cur_mb_fld != u4_top_mb_fld) + { + /****************************************************/ + /* Setting BS for mixed mode edge=1 when (Bs!=2) */ + /****************************************************/ + pu4_bs_table[0] = (pu4_bs_table[0] >> 1) + 0x01010101; + } + + { + /* Call to Compute Boundary Strength for Extra Left Edge */ + if(u2_mbx + && !(ps_cur_mb_params->u1_deblocking_mode + & MB_DISABLE_LEFT_EDGE)) + { + if(u4_cur_mb_fld != u4_left_mb_fld) + { + UWORD32 u4_left_mb_t_csbp = + ps_cur_mb_info->ps_left_mb[0].u2_luma_csbp; + UWORD32 u4_left_mb_b_csbp = + ps_cur_mb_info->ps_left_mb[1].u2_luma_csbp; + if(1 == ps_cur_mb_info->ps_left_mb[0].u1_tran_form8x8) + { + u4_left_mb_t_csbp = (UWORD32)ih264d_update_csbp_8x8( + (UWORD16)u4_left_mb_t_csbp); + } + + if(1 == ps_cur_mb_info->ps_left_mb[1].u1_tran_form8x8) + { + u4_left_mb_b_csbp = (UWORD32)ih264d_update_csbp_8x8( + (UWORD16)u4_left_mb_b_csbp); + } + ps_dec->pf_fill_bs_xtra_left_edge[u4_cur_mb_fld]( + pu4_bs_table, u4_left_mb_t_csbp, + u4_left_mb_b_csbp, u2_cur_csbp, u4_bot_mb); + + if(ps_dec->deblk_left_mb[0].u1_mb_type & D_INTRA_MB) + pu4_bs_table[4] = 0x04040404; + + if(ps_dec->deblk_left_mb[1].u1_mb_type & D_INTRA_MB) + pu4_bs_table[9] = 0x04040404; + + } + } + /* Call to Compute Boundary Strength for Extra Top Edge */ + if(u2_mby + && !(ps_cur_mb_params->u1_deblocking_mode + & MB_DISABLE_TOP_EDGE)) + { + if((((!u4_bot_mb) & (!u4_cur_mb_fld)) && u4_top_mb_fld)) + { + UWORD32 u4_topmb_t_csbp = + ps_cur_mb_info->ps_top_mb[-1].u2_luma_csbp; + UWORD32 u4_topmb_b_csbp = + ps_cur_mb_info->ps_top_mb[0].u2_luma_csbp; + if(1 == ps_cur_mb_info->ps_top_mb[-1].u1_tran_form8x8) + { + u4_topmb_t_csbp = (UWORD32)ih264d_update_csbp_8x8( + (UWORD16)u4_topmb_t_csbp); + } + + if(1 == ps_cur_mb_info->ps_top_mb[0].u1_tran_form8x8) + { + u4_topmb_b_csbp = (UWORD32)ih264d_update_csbp_8x8( + (UWORD16)u4_topmb_b_csbp); + } + ih264d_fill_bs_xtra_top_edge(pu4_bs_table, u4_topmb_t_csbp, + u4_topmb_b_csbp, u2_cur_csbp); + + if(ps_deblk_top_mb[0].u1_mb_type & D_INTRA_MB) + pu4_bs_table[8] = 0x03030303; + + if(ps_deblk_top_mb[1].u1_mb_type & D_INTRA_MB) + pu4_bs_table[0] = 0x03030303; + } + } + } + + ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16]( + ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, + pu4_bs_table, ps_left_mv_pred, ps_left_ngbr, + ps_cur_mb_info->ps_top_mb->u4_pic_addrress, + (4 >> u4_cur_mb_fld)); + } + + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + + { + /* Store Parameter for Top MvPred refernce frame Address */ + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][u4_bot_mb].u4_add; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + WORD8 * p1_refLeft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refLeft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refLeft0[1]]; + } + if(u4_bot_mb) + { + /* store The Left Mb Type*/ + ps_dec->deblk_left_mb[0].u1_mb_type = + (ps_cur_mb_params - 1)->u1_mb_type; + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + + } + ps_deblk_top_mb[u4_bot_mb].u1_mb_type = u1_cur_mb_type; + } + /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pu4_bs_table[1] = 0; + pu4_bs_table[3] = 0; + pu4_bs_table[5] = 0; + pu4_bs_table[7] = 0; + } + +} + + + +/*! + ************************************************************************** + * \if Function name : ih264d_fill_bs_for_mb \endif + * + * \brief + * Determines the boundary strength (Bs), for the complete MB. Bs is + * determined for each block boundary between two neighbouring 4x4 + * luma blocks, then packed in a UWORD32, first Bs placed in MSB and + * so on. Such packed Bs values for all 8 edges are kept in an array. + * + * \return + * Returns the packed boundary strength(Bs) MSB -> LSB Bs0|Bs1|Bs2|Bs3 + * + ************************************************************************** + */ + +void ih264d_fill_bs_for_mb(deblk_mb_t * ps_cur_mb_params, + deblk_mb_t * ps_top_mb_params, + deblk_mb_t * ps_left_mb_params, + mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + UWORD8 *puc_cur_nnz, + UWORD8 *puc_top_nnz, + void **ppv_map_ref_idx_to_poc, + UWORD32 ui_mbAff, + UWORD32 ui_bs_table[], /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + neighbouradd_t *ps_top_add) +{ + UWORD32 u4_bs_horz = 0; + UWORD8 edge, u1_top_intra = 0, u1_left_intra = 0; + mv_pred_t *ps_left_mv_pred; + WORD16 i2_cur_mv0, i2_cur_mv1, i16_curMv2, i16_curMv3; + WORD16 i2_left_mv0, i2_left_mv1, i2_left_mv2, i2_left_mv3; + WORD16 i2_top_mv0, i2_top_mv1, i16_topMv2, i16_topMv3; + WORD8 i1_cur_ref0, i1_cur_ref1, i1_left_ref0, i1_left_ref1, i1_top_ref0, i1_top_ref1; + UWORD8 uc_cur_nnz, uc_left_nnz, uc_top_nnz, u1_mb_type, uc_Bslice; + void **ppv_map_ref_idx_to_poc_l0, **ppv_map_ref_idx_to_poc_l1; + UWORD8 uc_temp; + UWORD8 uc_cur_mb_fld, uc_top_mb_fld; + UWORD32 c_mv_limit; + + u1_mb_type = ps_cur_mb_params->u1_mb_type; + uc_Bslice = u1_mb_type & D_B_SLICE; + ppv_map_ref_idx_to_poc_l0 = ppv_map_ref_idx_to_poc; + ppv_map_ref_idx_to_poc_l1 = ppv_map_ref_idx_to_poc + POC_LIST_L0_TO_L1_DIFF; + + ps_top_mb_params = ps_top_mb_params ? ps_top_mb_params : ps_cur_mb_params; + u1_top_intra = ps_top_mb_params->u1_mb_type & D_INTRA_MB; + u1_left_intra = ps_left_mb_params->u1_mb_type & D_INTRA_MB; + + ui_bs_table[4] = 0x04040404; //Default for INTRA MB Boundary edges. + uc_cur_mb_fld = (ps_cur_mb_params->u1_mb_type & D_FLD_MB) >> 7; + uc_top_mb_fld = (ps_top_mb_params->u1_mb_type & D_FLD_MB) >> 7; + + c_mv_limit = 4 >> uc_cur_mb_fld; + if((0 == uc_cur_mb_fld) && (0 == uc_top_mb_fld)) + { + ui_bs_table[0] = 0x04040404; + } + else + { + ui_bs_table[0] = 0x03030303; + } + + for(edge = 0; edge < 4; + edge++, ps_top_mv_pred = ps_cur_mv_pred - 4, puc_top_nnz = + puc_cur_nnz - 4) + { + //Each iteration of this loop fills the four BS values of one HORIZ edge and + //one BS value for each of the four VERT edges. + WORD8 i = 0; + UWORD8 uc_bs_horiz, uc_bs_vert; + UWORD32 ui_cnd; + void *ui_ref_pic_addr[4]; + UWORD8 uc_mixed_mode_edge; + + uc_mixed_mode_edge = 0; + + uc_temp = (ui_mbAff << 4) + 13; + + uc_cur_nnz = *(puc_cur_nnz - uc_temp); + ps_left_mv_pred = ps_leftmost_mv_pred + (edge << 2); + + for(i = 0; i < 4; i++, ps_top_mv_pred++, ps_cur_mv_pred++) + { + //Each iteration of this inner loop computes a HORIZ + //and a VERT BS value for a 4x4 block + + uc_left_nnz = uc_cur_nnz; + uc_cur_nnz = *puc_cur_nnz++; + uc_top_nnz = *puc_top_nnz++; + + //VERT edge is assigned BS values first + ui_cnd = !(uc_left_nnz || uc_cur_nnz); + uc_bs_vert = 2; + + if(ui_cnd) + { + i2_left_mv0 = ps_left_mv_pred->i2_mv[0]; + i2_left_mv1 = ps_left_mv_pred->i2_mv[1]; + i2_left_mv2 = ps_left_mv_pred->i2_mv[2]; + i2_left_mv3 = ps_left_mv_pred->i2_mv[3]; + + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + i16_curMv2 = ps_cur_mv_pred->i2_mv[2]; + i16_curMv3 = ps_cur_mv_pred->i2_mv[3]; + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + i1_cur_ref1 = ps_cur_mv_pred->i1_ref_frame[1]; + ui_ref_pic_addr[2] = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + ui_ref_pic_addr[3] = ppv_map_ref_idx_to_poc_l1[i1_cur_ref1]; + + if(i) + { + i1_left_ref0 = ps_left_mv_pred->i1_ref_frame[0]; + i1_left_ref1 = ps_left_mv_pred->i1_ref_frame[1]; + ui_ref_pic_addr[0] = ppv_map_ref_idx_to_poc_l0[i1_left_ref0]; + ui_ref_pic_addr[1] = ppv_map_ref_idx_to_poc_l1[i1_left_ref1]; + } + else + { + ui_ref_pic_addr[0] = ps_left_addr->u4_add[edge & 2]; + ui_ref_pic_addr[1] = ps_left_addr->u4_add[1 + (edge & 2)]; + } + if(!uc_Bslice) + { + uc_bs_vert = + (ui_ref_pic_addr[0] != ui_ref_pic_addr[2]) + | (ABS((i2_left_mv0 + - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv1 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit); + } + else + { + UWORD8 uc_bs_temp1, uc_bs_temp2; + + uc_bs_vert = 1; + + uc_bs_temp1 = + ((ABS((i2_left_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv1 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit) + | (ABS((i2_left_mv2 + - i16_curMv2)) + >= 4) + | (ABS((i2_left_mv3 + - i16_curMv3)) + >= (UWORD8)c_mv_limit)); + + uc_bs_temp2 = + ((ABS((i2_left_mv0 - i16_curMv2)) + >= 4) + | (ABS((i2_left_mv1 + - i16_curMv3)) + >= (UWORD8)c_mv_limit) + | (ABS((i2_left_mv2 + - i2_cur_mv0)) + >= 4) + | (ABS((i2_left_mv3 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit)); + + uc_bs_vert = + (((ui_ref_pic_addr[0] != ui_ref_pic_addr[2]) + || (ui_ref_pic_addr[1] + != ui_ref_pic_addr[3])) + || (uc_bs_temp1)) + && (((ui_ref_pic_addr[0] + != ui_ref_pic_addr[3]) + || (ui_ref_pic_addr[1] + != ui_ref_pic_addr[2])) + || (uc_bs_temp2)); + + } + } + //Fill the VERT BS, only if valid i.e., + //if it is a non-edge OR it is an edge, which is not yet filled + uc_bs_vert = (!i && u1_left_intra) ? 4 : uc_bs_vert; + ui_bs_table[i + 4] = (ui_bs_table[i + 4] << 8) | uc_bs_vert; + + //HORIZ edge is assigned BS values next + ui_cnd = !(uc_top_nnz || uc_cur_nnz); + uc_bs_horiz = 2; + + if(ui_cnd) + { + uc_mixed_mode_edge = + (0 == edge) ? (uc_top_mb_fld != uc_cur_mb_fld) : 0; + ui_cnd = 1 - uc_mixed_mode_edge; + uc_bs_horiz = uc_mixed_mode_edge; + } + + if(ui_cnd) + { + i2_cur_mv0 = ps_cur_mv_pred->i2_mv[0]; + i2_cur_mv1 = ps_cur_mv_pred->i2_mv[1]; + i16_curMv2 = ps_cur_mv_pred->i2_mv[2]; + i16_curMv3 = ps_cur_mv_pred->i2_mv[3]; + i1_cur_ref0 = ps_cur_mv_pred->i1_ref_frame[0]; + i1_cur_ref1 = ps_cur_mv_pred->i1_ref_frame[1]; + + i2_top_mv0 = ps_top_mv_pred->i2_mv[0]; + i2_top_mv1 = ps_top_mv_pred->i2_mv[1]; + i16_topMv2 = ps_top_mv_pred->i2_mv[2]; + i16_topMv3 = ps_top_mv_pred->i2_mv[3]; + ui_ref_pic_addr[2] = ppv_map_ref_idx_to_poc_l0[i1_cur_ref0]; + ui_ref_pic_addr[3] = ppv_map_ref_idx_to_poc_l1[i1_cur_ref1]; + if(edge) + { + i1_top_ref0 = ps_top_mv_pred->i1_ref_frame[0]; + i1_top_ref1 = ps_top_mv_pred->i1_ref_frame[1]; + ui_ref_pic_addr[0] = ppv_map_ref_idx_to_poc_l0[i1_top_ref0]; + ui_ref_pic_addr[1] = ppv_map_ref_idx_to_poc_l1[i1_top_ref1]; + } + else + { + ui_ref_pic_addr[0] = ps_top_add->u4_add[i & 2]; + ui_ref_pic_addr[1] = ps_top_add->u4_add[1 + (i & 2)]; + } + if(!uc_Bslice) + { + uc_bs_horiz = + (ui_ref_pic_addr[0] != ui_ref_pic_addr[2]) + | (ABS((i2_top_mv0 + - i2_cur_mv0)) + >= 4) + | (ABS((i2_top_mv1 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit); + } + else + { + UWORD8 uc_bs_temp1, uc_bs_temp2; + + uc_bs_horiz = 1; + + uc_bs_temp1 = + ((ABS((i2_top_mv0 - i2_cur_mv0)) + >= 4) + | (ABS((i2_top_mv1 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit) + | (ABS((i16_topMv2 + - i16_curMv2)) + >= 4) + | (ABS((i16_topMv3 + - i16_curMv3)) + >= (UWORD8)c_mv_limit)); + + uc_bs_temp2 = + ((ABS((i2_top_mv0 - i16_curMv2)) + >= 4) + | (ABS((i2_top_mv1 + - i16_curMv3)) + >= (UWORD8)c_mv_limit) + | (ABS((i16_topMv2 + - i2_cur_mv0)) + >= 4) + | (ABS((i16_topMv3 + - i2_cur_mv1)) + >= (UWORD8)c_mv_limit)); + + uc_bs_horiz = + (((ui_ref_pic_addr[0] != ui_ref_pic_addr[2]) + || (ui_ref_pic_addr[1] + != ui_ref_pic_addr[3])) + || (uc_bs_temp1)) + && (((ui_ref_pic_addr[0] + != ui_ref_pic_addr[3]) + || (ui_ref_pic_addr[1] + != ui_ref_pic_addr[2])) + || (uc_bs_temp2)); + + } + } + ps_left_mv_pred = ps_cur_mv_pred; + u4_bs_horz = (u4_bs_horz << 8) + uc_bs_horiz; + } + //Fill the HORIZ BS, only if valid i.e., + //if it is a non-edge OR it is an edge, which is not yet filled + if(edge || (!edge && !u1_top_intra)) + ui_bs_table[edge] = u4_bs_horz; + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_fill_bs_for_extra_left_edge \endif + * + * \brief + * Fills the boundary strength (Bs), for the top extra edge. ock + * + * \return + * Returns the packed boundary strength(Bs) MSB -> LSB Bs0|Bs1|Bs2|Bs3 + * + ************************************************************************** + */ +void ih264d_fill_bs_for_extra_left_edge(deblk_mb_t *ps_cur_deblk_mb, + deblk_mb_t *ps_leftDeblkMb, + UWORD8* puc_cur_nnz, + UWORD8 uc_botMb) +{ + /* Set the Flag in uc_deblocking_mode variable of current MB*/ + /* for mixed mode edge*/ + ps_cur_deblk_mb->u1_single_call = 0; + + if(ps_cur_deblk_mb->u1_mb_type & D_INTRA_MB) + { + ps_cur_deblk_mb->u4_bs_table[4] = 0x04040404; + ps_cur_deblk_mb->u4_bs_table[9] = 0x04040404; + } + else if((ps_leftDeblkMb->u1_mb_type & D_INTRA_MB) + && ((ps_leftDeblkMb + 1)->u1_mb_type & D_INTRA_MB)) + { + ps_cur_deblk_mb->u4_bs_table[4] = 0x04040404; + ps_cur_deblk_mb->u4_bs_table[9] = 0x04040404; + } + else + { + /* Get strengths of left MB edge */ + UWORD32 u4_bs; + UWORD8 uc_Bs; + WORD32 i; + UWORD32 ui_curMbFld; + UWORD8 *puc_left_nnz; + UWORD32 ui_bs_left_edge[2]; + + ui_curMbFld = (ps_cur_deblk_mb->u1_mb_type & D_FLD_MB) >> 7; + + puc_left_nnz = puc_cur_nnz - 29; + if((ui_curMbFld == 0) && uc_botMb) + { + puc_left_nnz -= 8; + } + else if(ui_curMbFld && uc_botMb) + { + puc_left_nnz -= 16; + } + + if(ui_curMbFld) + { + if(ps_leftDeblkMb->u1_mb_type & D_INTRA_MB) + { + ui_bs_left_edge[0] = 0x04040404; + puc_left_nnz += 16; + puc_cur_nnz += 8; + } + else + { + u4_bs = 0; + for(i = 4; i > 0; i--) + { + uc_Bs = ((*puc_cur_nnz || *puc_left_nnz)) ? 2 : 1; + u4_bs = (u4_bs << 8) | uc_Bs; + puc_left_nnz += 4; + if(i & 0x01) + puc_cur_nnz += 4; + } + ui_bs_left_edge[0] = u4_bs; + } + + if((ps_leftDeblkMb + 1)->u1_mb_type & D_INTRA_MB) + { + ui_bs_left_edge[1] = 0x04040404; + } + else + { + u4_bs = 0; + for(i = 4; i > 0; i--) + { + uc_Bs = ((*puc_cur_nnz || *puc_left_nnz)) ? 2 : 1; + u4_bs = (u4_bs << 8) | uc_Bs; + puc_left_nnz += 4; + if(i & 0x01) + puc_cur_nnz += 4; + } + ui_bs_left_edge[1] = u4_bs; + } + } + else + { + UWORD8 *puc_curNnzB, *puc_leftNnzB; + puc_curNnzB = puc_cur_nnz; + puc_leftNnzB = puc_left_nnz + 16; + if(ps_leftDeblkMb->u1_mb_type & D_INTRA_MB) + { + ui_bs_left_edge[0] = 0x04040404; + } + else + { + u4_bs = 0; + for(i = 4; i > 0; i--, puc_cur_nnz += 4) + { + uc_Bs = ((*puc_cur_nnz || *puc_left_nnz)) ? 2 : 1; + u4_bs = (u4_bs << 8) | uc_Bs; + if(i & 0x01) + puc_left_nnz += 4; + } + ui_bs_left_edge[0] = u4_bs; + } + + if((ps_leftDeblkMb + 1)->u1_mb_type & D_INTRA_MB) + { + ui_bs_left_edge[1] = 0x04040404; + } + else + { + u4_bs = 0; + for(i = 4; i > 0; i--, puc_curNnzB += 4) + { + uc_Bs = ((*puc_curNnzB || *puc_leftNnzB)) ? 2 : 1; + u4_bs = (u4_bs << 8) | uc_Bs; + if(i & 0x01) + puc_leftNnzB += 4; + } + ui_bs_left_edge[1] = u4_bs; + } + } + /* Copy The Values in Cur Deblk Mb Parameters */ + ps_cur_deblk_mb->u4_bs_table[4] = ui_bs_left_edge[0]; + ps_cur_deblk_mb->u4_bs_table[9] = ui_bs_left_edge[1]; + } + +} + +/*! + ************************************************************************** + * \if Function name : ih264d_fill_bs_for_extra_top_edge \endif + * + * \brief + * Fills the boundary strength (Bs), for the top extra edge. ock + * + * \return + * Returns the packed boundary strength(Bs) MSB -> LSB Bs0|Bs1|Bs2|Bs3 + * + ************************************************************************** + */ +void ih264d_fill_bs_for_extra_top_edge(deblk_mb_t *ps_cur_mb_params, + UWORD8 u1_Edge0_mb_typ, + UWORD8 u1_Edge1_mb_typ, + UWORD8 *pu1_curNnz, + UWORD8 *pu1_topNnz) +{ + UWORD32 u4_bs; + UWORD8 uc_Bs; + WORD32 i; + UWORD8 *pu1_cur_nnz_tmp; + UWORD8 *pu1_top_nnz_tmp; + UWORD8 u1_top_edge; + UWORD8 u1_top_mb_type; + for(u1_top_edge = 0; u1_top_edge < 2; u1_top_edge++) + { + u1_top_mb_type = u1_top_edge ? u1_Edge1_mb_typ : u1_Edge0_mb_typ; + pu1_cur_nnz_tmp = pu1_curNnz; + pu1_top_nnz_tmp = pu1_topNnz + (u1_top_edge << 2); + + if((ps_cur_mb_params->u1_mb_type & D_INTRA_MB) + + (u1_top_mb_type & D_INTRA_MB)) + { + u4_bs = 0x03030303; + } + else + { + u4_bs = 0; + for(i = 4; i > 0; i--, pu1_cur_nnz_tmp += 1, pu1_top_nnz_tmp += 1) + { + uc_Bs = ((*pu1_cur_nnz_tmp || *pu1_top_nnz_tmp)) ? 2 : 1; + u4_bs = (u4_bs << 8) | uc_Bs; + } + } + if(u1_top_edge) + ps_cur_mb_params->u4_bs_table[0] = u4_bs; + else + ps_cur_mb_params->u4_bs_table[8] = u4_bs; + } +} + + +void ih264d_fill_bs_mbedge_4(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb) +{ + + /* deblk_mb_t Params */ + deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */ + deblkmb_neighbour_t *ps_deblk_top_mb; + UWORD32 * pu4_bs_table; + UWORD8 u1_cur_mb_type; + + /* Neighbour availability */ + /* Initialization */ + const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx; + const UWORD32 u2_mby = ps_cur_mb_info->u2_mby; + const UWORD32 u1_pingpong = u2_mbx & 0x01; + ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx; + + + /* Pointer assignment for Current DeblkMB, Current Mv Pred */ + ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb; + + u1_cur_mb_type = ps_cur_mb_params->u1_mb_type; + + ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type; + + { + UWORD8 mb_qp_temp; + + ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp; + ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp; + ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + } + + ps_cur_mb_params->u1_single_call = 1; + + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + /* if no deblocking required for current Mb then continue */ + /* Check next Mbs in Mb group */ + if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING) + { + /* Storing the leftMbtype for next Mb */ + return; + } + + /* Compute BS function */ + pu4_bs_table = ps_cur_mb_params->u4_bs_table; + + pu4_bs_table[4] = 0x04040404; + pu4_bs_table[0] = 0x04040404; + pu4_bs_table[1] = 0; + pu4_bs_table[2] = 0; + pu4_bs_table[3] = 0; + pu4_bs_table[5] = 0; + pu4_bs_table[6] = 0; + pu4_bs_table[7] = 0; + +} + +void ih264d_fill_bs_mbedge_2(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb) +{ + + /* deblk_mb_t Params */ + deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */ + deblkmb_neighbour_t *ps_deblk_top_mb; + UWORD32 * pu4_bs_table; + UWORD8 u1_cur_mb_type; + + /* Neighbour availability */ + /* Initialization */ + const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx; + const UWORD32 u2_mby = ps_cur_mb_info->u2_mby; + const UWORD32 u1_pingpong = u2_mbx & 0x01; + ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx; + + + /* Pointer assignment for Current DeblkMB, Current Mv Pred */ + ps_cur_mb_params = ps_dec->ps_deblk_mbn + u2_mbxn_mb; + + u1_cur_mb_type = ps_cur_mb_params->u1_mb_type; + + ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type; + + { + UWORD8 mb_qp_temp; + + ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp; + ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp; + ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + } + + ps_cur_mb_params->u1_single_call = 1; + + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + /* if no deblocking required for current Mb then continue */ + /* Check next Mbs in Mb group */ + if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING) + { + /* Storing the leftMbtype for next Mb */ + return; + } + + /* Compute BS function */ + pu4_bs_table = ps_cur_mb_params->u4_bs_table; + + { + UWORD32 top_mb_csbp, left_mb_csbp, cur_mb_csbp; + UWORD32 top_edge, left_edge; + + top_mb_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp; + left_mb_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp; + cur_mb_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp; + + top_mb_csbp = top_mb_csbp >> 12; + top_edge = top_mb_csbp | (cur_mb_csbp & 0xf); + + if(top_edge) + pu4_bs_table[0] = 0x02020202; + else + pu4_bs_table[0] = 0; + + cur_mb_csbp = cur_mb_csbp & CSBP_LEFT_BLOCK_MASK; + left_mb_csbp = left_mb_csbp & CSBP_RIGHT_BLOCK_MASK; + + left_edge = cur_mb_csbp | left_mb_csbp; + + if(left_edge) + pu4_bs_table[4] = 0x02020202; + else + pu4_bs_table[4] = 0; + + pu4_bs_table[1] = 0; + pu4_bs_table[2] = 0; + pu4_bs_table[3] = 0; + pu4_bs_table[5] = 0; + pu4_bs_table[6] = 0; + pu4_bs_table[7] = 0; + } + +} diff --git a/decoder/ih264d_deblocking.c b/decoder/ih264d_deblocking.c new file mode 100755 index 0000000..ad4ce08 --- /dev/null +++ b/decoder/ih264d_deblocking.c @@ -0,0 +1,2134 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#include <string.h> + +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_debug.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_structs.h" +#include "ih264d_deblocking.h" +#include "ih264d_mb_utils.h" +#include "ih264d_error_handler.h" +#include "ih264d_utils.h" + + +#include "ih264d_defs.h" +#include "ih264d_format_conv.h" +#include "ih264d_deblocking.h" +#include "ih264d_tables.h" +//extern UWORD8 *g_dest_y, *g_dest_uv; + +/*! + ************************************************************************* + * \file ih264d_deblocking.c + * + * \brief + * Decoder specific deblocking routines + * + * \author AI + ************************************************************************* + */ + +/*! + ************************************************************************** + * \if Function name : HorizonPad \endif + * + * \brief + * Does the Horizontal padding on a whole pic. + * + * \return + * None + ************************************************************************** + */ + +/*! + ************************************************************************** + * \if Function name : FilterBoundaryLeft \endif + * + * \brief + * Filters MacroBlock Left Boundary egdes. + * + * \return + * None + ************************************************************************** + */ +void ih264d_filter_boundary_left_nonmbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + UWORD16 i4_strd_y, + UWORD16 i4_strd_uv, + deblk_mb_t * ps_left_mb, + UWORD32 pu4_bs_tab[], + UWORD8 u1_cur_fld) +{ + UWORD8 *pu1_y, *pu1_u, *pu1_v; + WORD32 uc_tmp, qp_avg; + WORD32 alpha_u = 0, beta_u = 0, alpha_v = 0, beta_v = 0; + WORD32 alpha_y = 0, beta_y = 0; + + WORD32 idx_b_u, idx_a_u, idx_b_v, idx_a_v; + WORD32 idx_b_y, idx_a_y; + + UWORD32 u4_bs_val; + + UWORD8 *pu1_cliptab_u, *pu1_cliptab_v, *pu1_cliptab_y; + + UWORD8 u1_double_cl = !ps_cur_mb->u1_single_call; + WORD32 ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + WORD32 ofst_b = ps_cur_mb->i1_slice_beta_offset; + + PROFILE_DISABLE_DEBLK() + + pu1_y = ps_tfr_cxt->pu1_mb_y; + pu1_u = ps_tfr_cxt->pu1_mb_u; + pu1_v = ps_tfr_cxt->pu1_mb_v; + + /* LUMA values */ + /* Deblock rounding change */ + qp_avg = + (UWORD8)((ps_cur_mb->u1_left_mb_qp + ps_cur_mb->u1_mb_qp + 1) + >> 1); + + idx_a_y = qp_avg + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = qp_avg + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + + /* Chroma cb values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_cur_mb->u1_left_mb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + /* Chroma cr values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_cur_mb->u1_left_mb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + + if(u1_double_cl == 0) + { + u4_bs_val = pu4_bs_tab[4]; + + if(0x04040404 == u4_bs_val) + { + ps_dec->pf_deblk_luma_vert_bs4(pu1_y, i4_strd_y, alpha_y, beta_y); + ps_dec->pf_deblk_chroma_vert_bs4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y, i4_strd_y, alpha_y, + beta_y, u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v, + u4_bs_val, pu1_cliptab_u, + pu1_cliptab_v); + + } + } + + } + else + { + + i4_strd_y <<= (!u1_cur_fld); + u4_bs_val = pu4_bs_tab[4]; + i4_strd_uv <<= (!u1_cur_fld); + + if(0x04040404 == u4_bs_val) + { + + ps_dec->pf_deblk_luma_vert_bs4_mbaff(pu1_y, i4_strd_y, alpha_y, + beta_y); + ps_dec->pf_deblk_chroma_vert_bs4_mbaff(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + + ps_dec->pf_deblk_luma_vert_bslt4_mbaff(pu1_y, i4_strd_y, + alpha_y, beta_y, + u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4_mbaff(pu1_u, i4_strd_uv, + alpha_u, beta_u, + alpha_v, beta_v, + u4_bs_val, + pu1_cliptab_u, + pu1_cliptab_v); + } + } + + { + + UWORD16 u2_shift = (i4_strd_y >> 1) << (u1_cur_fld ? 4 : 0); + pu1_y += u2_shift; + u2_shift = (i4_strd_uv >> 1) << (u1_cur_fld ? 3 : 0); + pu1_u += u2_shift; + pu1_v += u2_shift; + } + + qp_avg = (((ps_left_mb + 1)->u1_mb_qp + ps_cur_mb->u1_mb_qp + 1) >> 1); + + idx_a_y = qp_avg + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = qp_avg + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + u4_bs_val = pu4_bs_tab[9]; + + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = ((ps_left_mb + 1)->u1_mb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + u4_bs_val = pu4_bs_tab[9]; + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = ((ps_left_mb + 1)->u1_mb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + + if(0x04040404 == u4_bs_val) + { + ps_dec->pf_deblk_luma_vert_bs4_mbaff(pu1_y, i4_strd_y, alpha_y, + beta_y); + ps_dec->pf_deblk_chroma_vert_bs4_mbaff(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + + ps_dec->pf_deblk_luma_vert_bslt4_mbaff(pu1_y, i4_strd_y, + alpha_y, beta_y, + u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4_mbaff(pu1_u, i4_strd_uv, + alpha_u, beta_u, + alpha_v, beta_v, + u4_bs_val, + pu1_cliptab_u, + pu1_cliptab_v); + + } + } + } + +} + +/*! + ************************************************************************** + * \if Function name : FilterBoundaryTop \endif + * + * \brief + * Filters MacroBlock Top Boundary egdes. + * + * \return + * None + ************************************************************************** + */ + +void ih264d_filter_boundary_top_nonmbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + UWORD16 i4_strd_y, + UWORD16 i4_strd_uv, + deblk_mb_t * ps_top_mb, + UWORD32 u4_bs) +{ + UWORD8 *pu1_y, *pu1_u; + WORD32 alpha_u = 0, beta_u = 0, alpha_v = 0, beta_v = 0; + WORD32 alpha_y = 0, beta_y = 0; + WORD32 qp_avg; + WORD32 uc_QPav_Y; + WORD32 idx_b_u, idx_a_u, idx_b_v, idx_a_v; + WORD32 idx_b_y, idx_a_y; + UWORD16 uc_tmp; + + UWORD8 *pu1_cliptab_u, *pu1_cliptab_v, *pu1_cliptab_y; + WORD32 ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + WORD32 ofst_b = ps_cur_mb->i1_slice_beta_offset; + + UNUSED(ps_top_mb); + /* LUMA values */ + /* Deblock rounding change */ + uc_tmp = ((ps_cur_mb->u1_topmb_qp + ps_cur_mb->u1_mb_qp + 1) >> 1); + uc_QPav_Y = (UWORD8)uc_tmp; + idx_a_y = uc_QPav_Y + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = uc_QPav_Y + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + pu1_y = ps_tfr_cxt->pu1_mb_y; + + /* CHROMA cb values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_cur_mb->u1_topmb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + /* CHROMA cr values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_cur_mb->u1_topmb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + pu1_u = ps_tfr_cxt->pu1_mb_u; + + if(u4_bs == 0x04040404) + { + /* Code specific to the assembly module */ + + ps_dec->pf_deblk_luma_horz_bs4(pu1_y, i4_strd_y, alpha_y, beta_y); + ps_dec->pf_deblk_chroma_horz_bs4(pu1_u, i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v); + } + else + { + if(u4_bs) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_y]; + pu1_cliptab_u = + (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_u]; + pu1_cliptab_v = + (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_v]; + + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y, i4_strd_y, alpha_y, beta_y, + u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_horz_bslt4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v, + u4_bs, pu1_cliptab_u, + pu1_cliptab_v); + + } + } + +} + +void ih264d_deblock_mb_nonmbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + WORD32 i4_strd_y, + WORD32 i4_strd_uv, + deblk_mb_t * ps_top_mb, + deblk_mb_t * ps_left_mb) +{ + UWORD8 *pu1_y, *pu1_u; + UWORD32 u4_bs; + + WORD32 alpha, beta, alpha_u, beta_u, alpha_v, beta_v; + + UWORD8 *pu1_cliptab_u; + UWORD8 *pu1_cliptab_v; + UWORD8 *pu1_cliptab_y; + + UWORD32 * pu4_bs_tab = ps_cur_mb->u4_bs_table; + WORD32 idx_a_y, idx_a_u, idx_a_v; + + PROFILE_DISABLE_DEBLK() + /* Return from here to switch off deblocking */ + + /*---------------------------------------------------------------------*/ + /* Filter wrt Left edge */ + /* except */ + /* - Left Egde is Picture Boundary */ + /* - Left Egde is part of Slice Boundary and Deblocking */ + /* parameters of slice disable Filtering of Slice Boundary Edges*/ + /*---------------------------------------------------------------------*/ + if(ps_left_mb) + ih264d_filter_boundary_left_nonmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_strd_y, i4_strd_uv, ps_left_mb, + pu4_bs_tab, 0); + + /*--------------------------------------------------------------------*/ + /* Filter wrt Other Vertical Edges */ + /*--------------------------------------------------------------------*/ + { + WORD32 ofst_a, ofst_b, idx_b_y, idx_b_u, + idx_b_v; + WORD32 qp_avg, qp_avg_u, qp_avg_v; + ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + ofst_b = ps_cur_mb->i1_slice_beta_offset; + + qp_avg = ps_cur_mb->u1_mb_qp; + + idx_a_y = qp_avg + ofst_a; + alpha = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = qp_avg + ofst_b; + beta = gau1_ih264d_beta_table[12 + idx_b_y]; + + /* CHROMA values */ + /* CHROMA Cb values */ + qp_avg_u = (qp_avg + i1_cb_qp_idx_ofst); + qp_avg_u = gau1_ih264d_qp_scale_cr[12 + qp_avg_u]; + idx_a_u = qp_avg_u + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg_u + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + /* CHROMA Cr values */ + qp_avg_v = (qp_avg + i1_cr_qp_idx_ofst); + qp_avg_v = gau1_ih264d_qp_scale_cr[12 + qp_avg_v]; + idx_a_v = qp_avg_v + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg_v + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + } + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_y]; //this for Luma + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_u]; //this for chroma + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_v]; //this for chroma + + //edge=1 + + + u4_bs = pu4_bs_tab[5]; + pu1_y = ps_tfr_cxt->pu1_mb_y; + pu1_u = ps_tfr_cxt->pu1_mb_u; + + if(u4_bs) + { + + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 4, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + + } + //edge=2 + + u4_bs = pu4_bs_tab[6]; + if(u4_bs) + { + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 8, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4(pu1_u + 4 * YUV420SP_FACTOR, + i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v, u4_bs, + pu1_cliptab_u, pu1_cliptab_v); + + } + //edge=3 + + u4_bs = pu4_bs_tab[7]; + if(u4_bs) + { + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 12, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + + } + + /*--------------------------------------------------------------------*/ + /* Filter wrt Top edge */ + /* except */ + /* - Top Egde is Picture Boundary */ + /* - Top Egde is part of Slice Boundary and Deblocking */ + /* parameters of slice disable Filtering of Slice Boundary Edges*/ + /*--------------------------------------------------------------------*/ + if(ps_top_mb) + { + /** if top MB and MB AFF and cur MB is frame and top is field then */ + /* one extra top edge needs to be deblocked */ + + ih264d_filter_boundary_top_nonmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_strd_y, i4_strd_uv, ps_top_mb, + pu4_bs_tab[0]); + + } + + /*--------------------------------------------------------------------*/ + /* Filter wrt Other Horizontal Edges */ + /*--------------------------------------------------------------------*/ + + //edge1 + u4_bs = pu4_bs_tab[1]; + + if(u4_bs) + { + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y + (i4_strd_y << 2), i4_strd_y, + alpha, beta, u4_bs, pu1_cliptab_y); + + } + //edge2 + u4_bs = pu4_bs_tab[2]; + + if(u4_bs) + { + + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y + (i4_strd_y << 3), i4_strd_y, + alpha, beta, u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_horz_bslt4(pu1_u + (i4_strd_uv << 2), + i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v, u4_bs, + pu1_cliptab_u, pu1_cliptab_v); + + } + //edge3 + u4_bs = pu4_bs_tab[3]; + if(u4_bs) + { + ps_dec->pf_deblk_luma_horz_bslt4( + (pu1_y + (i4_strd_y << 3) + (i4_strd_y << 2)), + i4_strd_y, alpha, beta, u4_bs, pu1_cliptab_y); + + } + +} + +/************************************************************************** + * + * Function Name : ih264d_init_deblk_tfr_ctxt + * + * Description : This function is called once per deblockpicture call + * This sets up the transfer address contexts + * + * Revision History: + * + * DD MM YYYY Author(s) Changes (Describe the changes made) + * 14 06 2005 SWRN Draft + **************************************************************************/ +void ih264d_init_deblk_tfr_ctxt(dec_struct_t * ps_dec, + pad_mgr_t *ps_pad_mgr, + tfr_ctxt_t *ps_tfr_cxt, + UWORD16 u2_image_wd_mb, + UWORD8 u1_mbaff) +{ + + UWORD32 i4_wd_y; + UWORD32 i4_wd_uv; + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; /*< Field u4_flag */ + UNUSED(u2_image_wd_mb); + ps_tfr_cxt->pu1_src_y = ps_dec->s_cur_pic.pu1_buf1 - 4; + ps_tfr_cxt->pu1_src_u = ps_dec->s_cur_pic.pu1_buf2 - 4; + ps_tfr_cxt->pu1_src_v = ps_dec->s_cur_pic.pu1_buf3 - 4; + ps_tfr_cxt->pu1_dest_y = ps_tfr_cxt->pu1_src_y; + ps_tfr_cxt->pu1_dest_u = ps_tfr_cxt->pu1_src_u; + ps_tfr_cxt->pu1_dest_v = ps_tfr_cxt->pu1_src_v; + + i4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; + i4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; + ps_tfr_cxt->u4_y_inc = ((i4_wd_y << u1_mbaff) * 16 + - (ps_dec->u2_frm_wd_in_mbs << 4)); + + ps_tfr_cxt->u4_uv_inc = (i4_wd_uv << u1_mbaff) * 8 + - (ps_dec->u2_frm_wd_in_mbs << 4); + + /* padding related initialisations */ + if(ps_dec->ps_cur_slice->u1_nal_ref_idc) + { + ps_pad_mgr->u1_vert_pad_top = !(ps_dec->ps_cur_slice->u1_field_pic_flag + && ps_dec->ps_cur_slice->u1_bottom_field_flag); + ps_pad_mgr->u1_vert_pad_bot = + ((!ps_dec->ps_cur_slice->u1_field_pic_flag) + || ps_dec->ps_cur_slice->u1_bottom_field_flag); + ps_pad_mgr->u1_horz_pad = 1; + } + else + { + ps_pad_mgr->u1_horz_pad = 0; + ps_pad_mgr->u1_vert_pad_top = 0; + ps_pad_mgr->u1_vert_pad_bot = 0; + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_deblock_picture_mbaff */ +/* */ +/* Description : This function carries out deblocking on a whole picture */ +/* with MBAFF */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Processing : This functions calls deblock MB in the MB increment order*/ +/* */ +/* Outputs : Produces the deblocked picture */ +/* Returns : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 17 02 2005 NS Creation */ +/* 14 06 2005 SWRN clean-up */ +/*****************************************************************************/ + +void ih264d_deblock_picture_mbaff(dec_struct_t * ps_dec) +{ + WORD16 i2_mb_x, i2_mb_y; + deblk_mb_t *ps_cur_mb; + deblk_mb_t *ps_top_mb; + deblk_mb_t *ps_left_mb; + + UWORD8 u1_vert_pad_top = 1; + UWORD8 u1_cur_fld, u1_top_fld, u1_left_fld; + UWORD8 u1_first_row; + + UWORD8 * pu1_deb_y, *pu1_deb_u, *pu1_deb_v; + UWORD8 u1_deb_mode, u1_extra_top_edge; + WORD32 i4_wd_y, i4_wd_uv; + + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; /*< Field u4_flag */ + UWORD8 u1_bottom_field_flag = ps_dec->ps_cur_slice->u1_bottom_field_flag; /*< Bottom field u4_flag*/ + + /**************************************************/ + /* one time loads from ps_dec which will be used */ + /* frequently throughout the deblocking procedure */ + /**************************************************/ + pad_mgr_t * ps_pad_mgr = &ps_dec->s_pad_mgr; + tfr_ctxt_t s_tfr_ctxt; + tfr_ctxt_t * ps_tfr_cxt = &s_tfr_ctxt; + + UWORD16 u2_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + UWORD16 u2_image_ht_mb = ps_dec->u2_frm_ht_in_mbs; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + WORD8 i1_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + WORD8 i1_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + + /* Set up Parameter for DMA transfer */ + ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt, u2_image_wd_mb, + u1_mbaff); + + /* Pic level Initialisations */ + i2_mb_y = u2_image_ht_mb; + i2_mb_x = 0; + u1_extra_top_edge = 0; + + u1_first_row = 1; + + i4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; + i4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; + /* Initial filling of the buffers with deblocking data */ + + pu1_deb_y = ps_tfr_cxt->pu1_src_y + 4; + pu1_deb_u = ps_tfr_cxt->pu1_src_u + 4; + pu1_deb_v = ps_tfr_cxt->pu1_src_v + 4; + ps_cur_mb = ps_dec->ps_deblk_pic; + + if(ps_dec->u4_app_disable_deblk_frm == 0) + { + if(ps_dec->u4_mb_level_deblk == 0 || ps_dec->u4_num_cores >= 3) + { + + while(i2_mb_y > 0) + { + do + { + + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + ps_tfr_cxt->pu1_mb_y = pu1_deb_y; + ps_tfr_cxt->pu1_mb_u = pu1_deb_u; + ps_tfr_cxt->pu1_mb_v = pu1_deb_v; + + u1_cur_fld = (ps_cur_mb->u1_mb_type & D_FLD_MB) >> 7; + u1_cur_fld &= 1; + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 2; + } + else + { + ps_left_mb = NULL; + } + if(!u1_first_row) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb << 1) + 1; + u1_top_fld = (ps_top_mb->u1_mb_type & D_FLD_MB) + >> 7; + } + else + { + ps_top_mb = NULL; + u1_top_fld = 0; + } + + if((!u1_first_row) & u1_top_fld & u1_cur_fld) + ps_top_mb--; + + /********************************************************/ + /* if top MB and MB AFF and cur MB is frame and top is */ + /* field, then one extra top edge needs to be deblocked */ + /********************************************************/ + u1_extra_top_edge = (!u1_cur_fld) & u1_top_fld; + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_mbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_wd_y, i4_wd_uv, ps_top_mb, + ps_left_mb, u1_cur_fld, + u1_extra_top_edge); + } + + ps_cur_mb++; + + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + ps_tfr_cxt->pu1_mb_y = pu1_deb_y; + ps_tfr_cxt->pu1_mb_u = pu1_deb_u; + ps_tfr_cxt->pu1_mb_v = pu1_deb_v; + + u1_cur_fld = (ps_cur_mb->u1_mb_type & D_FLD_MB) >> 7; + u1_cur_fld &= 1; + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 2; + u1_left_fld = (ps_left_mb->u1_mb_type & D_FLD_MB) + >> 7; + } + else + { + ps_left_mb = NULL; + u1_left_fld = u1_cur_fld; + } + if(!u1_first_row) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb << 1); + } + else + { + ps_top_mb = NULL; + } + + { + UWORD8 u1_row_shift_y = 0, u1_row_shift_uv = 0; + if(!u1_cur_fld) + { + ps_top_mb = ps_cur_mb - 1; + u1_top_fld = (ps_top_mb->u1_mb_type & D_FLD_MB) + >> 7; + u1_row_shift_y = 4; + u1_row_shift_uv = 3; + } + ps_tfr_cxt->pu1_mb_y += i4_wd_y << u1_row_shift_y; + ps_tfr_cxt->pu1_mb_u += + (i4_wd_uv << u1_row_shift_uv); + ps_tfr_cxt->pu1_mb_v += i4_wd_uv << u1_row_shift_uv; + } + + /* point to A if top else A+1 */ + if(u1_left_fld ^ u1_cur_fld) + ps_left_mb--; + + /********************************************************/ + /* if top MB and MB AFF and cur MB is frame and top is */ + /* field, then one extra top edge needs to be deblocked */ + /********************************************************/ + u1_extra_top_edge = 0; + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_mbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_wd_y, i4_wd_uv, ps_top_mb, + ps_left_mb, u1_cur_fld, + u1_extra_top_edge); + } + + ps_cur_mb++; + i2_mb_x++; + + pu1_deb_y += 16; + pu1_deb_u += 8 * YUV420SP_FACTOR; + pu1_deb_v += 8; + + } + while(u2_image_wd_mb > i2_mb_x); + + pu1_deb_y += ps_tfr_cxt->u4_y_inc; + pu1_deb_u += ps_tfr_cxt->u4_uv_inc; + pu1_deb_v += ps_tfr_cxt->u4_uv_inc; + + i2_mb_x = 0; + i2_mb_y -= 2; + + u1_first_row = 0; + + } + } + + } + //Padd the Picture + //Horizontal Padd + + if(ps_pad_mgr->u1_horz_pad) + { + UWORD32 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + ps_dec->pf_pad_left_luma(ps_tfr_cxt->pu1_src_y + 4, + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, + PAD_LEN_Y_H); + ps_dec->pf_pad_right_luma( + ps_tfr_cxt->pu1_src_y + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, PAD_LEN_Y_H); + + ps_dec->pf_pad_left_chroma(ps_tfr_cxt->pu1_src_u + 4, + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + ps_dec->pf_pad_right_chroma( + ps_tfr_cxt->pu1_src_u + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + + } + +//Vertical Padd Top + if(ps_pad_mgr->u1_vert_pad_top) + { + ps_dec->pf_pad_top(ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H, + ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + ps_dec->pf_pad_top( + ps_dec->ps_cur_pic->pu1_buf2 + - PAD_LEN_UV_H * YUV420SP_FACTOR, + ps_dec->u2_frm_wd_uv, ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + ps_pad_mgr->u1_vert_pad_top = 0; + } + +//Vertical Padd Bottom + if(ps_pad_mgr->u1_vert_pad_bot) + { + + UWORD8 *pu1_buf; + pu1_buf = ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H; + pu1_buf += ps_dec->u2_pic_ht * ps_dec->u2_frm_wd_y; + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + pu1_buf = ps_dec->ps_cur_pic->pu1_buf2 - PAD_LEN_UV_H * YUV420SP_FACTOR; + pu1_buf += (ps_dec->u2_pic_ht >> 1) * ps_dec->u2_frm_wd_uv; + + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_uv, + ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_deblock_picture_non_mbaff */ +/* */ +/* Description : This function carries out deblocking on a whole picture */ +/* without MBAFF */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Processing : This functions calls deblock MB in the MB increment order*/ +/* */ +/* Outputs : Produces the deblocked picture */ +/* Returns : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 17 02 2005 NS Creation */ +/* 14 06 2005 SWRN clean-up */ +/*****************************************************************************/ + +void ih264d_deblock_picture_non_mbaff(dec_struct_t * ps_dec) +{ + WORD16 i2_mb_x, i2_mb_y; + deblk_mb_t *ps_cur_mb; + deblk_mb_t *ps_top_mb; + deblk_mb_t *ps_left_mb; + + UWORD8 u1_vert_pad_top = 1; + UWORD8 u1_first_row; + + UWORD8 u1_deb_mode; + WORD32 i4_wd_y, i4_wd_uv; + + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; /*< Field u4_flag */ + UWORD8 u1_bottom_field_flag = ps_dec->ps_cur_slice->u1_bottom_field_flag; /*< Bottom field u4_flag */ + + /**************************************************/ + /* one time loads from ps_dec which will be used */ + /* frequently throughout the deblocking procedure */ + /**************************************************/ + pad_mgr_t * ps_pad_mgr = &ps_dec->s_pad_mgr; + tfr_ctxt_t s_tfr_ctxt; + tfr_ctxt_t * ps_tfr_cxt = &s_tfr_ctxt; // = &ps_dec->s_tran_addrecon; + + UWORD16 u2_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + UWORD16 u2_image_ht_mb = ps_dec->u2_frm_ht_in_mbs; + WORD8 i1_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + WORD8 i1_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + + /* Set up Parameter for DMA transfer */ + ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt, u2_image_wd_mb, + 0); + + /* Pic level Initialisations */ + i2_mb_y = u2_image_ht_mb; + i2_mb_x = 0; + + u1_first_row = 1; + + i4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; + i4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; + /* Initial filling of the buffers with deblocking data */ + + ps_tfr_cxt->pu1_mb_y = ps_tfr_cxt->pu1_src_y + 4; + ps_tfr_cxt->pu1_mb_u = ps_tfr_cxt->pu1_src_u + 4; + ps_tfr_cxt->pu1_mb_v = ps_tfr_cxt->pu1_src_v + 4; + ps_cur_mb = ps_dec->ps_deblk_pic; + + if(ps_dec->u4_app_disable_deblk_frm == 0) + { + if((ps_dec->u4_mb_level_deblk == 0) && (ps_dec->u4_num_cores != 3)) + { + + while(i2_mb_y > 0) + { + do + { + + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + } + else + { + ps_left_mb = NULL; + } + if(!u1_first_row) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_wd_y, i4_wd_uv, ps_top_mb, + ps_left_mb); + } + + ps_cur_mb++; + i2_mb_x++; + + ps_tfr_cxt->pu1_mb_y += 16; + ps_tfr_cxt->pu1_mb_u += 8 * YUV420SP_FACTOR; + ps_tfr_cxt->pu1_mb_v += 8; + + } + while(i2_mb_x < u2_image_wd_mb); + + ps_tfr_cxt->pu1_mb_y += ps_tfr_cxt->u4_y_inc; + ps_tfr_cxt->pu1_mb_u += ps_tfr_cxt->u4_uv_inc; + ps_tfr_cxt->pu1_mb_v += ps_tfr_cxt->u4_uv_inc; + + i2_mb_x = 0; + i2_mb_y--; + u1_first_row = 0; + + } + } + + } + + //Padd the Picture + //Horizontal Padd + if(ps_pad_mgr->u1_horz_pad) + { + UWORD32 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + ps_dec->pf_pad_left_luma(ps_tfr_cxt->pu1_src_y + 4, + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, + PAD_LEN_Y_H); + ps_dec->pf_pad_right_luma( + ps_tfr_cxt->pu1_src_y + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, PAD_LEN_Y_H); + + ps_dec->pf_pad_left_chroma(ps_tfr_cxt->pu1_src_u + 4, + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + ps_dec->pf_pad_right_chroma( + ps_tfr_cxt->pu1_src_u + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + + } + +//Vertical Padd Top + if(ps_pad_mgr->u1_vert_pad_top) + { + ps_dec->pf_pad_top(ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H, + ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + ps_dec->pf_pad_top( + ps_dec->ps_cur_pic->pu1_buf2 + - PAD_LEN_UV_H * YUV420SP_FACTOR, + ps_dec->u2_frm_wd_uv, ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + ps_pad_mgr->u1_vert_pad_top = 0; + } + +//Vertical Padd Bottom + if(ps_pad_mgr->u1_vert_pad_bot) + { + + UWORD8 *pu1_buf; + pu1_buf = ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H; + pu1_buf += ps_dec->u2_pic_ht * ps_dec->u2_frm_wd_y; + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + pu1_buf = ps_dec->ps_cur_pic->pu1_buf2 - PAD_LEN_UV_H * YUV420SP_FACTOR; + pu1_buf += (ps_dec->u2_pic_ht >> 1) * ps_dec->u2_frm_wd_uv; + + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_uv, + ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + + } +} + +void ih264d_deblock_picture_progressive(dec_struct_t * ps_dec) +{ + WORD16 i2_mb_x, i2_mb_y; + + deblk_mb_t *ps_cur_mb; + deblk_mb_t *ps_top_mb; + deblk_mb_t *ps_left_mb; + + UWORD8 u1_vert_pad_top = 1; + UWORD8 u1_mbs_next, u1_first_row; + UWORD8 u1_deb_mode; + WORD32 i4_wd_y, i4_wd_uv; + + + /**************************************************/ + /* one time loads from ps_dec which will be used */ + /* frequently throughout the deblocking procedure */ + /**************************************************/ + pad_mgr_t * ps_pad_mgr = &ps_dec->s_pad_mgr; + + tfr_ctxt_t s_tfr_ctxt; + tfr_ctxt_t * ps_tfr_cxt = &s_tfr_ctxt; // = &ps_dec->s_tran_addrecon; + UWORD16 u2_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + UWORD16 u2_image_ht_mb = ps_dec->u2_frm_ht_in_mbs; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + + WORD8 i1_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + WORD8 i1_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + + /* Set up Parameter for deblocking */ + ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt, u2_image_wd_mb, + 0); + + /* Pic level Initialisations */ + i2_mb_y = u2_image_ht_mb; + i2_mb_x = 0; + + u1_first_row = 1; + + i4_wd_y = ps_dec->u2_frm_wd_y; + i4_wd_uv = ps_dec->u2_frm_wd_uv; + /* Initial filling of the buffers with deblocking data */ + + ps_tfr_cxt->pu1_mb_y = ps_tfr_cxt->pu1_src_y + 4; + ps_tfr_cxt->pu1_mb_u = ps_tfr_cxt->pu1_src_u + 4; + ps_tfr_cxt->pu1_mb_v = ps_tfr_cxt->pu1_src_v + 4; + ps_cur_mb = ps_dec->ps_deblk_pic; + + if(ps_dec->u4_app_disable_deblk_frm == 0) + { + + if((ps_dec->u4_mb_level_deblk == 0) && (ps_dec->u4_num_cores != 3)) + { + + while(i2_mb_y > 0) + { + + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + + } + else + { + ps_left_mb = NULL; + + } + if(!u1_first_row) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_wd_y, i4_wd_uv, ps_top_mb, + ps_left_mb); + } + + ps_cur_mb++; + i2_mb_x++; + u1_mbs_next = u2_image_wd_mb - i2_mb_x; + + ps_tfr_cxt->pu1_mb_y += 16; + ps_tfr_cxt->pu1_mb_u += 8 * YUV420SP_FACTOR; + ps_tfr_cxt->pu1_mb_v += 8; + + if(!u1_mbs_next) + { + ps_tfr_cxt->pu1_mb_y += ps_tfr_cxt->u4_y_inc; + ps_tfr_cxt->pu1_mb_u += ps_tfr_cxt->u4_uv_inc; + ps_tfr_cxt->pu1_mb_v += ps_tfr_cxt->u4_uv_inc; + + i2_mb_x = 0; + i2_mb_y--; + u1_first_row = 0; + } + + } + } + + } + + //Padd the Picture + //Horizontal Padd + if(ps_pad_mgr->u1_horz_pad) + { + UWORD32 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + ps_dec->pf_pad_left_luma(ps_tfr_cxt->pu1_src_y + 4, + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, + PAD_LEN_Y_H); + ps_dec->pf_pad_right_luma( + ps_tfr_cxt->pu1_src_y + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_y << u1_field_pic_flag, + ps_dec->u2_pic_ht >> u1_field_pic_flag, PAD_LEN_Y_H); + + ps_dec->pf_pad_left_chroma(ps_tfr_cxt->pu1_src_u + 4, + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + ps_dec->pf_pad_right_chroma( + ps_tfr_cxt->pu1_src_u + 4 + + (ps_dec->u2_frm_wd_in_mbs << 4), + ps_dec->u2_frm_wd_uv << u1_field_pic_flag, + (ps_dec->u2_pic_ht / 2) >> u1_field_pic_flag, + PAD_LEN_UV_H * YUV420SP_FACTOR); + + } + +//Vertical Padd Top + if(ps_pad_mgr->u1_vert_pad_top) + { + ps_dec->pf_pad_top(ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H, + ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + ps_dec->pf_pad_top( + ps_dec->ps_cur_pic->pu1_buf2 + - PAD_LEN_UV_H * YUV420SP_FACTOR, + ps_dec->u2_frm_wd_uv, ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + + } + +//Vertical Padd Bottom + if(ps_pad_mgr->u1_vert_pad_bot) + { + + UWORD8 *pu1_buf; + pu1_buf = ps_dec->ps_cur_pic->pu1_buf1 - PAD_LEN_Y_H; + pu1_buf += ps_dec->u2_pic_ht * ps_dec->u2_frm_wd_y; + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_y, ps_dec->u2_frm_wd_y, + ps_pad_mgr->u1_pad_len_y_v); + pu1_buf = ps_dec->ps_cur_pic->pu1_buf2 - PAD_LEN_UV_H * YUV420SP_FACTOR; + pu1_buf += (ps_dec->u2_pic_ht >> 1) * ps_dec->u2_frm_wd_uv; + + ps_dec->pf_pad_bottom(pu1_buf, ps_dec->u2_frm_wd_uv, + ps_dec->u2_frm_wd_uv, + ps_pad_mgr->u1_pad_len_cr_v); + + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_set_deblocking_parameters \endif + * + * \brief + * Sets the deblocking parameters of the macroblock + * + * \return + * 0 on Success and Error code otherwise + * + * \note + * Given the neighbour availablity information, and the deblocking + * parameters of the slice,this function will set the deblocking + * mode of the macroblock. + ************************************************************************** + */ + +WORD8 ih264d_set_deblocking_parameters(deblk_mb_t * ps_cur_mb, + dec_slice_params_t * ps_slice, + UWORD8 u1_mb_ngbr_availablity, + UWORD8 u1_mb_field_decoding_flag) +{ + /*------------------------------------------------------------------*/ + /* Set the deblocking parameters */ + /*------------------------------------------------------------------*/ + ps_cur_mb->i1_slice_alpha_c0_offset = ps_slice->i1_slice_alpha_c0_offset; + ps_cur_mb->i1_slice_beta_offset = ps_slice->i1_slice_beta_offset; + ps_cur_mb->u1_mb_type = (u1_mb_field_decoding_flag << 7); + + switch(ps_slice->u1_disable_dblk_filter_idc) + { + case DBLK_ENABLED: + ps_cur_mb->u1_deblocking_mode = MB_ENABLE_FILTERING; + break; + case DBLK_DISABLED: + ps_cur_mb->u1_deblocking_mode = MB_DISABLE_FILTERING; + break; + case SLICE_BOUNDARY_DBLK_DISABLED: + { + ps_cur_mb->u1_deblocking_mode = MB_ENABLE_FILTERING; + if(!(u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK)) + ps_cur_mb->u1_deblocking_mode |= MB_DISABLE_LEFT_EDGE; + if(!(u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK)) + ps_cur_mb->u1_deblocking_mode |= MB_DISABLE_TOP_EDGE; + break; + } + } + + return (0); +} + +void ih264d_copy_intra_pred_line(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index) +{ + UWORD8 *pu1_mb_last_row, u1_mb_field_decoding_flag; + UWORD32 u4_recWidth, u4_recwidth_cr; + + u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + + u4_recWidth = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + u4_recwidth_cr = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + + pu1_mb_last_row = ps_dec->s_tran_addrecon.pu1_dest_y + + (u4_recWidth * (MB_SIZE - 1)); + pu1_mb_last_row += MB_SIZE * nmb_index; + MEMCPY_16BYTES(ps_dec->pu1_cur_y_intra_pred_line, pu1_mb_last_row); + + pu1_mb_last_row = ps_dec->s_tran_addrecon.pu1_dest_u + + (u4_recwidth_cr * (BLK8x8SIZE - 1)); + pu1_mb_last_row += BLK8x8SIZE * nmb_index * YUV420SP_FACTOR; + + MEMCPY_16BYTES(ps_dec->pu1_cur_u_intra_pred_line, pu1_mb_last_row); + + ps_dec->pu1_cur_y_intra_pred_line = ps_dec->pu1_cur_y_intra_pred_line_base + + (MB_SIZE * (ps_cur_mb_info->u2_mbx + 1)); + ps_dec->pu1_cur_u_intra_pred_line = ps_dec->pu1_cur_u_intra_pred_line_base + + (BLK8x8SIZE * (ps_cur_mb_info->u2_mbx + 1)) + * YUV420SP_FACTOR; + ps_dec->pu1_cur_v_intra_pred_line = ps_dec->pu1_cur_v_intra_pred_line_base + + (BLK8x8SIZE * (ps_cur_mb_info->u2_mbx + 1)); + + if(ps_cur_mb_info->u2_mbx == (ps_dec->u2_frm_wd_in_mbs - 1)) + { + UWORD8* pu1_temp; + + ps_dec->pu1_cur_y_intra_pred_line = + ps_dec->pu1_cur_y_intra_pred_line_base; + ps_dec->pu1_cur_u_intra_pred_line = + ps_dec->pu1_cur_u_intra_pred_line_base; + ps_dec->pu1_cur_v_intra_pred_line = + ps_dec->pu1_cur_v_intra_pred_line_base; + + /*swap current and previous rows*/ + pu1_temp = ps_dec->pu1_cur_y_intra_pred_line; + ps_dec->pu1_cur_y_intra_pred_line = ps_dec->pu1_prev_y_intra_pred_line; + ps_dec->pu1_prev_y_intra_pred_line = pu1_temp; + + pu1_temp = ps_dec->pu1_cur_u_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line = ps_dec->pu1_prev_u_intra_pred_line; + ps_dec->pu1_prev_u_intra_pred_line = pu1_temp; + + pu1_temp = ps_dec->pu1_cur_v_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line = ps_dec->pu1_prev_v_intra_pred_line; + ps_dec->pu1_prev_v_intra_pred_line = pu1_temp; + + ps_dec->pu1_cur_y_intra_pred_line_base = + ps_dec->pu1_cur_y_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line_base = + ps_dec->pu1_cur_u_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line_base = + ps_dec->pu1_cur_v_intra_pred_line; + + + + + + } + +} + +void ih264d_deblock_mb_level(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index) +{ + UWORD8 u1_deb_mode; + deblk_mb_t *ps_cur_mb, *ps_left_mb, *ps_top_mb; + UWORD16 u2_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + UWORD16 u2_image_ht_mb = ps_dec->u2_frm_ht_in_mbs; + WORD8 i1_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + WORD8 i1_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + WORD32 i4_wd_y, i4_wd_uv; + tfr_ctxt_t * ps_tfr_cxt = &ps_dec->s_tran_addrecon; + WORD16 i2_mb_y, i2_mb_x; + UWORD8 u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + deblk_mb_t *ps_deblk_cur_mb; + + /*Copy the last row of every MB ,to be used for intra prediction f next row*/ + { + UWORD8 *pu1_mb_last_row, u1_mb_field_decoding_flag; + UWORD32 u4_recWidth, u4_recwidth_cr; + + u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + + u4_recWidth = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + u4_recwidth_cr = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + + pu1_mb_last_row = ps_dec->s_tran_addrecon.pu1_dest_y + + (u4_recWidth * (MB_SIZE - 1)); + pu1_mb_last_row += MB_SIZE * nmb_index; + MEMCPY_16BYTES(ps_dec->pu1_cur_y_intra_pred_line, pu1_mb_last_row); + + pu1_mb_last_row = ps_dec->s_tran_addrecon.pu1_dest_u + + (u4_recwidth_cr * (BLK8x8SIZE - 1)); + pu1_mb_last_row += BLK8x8SIZE * nmb_index * YUV420SP_FACTOR; + + MEMCPY_16BYTES(ps_dec->pu1_cur_u_intra_pred_line, pu1_mb_last_row); + + ps_dec->pu1_cur_y_intra_pred_line = + ps_dec->pu1_cur_y_intra_pred_line_base + + (MB_SIZE + * (ps_cur_mb_info->u2_mbx + + 1)); + ps_dec->pu1_cur_u_intra_pred_line = + ps_dec->pu1_cur_u_intra_pred_line_base + + (BLK8x8SIZE + * (ps_cur_mb_info->u2_mbx + + 1)) + * YUV420SP_FACTOR; + ps_dec->pu1_cur_v_intra_pred_line = + ps_dec->pu1_cur_v_intra_pred_line_base + + (BLK8x8SIZE + * (ps_cur_mb_info->u2_mbx + + 1)); + } + + i2_mb_y = ps_cur_mb_info->u2_mby; + i4_wd_y = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + i4_wd_uv = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + + if(ps_cur_mb_info->u2_mbx != 0) + { + /*Deblock the previous MB*/ + deblk_mb_t *ps_deblk_cur_mb; + + if(ps_dec->u1_separate_parse == 1) + { + ps_deblk_cur_mb = ps_dec->ps_deblk_mbn_dec_thrd + nmb_index - 1; + + } + else + { + + if(nmb_index == 0) + /*if first mb in Nmb ,pick up the context from previous Nmb data*/ + ps_deblk_cur_mb = ps_dec->ps_deblk_mbn_prev + + ps_dec->u4_num_mbs_prev_nmb - 1; + else + ps_deblk_cur_mb = ps_dec->ps_deblk_mbn + nmb_index - 1; + } + + ps_cur_mb = ps_deblk_cur_mb; + + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + + i2_mb_x = ps_cur_mb_info->u2_mbx - 1; + + if(ps_dec->u4_app_disable_deblk_frm == 1) + u1_deb_mode = MB_DISABLE_FILTERING; + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + + } + else + { + ps_left_mb = NULL; + + } + if(i2_mb_y) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, i4_wd_y, + i4_wd_uv, ps_top_mb, ps_left_mb); + } + + ps_tfr_cxt->pu1_mb_y += MB_SIZE; + ps_tfr_cxt->pu1_mb_u += (MB_SIZE >> 1) * YUV420SP_FACTOR; + ps_tfr_cxt->pu1_mb_v += (MB_SIZE >> 1); + } + + if(ps_cur_mb_info->u2_mbx == (ps_dec->u2_frm_wd_in_mbs - 1)) + { + /*Deblock the previous MB*/ + deblk_mb_t *ps_deblk_cur_mb; + UWORD8 *pu1_temp; + + if(ps_dec->u1_separate_parse == 1) + ps_deblk_cur_mb = ps_dec->ps_deblk_mbn_dec_thrd + nmb_index; + else + ps_deblk_cur_mb = ps_dec->ps_deblk_mbn + nmb_index; + + i2_mb_x = ps_cur_mb_info->u2_mbx; + + ps_cur_mb = ps_deblk_cur_mb; + u1_deb_mode = ps_cur_mb->u1_deblocking_mode; + + if(ps_dec->u4_app_disable_deblk_frm == 1) + u1_deb_mode = MB_DISABLE_FILTERING; + + if(!(u1_deb_mode & MB_DISABLE_FILTERING)) + { + + if(i2_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + + } + else + { + ps_left_mb = NULL; + + } + if(i2_mb_y) + { + ps_top_mb = ps_cur_mb - (u2_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u1_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u1_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, i4_wd_y, + i4_wd_uv, ps_top_mb, ps_left_mb); + } + + ps_dec->pu1_cur_y_intra_pred_line = + ps_dec->pu1_cur_y_intra_pred_line_base; + ps_dec->pu1_cur_u_intra_pred_line = + ps_dec->pu1_cur_u_intra_pred_line_base; + ps_dec->pu1_cur_v_intra_pred_line = + ps_dec->pu1_cur_v_intra_pred_line_base; + + /*swap current and previous rows*/ + pu1_temp = ps_dec->pu1_cur_y_intra_pred_line; + ps_dec->pu1_cur_y_intra_pred_line = ps_dec->pu1_prev_y_intra_pred_line; + ps_dec->pu1_prev_y_intra_pred_line = pu1_temp; + + pu1_temp = ps_dec->pu1_cur_u_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line = ps_dec->pu1_prev_u_intra_pred_line; + ps_dec->pu1_prev_u_intra_pred_line = pu1_temp; + + pu1_temp = ps_dec->pu1_cur_v_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line = ps_dec->pu1_prev_v_intra_pred_line; + ps_dec->pu1_prev_v_intra_pred_line = pu1_temp; + + ps_dec->pu1_cur_y_intra_pred_line_base = + ps_dec->pu1_cur_y_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line_base = + ps_dec->pu1_cur_u_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line_base = + ps_dec->pu1_cur_v_intra_pred_line; + + } + +} + +void ih264d_filter_boundary_left_mbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + UWORD16 i4_strd_y, + UWORD16 i4_strd_uv, + deblk_mb_t * ps_left_mb, /* Neighbouring MB parameters */ + UWORD32 pu4_bs_tab[], /* pointer to the BsTable array */ + UWORD8 u1_cur_fld) +{ + UWORD8 *pu1_y, *pu1_u, *pu1_v; + UWORD8 uc_tmp, qp_avg, uc_QPav_Y; + WORD32 alpha_u = 0, beta_u = 0, alpha_v = 0, beta_v = 0; + WORD32 alpha_y = 0, beta_y = 0; + + WORD32 idx_b_u, idx_a_u, idx_b_v, idx_a_v; + WORD32 idx_b_y, idx_a_y; + + UWORD32 u4_bs_val; + + UWORD8 *pu1_cliptab_u, *pu1_cliptab_v, *pu1_cliptab_y; + + UWORD8 u1_double_cl = !ps_cur_mb->u1_single_call; + WORD32 ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + WORD32 ofst_b = ps_cur_mb->i1_slice_beta_offset; + + PROFILE_DISABLE_DEBLK() + + pu1_y = ps_tfr_cxt->pu1_mb_y; + pu1_u = ps_tfr_cxt->pu1_mb_u; + pu1_v = ps_tfr_cxt->pu1_mb_v; + + /* LUMA values */ + /* Deblock rounding change */ + uc_tmp = (UWORD8)((ps_left_mb->u1_mb_qp + ps_cur_mb->u1_mb_qp + 1) >> 1); + uc_QPav_Y = uc_tmp; + idx_a_y = uc_QPav_Y + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = uc_QPav_Y + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + + /* Chroma cb values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_left_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + + /* Chroma cr values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_left_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + + if(u1_double_cl == 0) + { + u4_bs_val = pu4_bs_tab[4]; + + if(0x04040404 == u4_bs_val) + { + ps_dec->pf_deblk_luma_vert_bs4(pu1_y, i4_strd_y, alpha_y, beta_y); + ps_dec->pf_deblk_chroma_vert_bs4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y, i4_strd_y, alpha_y, + beta_y, u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v, + u4_bs_val, pu1_cliptab_u, + pu1_cliptab_v); + + } + } + + } + else + { + + i4_strd_y <<= (!u1_cur_fld); + u4_bs_val = pu4_bs_tab[4]; + i4_strd_uv <<= (!u1_cur_fld); + + if(0x04040404 == u4_bs_val) + { + ps_dec->pf_deblk_luma_vert_bs4_mbaff(pu1_y, i4_strd_y, alpha_y, + beta_y); + ps_dec->pf_deblk_chroma_vert_bs4_mbaff(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + ps_dec->pf_deblk_luma_vert_bslt4_mbaff(pu1_y, i4_strd_y, + alpha_y, beta_y, + u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4_mbaff(pu1_u, i4_strd_uv, + alpha_u, beta_u, + alpha_v, beta_v, + u4_bs_val, + pu1_cliptab_u, + pu1_cliptab_v); + + } + } + + { + + UWORD16 u2_shift = (i4_strd_y >> 1) << (u1_cur_fld ? 4 : 0); + pu1_y += u2_shift; + u2_shift = (i4_strd_uv >> 1) << (u1_cur_fld ? 3 : 0); + pu1_u += u2_shift; + pu1_v += u2_shift; + } + + uc_tmp = (((ps_left_mb + 1)->u1_mb_qp + ps_cur_mb->u1_mb_qp + 1) >> 1); + uc_QPav_Y = uc_tmp; + idx_a_y = uc_QPav_Y + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = uc_QPav_Y + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + u4_bs_val = pu4_bs_tab[9]; + + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = ((ps_left_mb + 1)->u1_mb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + u4_bs_val = pu4_bs_tab[9]; + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = ((ps_left_mb + 1)->u1_mb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + + if(0x04040404 == u4_bs_val) + { + ps_dec->pf_deblk_luma_vert_bs4_mbaff(pu1_y, i4_strd_y, alpha_y, + beta_y); + ps_dec->pf_deblk_chroma_vert_bs4_mbaff(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v); + + } + else + { + if(u4_bs_val) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_y]; + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_u]; + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + + idx_a_v]; + + ps_dec->pf_deblk_luma_vert_bslt4_mbaff(pu1_y, i4_strd_y, + alpha_y, beta_y, + u4_bs_val, + pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4_mbaff(pu1_u, i4_strd_uv, + alpha_u, beta_u, + alpha_v, beta_v, + u4_bs_val, + pu1_cliptab_u, + pu1_cliptab_v); + + } + } + } + +} + +void ih264d_filter_boundary_topmbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + UWORD16 i4_strd_y, + UWORD16 i4_strd_uv, + deblk_mb_t * ps_top_mb, + UWORD32 u4_bs) +{ + UWORD8 *pu1_y, *pu1_u; + WORD32 alpha_u = 0, beta_u = 0, alpha_v = 0, beta_v = 0; + WORD32 alpha_y = 0, beta_y = 0; + WORD32 qp_avg; + WORD32 uc_QPav_Y; + WORD32 idx_b_u, idx_a_u, idx_b_v, idx_a_v; + WORD32 idx_b_y, idx_a_y; + UWORD16 uc_tmp; + + UWORD8 *pu1_cliptab_u, *pu1_cliptab_v, *pu1_cliptab_y; + WORD32 ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + WORD32 ofst_b = ps_cur_mb->i1_slice_beta_offset; + + /* LUMA values */ + /* Deblock rounding change */ + uc_tmp = ((ps_top_mb->u1_mb_qp + ps_cur_mb->u1_mb_qp + 1) >> 1); + uc_QPav_Y = (UWORD8)uc_tmp; + idx_a_y = uc_QPav_Y + ofst_a; + alpha_y = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = uc_QPav_Y + ofst_b; + beta_y = gau1_ih264d_beta_table[12 + idx_b_y]; + pu1_y = ps_tfr_cxt->pu1_mb_y; + + /* CHROMA cb values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_top_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cb_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + + idx_a_u = qp_avg + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + /* CHROMA cr values */ + { + UWORD8 u1_mb_qp1, u1_mb_qp2; + u1_mb_qp1 = (ps_top_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + u1_mb_qp2 = (ps_cur_mb->u1_mb_qp + i1_cr_qp_idx_ofst); + qp_avg = (UWORD8)((gau1_ih264d_qp_scale_cr[12 + u1_mb_qp1] + + gau1_ih264d_qp_scale_cr[12 + u1_mb_qp2] + 1) >> 1); + } + + idx_a_v = qp_avg + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + pu1_u = ps_tfr_cxt->pu1_mb_u; + + if(u4_bs == 0x04040404) + { + /* Code specific to the assembly module */ + ps_dec->pf_deblk_luma_horz_bs4(pu1_y, i4_strd_y, alpha_y, beta_y); + ps_dec->pf_deblk_chroma_horz_bs4(pu1_u, i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v); + + } + else + { + if(u4_bs) + { + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_y]; + pu1_cliptab_u = + (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_u]; + pu1_cliptab_v = + (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_v]; + + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y, i4_strd_y, alpha_y, beta_y, + u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_horz_bslt4(pu1_u, i4_strd_uv, alpha_u, + beta_u, alpha_v, beta_v, + u4_bs, pu1_cliptab_u, + pu1_cliptab_v); + + } + } + +} + +void ih264d_deblock_mb_mbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * ps_tfr_cxt, + WORD8 i1_cb_qp_idx_ofst, + WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * ps_cur_mb, + WORD32 i4_strd_y, + WORD32 i4_strd_uv, + deblk_mb_t * ps_top_mb, + deblk_mb_t * ps_left_mb, + UWORD8 u1_cur_fld, + UWORD8 u1_extra_top_edge) +{ + UWORD8 *pu1_y, *pu1_u; + UWORD32 u4_bs; +// WORD8 edge; + WORD32 alpha, beta, alpha_u, beta_u, alpha_v, beta_v; + + UWORD8 *pu1_cliptab_u; + UWORD8 *pu1_cliptab_v; + UWORD8 *pu1_cliptab_y; + + UWORD32 * pu4_bs_tab = ps_cur_mb->u4_bs_table; + WORD32 idx_a_y, idx_a_u, idx_a_v; + /* Return from here to switch off deblocking */ + PROFILE_DISABLE_DEBLK() + + i4_strd_y <<= u1_cur_fld; + i4_strd_uv <<= u1_cur_fld; + /*--------------------------------------------------------------------*/ + /* Filter wrt Left edge */ + /* except */ + /* - Left Egde is Picture Boundary */ + /* - Left Egde is part of Slice Boundary and Deblocking */ + /* parameters of slice disable Filtering of Slice Boundary Edges*/ + /*--------------------------------------------------------------------*/ + if(ps_left_mb) + ih264d_filter_boundary_left_mbaff(ps_dec, ps_tfr_cxt, i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_strd_y, i4_strd_uv, ps_left_mb, + pu4_bs_tab, u1_cur_fld); + + /*--------------------------------------------------------------------*/ + /* Filter wrt Other Vertical Edges */ + /*--------------------------------------------------------------------*/ + { + WORD32 ofst_a, ofst_b, idx_b_y, idx_b_u, + idx_b_v; + WORD32 qp_avg, qp_avg_u, qp_avg_v; + ofst_a = ps_cur_mb->i1_slice_alpha_c0_offset; + ofst_b = ps_cur_mb->i1_slice_beta_offset; + qp_avg = ps_cur_mb->u1_mb_qp; + idx_a_y = qp_avg + ofst_a; + alpha = gau1_ih264d_alpha_table[12 + idx_a_y]; + idx_b_y = qp_avg + ofst_b; + beta = gau1_ih264d_beta_table[12 + idx_b_y]; + + /* CHROMA Cb values */ + qp_avg_u = (qp_avg + i1_cb_qp_idx_ofst); + qp_avg_u = gau1_ih264d_qp_scale_cr[12 + qp_avg_u]; + idx_a_u = qp_avg_u + ofst_a; + alpha_u = gau1_ih264d_alpha_table[12 + idx_a_u]; + idx_b_u = qp_avg_u + ofst_b; + beta_u = gau1_ih264d_beta_table[12 + idx_b_u]; + /* CHROMA Cr values */ + qp_avg_v = (qp_avg + i1_cr_qp_idx_ofst); + qp_avg_v = gau1_ih264d_qp_scale_cr[12 + qp_avg_v]; + idx_a_v = qp_avg_v + ofst_a; + alpha_v = gau1_ih264d_alpha_table[12 + idx_a_v]; + idx_b_v = qp_avg_v + ofst_b; + beta_v = gau1_ih264d_beta_table[12 + idx_b_v]; + } + + //STARTL4_FILTER_VERT; + + pu1_cliptab_y = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_y]; //this for Luma + pu1_cliptab_u = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_u]; //this for chroma + pu1_cliptab_v = (UWORD8 *)&gau1_ih264d_clip_table[12 + idx_a_v]; //this for chroma + + //edge=1 + + + u4_bs = pu4_bs_tab[5]; + pu1_y = ps_tfr_cxt->pu1_mb_y; + pu1_u = ps_tfr_cxt->pu1_mb_u; + + if(u4_bs) + { + + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 4, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + + } + //edge=2 + + u4_bs = pu4_bs_tab[6]; + if(u4_bs) + { + + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 8, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_vert_bslt4(pu1_u + 4 * YUV420SP_FACTOR, + i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v, u4_bs, + pu1_cliptab_u, pu1_cliptab_v); + } + //edge=3 + + u4_bs = pu4_bs_tab[7]; + if(u4_bs) + { + + ps_dec->pf_deblk_luma_vert_bslt4(pu1_y + 12, i4_strd_y, alpha, beta, + u4_bs, pu1_cliptab_y); + + } + + /*--------------------------------------------------------------------*/ + /* Filter wrt Top edge */ + /* except */ + /* - Top Egde is Picture Boundary */ + /* - Top Egde is part of Slice Boundary and Deblocking */ + /* parameters of slice disable Filtering of Slice Boundary Edges*/ + /*--------------------------------------------------------------------*/ + if(ps_top_mb) + { + /** if top MB and MB AFF and cur MB is frame and top is field then */ + /* one extra top edge needs to be deblocked */ + if(u1_extra_top_edge) + { + ih264d_filter_boundary_topmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + (UWORD16)(i4_strd_y << 1), + (UWORD16)(i4_strd_uv << 1), + ps_top_mb - 1, pu4_bs_tab[8]); + ps_tfr_cxt->pu1_mb_y += i4_strd_y; + ps_tfr_cxt->pu1_mb_u += i4_strd_uv; + ps_tfr_cxt->pu1_mb_v += i4_strd_uv; + + ih264d_filter_boundary_topmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + (UWORD16)(i4_strd_y << 1), + (UWORD16)(i4_strd_uv << 1), + ps_top_mb, pu4_bs_tab[0]); + ps_tfr_cxt->pu1_mb_y -= i4_strd_y; + ps_tfr_cxt->pu1_mb_u -= i4_strd_uv; + ps_tfr_cxt->pu1_mb_v -= i4_strd_uv; + } + else + { + ih264d_filter_boundary_topmbaff(ps_dec, ps_tfr_cxt, + i1_cb_qp_idx_ofst, + i1_cr_qp_idx_ofst, ps_cur_mb, + i4_strd_y, i4_strd_uv, ps_top_mb, + pu4_bs_tab[0]); + } + } + + /*--------------------------------------------------------------------*/ + /* Filter wrt Other Horizontal Edges */ + /*--------------------------------------------------------------------*/ + + //edge1 + u4_bs = pu4_bs_tab[1]; + + if(u4_bs) + { + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y + (i4_strd_y << 2), i4_strd_y, + alpha, beta, u4_bs, pu1_cliptab_y); + + } + //edge2 + u4_bs = pu4_bs_tab[2]; + + if(u4_bs) + { + + ps_dec->pf_deblk_luma_horz_bslt4(pu1_y + (i4_strd_y << 3), i4_strd_y, + alpha, beta, u4_bs, pu1_cliptab_y); + ps_dec->pf_deblk_chroma_horz_bslt4(pu1_u + (i4_strd_uv << 2), + i4_strd_uv, alpha_u, beta_u, + alpha_v, beta_v, u4_bs, + pu1_cliptab_u, pu1_cliptab_v); + + } + //edge3 + u4_bs = pu4_bs_tab[3]; + if(u4_bs) + { + + ps_dec->pf_deblk_luma_horz_bslt4( + (pu1_y + (i4_strd_y << 3) + (i4_strd_y << 2)), + i4_strd_y, alpha, beta, u4_bs, pu1_cliptab_y); + + } + +} + diff --git a/decoder/ih264d_deblocking.h b/decoder/ih264d_deblocking.h new file mode 100755 index 0000000..21601aa --- /dev/null +++ b/decoder/ih264d_deblocking.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_DEBLOCKING_H_ +#define _IH264D_DEBLOCKING_H_ +/*! + ************************************************************************** + * \file ih264d_deblocking.h + * + * \brief + * Declarations of deblocking functions + * + * \date + * 23/11/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" + +WORD8 ih264d_set_deblocking_parameters(deblk_mb_t * ps_cur_deblk_mb, + dec_slice_params_t * ps_slice, + UWORD8 u1_mb_ngbr_availablity, + UWORD8 u1_mb_field_decoding_flag); + +void FilterBoundaryLeft(tfr_ctxt_t * const ps_tfr_cxt, + const WORD8 i1_cb_qp_idx_ofst, + const WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * const ps_cur_mb, + UWORD16 u2_strd_y, + UWORD16 u2_strd_uv, + deblk_mb_t * const ps_left_mb, + const UWORD32 pu4_bs_tab[], + const UWORD8 u1_cur_fld); +void FilterBoundaryTop(tfr_ctxt_t * const ps_tfr_cxt, + const WORD8 i1_cb_qp_idx_ofst, + const WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * const ps_cur_mb, + const UWORD16 u2_strd_y, + const UWORD16 u2_strd_uv, + deblk_mb_t * const ps_top_mb, + const UWORD32 u4_bs); +void deblock_mb(tfr_ctxt_t * const ps_tfr_cxt, + const WORD8 i1_cb_qp_idx_ofst, + const WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * const ps_cur_mb, + WORD32 i4_strd_y, + WORD32 i4_strd_uv, + deblk_mb_t * const ps_top_mb, + deblk_mb_t * const ps_left_mb, + const UWORD8 u1_cur_fld, + const UWORD8 u1_extra_top_edge); +void ih264d_deblock_mb_mbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * const ps_tfr_cxt, + const WORD8 i1_cb_qp_idx_ofst, + const WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * const ps_cur_mb, + WORD32 i4_strd_y, + WORD32 i4_strd_uv, + deblk_mb_t * const ps_top_mb, + deblk_mb_t * const ps_left_mb, + const UWORD8 u1_cur_fld, + const UWORD8 u1_extra_top_edge); + +void ih264d_deblock_picture_mbaff(dec_struct_t * const ps_dec); + +void ih264d_deblock_picture_non_mbaff(dec_struct_t * const ps_dec); + +void ih264d_deblock_picture_progressive(dec_struct_t * const ps_dec); + +void ih264d_compute_bs_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb); +void ih264d_compute_bs_non_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb); + +void ih264d_fill_bs_mbedge_2(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb); + +void ih264d_fill_bs_mbedge_4(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb); + +void ih264d_fill_bs1_16x16mb_pslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit); + +void ih264d_fill_bs1_non16x16mb_pslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit); + +void ih264d_fill_bs1_16x16mb_bslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit); + +void ih264d_fill_bs1_non16x16mb_bslice(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit); + +void ih264d_fill_bs_xtra_left_edge_cur_fld(UWORD32 *pu4_bs, + WORD32 u4_left_mb_t_csbp, + WORD32 u4_left_mb_b_csbp, + WORD32 u4_cur_mb_csbp, + UWORD32 u4_cur_mb_top); + +void ih264d_fill_bs_xtra_left_edge_cur_frm(UWORD32 *pu4_bs, + WORD32 u4_left_mb_t_csbp, + WORD32 u4_left_mb_b_csbp, + WORD32 u4_cur_mb_csbp, + UWORD32 u4_cur_mb_top); + +void ih264d_deblock_mb_nonmbaff(dec_struct_t *ps_dec, + tfr_ctxt_t * const ps_tfr_cxt, + const WORD8 i1_cb_qp_idx_ofst, + const WORD8 i1_cr_qp_idx_ofst, + deblk_mb_t * const ps_cur_mb, + WORD32 i4_strd_y, + WORD32 i4_strd_uv, + deblk_mb_t * const ps_top_mb, + deblk_mb_t * const ps_left_mb); + +void ih264d_init_deblk_tfr_ctxt(dec_struct_t * ps_dec, + pad_mgr_t *ps_pad_mgr, + tfr_ctxt_t *ps_tfr_cxt, + UWORD16 u2_image_wd_mb, + UWORD8 u1_mbaff); + +void ih264d_deblock_mb_level(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index); + +#endif /* _IH264D_DEBLOCKING_H_ */ diff --git a/decoder/ih264d_debug.c b/decoder/ih264d_debug.c new file mode 100755 index 0000000..5650e20 --- /dev/null +++ b/decoder/ih264d_debug.c @@ -0,0 +1,40 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_debug.c + * + * \brief + * Contains routines that can be used in debugging + * + * \date + * 20/11/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_debug.h" +#include "ih264d_defs.h" + diff --git a/decoder/ih264d_debug.h b/decoder/ih264d_debug.h new file mode 100755 index 0000000..787b697 --- /dev/null +++ b/decoder/ih264d_debug.h @@ -0,0 +1,135 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_DEBUG_H_ +#define _IH264D_DEBUG_H_ + +/*! + ************************************************************************** + * \file ih264d_debug.h + * + * \brief + * Contains declarations used for debugging + * + * \date + * 2/12/2002 + * + * \author AI + ************************************************************************** + */ +#ifdef DEBUG_DEC +#define H264_DEC_DEBUG_PRINT(...) printf("\n[H264_DEBUG] %s/%d:: ", __FUNCTION__, __LINE__);printf(__VA_ARGS__) +#else //DEBUG_DEC +#define H264_DEC_DEBUG_PRINT(...) {} +#endif //DEBUG_DEC +#define STRENGTH_DEBLOCKING 0 //sanjeev +#define DEBUG_RECONSTRUCT_LUMA 0 +#define DEBUG_RECONSTRUCT_CHROMA 0 + +#define DEBUG_IDCT 0 +#define DEBUG_LUMA_IDCT 0 +#define DEBUG_REF_IDCT 0 + +#define BIN_BIT_RATIO 0 +#define MB_PART_HIST 0 + +#define MB_INTRA_PREDICTION 1 + +#ifdef WIN32 +#define CHK_PURIFY 0 +#else +#define CHK_PURIFY 0 +#endif + +#if MB_INTRA_PREDICTION +#define MB_INTRA_CHROMA_PREDICTION_ON 1 +#define MB_INTRA_4x4_PREDICTION_ON 1 +#define MB_INTRA_16x16_PREDICTION_ON 1 +#endif + +#define TRACE 0 +#define DEBUG_CABAC 0 +#define DEBUG_ABS_MVD 0 +#define DEBUG_INTRA_PRED_MODES 0 +#define DEBUG_DEBLOCKING 0 + +#define COPYTHECONTEXT(s,val) +#define PRINT_TRACE +#define PRINT_TRACE_CAB +#define SWITCHOFFTRACE +#define SWITCHONTRACE +#define SWITCHOFFTRACECABAC +#define SWITCHONTRACECABAC + +#define INC_BIN_COUNT(ps_cab_env) +#define INC_DECISION_BINS(ps_cab_env) +#define INC_BYPASS_BINS(ps_cab_env) +#define INC_SYM_COUNT(ps_cab_env) +#define PRINT_BIN_BIT_RATIO(ps_dec) +#define RESET_BIN_COUNTS(ps_cab_env) + + +#ifdef PROFILE_DIS_DEBLK +#define PROFILE_DISABLE_DEBLK() return; +#else +#define PROFILE_DISABLE_DEBLK() ; +#endif + +#ifdef PROFILE_DIS_IQ_IT_RECON +#define PROFILE_DISABLE_IQ_IT_RECON() if (0) +#define PROFILE_DISABLE_IQ_IT_RECON_RETURN() return; +#else +#define PROFILE_DISABLE_IQ_IT_RECON() ; +#define PROFILE_DISABLE_IQ_IT_RECON_RETURN() ; +#endif + +#ifdef PROFILE_DIS_INTRA_PRED +#define PROFILE_DISABLE_INTRA_PRED() if (0) +#else +#define PROFILE_DISABLE_INTRA_PRED() ; +#endif + +#ifdef PROFILE_DIS_UNPACK +#define PROFILE_DISABLE_UNPACK_LUMA() return 0; +#define PROFILE_DISABLE_UNPACK_CHROMA() return ; +#else +#define PROFILE_DISABLE_UNPACK_LUMA() ; +#define PROFILE_DISABLE_UNPACK_CHROMA() ; +#endif + +#ifdef PROFILE_DIS_INTER_PRED +#define PROFILE_DISABLE_INTER_PRED() return; +#else +#define PROFILE_DISABLE_INTER_PRED() ; +#endif + +#ifdef PROFILE_DIS_BOUNDARY_STRENGTH +#define PROFILE_DISABLE_BOUNDARY_STRENGTH() return; +#else +#define PROFILE_DISABLE_BOUNDARY_STRENGTH() ; +#endif + +#ifdef PROFILE_DIS_MB_PART_INFO +#define PROFILE_DISABLE_MB_PART_INFO() return 0; +#else +#define PROFILE_DISABLE_MB_PART_INFO() ; +#endif + +#endif /* _IH264D_DEBUG_H_ */ + diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h new file mode 100755 index 0000000..3f8bc58 --- /dev/null +++ b/decoder/ih264d_defs.h @@ -0,0 +1,671 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_DEFS_H_ +#define _IH264D_DEFS_H_ + +/** + ************************************************************************ + * \file ih264d_defs.h + * + * \brief + * Type definitions used in the code + * + * \date + * 19/11/2002 + * + * \author Sriram Sethuraman + * + ************************************************************************ + */ +#define H264_MAX_FRAME_WIDTH 3840 +#define H264_MAX_FRAME_HEIGHT 2160 + +#define H264_MIN_FRAME_WIDTH 16 +#define H264_MIN_FRAME_HEIGHT 16 + +#define IH264DEC_MAX_NAL_UNIT_SIZE 311040 +#define IH264DEC_NUM_ZEROS_IN_START_CODE 2 +#define H264DEC_MEM_ALLOC_SUCCESS 1 +#define H264DEC_MEM_ALLOC_FAILURE 0 +#define H264DEC_CREATE_FAILED (NULL) + +#define H264_NO_BUF_TO_DISPLAY -1 +#define H264_DISPLAY_BUF_FOUND 0 +#define IH264DEC_YUV420 0 +#define IH264DEC_YUV422 1 +#define IH264DEC_YUV422INTERLACED 2 +#define IH264DEC_RGB 4 // Original Size +/* Ceiling of variables to the nearest power of 2 */ +#define FILL_POWEROF2(x,y) (size_t)(((x) & ((1<<(y))-1))?((1<<(y)) - ((x) & ((1<<(y))-1))): 0) +#define ALIGN_POWEROF2(x,y) (x) = (x)+FILL_POWEROF2((size_t)(x),y) + +/** Bit manipulation macros */ +#define CHECKBIT(a,i) ((a) & (1 << i)) +#define CLEARBIT(a,i) ((a) &= ~(1 << i)) + +/** Macro to convert a integer to a boolean value */ +#define BOOLEAN(x) (!!(x)) + +/** Arithmetic operations */ +#define MOD(x,y) ((x)%(y)) +#define DIV(x,y) ((x)/(y)) +#define MUL(x,y) ((x)*(y)) +#define SIGN_POW2_DIV(x, y) (((x) < 0) ? (-((-(x)) >> (y))) : ((x) >> (y))) + +#define MB_ENABLE_FILTERING 0x00 +#define MB_DISABLE_FILTERING 0x01 +#define MB_DISABLE_TOP_EDGE 0x02 +#define MB_DISABLE_LEFT_EDGE 0x04 + +/** Maximum number of reference pics */ +#define MAX_REF_BUFS 32 +#define MAX_DISP_BUFS_NEW 64 +#define MAX_FRAMES 16 +#define MAX_MBS_IN_ROW (720/16) +#define INVALID_FRAME_NUM 0x0fffffff +#define GAP_FRAME_NUM 0x1fffffff +#define MAX_PIC_SIZE 622080 // 720 * 576 * 1.5 +/** macros for reference picture lists, refIdx to POC mapping */ +// 1 extra entry into reference picture lists for refIdx = -1. +// this entry is always 0. this saves conditional checks in +// FillBs modules. +#define POC_LIST_L0_TO_L1_DIFF (( 2*MAX_FRAMES) + 1) +#define POC_LIST_L0_TO_L1_DIFF_1 ((MAX_FRAMES) + 1) + +#define FRM_LIST_L0 0 //0 +#define FRM_LIST_L1 1 * POC_LIST_L0_TO_L1_DIFF//FRM_LIST_L0 + POC_LIST_L0_TO_L1_DIFF //0+33 //(1 * POC_LIST_L0_TO_L1_DIFF) +#define TOP_LIST_FLD_L0 2 * POC_LIST_L0_TO_L1_DIFF//FRM_LIST_L1 + POC_LIST_L0_TO_L1_DIFF //0+33+33 //(2 * POC_LIST_L0_TO_L1_DIFF) +#define TOP_LIST_FLD_L1 3 * POC_LIST_L0_TO_L1_DIFF//TOP_LIST_FLD_L0 + POC_LIST_L0_TO_L1_DIFF_1 //0+33+33+17 //(3 * POC_LIST_L0_TO_L1_DIFF) +#define BOT_LIST_FLD_L0 4 * POC_LIST_L0_TO_L1_DIFF//TOP_LIST_FLD_L1 + POC_LIST_L0_TO_L1_DIFF_1 //0+33+33+17+17 +#define BOT_LIST_FLD_L1 5 * POC_LIST_L0_TO_L1_DIFF//BOT_LIST_FLD_L0 + POC_LIST_L0_TO_L1_DIFF_1 //0+33+33+17+17+17 +#define TOTAL_LIST_ENTRIES 6 * POC_LIST_L0_TO_L1_DIFF//BOT_LIST_FLD_L1 + POC_LIST_L0_TO_L1_DIFF_1 //0+33+33+17+17+17+17 +#define PAD_MV_BANK_ROW 64 +#define OFFSET_MV_BANK_ROW ((PAD_MV_BANK_ROW)>>1) +#define PAD_PUC_CURNNZ 32 +#define OFFSET_PUC_CURNNZ (PAD_PUC_CURNNZ) +#define PAD_MAP_IDX_POC (1) +#define OFFSET_MAP_IDX_POC (1) + +#define OFFSET_MAP_IDX_POC (1) + +#define NAL_REF_IDC(nal_first_byte) ((nal_first_byte >> 5) & 0x3) +#define NAL_FORBIDDEN_BIT(nal_first_byte) (nal_first_byte>>7) +#define NAL_UNIT_TYPE(nal_first_byte) (nal_first_byte & 0x1F) + +#define INT_PIC_TYPE_I (0x00) + +#define YIELD_CNT_THRESHOLD 8 +#define ENABLE_420P_UV_SHARING 1 + +#define OK 0 +#define END 1 +#define NOT_OK -1 + +/* For 420SP */ +#define YUV420SP_FACTOR 2 + + +/** + *************************************************************************** + * Enum to hold various mem records being request + **************************************************************************** + */ +enum +{ + /** + * Codec Object at API level + */ + MEM_REC_IV_OBJ, + + /** + * Codec context + */ + MEM_REC_CODEC, + + /** + * Bitstream buffer which holds emulation prevention removed bytes + */ + MEM_REC_BITSBUF, + + /** + * Buffer to hold coeff data + */ + MEM_REC_COEFF_DATA, + + /** + * Motion vector bank + */ + MEM_REC_MVBANK, + + /** + * Holds mem records passed to the codec. + */ + MEM_REC_BACKUP, + + /** + * Holds SPS + */ + MEM_REC_SPS, + + /** + * Holds PPS + */ + MEM_REC_PPS, + + /** + * Holds Slice Headers + */ + MEM_REC_SLICE_HDR, + + /** + * Holds thread handles + */ + MEM_REC_THREAD_HANDLE, + + /** + * Contains i4_status map indicating parse i4_status per MB basis + */ + MEM_REC_PARSE_MAP, + + /** + * Contains i4_status map indicating processing i4_status per MB basis + */ + MEM_REC_PROC_MAP, + + /** + * Contains slice number info for each MB + */ + + MEM_REC_SLICE_NUM_MAP, + + /** + * Holds dpb manager context + */ + MEM_REC_DPB_MGR, + + /** + * Holds neighbors' info + */ + MEM_REC_NEIGHBOR_INFO, + + /** + * Holds neighbors' info + */ + MEM_REC_PRED_INFO, + + + /** + * Holds inter pred inforamation on packed format info + */ + MEM_REC_PRED_INFO_PKD, + /** + * Holds neighbors' info + */ + MEM_REC_MB_INFO, + + /** + * Holds deblock Mb info structure frame level) + */ + MEM_REC_DEBLK_MB_INFO, + + /** + * Holds reference picture buffers in non-shared mode + */ + MEM_REC_REF_PIC, + + /** + * Holds some misc intermediate_buffers + */ + MEM_REC_EXTRA_MEM, + + /** + * Holds some misc intermediate_buffers + */ + MEM_REC_INTERNAL_SCRATCH, + + /** + * Holds some misc intermediate_buffers + */ + MEM_REC_INTERNAL_PERSIST, + + /* holds structures related to picture buffer manager*/ + MEM_REC_PIC_BUF_MGR, + + /*holds structure related to MV buffer manager*/ + MEM_REC_MV_BUF_MGR, + + /** + * Place holder to compute number of memory records. + */ + MEM_REC_CNT +/* Do not add anything below */ +}; + +#ifdef DEBLOCK_THREAD +#define H264_MUTEX_LOCK(lock) ithread_mutex_lock(lock) +#define H264_MUTEX_UNLOCK(lock) ithread_mutex_unlock(lock) +#else //DEBLOCK_THREAD +#define H264_MUTEX_LOCK(lock) +#define H264_MUTEX_UNLOCK(lock) + +#define DEBUG_THREADS_PRINTF(...) +#define DEBUG_PERF_PRINTF(...) + +/** Profile Types*/ +#define BASE_PROFILE_IDC 66 +#define MAIN_PROFILE_IDC 77 +#define HIGH_PROFILE_IDC 100 +#define MAIN_PROFILE 1 + +#define MB_SIZE 16 +#define BLK8x8SIZE 8 +#define BLK_SIZE 4 +#define NUM_BLKS_PER_MB 24 +#define NUM_LUM_BLKS_PER_MB 16 +#define LUM_BLK 0 +#define CHROM_BLK 1 +#define NUM_PELS_IN_MB 64 + +/* Level Types */ +#define H264_LEVEL_1_0 10 +#define H264_LEVEL_1_1 11 +#define H264_LEVEL_1_2 12 +#define H264_LEVEL_1_3 13 +#define H264_LEVEL_2_0 20 +#define H264_LEVEL_2_1 21 +#define H264_LEVEL_2_2 22 +#define H264_LEVEL_3_0 30 +#define H264_LEVEL_3_1 31 +#define H264_LEVEL_3_2 32 +#define H264_LEVEL_4_0 40 +#define H264_LEVEL_4_1 41 +#define H264_LEVEL_4_2 42 +#define H264_LEVEL_5_0 50 +#define H264_LEVEL_5_1 51 + +#define MAX_MBS_LEVEL_51 36864 +#define MAX_MBS_LEVEL_50 22080 +#define MAX_MBS_LEVEL_42 8704 +#define MAX_MBS_LEVEL_41 8192 +#define MAX_MBS_LEVEL_40 8192 +#define MAX_MBS_LEVEL_32 5120 +#define MAX_MBS_LEVEL_31 3600 +#define MAX_MBS_LEVEL_30 1620 +#define MAX_MBS_LEVEL_22 1620 +#define MAX_MBS_LEVEL_21 792 +#define MAX_MBS_LEVEL_20 396 +#define MAX_MBS_LEVEL_13 396 +#define MAX_MBS_LEVEL_12 396 +#define MAX_MBS_LEVEL_11 396 +#define MAX_MBS_LEVEL_10 99 + + +/* + | Legend: + | LVL Level*10 + | MPR Macroblk processing rate + | MMF Max Mbs/Frm + | MDK Max DbpSize (in kB) + | MDB max DbpSize (in bytes) + | MFS FrmSizeYUV (in bytes) + | MDP Max DBPics + | MDC Ceiling DBPics + | FPS Frame/Second + | + | LVL MPR MMF MDK MDB MFS MDP MDC FPS + | 10 1485 99 148.5 152064 38016 4.00 4.00 15.00 + | 11 3000 396 337.5 345600 152064 2.27 3.00 7.58 + | 12 6000 396 891 912384 152064 6.00 6.00 15.15 + | 13 11880 396 891 912384 152064 6.00 6.00 30.00 + | 20 11880 396 891 912384 152064 6.00 6.00 30.00 + | 21 19800 792 1782 1824768 304128 6.00 6.00 25.00 + | 22 20250 1620 3037.5 3110400 622080 5.00 5.00 12.50 + | 30 40500 1620 3037.5 3110400 622080 5.00 5.00 25.00 + */ +#define MAX_REF_LEVEL_1_0 4 +#define MAX_REF_LEVEL_1_1 3 +#define MAX_REF_LEVEL_1_2 6 +#define MAX_REF_LEVEL_1_3 6 +#define MAX_REF_LEVEL_2_0 6 +#define MAX_REF_LEVEL_2_1 6 +#define MAX_REF_LEVEL_2_2 5 +#define MAX_REF_LEVEL_3_0 5 +#define H264_MAX_REF_PICS 16 + +#define MIN_LEVEL_SUPPORTED 10 +#define MAX_LEVEL_SUPPORTED 64 + +/** NAL Types */ +#define SLICE_NAL 1 +#define SLICE_DATA_PARTITION_A_NAL 2 +#define SLICE_DATA_PARTITION_B_NAL 3 +#define SLICE_DATA_PARTITION_C_NAL 4 +#define IDR_SLICE_NAL 5 +#define SEI_NAL 6 +#define SEQ_PARAM_NAL 7 +#define PIC_PARAM_NAL 8 +#define ACCESS_UNIT_DELIMITER_RBSP 9 +#define END_OF_SEQ_RBSP 10 +#define END_OF_STREAM_RBSP 11 +#define FILLER_DATA_NAL 12 + +/** Entropy coding modes */ +#define CAVLC 0 +#define CABAC 1 + +/** Picture Types */ +#define I_PIC 0 +#define IP_PIC 1 +#define IPB_PIC 2 +#define SI_PIC 3 +#define SIP_PIC 4 +#define ISI_PIC 5 +#define ISI_PSP_PIC 6 +#define ALL_PIC 7 + +/* Frame or field picture type */ +#define FRM_PIC 0x00 +#define TOP_FLD 0x01 +#define BOT_FLD 0x02 +#define COMP_FLD_PAIR 0x03 /* TOP_FLD | BOT_FLD */ +#define AFRM_PIC 0x04 +#define TOP_REF 0x08 +#define BOT_REF 0x10 +#define PIC_MASK 0x03 +#define NON_EXISTING 0xff + +/* field picture type for display */ +#define DISP_TOP_FLD 0x00 +#define DISP_BOT_FLD 0x01 + +/** Slice Types */ +#define P_SLICE 0 +#define B_SLICE 1 +#define I_SLICE 2 +#define SP_SLICE 3 +#define SI_SLICE 4 + +/* Definition for picture skip */ +#define SKIP_NONE (0x0) +#define I_SLC_BIT (0x1) +#define P_SLC_BIT (0x2) +#define B_SLC_BIT (0x4) + +/** Macros used for Deblocking */ +#define D_INTER_MB 0 +#define D_INTRA_MB 1 +#define D_PRED_NON_16x16 2 +#define D_B_SLICE 4 +#define D_B_SUBMB 6 //D_B_SLICE | D_PRED_NON_16x16 | D_INTER_MB +#define D_FLD_MB 0x80 + +/** Macros for Cabac checks */ +/** MbType */ +/** |x|x|I_PCM|SKIP| + |S|Inter/Intra|P/B|NON-BD16x16/BD16x16,I16x16/I4x4| */ +#define CAB_INTRA 0x00 /* 0000 00xx */ +#define CAB_INTER 0x04 /* 0000 01xx */ +#define CAB_I4x4 0x00 /* 0000 00x0 */ +#define CAB_I16x16 0x01 /* 0000 00x1 */ +#define CAB_BD16x16 0x04 /* 0000 0100 */ +#define CAB_NON_BD16x16 0x05 /* 0000 0101 */ +#define CAB_P 0x07 /* 0000 0111 */ +#define CAB_SI4x4 0x08 /* 0000 10x0 */ +#define CAB_SI16x16 0x09 /* 0000 10x1 */ +#define CAB_SKIP_MASK 0x10 /* 0001 0000 */ +#define CAB_SKIP 0x10 /* 0001 0000 */ +#define CAB_P_SKIP 0x16 /* 0001 x11x */ +#define CAB_B_SKIP 0x14 /* 0001 x100 */ +#define CAB_BD16x16_MASK 0x07 /* 0000 0111 */ +#define CAB_INTRA_MASK 0x04 /* 0000 0100 */ +#define CAB_I_PCM 0x20 /* 001x xxxx */ + +/**< Binarization types for CABAC */ +/* |x|x|x|x|MSB_FIRST_FLC|FLC|TUNARY|UNARY| */ +#define UNARY 1 +#define TUNARY 2 +#define FLC 4 +#define MSB_FIRST_FLC 12 + +/** Macroblock Types */ +#define I_4x4_MB 0 +#define I_16x16_MB 1 +#define P_MB 2 +#define B_MB 3 +#define SI_MB 4 +#define SP_MB 5 +#define I_PCM_MB 6 + +#define SI4x4_MB 0xFF + +/** Intra luma 16x16 and chroma 8x8 prediction modes */ +#define NUM_INTRA_PRED_MODES 4 +#define VERT 0 +#define HORIZ 1 +#define DC 2 +#define PLANE 3 +#define NOT_VALID -1 +#define DC_DC_DC_DC 0x02020202 /*packed 4 bytes used in Decode Intra Mb*/ + +/** Intra luma 4x4 prediction modes */ +#define NUM_INTRA4x4_PRED_MODES 9 + +/** VERT, HORIZ, DC are applicable to 4x4 as well */ +/** D - Down; U - Up; L - Left; R - Right */ +#define DIAG_DL 3 +#define DIAG_DR 4 +#define VERT_R 5 +#define HORIZ_D 6 +#define VERT_L 7 +#define HORIZ_U 8 + +/** P_MB prediction modes */ +#define NUM_INTER_MB_PRED_MODES 5 +#define PRED_16x16 0 +#define PRED_16x8 1 +#define PRED_8x16 2 +#define PRED_8x8 3 +#define PRED_8x8R0 4 +#define MAGIC_16x16 5 +#define MB_SKIP 255 + +/* P_MB submb modes */ +#define P_L0_8x8 0 +#define P_L0_8x4 1 +#define P_L0_4x8 2 +#define P_L0_4x4 3 + +/* B_MB submb modes */ +#define B_DIRECT_8x8 0 +#define B_L0_8x8 1 +#define B_L1_8x8 2 +#define B_BI_8x8 3 +#define B_L0_8x4 4 +#define B_L0_4x8 5 +#define B_L1_8x4 6 +#define B_L1_4x8 7 +#define B_BI_8x4 8 +#define B_BI_4x8 9 +#define B_L0_4x4 10 +#define B_L1_4x4 11 +#define B_BI_4x4 12 + +/** B_MB prediction modes */ +#define B_8x8 22 +#define PRED_INVALID -1 +#define B_DIRECT 0 +#define PRED_L0 1 +#define PRED_L1 2 +#define BI_PRED 3 +#define B_DIRECT_BI_PRED 23 +#define B_DIRECT_PRED_L0 24 +#define B_DIRECT_PRED_L1 25 +#define B_DIRECT_SPATIAL 26 + +#define B_DIRECT8x8_BI_PRED 13 +#define B_DIRECT8x8_PRED_L0 14 +#define B_DIRECT8x8_PRED_L1 15 + +#define ONE_TO_ONE 0 +#define FRM_TO_FLD 1 +#define FLD_TO_FRM 2 + +/** Inter Sub MB Pred modes */ +#define NUM_INTER_SUBMB_PRED_MODES 4 +#define SUBMB_8x8 0 +#define SUBMB_8x4 1 +#define SUBMB_4x8 2 +#define SUBMB_4x4 3 + +/** Coded Block Pattern - Chroma */ +#define CBPC_ALLZERO 0 +#define CBPC_ACZERO 1 +#define CBPC_NONZERO 2 + +/** Index for accessing the left MB in the MV predictor array */ +#define LEFT 0 +/** Index for accessing the top MB in the MV predictor array */ +#define TOP 1 +/** Index for accessing the top right MB in the MV predictor array */ +#define TOP_R 2 +/** Index for accessing the top Left MB in the MV predictor array */ +#define TOP_L 3 + +/** Maximum number of Sequence Parameter sets */ +#define MAX_NUM_SEQ_PARAMS 32 + +/** Maximum number of Picture Parameter sets */ +#define MAX_NUM_PIC_PARAMS 256 + +#define MASK_ERR_SEQ_SET_ID (0xFFFFFFE0) +#define MASK_ERR_PIC_SET_ID (0xFFFFFF00) + +#define MAX_PIC_ORDER_CNT_TYPE 2 + +#define MAX_BITS_IN_FRAME_NUM 16 +#define MAX_BITS_IN_POC_LSB 16 + +#define H264_MAX_REF_PICS 16 +#define H264_MAX_REF_IDX 32 +#define MAX_WEIGHT_BIPRED_IDC 2 +#define MAX_CABAC_INIT_IDC 2 + +#define H264_DEFAULT_NUM_CORES 1 +#define DEFAULT_SEPARATE_PARSE (H264_DEFAULT_NUM_CORES == 2)? 1 :0 + +/** Maximum number of Slice groups */ +#define MAX_NUM_SLICE_GROUPS 8 +#define MAX_NUM_REF_FRAMES_OFFSET 255 + +/** Deblocking modes for a slice */ +#define SLICE_BOUNDARY_DBLK_DISABLED 2 +#define DBLK_DISABLED 1 +#define DBLK_ENABLED 0 +#define MIN_DBLK_FIL_OFF -12 +#define MAX_DBLK_FIL_OFF 12 + +/** Width of the predictor buffers used for MC */ +#define MB_SIZE 16 +#define BLK8x8SIZE 8 +#define BLK_SIZE 4 +#define NUM_BLKS_PER_MB 24 +#define NUM_LUM_BLKS_PER_MB 16 + +#define SUB_BLK_WIDTH 4 +#define SUB_SUB_BLK_SIZE 4 /* 2x2 pixel i4_size */ +#define SUB_BLK_SIZE ((SUB_BLK_WIDTH) * (SUB_BLK_WIDTH)) +#define MB_LUM_SIZE 256 +#define MB_CHROM_SIZE 64 + +/**< Width to pad the luminance frame buff */ +/**< Height to pad the luminance frame buff */ +/**< Width to pad the chrominance frame buff */ +/**< Height to pad the chrominance frame buff */ + +#define PAD_LEN_Y_H 32 +#define PAD_LEN_Y_V 20 +#define PAD_LEN_UV_H 16 +#define PAD_LEN_UV_V 8 + +#define PAD_MV_BANK_ROW 64 + +/**< Maimum u4_ofst by which the Mvs could point outside the frame buffers + horizontally in the left and vertically in the top direction */ +#define MAX_OFFSET_OUTSIDE_X_FRM -20 +#define MAX_OFFSET_OUTSIDE_Y_FRM -20 +#define MAX_OFFSET_OUTSIDE_UV_FRM -8 + +/** UVLC parsing macros */ +#define UEV 1 +#define SEV 2 +#define TEV 3 + +/** Defines for Boolean values */ +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#define UNUSED_FOR_REF 0 +#define IS_SHORT_TERM 1 +#define IS_LONG_TERM 2 + +/** Defines for which field gets displayed first */ +#define MAX_FRAMES 16 +#define INVALID_FRAME_NUM 0x0fffffff +#define DO_NOT_DISP 254 +#define DISP_FLD_FIRST_UNDEF 0 +#define DISP_TOP_FLD_FIRST 1 +#define DISP_BOT_FLD_FIRST 2 + +/** Misc error resilience requirements*/ +#define MASK_LOG2_WEIGHT_DENOM 0xFFFFFFF8 +#define MASK_PRED_WEIGHT_OFFSET 0xFFFFFF00 +#define MAX_REDUNDANT_PIC_CNT 127 + +#define DPB_HACK 0 +#define DPB_HACK_NEW 0 + + + +#define PD_MB_BUF_SIZE (H264_MAX_FRAME_WIDTH * H264_MAX_FRAME_WIDTH / 256) +#define PD_MB_BUF_SIZE_MOD 0xffffffff +#define MAX_PRED_INFO_LIMIT (PD_MB_BUF_SIZE * 32 * 2) + +#endif //DEBLOCK_THREAD + + +#define NO_DC_SB 0 +#define SUB_BLK_MASK 0xFFFFFF00 +#define NUM_COEFFS_IN_4x4BLK 16 + + +#define MEMSET_16BYTES(pu4_start,value) \ + { \ + memset(pu4_start,value,16); \ + } + +#define MEMCPY_16BYTES(dst,src) \ +{ \ + memcpy(dst,src,16); \ +} + + +#endif /*_IH264D_DEFS_H_*/ diff --git a/decoder/ih264d_dpb_manager.h b/decoder/ih264d_dpb_manager.h new file mode 100755 index 0000000..a9539c8 --- /dev/null +++ b/decoder/ih264d_dpb_manager.h @@ -0,0 +1,173 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_DPB_MANAGER_H_ +#define _IH264D_DPB_MANAGER_H_ +/*! +*************************************************************************** +* \file ih264d_dpb_manager.h +* +* \brief +* Decoded Picture Buffer Manager Include File +* +* Detailed_description +* +* \date +* 19-12-2002 +* +* \author Sriram Sethuraman +*************************************************************************** +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" + +#define END_OF_MMCO 0 +#define MARK_ST_PICNUM_AS_NONREF 1 +#define MARK_LT_INDEX_AS_NONREF 2 +#define MARK_ST_PICNUM_AS_LT_INDEX 3 +#define SET_MAX_LT_INDEX 4 +#define RESET_REF_PICTURES 5 +#define SET_LT_INDEX 6 +#define RESET_NONREF_PICTURES 7 +#define RESET_ALL_PICTURES 8 + +struct field_t +{ + /* picNum of tbe reference field */ + WORD32 i4_pic_num; + + /* assigned when used for long term reference */ + /* else MAX_REF_BUFS+1 */ + UWORD8 u1_long_term_frame_idx; + + /* 0 : unused for reference */ + /* 1 : used for short term reference */ + /* 2 : used for long term reference */ + UWORD8 u1_reference_info; +}; + + +struct dpb_info_t +{ + struct pic_buffer_t *ps_pic_buf; /** Pointer to picture buffer structure */ + WORD32 i4_frame_num; /** frame number of picture - unique for each ref*/ + struct dpb_info_t *ps_prev_short;/** Link to the DPB with previous picNum */ + struct dpb_info_t *ps_prev_long; /** Link to the DPB with previous long term frame*/ + struct field_t s_top_field; /** Contains information of the top_field + reference info, pic num and longt term frame idx */ + struct field_t s_bot_field; /** Contains information of the bot_field + reference info, pic num and longt term frame idx */ + UWORD8 u1_buf_id; /** bufID from bufAPI */ + UWORD8 u1_used_as_ref; /** whether buffer is used as ref for frame or + complementary reference field pair */ + UWORD8 u1_lt_idx; /** If buf is assigned long-term index; else MAX_REF_BUFS+1 */ + +}; + +typedef struct +{ + struct pic_buffer_t *ps_def_dpb[MAX_REF_BUFS];/** DPB in default index order */ + struct pic_buffer_t *ps_mod_dpb[2][2 * MAX_REF_BUFS];/** DPB in reordered index order, 0-fwd,1-bwd */ + struct pic_buffer_t *ps_init_dpb[2][2 * MAX_REF_BUFS];/** DPB in reordered index order, 0-fwd,1-bwd */ + struct dpb_info_t *ps_dpb_st_head; /** Pointer to the most recent picNum */ + struct dpb_info_t *ps_dpb_ht_head; /** Pointer to the smallest LT index */ + struct dpb_info_t as_dpb_info[MAX_REF_BUFS]; /** Physical storage for dpbInfo for ref bufs */ + UWORD8 u1_num_st_ref_bufs; /** Number of short term ref. buffers */ + UWORD8 u1_num_lt_ref_bufs; /** Number of long term ref. buffer */ + UWORD8 u1_max_lt_pic_idx_plus1; /** Maximum long term pictures - 0 to max_long_term_pic_idx */ + UWORD8 u1_num_gaps; /** Total number of outstanding gaps */ + void * pv_codec_handle; /* For Error Handling */ + WORD32 i4_max_frm_num; /** Max frame number */ + WORD32 ai4_gaps_start_frm_num[MAX_FRAMES];/** start frame number for a gap seqn */ + WORD32 ai4_gaps_end_frm_num[MAX_FRAMES]; /** start frame number for a gap seqn */ + WORD8 ai1_gaps_per_seq[MAX_FRAMES]; /** number of gaps with each gap seqn */ + WORD32 ai4_poc_buf_id_map[MAX_FRAMES][3]; + WORD8 i1_poc_buf_id_entries; + WORD8 i1_gaps_deleted; + UWORD16 u2_pic_wd; + UWORD16 u2_pic_ht; +}dpb_manager_t; + +/** Structure store the MMC Commands */ +struct MMCParams +{ + UWORD32 u4_mmco; /** memory managemet control operation */ + UWORD32 u4_diff_pic_num; /** diff Of Pic Nums Minus1 */ + UWORD32 u4_lt_idx; /** Long Term Pic Idx */ + UWORD32 u4_max_lt_idx_plus1; /** MaxLongTermPicIdxPlus1 */ +}; + +typedef struct +{ + UWORD8 u1_dpb_commands_read; /** Flag to indicate that DBP commands are read */ + UWORD8 u1_buf_mode; /** decoder Pic bugffering mode*/ + UWORD8 u1_num_of_commands; /** Number of MMC commands */ + /* These variables are ised in case of IDR pictures only */ + UWORD8 u1_idr_pic; /** = 1 ,IDR pic */ + UWORD8 u1_no_output_of_prior_pics_flag; + UWORD8 u1_long_term_reference_flag; + struct MMCParams as_mmc_params[MAX_REF_BUFS]; /* < Buffer to store MMC commands */ + UWORD8 u1_dpb_commands_read_slc; +}dpb_commands_t; + +void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr); + +WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr, + struct pic_buffer_t *ps_pic_buf, + UWORD8 u1_buf_id, + UWORD32 u2_cur_pic_num); +WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr); +WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, + dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_numRef_frames_for_seq, + UWORD32 u4_cur_pic_num, + UWORD32 u2_u4_max_pic_num_minus1, + UWORD8 u1_nal_unit_type, + struct pic_buffer_t *ps_pic_buf, + UWORD8 u1_buf_id, + UWORD8 u1_fld_pic_flag, + UWORD8 u1_curr_pic_in_err); +void ih264d_release_pics_in_dpb(void *pv_dec, + UWORD8 u1_disp_bufs); +void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr); +WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr, + WORD32 u4_pic_num, + UWORD32 u4_lt_idx, + UWORD8 u1_fld_pic_flag); + +WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr, + WORD32 i4_frame_num, + UWORD8 *pu1_del_node); + +WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr, + WORD32 i4_frame_num, + UWORD8 *pu1_del_node); + +WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_num_ref_frames); + +WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_buf_id, + WORD32 i4_display_poc, + UWORD32 u4_frame_num); +void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr); +#endif /* _IH264D_DPB_MANAGER_H_ */ diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c new file mode 100755 index 0000000..205bc9b --- /dev/null +++ b/decoder/ih264d_dpb_mgr.c @@ -0,0 +1,1987 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "iv.h" +#include "ih264d_dpb_manager.h" +#include "ih264d_bitstrm.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_defs.h" +#include "ih264d_structs.h" +#include "ih264d_process_bslice.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_error_handler.h" +#include "string.h" +#include "ih264d_defs.h" +#include "ih264_error.h" +#include "ih264_buf_mgr.h" +#include "assert.h" + +/*! + *************************************************************************** + * \file ih264d_dpb_mgr.c + * + * \brief + * Functions for managing the decoded picture buffer + * + * Detailed_description + * + * \date + * 19-12-2002 + * + * \author Sriram Sethuraman + *************************************************************************** + */ + +/*! + ************************************************************************** + * \if Function name : ih264d_init_ref_bufs \endif + * + * \brief + * Called at the start for initialization. + * + * \return + * none + ************************************************************************** + */ +void ih264d_init_ref_bufs(dpb_manager_t *ps_dpb_mgr) +{ + UWORD32 i; + struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; + for(i = 0; i < MAX_REF_BUFS; i++) + { + ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; + ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; + ps_dpb_info[i].ps_prev_short = NULL; + ps_dpb_info[i].ps_prev_long = NULL; + ps_dpb_info[i].ps_pic_buf = NULL; + ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; + ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; + ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; + ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; + + } + ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; + ps_dpb_mgr->ps_dpb_st_head = NULL; + ps_dpb_mgr->ps_dpb_ht_head = NULL; + ps_dpb_mgr->i1_gaps_deleted = 0; + ps_dpb_mgr->i1_poc_buf_id_entries = 0; + + ps_dpb_mgr->u1_num_gaps = 0; + for(i = 0; i < MAX_FRAMES; i++) + { + ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; + ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; + ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; + ps_dpb_mgr->ai4_poc_buf_id_map[i][0] = -1; + ps_dpb_mgr->ai4_poc_buf_id_map[i][1] = 0x7fffffff; + ps_dpb_mgr->ai4_poc_buf_id_map[i][2] = 0; + } + +} + +void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id) +{ + dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; + + if((pic_buf_id == ps_dec->u1_pic_buf_id) && + ps_dec->ps_cur_slice->u1_field_pic_flag && + (ps_dec->u1_top_bottom_decoded == 0)) + { + return; + } + + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + pic_buf_id, + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[pic_buf_id], + BUF_MGR_REF); +} +/*! + ************************************************************************** + * \if Function name : ih264d_delete_lt_node \endif + * + * \brief + * Delete a buffer with a long term index from the LT linked list + * + * \return + * none + ************************************************************************** + */ +WORD32 ih264d_delete_lt_node(dpb_manager_t *ps_dpb_mgr, + UWORD32 u4_lt_idx, + UWORD8 u1_fld_pic_flag, + struct dpb_info_t *ps_lt_node_to_insert, + WORD32 *pi4_status) +{ + *pi4_status = 0; + if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) + { + WORD32 i; + struct dpb_info_t *ps_next_dpb; + /* ps_unmark_node points to the node to be removed */ + /* from long term list. */ + struct dpb_info_t *ps_unmark_node; + //Find the node with matching LTIndex + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + if(ps_next_dpb->u1_lt_idx == u4_lt_idx) + { + ps_unmark_node = ps_next_dpb; + } + else + { + for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + if(ps_next_dpb->ps_prev_long->u1_lt_idx == u4_lt_idx) + break; + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + if(i == ps_dpb_mgr->u1_num_lt_ref_bufs) + *pi4_status = 1; + else + ps_unmark_node = ps_next_dpb->ps_prev_long; + } + + if(*pi4_status == 0) + { + if(u1_fld_pic_flag) + { + if(ps_lt_node_to_insert != ps_unmark_node) + { + UWORD8 u1_deleted = 0; + /* for the ps_unmark_node mark the corresponding field */ + /* field as unused for reference */ + + if(ps_unmark_node->s_top_field.u1_long_term_frame_idx + == u4_lt_idx) + { + ps_unmark_node->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_unmark_node->s_top_field.u1_long_term_frame_idx = + MAX_REF_BUFS + 1; + u1_deleted = 1; + } + if(ps_unmark_node->s_bot_field.u1_long_term_frame_idx + == u4_lt_idx) + { + ps_unmark_node->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ps_unmark_node->s_bot_field.u1_long_term_frame_idx = + MAX_REF_BUFS + 1; + u1_deleted = 1; + } + + if(!u1_deleted) + { + + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + + return i4_error_code; + } + } + + ps_unmark_node->u1_used_as_ref = + ps_unmark_node->s_top_field.u1_reference_info + | ps_unmark_node->s_bot_field.u1_reference_info; + } + else + ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; + + if(UNUSED_FOR_REF == ps_unmark_node->u1_used_as_ref) + { + if(ps_unmark_node == ps_dpb_mgr->ps_dpb_ht_head) + ps_dpb_mgr->ps_dpb_ht_head = ps_next_dpb->ps_prev_long; + + ps_unmark_node->u1_lt_idx = MAX_REF_BUFS + 1; + ps_unmark_node->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_unmark_node->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + // Release the physical buffer + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_unmark_node->u1_buf_id); + ps_next_dpb->ps_prev_long = ps_unmark_node->ps_prev_long; //update link + ps_unmark_node->ps_prev_long = NULL; + ps_dpb_mgr->u1_num_lt_ref_bufs--; //decrement LT buf count + } + } + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_insert_lt_node \endif + * + * \brief + * Insert a buffer into the LT linked list at a given LT index + * + * \return + * none + ************************************************************************** + */ +WORD32 ih264d_insert_lt_node(dpb_manager_t *ps_dpb_mgr, + struct dpb_info_t *ps_mov_node, + UWORD32 u4_lt_idx, + UWORD8 u1_fld_pic_flag) +{ + UWORD8 u1_mark_top_field_long_term = 0; + UWORD8 u1_mark_bot_field_long_term = 0; + + { + if(u1_fld_pic_flag) + { + /* Assign corresponding field (top or bottom) long_term_frame_idx */ + + if((ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) + && (ps_mov_node->s_bot_field.u1_reference_info + == IS_LONG_TERM)) + { + if(ps_mov_node->u1_lt_idx == u4_lt_idx) + u1_mark_bot_field_long_term = 1; + else + { + + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + + return i4_error_code; + + } + } + else if(ps_mov_node->s_top_field.u1_reference_info == IS_LONG_TERM) + { + u1_mark_top_field_long_term = 1; + } + + if(!(u1_mark_top_field_long_term || u1_mark_bot_field_long_term)) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + } + else + { + ps_mov_node->s_top_field.u1_reference_info = IS_LONG_TERM; + ps_mov_node->s_bot_field.u1_reference_info = IS_LONG_TERM; + ps_mov_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; + ps_mov_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; + } + + ps_mov_node->u1_lt_idx = u4_lt_idx; //Assign the LT index to the node + ps_mov_node->ps_pic_buf->u1_long_term_frm_idx = u4_lt_idx; + ps_mov_node->u1_used_as_ref = IS_LONG_TERM; + + /* Insert the new long term in the LT list with u4_lt_idx */ + /* in ascending order. */ + if(ps_dpb_mgr->u1_num_lt_ref_bufs > 0) + { + struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + if(u4_lt_idx < ps_next_dpb->u1_lt_idx) + { + //LTIndex to be inserted is the smallest LT index + //Update head and point prev to the next higher index + ps_mov_node->ps_prev_long = ps_next_dpb; + ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; + } + else + { + WORD32 i; + struct dpb_info_t *ps_nxtDPB = ps_next_dpb; + ps_next_dpb = ps_next_dpb->ps_prev_long; + for(i = 1; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + if(ps_next_dpb->u1_lt_idx > u4_lt_idx) + break; + ps_nxtDPB = ps_next_dpb; + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + + ps_nxtDPB->ps_prev_long = ps_mov_node; + ps_mov_node->ps_prev_long = ps_next_dpb; + } + } + else + { + ps_dpb_mgr->ps_dpb_ht_head = ps_mov_node; + ps_mov_node->ps_prev_long = NULL; + } + /* Identify the picture buffer as a long term picture buffer */ + ps_mov_node->ps_pic_buf->u1_is_short = 0; + + /* Increment LT buf count only if new LT node inserted */ + /* If Increment during top_field is done, don't increment */ + /* for bottom field, as both them are part of same pic. */ + if(!u1_mark_bot_field_long_term) + ps_dpb_mgr->u1_num_lt_ref_bufs++; + + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_insert_st_node \endif + * + * \brief + * Adds a short term reference picture into the ST linked list + * + * \return + * None + * + * \note + * Called only for a new coded picture with nal_ref_idc!=0 + ************************************************************************** + */ +WORD32 ih264d_insert_st_node(dpb_manager_t *ps_dpb_mgr, + struct pic_buffer_t *ps_pic_buf, + UWORD8 u1_buf_id, + UWORD32 u4_cur_pic_num) +{ + WORD32 i; + struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; + UWORD8 u1_picture_type = ps_pic_buf->u1_picturetype; + /* Find an unused dpb location */ + for(i = 0; i < MAX_REF_BUFS; i++) + { + if((ps_dpb_info[i].ps_pic_buf == ps_pic_buf) + && ps_dpb_info[i].u1_used_as_ref) + { + /* Can occur only for field bottom pictures */ + ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; + return 0; + } + + if((ps_dpb_info[i].u1_used_as_ref == UNUSED_FOR_REF) + && (ps_dpb_info[i].s_top_field.u1_reference_info + == UNUSED_FOR_REF) + && (ps_dpb_info[i].s_bot_field.u1_reference_info + == UNUSED_FOR_REF)) + break; + } + if(i == MAX_REF_BUFS) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + /* Create dpb info */ + ps_dpb_info[i].ps_pic_buf = ps_pic_buf; + ps_dpb_info[i].ps_prev_short = ps_dpb_mgr->ps_dpb_st_head; + ps_dpb_info[i].u1_buf_id = u1_buf_id; + ps_dpb_info[i].u1_used_as_ref = TRUE; + ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; + ps_dpb_info[i].i4_frame_num = u4_cur_pic_num; + ps_dpb_info[i].ps_pic_buf->i4_frame_num = u4_cur_pic_num; + + /* update the head node of linked list to point to the cur Pic */ + ps_dpb_mgr->ps_dpb_st_head = ps_dpb_info + i; + + // Increment Short term bufCount + ps_dpb_mgr->u1_num_st_ref_bufs++; + /* Identify the picture as a short term picture buffer */ + ps_pic_buf->u1_is_short = IS_SHORT_TERM; + + if((u1_picture_type & 0x03) == FRM_PIC) + { + ps_dpb_info[i].u1_used_as_ref = IS_SHORT_TERM; + ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; + ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; + } + + if((u1_picture_type & 0x03) == TOP_FLD) + ps_dpb_info[i].s_top_field.u1_reference_info = IS_SHORT_TERM; + + if((u1_picture_type & 0x03) == BOT_FLD) + ps_dpb_info[i].s_bot_field.u1_reference_info = IS_SHORT_TERM; + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_delete_st_node_or_make_lt \endif + * + * \brief + * Delete short term ref with a given picNum from the ST linked list or + * make it an LT node + * + * \return + * 0 - if successful; -1 - otherwise + * + * \note + * Common parts to MMCO==1 and MMCO==3 have been combined here + ************************************************************************** + */ +WORD32 ih264d_delete_st_node_or_make_lt(dpb_manager_t *ps_dpb_mgr, + WORD32 i4_pic_num, + UWORD32 u4_lt_idx, + UWORD8 u1_fld_pic_flag) +{ + WORD32 i; + struct dpb_info_t *ps_next_dpb; + WORD32 i4_frame_num = i4_pic_num; + struct dpb_info_t *ps_unmark_node = NULL; + UWORD8 u1_del_node = 0, u1_del_st = 0; + UWORD8 u1_reference_type = UNUSED_FOR_REF; + WORD32 ret; + + if(u1_fld_pic_flag) + { + i4_frame_num = i4_frame_num >> 1; + + if(u4_lt_idx == (MAX_REF_BUFS + 1)) + u1_reference_type = UNUSED_FOR_REF; + else + u1_reference_type = IS_LONG_TERM; + } + + //Find the node with matching picNum + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + if((WORD32)ps_next_dpb->i4_frame_num == i4_frame_num) + { + ps_unmark_node = ps_next_dpb; + } + else + { + for(i = 1; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_prev_short->i4_frame_num == i4_frame_num) + break; + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + if(i == ps_dpb_mgr->u1_num_st_ref_bufs) + { + if(ps_dpb_mgr->u1_num_gaps) + { + ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_frame_num, &u1_del_st); + if(ret != OK) + return ret; + } + else + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + + return i4_error_code; + } + + if(u1_del_st) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + else + { + return 0; + } + } + else + ps_unmark_node = ps_next_dpb->ps_prev_short; + } + + if(u1_fld_pic_flag) + { + /* Mark the corresponding field ( top or bot) as */ + /* UNUSED_FOR_REF or IS_LONG_TERM depending on */ + /* u1_reference_type. */ + if(ps_unmark_node->s_top_field.i4_pic_num == i4_pic_num) + { + ps_unmark_node->s_top_field.u1_reference_info = u1_reference_type; + ps_unmark_node->s_top_field.u1_long_term_frame_idx = u4_lt_idx; + { + UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; + WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd + * ps_dpb_mgr->u2_pic_ht) >> 5); + /* memset the colocated zero u4_flag buffer */ + memset(pu1_src, 0, i4_size); + } + } + + else if(ps_unmark_node->s_bot_field.i4_pic_num == i4_pic_num) + { + + ps_unmark_node->s_bot_field.u1_reference_info = u1_reference_type; + ps_unmark_node->s_bot_field.u1_long_term_frame_idx = u4_lt_idx; + { + UWORD8 *pu1_src = + ps_unmark_node->ps_pic_buf->pu1_col_zero_flag + + ((ps_dpb_mgr->u2_pic_wd + * ps_dpb_mgr->u2_pic_ht) + >> 5); + WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd + * ps_dpb_mgr->u2_pic_ht) >> 5); + /* memset the colocated zero u4_flag buffer */ + memset(pu1_src, 0, i4_size); + } + } + ps_unmark_node->u1_used_as_ref = + ps_unmark_node->s_top_field.u1_reference_info + | ps_unmark_node->s_bot_field.u1_reference_info; + } + else + { + ps_unmark_node->u1_used_as_ref = UNUSED_FOR_REF; + ps_unmark_node->s_top_field.u1_reference_info = UNUSED_FOR_REF; + ps_unmark_node->s_bot_field.u1_reference_info = UNUSED_FOR_REF; + + { + UWORD8 *pu1_src = ps_unmark_node->ps_pic_buf->pu1_col_zero_flag; + + WORD32 i4_size = ((ps_dpb_mgr->u2_pic_wd + * ps_dpb_mgr->u2_pic_ht) >> 4); + /* memset the colocated zero u4_flag buffer */ + memset(pu1_src, 0, i4_size); + } + } + + if(!(ps_unmark_node->u1_used_as_ref & IS_SHORT_TERM)) + { + if(ps_unmark_node == ps_dpb_mgr->ps_dpb_st_head) + ps_dpb_mgr->ps_dpb_st_head = ps_next_dpb->ps_prev_short; + else + ps_next_dpb->ps_prev_short = ps_unmark_node->ps_prev_short; //update link + ps_dpb_mgr->u1_num_st_ref_bufs--; //decrement ST buf count + u1_del_node = 1; + } + + if(u4_lt_idx == MAX_REF_BUFS + 1) + { + if(u1_del_node) + { + // Release the physical buffer + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_unmark_node->u1_buf_id); + ps_unmark_node->ps_prev_short = NULL; + } + } + else + { + WORD32 i4_status; + //If another node has the same LT index, delete that node + ret = ih264d_delete_lt_node(ps_dpb_mgr, u4_lt_idx, + u1_fld_pic_flag, ps_unmark_node, &i4_status); + if(ret != OK) + return ret; + // Now insert the short term node as a long term node + ret = ih264d_insert_lt_node(ps_dpb_mgr, ps_unmark_node, u4_lt_idx, + u1_fld_pic_flag); + if(ret != OK) + return ret; + } + return OK; +} +/*! + ************************************************************************** + * \if Function name : ih264d_reset_ref_bufs \endif + * + * \brief + * Called if MMCO==5/7 or on the first slice of an IDR picture + * + * \return + * none + ************************************************************************** + */ +void ih264d_reset_ref_bufs(dpb_manager_t *ps_dpb_mgr) +{ + WORD32 i; + struct dpb_info_t *ps_dpb_info = ps_dpb_mgr->as_dpb_info; + + for(i = 0; i < MAX_REF_BUFS; i++) + { + if(ps_dpb_info[i].u1_used_as_ref) + { + ps_dpb_info[i].u1_used_as_ref = UNUSED_FOR_REF; + ps_dpb_info[i].u1_lt_idx = MAX_REF_BUFS + 1; + ps_dpb_info[i].ps_prev_short = NULL; + ps_dpb_info[i].ps_prev_long = NULL; + ps_dpb_info[i].ps_pic_buf = NULL; + ps_dpb_info[i].s_top_field.u1_reference_info = UNUSED_FOR_REF; + ps_dpb_info[i].s_bot_field.u1_reference_info = UNUSED_FOR_REF; + ps_dpb_info[i].s_top_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; + ps_dpb_info[i].s_bot_field.u1_long_term_frame_idx = MAX_REF_BUFS + 1; + + //Release physical buffer + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_dpb_info[i].u1_buf_id); + } + } + ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0; + ps_dpb_mgr->ps_dpb_st_head = NULL; + ps_dpb_mgr->ps_dpb_ht_head = NULL; + + /* release all gaps */ + ps_dpb_mgr->u1_num_gaps = 0; + for(i = 0; i < MAX_FRAMES; i++) + { + ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; + ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; + ps_dpb_mgr->ai1_gaps_per_seq[i] = 0; + } +} + +/*! + ************************************************************************** + * \if Function name : Name \endif + * + * \brief + * create the default index list after an MMCO + * + * \return + * 0 - if no_error; -1 - error + * + ************************************************************************** + */ +WORD32 ih264d_update_default_index_list(dpb_manager_t *ps_dpb_mgr) +{ + WORD32 i; + struct dpb_info_t *ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + for(;i< ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + ps_dpb_mgr->ps_def_dpb[i] = ps_next_dpb->ps_pic_buf; + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + return 0; +} + +/*! + ************************************************************************** + * \if Function name : ref_idx_reordering \endif + * + * \brief + * Parse the bitstream and reorder indices for the current slice + * + * \return + * 0 - if no_error; -1 - error + * + * \note + * Called only if ref_idx_reordering_flag_l0 is decoded as 1 + * Remove error checking for unmatching picNum or LTIndex later (if not needed) + * \para + * This section implements 7.3.3.1 and 8.2.6.4 + * Uses the default index list as the starting point and + * remaps the picNums sent to the next higher index in the + * modified list. The unmodified ones are copied from the + * default to modified list retaining their order in the default list. + * + ************************************************************************** + */ +WORD32 ih264d_ref_idx_reordering(dec_struct_t *ps_dec, UWORD8 uc_lx) +{ + dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; + UWORD16 u4_cur_pic_num = ps_dec->ps_cur_slice->u2_frame_num; + /*< Maximum Picture Number Minus 1 */ + UWORD16 ui_max_frame_num = + ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; + + WORD32 i; + UWORD32 ui_remapIdc, ui_nextUev; + WORD16 u2_pred_frame_num = u4_cur_pic_num; + WORD32 i_temp; + UWORD16 u2_def_mod_flag = 0; /* Flag to keep track of which indices have been remapped */ + UWORD8 modCount = 0; + UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + + if(u1_field_pic_flag) + { + u4_cur_pic_num = u4_cur_pic_num * 2 + 1; + ui_max_frame_num = ui_max_frame_num * 2; + } + + u2_pred_frame_num = u4_cur_pic_num; + + ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + while(ui_remapIdc != 3) + { + ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(ui_remapIdc != 2) + { + ui_nextUev = ui_nextUev + 1; + if(ui_remapIdc == 0) + { + // diffPicNum is -ve + i_temp = u2_pred_frame_num - ui_nextUev; + if(i_temp < 0) + i_temp += ui_max_frame_num; + } + else + { + // diffPicNum is +ve + i_temp = u2_pred_frame_num + ui_nextUev; + if(i_temp >= ui_max_frame_num) + i_temp -= ui_max_frame_num; + } + /* Find the dpb with the matching picNum (picNum==frameNum for framePic) */ + + if(i_temp > u4_cur_pic_num) + i_temp = i_temp - ui_max_frame_num; + + for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) + { + if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->i4_pic_num == i_temp) + break; + } + if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + u2_def_mod_flag |= (1 << i); + ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = + ps_dpb_mgr->ps_init_dpb[uc_lx][i]; + u2_pred_frame_num = i_temp; //update predictor to be the picNum just obtained + } + else //2 + { + UWORD8 u1_lt_idx = (UWORD8)ui_nextUev; + + for(i = 0; i < (ps_cur_slice->u1_initial_list_size[uc_lx]); i++) + { + if(!ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_is_short) + { + if(ps_dpb_mgr->ps_init_dpb[uc_lx][i]->u1_long_term_pic_num + == u1_lt_idx) + break; + } + } + if(i == (ps_cur_slice->u1_initial_list_size[uc_lx])) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + u2_def_mod_flag |= (1 << i); + ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = + ps_dpb_mgr->ps_init_dpb[uc_lx][i]; + } + + ui_remapIdc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + /* Get the remapping_idc - 0/1/2/3 */ + } + + //Handle the ref indices that were not remapped + for(i = 0; i < (ps_cur_slice->u1_num_ref_idx_lx_active[uc_lx]); i++) + { + if(!(u2_def_mod_flag & (1 << i))) + ps_dpb_mgr->ps_mod_dpb[uc_lx][modCount++] = + ps_dpb_mgr->ps_init_dpb[uc_lx][i]; + } + return OK; +} +/*! + ************************************************************************** + * \if Function name : ih264d_read_mmco_commands \endif + * + * \brief + * Parses MMCO commands and stores them in a structure for later use. + * + * \return + * 0 - No error; -1 - Error + * + * \note + * This function stores MMCO commands in structure only for the first time. + * In case of MMCO commands being issued for same Picture Number, they are + * just parsed and not stored them in the structure. + * + ************************************************************************** + */ +WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec) +{ + dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; + dpb_commands_t *ps_dpb_cmds = ps_dec->ps_dpb_cmds; + dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; + WORD32 j; + UWORD8 u1_buf_mode; + struct MMCParams *ps_mmc_params; + UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst; + + ps_slice->u1_mmco_equalto5 = 0; + { + if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) + { + ps_slice->u1_no_output_of_prior_pics_flag = + ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: no_output_of_prior_pics_flag", + ps_slice->u1_no_output_of_prior_pics_flag); + ps_slice->u1_long_term_reference_flag = ih264d_get_bit_h264( + ps_bitstrm); + COPYTHECONTEXT("SH: long_term_reference_flag", + ps_slice->u1_long_term_reference_flag); + ps_dpb_cmds->u1_idr_pic = 1; + ps_dpb_cmds->u1_no_output_of_prior_pics_flag = + ps_slice->u1_no_output_of_prior_pics_flag; + ps_dpb_cmds->u1_long_term_reference_flag = + ps_slice->u1_long_term_reference_flag; + } + else + { + u1_buf_mode = ih264d_get_bit_h264(ps_bitstrm); //0 - sliding window; 1 - arbitrary + COPYTHECONTEXT("SH: adaptive_ref_pic_buffering_flag", u1_buf_mode); + ps_dpb_cmds->u1_buf_mode = u1_buf_mode; + j = 0; + + if(u1_buf_mode == 1) + { + UWORD32 u4_mmco; + UWORD32 u4_diff_pic_num; + UWORD32 u4_lt_idx, u4_max_lt_idx; + + u4_mmco = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + while(u4_mmco != END_OF_MMCO) + { + ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; + ps_mmc_params->u4_mmco = u4_mmco; + switch(u4_mmco) + { + case MARK_ST_PICNUM_AS_NONREF: + u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + //Get absDiffPicnumMinus1 + ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; + break; + + case MARK_LT_INDEX_AS_NONREF: + u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_mmc_params->u4_lt_idx = u4_lt_idx; + break; + + case MARK_ST_PICNUM_AS_LT_INDEX: + u4_diff_pic_num = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_mmc_params->u4_diff_pic_num = u4_diff_pic_num; + u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_mmc_params->u4_lt_idx = u4_lt_idx; + break; + + case SET_MAX_LT_INDEX: + { + u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx; + break; + } + case RESET_REF_PICTURES: + { + ps_slice->u1_mmco_equalto5 = 1; + break; + } + + case SET_LT_INDEX: + u4_lt_idx = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_mmc_params->u4_lt_idx = u4_lt_idx; + break; + + default: + break; + } + u4_mmco = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + + j++; + } + ps_dpb_cmds->u1_num_of_commands = j; + + } + } + ps_dpb_cmds->u1_dpb_commands_read = 1; + ps_dpb_cmds->u1_dpb_commands_read_slc = 1; + + } + u4_bit_ofst = ps_dec->ps_bitstrm->u4_ofst - u4_bit_ofst; + return u4_bit_ofst; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_do_mmco_buffer \endif + * + * \brief + * Perform decoded picture buffer memory management control operations + * + * \return + * 0 - No error; -1 - Error + * + * \note + * Bitstream is also parsed here to get the MMCOs + * + ************************************************************************** + */ +WORD32 ih264d_do_mmco_buffer(dpb_commands_t *ps_dpb_cmds, + dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_numRef_frames_for_seq, /*!< num_ref_frames from active SeqParSet*/ + UWORD32 u4_cur_pic_num, + UWORD32 u2_u4_max_pic_num_minus1, + UWORD8 u1_nal_unit_type, + struct pic_buffer_t *ps_pic_buf, + UWORD8 u1_buf_id, + UWORD8 u1_fld_pic_flag, + UWORD8 u1_curr_pic_in_err) +{ + WORD32 i; + UWORD8 u1_buf_mode, u1_marked_lt; + struct dpb_info_t *ps_next_dpb; + UWORD8 u1_num_gaps; + UWORD8 u1_del_node = 1; + UWORD8 u1_insert_st_pic = 1; + WORD32 ret; + UNUSED(u1_nal_unit_type); + UNUSED(u2_u4_max_pic_num_minus1); + u1_buf_mode = ps_dpb_cmds->u1_buf_mode; //0 - sliding window; 1 - Adaptive + u1_marked_lt = 0; + u1_num_gaps = ps_dpb_mgr->u1_num_gaps; + + if(!u1_buf_mode) + { + //Sliding window - implements 8.2.5.3 + if((ps_dpb_mgr->u1_num_st_ref_bufs + + ps_dpb_mgr->u1_num_lt_ref_bufs + u1_num_gaps) + == u1_numRef_frames_for_seq) + { + UWORD8 u1_new_node_flag = 1; + if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps)) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + // Chase the links to reach the last but one picNum, if available + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + + if(ps_dpb_mgr->u1_num_st_ref_bufs > 1) + { + if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) + { + /* Incase of filed pictures top_field has been allocated */ + /* picture buffer and complementary bottom field pair comes */ + /* then the sliding window mechanism should not allocate a */ + /* new node */ + u1_new_node_flag = 0; + } + + for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++) + { + if(ps_next_dpb == NULL) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) + { + /* Incase of field pictures top_field has been allocated */ + /* picture buffer and complementary bottom field pair comes */ + /* then the sliding window mechanism should not allocate a */ + /* new node */ + u1_new_node_flag = 0; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + if(u1_new_node_flag) + { + if(u1_num_gaps) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->ps_prev_short->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + } + + if(u1_del_node) + { + ps_dpb_mgr->u1_num_st_ref_bufs--; + ps_next_dpb->ps_prev_short->u1_used_as_ref = + UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->ps_prev_short->u1_buf_id); + ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; + ps_next_dpb->ps_prev_short = NULL; + } + } + } + else + { + if(ps_dpb_mgr->u1_num_st_ref_bufs) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num) + && u1_del_node) + { + ps_dpb_mgr->u1_num_st_ref_bufs--; + ps_next_dpb->u1_used_as_ref = FALSE; + ps_next_dpb->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->u1_buf_id); + ps_next_dpb->ps_pic_buf = NULL; + ps_next_dpb->ps_prev_short = NULL; + ps_dpb_mgr->ps_dpb_st_head = NULL; + ps_next_dpb = NULL; + } + else if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) + { + if(u1_curr_pic_in_err) + { + u1_insert_st_pic = 0; + } + else if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) + { + ps_dpb_mgr->u1_num_st_ref_bufs--; + ps_next_dpb->u1_used_as_ref = FALSE; + ps_next_dpb->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->u1_buf_id); + ps_next_dpb->ps_pic_buf = NULL; + ps_next_dpb = NULL; + } + } + } + else + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + INVALID_FRAME_NUM, + &u1_del_node); + if(ret != OK) + return ret; + if(u1_del_node) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + } + } + } + } + else + { + //Adaptive memory control - implements 8.2.5.4 + UWORD32 u4_mmco; + UWORD32 u4_diff_pic_num; + WORD32 i4_pic_num; + UWORD32 u4_lt_idx; + WORD32 j; + struct MMCParams *ps_mmc_params; + + for(j = 0; j < ps_dpb_cmds->u1_num_of_commands; j++) + { + ps_mmc_params = &ps_dpb_cmds->as_mmc_params[j]; + u4_mmco = ps_mmc_params->u4_mmco; //Get MMCO + + switch(u4_mmco) + { + case MARK_ST_PICNUM_AS_NONREF: + { + + { + UWORD32 i4_cur_pic_num = u4_cur_pic_num; + u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 + if(u1_fld_pic_flag) + i4_cur_pic_num = i4_cur_pic_num * 2 + 1; + i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1); + } + + if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) + { + ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, + i4_pic_num, + MAX_REF_BUFS + 1, + u1_fld_pic_flag); + if(ret != OK) + return ret; + } + else + { + UWORD8 u1_dummy; + ret = ih264d_delete_gap_frm_mmco(ps_dpb_mgr, i4_pic_num, &u1_dummy); + if(ret != OK) + return ret; + } + break; + } + case MARK_LT_INDEX_AS_NONREF: + { + WORD32 i4_status; + u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index + ret = ih264d_delete_lt_node(ps_dpb_mgr, + u4_lt_idx, + u1_fld_pic_flag, + 0, &i4_status); + if(ret != OK) + return ret; + if(i4_status) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + break; + } + + case MARK_ST_PICNUM_AS_LT_INDEX: + { + { + UWORD32 i4_cur_pic_num = u4_cur_pic_num; + u4_diff_pic_num = ps_mmc_params->u4_diff_pic_num; //Get absDiffPicnumMinus1 + if(u1_fld_pic_flag) + i4_cur_pic_num = i4_cur_pic_num * 2 + 1; + + i4_pic_num = i4_cur_pic_num - (u4_diff_pic_num + 1); + } + + u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index + if(ps_dpb_mgr->u1_num_st_ref_bufs > 0) + { + ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, + i4_pic_num, u4_lt_idx, + u1_fld_pic_flag); + if(ret != OK) + return ret; + } + break; + } + case SET_MAX_LT_INDEX: + { + UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs; + u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1 + if(u4_lt_idx < ps_dpb_mgr->u1_max_lt_pic_idx_plus1 + && uc_numLT > 0) + { + struct dpb_info_t *ps_nxtDPB; + //Set all LT buffers with index >= u4_lt_idx to nonreference + ps_nxtDPB = ps_dpb_mgr->ps_dpb_ht_head; + ps_next_dpb = ps_nxtDPB->ps_prev_long; + if(ps_nxtDPB->u1_lt_idx >= u4_lt_idx) + { + i = 0; + ps_dpb_mgr->ps_dpb_ht_head = NULL; + } + else + { + for(i = 1; i < uc_numLT; i++) + { + if(ps_next_dpb->u1_lt_idx >= u4_lt_idx) + break; + ps_nxtDPB = ps_next_dpb; + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + ps_nxtDPB->ps_prev_long = NULL; //Terminate the link of the closest LTIndex that is <=Max + } + ps_dpb_mgr->u1_num_lt_ref_bufs = i; + if(i == 0) + ps_next_dpb = ps_nxtDPB; + + for(; i < uc_numLT; i++) + { + ps_nxtDPB = ps_next_dpb; + ps_nxtDPB->u1_lt_idx = MAX_REF_BUFS + 1; + ps_nxtDPB->u1_used_as_ref = UNUSED_FOR_REF; + ps_nxtDPB->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_nxtDPB->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + + ps_nxtDPB->ps_pic_buf = NULL; + //Release buffer + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_nxtDPB->u1_buf_id); + ps_next_dpb = ps_nxtDPB->ps_prev_long; + ps_nxtDPB->ps_prev_long = NULL; + } + } + ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx; + + break; + } + case SET_LT_INDEX: + { + u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index + ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, + u4_cur_pic_num); + if(ret != OK) + return ret; + ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr, + u4_cur_pic_num, u4_lt_idx, + u1_fld_pic_flag); + if(ret != OK) + return ret; + u1_marked_lt = 1; + break; + } + + default: + break; + } + if(u4_mmco == RESET_REF_PICTURES || u4_mmco == RESET_ALL_PICTURES) + { + ih264d_reset_ref_bufs(ps_dpb_mgr); + u4_cur_pic_num = 0; + } + } + } + if(!u1_marked_lt && u1_insert_st_pic) + { + ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id, + u4_cur_pic_num); + if(ret != OK) + return ret; + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_release_pics_in_dpb */ +/* */ +/* Description : This function deletes all pictures from DPB */ +/* */ +/* Inputs : h_pic_buf_api: pointer to picture buffer API */ +/* u1_disp_bufs: number pictures ready for display */ +/* */ +/* Globals : None */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 06 2005 NS Draft */ +/* */ +/*****************************************************************************/ +void ih264d_release_pics_in_dpb(void *pv_dec, + UWORD8 u1_disp_bufs) +{ + WORD8 i; + dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; + + for(i = 0; i < u1_disp_bufs; i++) + { + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + i, + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[i], + BUF_MGR_REF); + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_delete_gap_frm_sliding */ +/* */ +/* Description : This function deletes a picture from the list of gaps, */ +/* if the frame number of gap frame is lesser than the one */ +/* to be deleted by sliding window */ +/* Inputs : ps_dpb_mgr: pointer to dpb manager */ +/* i4_frame_num: frame number of picture that's going to */ +/* be deleted by sliding window */ +/* pu1_del_node: holds 0 if a gap is deleted else 1 */ +/* Globals : None */ +/* Processing : Function searches for frame number lesser than */ +/* i4_frame_num in the gaps list */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 06 2005 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_delete_gap_frm_sliding(dpb_manager_t *ps_dpb_mgr, + WORD32 i4_frame_num, + UWORD8 *pu1_del_node) +{ + WORD8 i1_gap_idx, i, j, j_min; + WORD32 *pi4_gaps_start_frm_num, *pi4_gaps_end_frm_num, i4_gap_frame_num; + WORD32 i4_start_frm_num, i4_end_frm_num; + WORD32 i4_max_frm_num; + WORD32 i4_frm_num, i4_gap_frm_num_min; + + /* find the least frame num from gaps and current DPB node */ + /* Delete the least one */ + *pu1_del_node = 1; + if(0 == ps_dpb_mgr->u1_num_gaps) + return OK; + pi4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; + pi4_gaps_end_frm_num = ps_dpb_mgr->ai4_gaps_end_frm_num; + i4_gap_frame_num = INVALID_FRAME_NUM; + i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; + + i1_gap_idx = -1; + if(INVALID_FRAME_NUM != i4_frame_num) + { + i4_gap_frame_num = i4_frame_num; + for(i = 0; i < MAX_FRAMES; i++) + { + i4_start_frm_num = pi4_gaps_start_frm_num[i]; + if(INVALID_FRAME_NUM != i4_start_frm_num) + { + i4_end_frm_num = pi4_gaps_end_frm_num[i]; + if(i4_end_frm_num < i4_max_frm_num) + { + if(i4_start_frm_num <= i4_gap_frame_num) + { + i4_gap_frame_num = i4_start_frm_num; + i1_gap_idx = i; + } + } + else + { + if(((i4_start_frm_num <= i4_gap_frame_num) + && (i4_gap_frame_num <= i4_max_frm_num)) + || ((i4_start_frm_num >= i4_gap_frame_num) + && ((i4_gap_frame_num + + i4_max_frm_num) + >= i4_end_frm_num))) + { + i4_gap_frame_num = i4_start_frm_num; + i1_gap_idx = i; + } + } + } + } + } + else + { + /* no valid short term buffers, delete one gap from the least start */ + /* of gap sequence */ + i4_gap_frame_num = pi4_gaps_start_frm_num[0]; + i1_gap_idx = 0; + for(i = 1; i < MAX_FRAMES; i++) + { + if(INVALID_FRAME_NUM != pi4_gaps_start_frm_num[i]) + { + if(pi4_gaps_start_frm_num[i] < i4_gap_frame_num) + { + i4_gap_frame_num = pi4_gaps_start_frm_num[i]; + i1_gap_idx = i; + } + } + } + if(INVALID_FRAME_NUM == i4_gap_frame_num) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + } + + if(-1 != i1_gap_idx) + { + /* find least frame_num in the poc_map, which is in this range */ + i4_start_frm_num = pi4_gaps_start_frm_num[i1_gap_idx]; + if(i4_start_frm_num < 0) + i4_start_frm_num += i4_max_frm_num; + i4_end_frm_num = pi4_gaps_end_frm_num[i1_gap_idx]; + if(i4_end_frm_num < 0) + i4_end_frm_num += i4_max_frm_num; + + i4_gap_frm_num_min = 0xfffffff; + j_min = MAX_FRAMES; + for(j = 0; j < MAX_FRAMES; j++) + { + i4_frm_num = ps_dpb_mgr->ai4_poc_buf_id_map[j][2]; + if((i4_start_frm_num <= i4_frm_num) + && (i4_end_frm_num >= i4_frm_num)) + { + if(i4_frm_num < i4_gap_frm_num_min) + { + j_min = j; + i4_gap_frm_num_min = i4_frm_num; + } + } + } + + if(j_min != MAX_FRAMES) + { + + ps_dpb_mgr->ai4_poc_buf_id_map[j_min][0] = -1; + ps_dpb_mgr->ai4_poc_buf_id_map[j_min][1] = 0x7fffffff; + ps_dpb_mgr->ai4_poc_buf_id_map[j_min][2] = GAP_FRAME_NUM; + ps_dpb_mgr->i1_gaps_deleted++; + + ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]--; + ps_dpb_mgr->u1_num_gaps--; + *pu1_del_node = 0; + if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i1_gap_idx]) + { + ps_dpb_mgr->ai4_gaps_start_frm_num[i1_gap_idx] = + INVALID_FRAME_NUM; + ps_dpb_mgr->ai4_gaps_end_frm_num[i1_gap_idx] = 0; + } + } + } + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_delete_gap_frm_mmco */ +/* */ +/* Description : This function deletes a picture from the list of gaps, */ +/* if the frame number (specified by mmco commands) to be */ +/* deleted is in the range by gap sequence. */ +/* */ +/* Inputs : ps_dpb_mgr: pointer to dpb manager */ +/* i4_frame_num: frame number of picture that's going to */ +/* be deleted by mmco */ +/* pu1_del_node: holds 0 if a gap is deleted else 1 */ +/* Globals : None */ +/* Processing : Function searches for frame number lesser in the range */ +/* specified by gap sequence */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 22 06 2005 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_delete_gap_frm_mmco(dpb_manager_t *ps_dpb_mgr, + WORD32 i4_frame_num, + UWORD8 *pu1_del_node) +{ + WORD8 i, j; + WORD32 *pi4_start, *pi4_end; + WORD32 i4_start_frm_num, i4_end_frm_num, i4_max_frm_num; + + /* find the least frame num from gaps and current DPB node */ + /* Delete the gaps */ + *pu1_del_node = 1; + pi4_start = ps_dpb_mgr->ai4_gaps_start_frm_num; + pi4_end = ps_dpb_mgr->ai4_gaps_end_frm_num; + i4_max_frm_num = ps_dpb_mgr->i4_max_frm_num; + + if(0 == ps_dpb_mgr->u1_num_gaps) + return OK; + + if(i4_frame_num < 0) + i4_frame_num += i4_max_frm_num; + for(i = 0; i < MAX_FRAMES; i++) + { + i4_start_frm_num = pi4_start[i]; + if(i4_start_frm_num < 0) + i4_start_frm_num += i4_max_frm_num; + if(INVALID_FRAME_NUM != i4_start_frm_num) + { + i4_end_frm_num = pi4_end[i]; + if(i4_end_frm_num < 0) + i4_end_frm_num += i4_max_frm_num; + + if((i4_frame_num >= i4_start_frm_num) + && (i4_frame_num <= i4_end_frm_num)) + { + break; + } + else + { + if(((i4_frame_num + i4_max_frm_num) >= i4_start_frm_num) + && ((i4_frame_num + i4_max_frm_num) + <= i4_end_frm_num)) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + } + } + } + + /* find frame_num index, in the poc_map which needs to be deleted */ + for(j = 0; j < MAX_FRAMES; j++) + { + if(i4_frame_num == ps_dpb_mgr->ai4_poc_buf_id_map[j][2]) + break; + } + + if(MAX_FRAMES != i) + { + if(j == MAX_FRAMES) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + ps_dpb_mgr->ai4_poc_buf_id_map[j][0] = -1; + ps_dpb_mgr->ai4_poc_buf_id_map[j][1] = 0x7fffffff; + ps_dpb_mgr->ai4_poc_buf_id_map[j][2] = GAP_FRAME_NUM; + ps_dpb_mgr->i1_gaps_deleted++; + + ps_dpb_mgr->ai1_gaps_per_seq[i]--; + ps_dpb_mgr->u1_num_gaps--; + *pu1_del_node = 0; + if(0 == ps_dpb_mgr->ai1_gaps_per_seq[i]) + { + ps_dpb_mgr->ai4_gaps_start_frm_num[i] = INVALID_FRAME_NUM; + ps_dpb_mgr->ai4_gaps_end_frm_num[i] = 0; + } + } + else + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_do_mmco_for_gaps \endif + * + * \brief + * Perform decoded picture buffer memory management control operations + * + * \return + * 0 - No error; -1 - Error + * + * \note + * Bitstream is also parsed here to get the MMCOs + * + ************************************************************************** + */ +WORD32 ih264d_do_mmco_for_gaps(dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_num_ref_frames /*!< num_ref_frames from active SeqParSet*/ + ) +{ + struct dpb_info_t *ps_next_dpb; + UWORD8 u1_num_gaps; + UWORD8 u1_st_ref_bufs, u1_lt_ref_bufs, u1_del_node; + WORD8 i; + WORD32 i4_frame_gaps = 1; + WORD32 ret; + + //Sliding window - implements 8.2.5.3, flush out buffers + u1_st_ref_bufs = ps_dpb_mgr->u1_num_st_ref_bufs; + u1_lt_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs; + + while(1) + { + u1_num_gaps = ps_dpb_mgr->u1_num_gaps; + if((u1_st_ref_bufs + u1_lt_ref_bufs + u1_num_gaps + i4_frame_gaps) + > u1_num_ref_frames) + { + if(0 == (u1_st_ref_bufs + u1_num_gaps)) + { + i4_frame_gaps = 0; + ps_dpb_mgr->u1_num_gaps = (u1_num_ref_frames + - u1_lt_ref_bufs); + } + else + { + u1_del_node = 1; + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + + if(u1_st_ref_bufs > 1) + { + for(i = 1; i < (u1_st_ref_bufs - 1); i++) + { + if(ps_next_dpb == NULL) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; + return i4_error_code; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) + { + return ERROR_DBP_MANAGER_T; + } + + if(u1_num_gaps) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->ps_prev_short->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + } + + if(u1_del_node) + { + u1_st_ref_bufs--; + ps_next_dpb->ps_prev_short->u1_used_as_ref = + UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->ps_prev_short->u1_buf_id); + ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; + ps_next_dpb->ps_prev_short = NULL; + } + } + else + { + if(u1_st_ref_bufs) + { + if(u1_num_gaps) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + } + + if(u1_del_node) + { + u1_st_ref_bufs--; + ps_next_dpb->u1_used_as_ref = FALSE; + ps_next_dpb->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->u1_buf_id); + ps_next_dpb->ps_pic_buf = NULL; + ps_next_dpb = NULL; + ps_dpb_mgr->ps_dpb_st_head = NULL; + ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; + } + } + else + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + INVALID_FRAME_NUM, + &u1_del_node); + if(ret != OK) + return ret; + if(u1_del_node) + { + return ERROR_DBP_MANAGER_T; + } + } + } + } + } + else + { + ps_dpb_mgr->u1_num_gaps += i4_frame_gaps; + break; + } + } + + ps_dpb_mgr->u1_num_st_ref_bufs = u1_st_ref_bufs; + + return OK; +} +/****************************************************************************/ +/* */ +/* Function Name : ih264d_free_node_from_dpb */ +/* */ +/* Description : */ +/* */ +/* Inputs : */ +/* */ +/* Globals : */ +/* */ +/* Processing : */ +/* */ +/* Outputs : */ +/* */ +/* Returns : */ +/* */ +/* Known Issues : */ +/* */ +/* Revision History */ +/* */ +/* DD MM YY Author Changes */ +/* Sarat */ +/****************************************************************************/ +/**** Function Added for Error Resilience *****/ +WORD32 ih264d_free_node_from_dpb(dpb_manager_t *ps_dpb_mgr, + UWORD32 u4_cur_pic_num, + UWORD8 u1_numRef_frames_for_seq) +{ + WORD32 i; + UWORD8 u1_num_gaps = ps_dpb_mgr->u1_num_gaps; + struct dpb_info_t *ps_next_dpb; + UWORD8 u1_del_node = 1; + WORD32 ret; + + //Sliding window - implements 8.2.5.3 + if((ps_dpb_mgr->u1_num_st_ref_bufs + ps_dpb_mgr->u1_num_lt_ref_bufs + + u1_num_gaps) == u1_numRef_frames_for_seq) + { + UWORD8 u1_new_node_flag = 1; + if((0 == ps_dpb_mgr->u1_num_st_ref_bufs) && (0 == u1_num_gaps)) + { + return ERROR_DBP_MANAGER_T; + } + + // Chase the links to reach the last but one picNum, if available + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + + if(ps_dpb_mgr->u1_num_st_ref_bufs > 1) + { + if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) + { + /* Incase of filed pictures top_field has been allocated */ + /* picture buffer and complementary bottom field pair comes */ + /* then the sliding window mechanism should not allocate a */ + /* new node */ + u1_new_node_flag = 0; + } + + for(i = 1; i < (ps_dpb_mgr->u1_num_st_ref_bufs - 1); i++) + { + if(ps_next_dpb == NULL) + return ERROR_DBP_MANAGER_T; + + if(ps_next_dpb->i4_frame_num == (WORD32)u4_cur_pic_num) + { + /* Incase of field pictures top_field has been allocated */ + /* picture buffer and complementary bottom field pair comes */ + /* then the sliding window mechanism should not allocate a */ + /* new node */ + u1_new_node_flag = 0; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + if(ps_next_dpb->ps_prev_short->ps_prev_short != NULL) + return ERROR_DBP_MANAGER_T; + + if(u1_new_node_flag) + { + if(u1_num_gaps) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->ps_prev_short->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + } + + if(u1_del_node) + { + ps_dpb_mgr->u1_num_st_ref_bufs--; + ps_next_dpb->ps_prev_short->u1_used_as_ref = UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_top_field.u1_reference_info = + UNUSED_FOR_REF; + ps_next_dpb->ps_prev_short->s_bot_field.u1_reference_info = + UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->ps_prev_short->u1_buf_id); + ps_next_dpb->ps_prev_short->ps_pic_buf = NULL; + ps_next_dpb->ps_prev_short = NULL; + } + } + } + else + { + if(ps_dpb_mgr->u1_num_st_ref_bufs) + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, + ps_next_dpb->i4_frame_num, + &u1_del_node); + if(ret != OK) + return ret; + if((ps_next_dpb->i4_frame_num != (WORD32)u4_cur_pic_num) + && u1_del_node) + { + ps_dpb_mgr->u1_num_st_ref_bufs--; + ps_next_dpb->u1_used_as_ref = FALSE; + ps_next_dpb->s_top_field.u1_reference_info = UNUSED_FOR_REF; + ps_next_dpb->s_bot_field.u1_reference_info = UNUSED_FOR_REF; + ih264d_free_ref_pic_mv_bufs(ps_dpb_mgr->pv_codec_handle, + ps_next_dpb->u1_buf_id); + ps_next_dpb->ps_pic_buf = NULL; + ps_next_dpb = NULL; + } + } + else + { + ret = ih264d_delete_gap_frm_sliding(ps_dpb_mgr, INVALID_FRAME_NUM, &u1_del_node); + if(ret != OK) + return ret; + if(u1_del_node) + return ERROR_DBP_MANAGER_T; + } + } + } + return OK; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_delete_nonref_nondisplay_pics */ +/* */ +/* Description : */ +/* */ +/* */ +/* Inputs : */ +/* Globals : */ +/* Processing : */ +/* */ +/* Outputs : */ +/* Returns : */ +/* */ +/* Issues : */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 05 06 2007 Varun Draft */ +/* */ +/*****************************************************************************/ + +void ih264d_delete_nonref_nondisplay_pics(dpb_manager_t *ps_dpb_mgr) +{ + WORD8 i; + WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; + + /* remove all gaps marked as unused for ref */ + for(i = 0; (i < MAX_FRAMES) && ps_dpb_mgr->i1_gaps_deleted; i++) + { + if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) + { + ps_dpb_mgr->i1_gaps_deleted--; + ps_dpb_mgr->i1_poc_buf_id_entries--; + i4_poc_buf_id_map[i][0] = -1; + i4_poc_buf_id_map[i][1] = 0x7fffffff; + i4_poc_buf_id_map[i][2] = 0; + } + } +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_insert_pic_in_display_list */ +/* */ +/* Description : */ +/* */ +/* */ +/* Inputs : */ +/* Globals : */ +/* Processing : */ +/* */ +/* Outputs : */ +/* Returns : */ +/* */ +/* Issues : */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 05 06 2007 Varun Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_insert_pic_in_display_list(dpb_manager_t *ps_dpb_mgr, + UWORD8 u1_buf_id, + WORD32 i4_display_poc, + UWORD32 u4_frame_num) +{ + WORD8 i; + WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; + + for(i = 0; i < MAX_FRAMES; i++) + { + /* Find an empty slot */ + if(i4_poc_buf_id_map[i][0] == -1) + { + if(GAP_FRAME_NUM == i4_poc_buf_id_map[i][2]) + ps_dpb_mgr->i1_gaps_deleted--; + else + ps_dpb_mgr->i1_poc_buf_id_entries++; + + i4_poc_buf_id_map[i][0] = u1_buf_id; + i4_poc_buf_id_map[i][1] = i4_display_poc; + i4_poc_buf_id_map[i][2] = u4_frame_num; + + break; + } + } + + if(MAX_FRAMES == i) + { + + UWORD32 i4_error_code; + i4_error_code = ERROR_GAPS_IN_FRM_NUM; + return i4_error_code; + } + return OK; +} + diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h new file mode 100755 index 0000000..20c0f89 --- /dev/null +++ b/decoder/ih264d_error_handler.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_ERROR_HANDLER_H_ +#define _IH264D_ERROR_HANDLER_H_ + +/*! + ************************************************************************* + * \file ih264d_error_handler.h + * + * \brief + * Contains declaration of ih264d_global_error_handler function + * + * \date + * 21/11/2002 + * + * \author AI + ************************************************************************* + */ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" + +typedef enum +{ + + ERROR_MEM_ALLOC_ISRAM_T = 0x50, + ERROR_MEM_ALLOC_SDRAM_T = 0x51, + ERROR_BUF_MGR = 0x52, + ERROR_DBP_MANAGER_T = 0x53, + ERROR_GAPS_IN_FRM_NUM = 0x54, + ERROR_UNKNOWN_NAL = 0x55, + ERROR_INV_MB_SLC_GRP_T = 0x56, + ERROR_MULTIPLE_SLC_GRP_T = 0x57, + ERROR_UNKNOWN_LEVEL = 0x58, + ERROR_FEATURE_UNAVAIL = 0x59, + ERROR_NOT_SUPP_RESOLUTION = 0x5A, + ERROR_INVALID_PIC_PARAM = 0x5B, + ERROR_INVALID_SEQ_PARAM = 0x5C, + ERROR_EGC_EXCEED_32_1_T = 0x5D, + ERROR_EGC_EXCEED_32_2_T = 0x5E, + ERROR_INV_RANGE_TEV_T = 0x5F, + ERROR_INV_SLC_TYPE_T = 0x60, + ERROR_UNAVAIL_PICBUF_T = 0x61, + ERROR_UNAVAIL_MVBUF_T = 0x62, + ERROR_UNAVAIL_DISPBUF_T = 0x63, + ERROR_INV_POC_TYPE_T = 0x64, + ERROR_PIC1_NOT_FOUND_T = 0x65, + ERROR_PIC0_NOT_FOUND_T = 0x66, + ERROR_NUM_REF = 0x67, + ERROR_REFIDX_ORDER_T = 0x68, + ERROR_EOB_FLUSHBITS_T = 0x69, + ERROR_EOB_GETBITS_T = 0x6A, + ERROR_EOB_GETBIT_T = 0x6B, + ERROR_EOB_BYPASS_T = 0x6C, + ERROR_EOB_DECISION_T = 0x6D, + ERROR_EOB_TERMINATE_T = 0x6E, + ERROR_EOB_READCOEFF4X4CAB_T = 0x6F, + ERROR_INV_RANGE_QP_T = 0x70, + ERROR_END_OF_FRAME_EXPECTED_T = 0x71, + ERROR_MB_TYPE = 0x72, + ERROR_SUB_MB_TYPE = 0x73, + ERROR_CBP = 0x74, + ERROR_REF_IDX = 0x75, + ERROR_NUM_MV = 0x76, + ERROR_CHROMA_PRED_MODE = 0x77, + ERROR_INTRAPRED = 0x78, + ERROR_NEXT_MB_ADDRESS_T = 0x79, + ERROR_MB_ADDRESS_T = 0x7A, + ERROR_MB_GROUP_ASSGN_T = 0x7B, + ERROR_CAVLC_NUM_COEFF_T = 0x7C, + ERROR_CAVLC_SCAN_POS_T = 0x7D, + ERROR_CABAC_RENORM_T = 0x7E, + ERROR_CABAC_SIG_COEFF1_T = 0x7F, + ERROR_CABAC_SIG_COEFF2_T = 0x80, + ERROR_CABAC_ENCODE_COEFF_T = 0x81, + ERROR_INV_SPS_PPS_T = 0x82, + ERROR_INV_SLICE_HDR_T = 0x83, + ERROR_PRED_WEIGHT_TABLE_T = 0x84, + IH264D_VERS_BUF_INSUFFICIENT = 0x85, + ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT = 0x86, + ERROR_CORRUPTED_SLICE = 0x87, + ERROR_FRAME_LIMIT_OVER = 0x88, + ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT = 0x89, + ERROR_PROFILE_NOT_SUPPORTED = 0x8A, + ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH = 0x8B, + ERROR_DISP_WIDTH_INVALID = 0x8C, + ERROR_DANGLING_FIELD_IN_PIC = 0x8D, + ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED = 0x8E, + ERROR_INIT_NOT_DONE = 0x8F, + ERROR_LEVEL_UNSUPPORTED = 0x90, + ERROR_START_CODE_NOT_FOUND = 0x91, + ERROR_PIC_NUM_IS_REPEATED = 0x92, + +} h264_decoder_error_code_t; + +#endif /* _IH264D_ERROR_HANDLER_H_ */ diff --git a/decoder/ih264d_format_conv.c b/decoder/ih264d_format_conv.c new file mode 100755 index 0000000..9a8494e --- /dev/null +++ b/decoder/ih264d_format_conv.c @@ -0,0 +1,838 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_format_conv.c */ +/* */ +/* Description : Contains functions needed to convert the images in */ +/* different color spaces to yuv 422i color space */ +/* */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 28 08 2007 Naveen Kumar T Draft */ +/* */ +/*****************************************************************************/ +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System include files */ +#include <string.h> +/* User include files */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_format_conv.h" +#include "ih264d_defs.h" + + + +#ifdef LOGO_EN +#include "ih264d_ittiam_logo.h" +#define INSERT_LOGO(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride, u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht) \ + ih264d_insert_logo(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride,\ + u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht) +#else +#define INSERT_LOGO(pu1_buf_y,pu1_buf_u,pu1_buf_v, u4_stride, u4_x_pos, u4_y_pos, u4_yuv_fmt, u4_disp_wd, u4_disp_ht) +#endif + +/** + ******************************************************************************* + * + * @brief Function used from copying a 420SP buffer + * + * @par Description + * Function used from copying a 420SP buffer + * + * @param[in] pu1_y_src + * Input Y pointer + * + * @param[in] pu1_uv_src + * Input UV pointer (UV is interleaved either in UV or VU format) + * + * @param[in] pu1_y_dst + * Output Y pointer + * + * @param[in] pu1_uv_dst + * Output UV pointer (UV is interleaved in the same format as that of input) + * + * @param[in] wd + * Width + * + * @param[in] ht + * Height + * + * @param[in] src_y_strd + * Input Y Stride + * + * @param[in] src_uv_strd + * Input UV stride + * + * @param[in] dst_y_strd + * Output Y stride + * + * @param[in] dst_uv_strd + * Output UV stride + * + * @returns None + * + * @remarks In case there is a need to perform partial frame copy then + * by passion appropriate source and destination pointers and appropriate + * values for wd and ht it can be done + * + ******************************************************************************* + */ +void ih264d_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD16 *pu2_rgb_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_strd, + WORD32 is_u_first) +{ + + WORD16 i2_r, i2_g, i2_b; + UWORD32 u4_r, u4_g, u4_b; + WORD16 i2_i, i2_j; + UWORD8 *pu1_y_src_nxt; + UWORD16 *pu2_rgb_dst_next_row; + + UWORD8 *pu1_u_src, *pu1_v_src; + + if(is_u_first) + { + pu1_u_src = (UWORD8 *)pu1_uv_src; + pu1_v_src = (UWORD8 *)pu1_uv_src + 1; + } + else + { + pu1_u_src = (UWORD8 *)pu1_uv_src + 1; + pu1_v_src = (UWORD8 *)pu1_uv_src; + } + + pu1_y_src_nxt = pu1_y_src + src_y_strd; + pu2_rgb_dst_next_row = pu2_rgb_dst + dst_strd; + + for(i2_i = 0; i2_i < (ht >> 1); i2_i++) + { + for(i2_j = (wd >> 1); i2_j > 0; i2_j--) + { + i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); + i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) + >> 13; + i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; + + pu1_u_src += 2; + pu1_v_src += 2; + /* pixel 0 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src + i2_b); + u4_b >>= 3; + /* G */ + u4_g = CLIP_U8(*pu1_y_src + i2_g); + u4_g >>= 2; + /* R */ + u4_r = CLIP_U8(*pu1_y_src + i2_r); + u4_r >>= 3; + + pu1_y_src++; + *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); + + /* pixel 1 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src + i2_b); + u4_b >>= 3; + /* G */ + u4_g = CLIP_U8(*pu1_y_src + i2_g); + u4_g >>= 2; + /* R */ + u4_r = CLIP_U8(*pu1_y_src + i2_r); + u4_r >>= 3; + + pu1_y_src++; + *pu2_rgb_dst++ = ((u4_r << 11) | (u4_g << 5) | u4_b); + + /* pixel 2 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); + u4_b >>= 3; + /* G */ + u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); + u4_g >>= 2; + /* R */ + u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); + u4_r >>= 3; + + pu1_y_src_nxt++; + *pu2_rgb_dst_next_row++ = ((u4_r << 11) | (u4_g << 5) | u4_b); + + /* pixel 3 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); + u4_b >>= 3; + /* G */ + u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); + u4_g >>= 2; + /* R */ + u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); + u4_r >>= 3; + + pu1_y_src_nxt++; + *pu2_rgb_dst_next_row++ = ((u4_r << 11) | (u4_g << 5) | u4_b); + + } + + pu1_u_src = pu1_u_src + src_uv_strd - wd; + pu1_v_src = pu1_v_src + src_uv_strd - wd; + + pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; + pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; + + pu2_rgb_dst = pu2_rgb_dst_next_row - wd + dst_strd; + pu2_rgb_dst_next_row = pu2_rgb_dst_next_row + (dst_strd << 1) - wd; + } + +} + +void ih264d_fmt_conv_420sp_to_rgba8888(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD32 *pu4_rgba_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_strd, + WORD32 is_u_first) +{ + + WORD16 i2_r, i2_g, i2_b; + UWORD32 u4_r, u4_g, u4_b; + WORD16 i2_i, i2_j; + UWORD8 *pu1_y_src_nxt; + UWORD32 *pu4_rgba_dst_next_row; + + UWORD8 *pu1_u_src, *pu1_v_src; + + if(is_u_first) + { + pu1_u_src = (UWORD8 *)pu1_uv_src; + pu1_v_src = (UWORD8 *)pu1_uv_src + 1; + } + else + { + pu1_u_src = (UWORD8 *)pu1_uv_src + 1; + pu1_v_src = (UWORD8 *)pu1_uv_src; + } + + pu1_y_src_nxt = pu1_y_src + src_y_strd; + pu4_rgba_dst_next_row = pu4_rgba_dst + dst_strd; + + for(i2_i = 0; i2_i < (ht >> 1); i2_i++) + { + for(i2_j = (wd >> 1); i2_j > 0; i2_j--) + { + i2_b = ((*pu1_u_src - 128) * COEFF4 >> 13); + i2_g = ((*pu1_u_src - 128) * COEFF2 + (*pu1_v_src - 128) * COEFF3) + >> 13; + i2_r = ((*pu1_v_src - 128) * COEFF1) >> 13; + + pu1_u_src += 2; + pu1_v_src += 2; + /* pixel 0 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src + i2_b); + /* G */ + u4_g = CLIP_U8(*pu1_y_src + i2_g); + /* R */ + u4_r = CLIP_U8(*pu1_y_src + i2_r); + + pu1_y_src++; + *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); + + /* pixel 1 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src + i2_b); + /* G */ + u4_g = CLIP_U8(*pu1_y_src + i2_g); + /* R */ + u4_r = CLIP_U8(*pu1_y_src + i2_r); + + pu1_y_src++; + *pu4_rgba_dst++ = ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); + + /* pixel 2 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); + /* G */ + u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); + /* R */ + u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); + + pu1_y_src_nxt++; + *pu4_rgba_dst_next_row++ = + ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); + + /* pixel 3 */ + /* B */ + u4_b = CLIP_U8(*pu1_y_src_nxt + i2_b); + /* G */ + u4_g = CLIP_U8(*pu1_y_src_nxt + i2_g); + /* R */ + u4_r = CLIP_U8(*pu1_y_src_nxt + i2_r); + + pu1_y_src_nxt++; + *pu4_rgba_dst_next_row++ = + ((u4_r << 16) | (u4_g << 8) | (u4_b << 0)); + + } + + pu1_u_src = pu1_u_src + src_uv_strd - wd; + pu1_v_src = pu1_v_src + src_uv_strd - wd; + + pu1_y_src = pu1_y_src + (src_y_strd << 1) - wd; + pu1_y_src_nxt = pu1_y_src_nxt + (src_y_strd << 1) - wd; + + pu4_rgba_dst = pu4_rgba_dst_next_row - wd + dst_strd; + pu4_rgba_dst_next_row = pu4_rgba_dst_next_row + (dst_strd << 1) - wd; + } + +} + +/** + ******************************************************************************* + * + * @brief Function used from copying a 420SP buffer + * + * @par Description + * Function used from copying a 420SP buffer + * + * @param[in] pu1_y_src + * Input Y pointer + * + * @param[in] pu1_uv_src + * Input UV pointer (UV is interleaved either in UV or VU format) + * + * @param[in] pu1_y_dst + * Output Y pointer + * + * @param[in] pu1_uv_dst + * Output UV pointer (UV is interleaved in the same format as that of input) + * + * @param[in] wd + * Width + * + * @param[in] ht + * Height + * + * @param[in] src_y_strd + * Input Y Stride + * + * @param[in] src_uv_strd + * Input UV stride + * + * @param[in] dst_y_strd + * Output Y stride + * + * @param[in] dst_uv_strd + * Output UV stride + * + * @returns None + * + * @remarks In case there is a need to perform partial frame copy then + * by passion appropriate source and destination pointers and appropriate + * values for wd and ht it can be done + * + ******************************************************************************* + */ + +void ih264d_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_uv_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd) +{ + UWORD8 *pu1_src, *pu1_dst; + WORD32 num_rows, num_cols, src_strd, dst_strd; + WORD32 i; + + /* copy luma */ + pu1_src = (UWORD8 *)pu1_y_src; + pu1_dst = (UWORD8 *)pu1_y_dst; + + num_rows = ht; + num_cols = wd; + + src_strd = src_y_strd; + dst_strd = dst_y_strd; + + for(i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, num_cols); + pu1_dst += dst_strd; + pu1_src += src_strd; + } + + /* copy U and V */ + pu1_src = (UWORD8 *)pu1_uv_src; + pu1_dst = (UWORD8 *)pu1_uv_dst; + + num_rows = ht >> 1; + num_cols = wd; + + src_strd = src_uv_strd; + dst_strd = dst_uv_strd; + + for(i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, num_cols); + pu1_dst += dst_strd; + pu1_src += src_strd; + } + return; +} + +/** + ******************************************************************************* + * + * @brief Function used from copying a 420SP buffer + * + * @par Description + * Function used from copying a 420SP buffer + * + * @param[in] pu1_y_src + * Input Y pointer + * + * @param[in] pu1_uv_src + * Input UV pointer (UV is interleaved either in UV or VU format) + * + * @param[in] pu1_y_dst + * Output Y pointer + * + * @param[in] pu1_uv_dst + * Output UV pointer (UV is interleaved in the same format as that of input) + * + * @param[in] wd + * Width + * + * @param[in] ht + * Height + * + * @param[in] src_y_strd + * Input Y Stride + * + * @param[in] src_uv_strd + * Input UV stride + * + * @param[in] dst_y_strd + * Output Y stride + * + * @param[in] dst_uv_strd + * Output UV stride + * + * @returns None + * + * @remarks In case there is a need to perform partial frame copy then + * by passion appropriate source and destination pointers and appropriate + * values for wd and ht it can be done + * + ******************************************************************************* + */ +void ih264d_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_uv_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd) +{ + UWORD8 *pu1_src, *pu1_dst; + WORD32 num_rows, num_cols, src_strd, dst_strd; + WORD32 i; + + /* copy luma */ + pu1_src = (UWORD8 *)pu1_y_src; + pu1_dst = (UWORD8 *)pu1_y_dst; + + num_rows = ht; + num_cols = wd; + + src_strd = src_y_strd; + dst_strd = dst_y_strd; + + for(i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, num_cols); + pu1_dst += dst_strd; + pu1_src += src_strd; + } + + /* copy U and V */ + pu1_src = (UWORD8 *)pu1_uv_src; + pu1_dst = (UWORD8 *)pu1_uv_dst; + + num_rows = ht >> 1; + num_cols = wd; + + src_strd = src_uv_strd; + dst_strd = dst_uv_strd; + + for(i = 0; i < num_rows; i++) + { + WORD32 j; + for(j = 0; j < num_cols; j += 2) + { + pu1_dst[j + 0] = pu1_src[j + 1]; + pu1_dst[j + 1] = pu1_src[j + 0]; + } + pu1_dst += dst_strd; + pu1_src += src_strd; + } + return; +} +/** + ******************************************************************************* + * + * @brief Function used from copying a 420SP buffer + * + * @par Description + * Function used from copying a 420SP buffer + * + * @param[in] pu1_y_src + * Input Y pointer + * + * @param[in] pu1_uv_src + * Input UV pointer (UV is interleaved either in UV or VU format) + * + * @param[in] pu1_y_dst + * Output Y pointer + * + * @param[in] pu1_u_dst + * Output U pointer + * + * @param[in] pu1_v_dst + * Output V pointer + * + * @param[in] wd + * Width + * + * @param[in] ht + * Height + * + * @param[in] src_y_strd + * Input Y Stride + * + * @param[in] src_uv_strd + * Input UV stride + * + * @param[in] dst_y_strd + * Output Y stride + * + * @param[in] dst_uv_strd + * Output UV stride + * + * @param[in] is_u_first + * Flag to indicate if U is the first byte in input chroma part + * + * @returns none + * + * @remarks In case there is a need to perform partial frame copy then + * by passion appropriate source and destination pointers and appropriate + * values for wd and ht it can be done + * + ******************************************************************************* + */ + +void ih264d_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_u_dst, + UWORD8 *pu1_v_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd, + WORD32 is_u_first, + WORD32 disable_luma_copy) +{ + UWORD8 *pu1_src, *pu1_dst; + UWORD8 *pu1_u_src, *pu1_v_src; + WORD32 num_rows, num_cols, src_strd, dst_strd; + WORD32 i, j; + + if(0 == disable_luma_copy) + { + /* copy luma */ + pu1_src = (UWORD8 *)pu1_y_src; + pu1_dst = (UWORD8 *)pu1_y_dst; + + num_rows = ht; + num_cols = wd; + + src_strd = src_y_strd; + dst_strd = dst_y_strd; + + for(i = 0; i < num_rows; i++) + { + memcpy(pu1_dst, pu1_src, num_cols); + pu1_dst += dst_strd; + pu1_src += src_strd; + } + } + /* de-interleave U and V and copy to destination */ + if(is_u_first) + { + pu1_u_src = (UWORD8 *)pu1_uv_src; + pu1_v_src = (UWORD8 *)pu1_uv_src + 1; + } + else + { + pu1_u_src = (UWORD8 *)pu1_uv_src + 1; + pu1_v_src = (UWORD8 *)pu1_uv_src; + } + + num_rows = ht >> 1; + num_cols = wd >> 1; + + src_strd = src_uv_strd; + dst_strd = dst_uv_strd; + + for(i = 0; i < num_rows; i++) + { + for(j = 0; j < num_cols; j++) + { + pu1_u_dst[j] = pu1_u_src[j * 2]; + pu1_v_dst[j] = pu1_v_src[j * 2]; + } + + pu1_u_dst += dst_strd; + pu1_v_dst += dst_strd; + pu1_u_src += src_strd; + pu1_v_src += src_strd; + } + return; +} + +/*****************************************************************************/ +/* Function Name : ih264d_format_convert */ +/* */ +/* Description : Implements format conversion/frame copy */ +/* Inputs : ps_dec - Decoder parameters */ +/* Globals : None */ +/* Processing : Refer bumping process in the standard */ +/* Outputs : Assigns display sequence number. */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 04 2005 NS Draft */ +/* */ +/*****************************************************************************/ +void ih264d_format_convert(dec_struct_t *ps_dec, + ivd_get_display_frame_op_t *pv_disp_op, + UWORD32 u4_start_y, + UWORD32 u4_num_rows_y) +{ + UWORD32 convert_uv_only = 0; + iv_yuv_buf_t *ps_op_frm; + + if(1 == pv_disp_op->u4_error_code) + return; + + ps_op_frm = &(ps_dec->s_disp_frame_info); + + /* Requires u4_start_y and u4_num_rows_y to be even */ + if(u4_start_y & 1) + { + H264_DEC_DEBUG_PRINT( + "Requires even number of rows and even u4_start_y for format conversion\n"); + return; + } + + if((1 == ps_dec->u4_share_disp_buf) + && ((pv_disp_op->e_output_format == IV_YUV_420SP_UV))) + { + return; + } + if(pv_disp_op->e_output_format == IV_YUV_420P) + { + UWORD8 *pu1_src, *pu1_dst; + UWORD16 i; + UWORD16 iter; + + IV_COLOR_FORMAT_T e_output_format = pv_disp_op->e_output_format; + UWORD32 start_uv = u4_start_y >> 1; + UWORD32 num_rows_uv = (u4_num_rows_y + 1) >> 1; + if(0 == ps_dec->u4_share_disp_buf) + { + convert_uv_only = 0; + } + else + { + convert_uv_only = 1; + } + { + + UWORD8 *pu1_y_src, *pu1_u_src, *pu1_v_src; + UWORD8 *pu1_y_dst, *pu1_u_dst, *pu1_v_dst; + UWORD32 width, height; + UWORD32 src_luma_stride, src_chroma_stride; + UWORD32 dst_luma_stride, dst_chroma_stride; + + pu1_y_src = (UWORD8 *)ps_op_frm->pv_y_buf; + pu1_y_src += u4_start_y * ps_op_frm->u4_y_strd; + + pu1_y_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf; + pu1_y_dst += u4_start_y * pv_disp_op->s_disp_frm_buf.u4_y_strd; + + pu1_u_src = (UWORD8 *)ps_op_frm->pv_u_buf; + pu1_u_src += start_uv * ps_op_frm->u4_u_strd; + + pu1_u_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_u_buf; + pu1_u_dst += start_uv * pv_disp_op->s_disp_frm_buf.u4_u_strd; + + pu1_v_src = (UWORD8 *)ps_op_frm->pv_v_buf; + pu1_v_src += start_uv * ps_op_frm->u4_v_strd; + + pu1_v_dst = (UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_v_buf; + pu1_v_dst += start_uv * pv_disp_op->s_disp_frm_buf.u4_v_strd; + + src_luma_stride = ps_op_frm->u4_y_strd; + src_chroma_stride = ps_op_frm->u4_u_strd; + + dst_luma_stride = pv_disp_op->s_disp_frm_buf.u4_y_strd; + dst_chroma_stride = pv_disp_op->s_disp_frm_buf.u4_u_strd; + + width = ps_op_frm->u4_y_wd; + height = u4_num_rows_y; + ih264d_fmt_conv_420sp_to_420p(pu1_y_src, pu1_u_src, pu1_y_dst, + pu1_u_dst, pu1_v_dst, width, height, + src_luma_stride, src_chroma_stride, + dst_luma_stride, dst_chroma_stride, 1, + convert_uv_only); + } + + } + + else if((pv_disp_op->e_output_format == IV_YUV_420SP_UV) + || (pv_disp_op->e_output_format == IV_YUV_420SP_VU)) + + { + + UWORD32 start_uv = u4_start_y >> 1; + UWORD32 num_rows_uv = (u4_num_rows_y + 1) >> 1; + + + if(pv_disp_op->e_output_format == IV_YUV_420SP_UV) + { + ih264d_fmt_conv_420sp_to_420sp( + (UWORD8 *)ps_op_frm->pv_y_buf + + u4_start_y * ps_op_frm->u4_y_strd, + ((UWORD8 *)ps_op_frm->pv_u_buf + + start_uv * ps_op_frm->u4_u_strd), + ((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf + + u4_start_y + * pv_disp_op->s_disp_frm_buf.u4_y_strd), + ((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_u_buf + + start_uv + * pv_disp_op->s_disp_frm_buf.u4_u_strd), + ps_op_frm->u4_y_wd, u4_num_rows_y, + ps_op_frm->u4_y_strd, ps_op_frm->u4_u_strd, + pv_disp_op->s_disp_frm_buf.u4_y_strd, + pv_disp_op->s_disp_frm_buf.u4_u_strd); + } + else + { + + ih264d_fmt_conv_420sp_to_420sp_swap_uv( + (UWORD8 *)ps_op_frm->pv_y_buf + + u4_start_y * ps_op_frm->u4_y_strd, + ((UWORD8 *)ps_op_frm->pv_u_buf + + start_uv * ps_op_frm->u4_u_strd), + ((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf + + u4_start_y + * pv_disp_op->s_disp_frm_buf.u4_y_strd), + ((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_u_buf + + start_uv + * pv_disp_op->s_disp_frm_buf.u4_u_strd), + ps_op_frm->u4_y_wd, u4_num_rows_y, + ps_op_frm->u4_y_strd, ps_op_frm->u4_u_strd, + pv_disp_op->s_disp_frm_buf.u4_y_strd, + pv_disp_op->s_disp_frm_buf.u4_u_strd); + + } + + } + else if(pv_disp_op->e_output_format == IV_RGB_565) + { + UWORD32 temp = 0; + UWORD32 u2_width_rem; + + UWORD32 start_uv = u4_start_y >> 1; + + ih264d_fmt_conv_420sp_to_rgb565( + (UWORD8 *)ps_op_frm->pv_y_buf + + u4_start_y * ps_op_frm->u4_y_strd, + ((UWORD8 *)ps_op_frm->pv_u_buf + + start_uv * ps_op_frm->u4_u_strd), + ((UWORD16 *)pv_disp_op->s_disp_frm_buf.pv_y_buf + + u4_start_y + * pv_disp_op->s_disp_frm_buf.u4_y_strd), + ps_op_frm->u4_y_wd, u4_num_rows_y, ps_op_frm->u4_y_strd, + ps_op_frm->u4_u_strd, + pv_disp_op->s_disp_frm_buf.u4_y_strd, 1); + + + } + + if((u4_start_y + u4_num_rows_y) >= ps_dec->s_disp_frame_info.u4_y_ht) + { + + INSERT_LOGO(pv_disp_op->s_disp_frm_buf.pv_y_buf, + pv_disp_op->s_disp_frm_buf.pv_u_buf, + pv_disp_op->s_disp_frm_buf.pv_v_buf, pv_disp_op->s_disp_frm_buf.u4_y_strd, + ps_dec->u2_disp_width, + ps_dec->u2_disp_height, + pv_disp_op->e_output_format, + ps_op_frm->u4_y_wd, + ps_op_frm->u4_y_ht); + } + + return; +} diff --git a/decoder/ih264d_format_conv.h b/decoder/ih264d_format_conv.h new file mode 100755 index 0000000..81a8a0f --- /dev/null +++ b/decoder/ih264d_format_conv.h @@ -0,0 +1,120 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_format_conv.h */ +/* */ +/* Description : Contains coefficients and constant reqquired for */ +/* converting from rgb and gray color spaces to yuv422i */ +/* color space */ +/* */ +/* List of Functions : None */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 08 2007 Naveen Kumar T Draft */ +/* */ +/*****************************************************************************/ + +#ifndef _IH264D_FORMAT_CONV_H_ +#define _IH264D_FORMAT_CONV_H_ + +/*****************************************************************************/ +/* Typedefs */ +/*****************************************************************************/ + +#define COEFF_0_Y 66 +#define COEFF_1_Y 129 +#define COEFF_2_Y 25 +#define COEFF_0_U -38 +#define COEFF_1_U -75 +#define COEFF_2_U 112 +#define COEFF_0_V 112 +#define COEFF_1_V -94 +#define COEFF_2_V -18 +#define CONST_RGB_YUV1 4096 +#define CONST_RGB_YUV2 32768 +#define CONST_GRAY_YUV 128 +#define COEF_2_V2_U 0xFFEE0070 + +#define COF_2Y_0Y 0X00190042 +#define COF_1U_0U 0XFFB5FFDA +#define COF_1V_0V 0XFFA20070 + +void ih264d_fmt_conv_420sp_to_420p(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_u_dst, + UWORD8 *pu1_v_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd, + WORD32 is_u_first, + WORD32 disable_luma_copy); + +void ih264d_fmt_conv_420sp_to_420sp_swap_uv(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_uv_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd); + +void ih264d_fmt_conv_420sp_to_420sp(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD8 *pu1_y_dst, + UWORD8 *pu1_uv_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_y_strd, + WORD32 dst_uv_strd); + +void ih264d_fmt_conv_420sp_to_rgb565(UWORD8 *pu1_y_src, + UWORD8 *pu1_uv_src, + UWORD16 *pu2_rgb_dst, + WORD32 wd, + WORD32 ht, + WORD32 src_y_strd, + WORD32 src_uv_strd, + WORD32 dst_strd, + WORD32 is_u_first); +#define COEFF1 13073 +#define COEFF2 -3207 +#define COEFF3 -6664 +#define COEFF4 16530 + +void ih264d_format_convert(dec_struct_t *ps_dec, + ivd_get_display_frame_op_t *pv_disp_op, + UWORD32 u4_start_y, + UWORD32 u4_num_rows_y); + + +#endif /* _IH264D_FORMAT_CONV_H_ */ diff --git a/decoder/ih264d_function_selector.h b/decoder/ih264d_function_selector.h new file mode 100755 index 0000000..92ad959 --- /dev/null +++ b/decoder/ih264d_function_selector.h @@ -0,0 +1,75 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 + * ih264d_function_selector.h + * + * @brief + * Structure definitions used in the decoder + * + * @author + * Harish + * + * @par List of Functions: + * + * @remarks + * None + * + ******************************************************************************* + */ + +#ifndef _IH264D_FUNCTION_SELECTOR_H_ +#define _IH264D_FUNCTION_SELECTOR_H_ + +#define D_ARCH_NA 1 +#define D_ARCH_ARM_NONEON 2 +#define D_ARCH_ARM_A9Q 3 +#define D_ARCH_ARM_A9A 4 +#define D_ARCH_ARM_A9 5 +#define D_ARCH_ARM_A7 6 +#define D_ARCH_ARM_A5 7 +#define D_ARCH_ARM_A15 8 +#define D_ARCH_ARM_NEONINTR 9 +#define D_ARCH_ARMV8_GENERIC 10 +#define D_ARCH_X86_GENERIC 11 +#define D_ARCH_X86_SSSE3 12 +#define D_ARCH_X86_SSE42 13 +#define D_ARCH_X86_AVX2 14 +#define D_ARCH_MIPS_GENERIC 15 +#define D_ARCH_MIPS_32 16 + +void ih264d_init_arch(dec_struct_t *ps_codec); + +void ih264d_init_function_ptr(dec_struct_t *ps_codec); + +void ih264d_init_function_ptr_generic(dec_struct_t *ps_codec); +void ih264d_init_function_ptr_ssse3(dec_struct_t *ps_codec); +void ih264d_init_function_ptr_sse42(dec_struct_t *ps_codec); + +#ifndef DISABLE_AVX2 +void ih264d_init_function_ptr_avx2(dec_struct_t *ps_codec); +#endif + +void ih264d_init_function_ptr_a9q(dec_struct_t *ps_codec); +void ih264d_init_function_ptr_av8(dec_struct_t *ps_codec); + +#endif /* _IH264D_FUNCTION_SELECTOR_H_ */ diff --git a/decoder/ih264d_function_selector_generic.c b/decoder/ih264d_function_selector_generic.c new file mode 100755 index 0000000..48956ef --- /dev/null +++ b/decoder/ih264d_function_selector_generic.c @@ -0,0 +1,222 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 + * ih264e_function_selector_generic.c + * + * @brief + * Contains functions to initialize function pointers of codec context + * + * @author + * Ittiam + * + * @par List of Functions: + * - ih264e_init_function_ptr_generic + * + * @remarks + * None + * + ******************************************************************************* + */ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" +#include "ih264d_function_selector.h" + +/** + ******************************************************************************* + * + * @brief Initialize the intra/inter/transform/deblk function pointers of + * codec context + * + * @par Description: the current routine initializes the function pointers of + * codec context basing on the architecture in use + * + * @param[in] ps_codec + * Codec context pointer + * + * @returns none + * + * @remarks none + * + ******************************************************************************* + */ +void ih264d_init_function_ptr_generic(dec_struct_t *ps_codec) +{ + + WORD32 i = 0; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_luma_16x16[0] = + ih264_intra_pred_luma_16x16_mode_vert; + ps_codec->apf_intra_pred_luma_16x16[1] = + ih264_intra_pred_luma_16x16_mode_horz; + ps_codec->apf_intra_pred_luma_16x16[2] = + ih264_intra_pred_luma_16x16_mode_dc; + ps_codec->apf_intra_pred_luma_16x16[3] = + ih264_intra_pred_luma_16x16_mode_plane; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_luma_4x4[0] = ih264_intra_pred_luma_4x4_mode_vert; + ps_codec->apf_intra_pred_luma_4x4[1] = ih264_intra_pred_luma_4x4_mode_horz; + ps_codec->apf_intra_pred_luma_4x4[2] = ih264_intra_pred_luma_4x4_mode_dc; + ps_codec->apf_intra_pred_luma_4x4[3] = + ih264_intra_pred_luma_4x4_mode_diag_dl; + ps_codec->apf_intra_pred_luma_4x4[4] = + ih264_intra_pred_luma_4x4_mode_diag_dr; + ps_codec->apf_intra_pred_luma_4x4[5] = + ih264_intra_pred_luma_4x4_mode_vert_r; + ps_codec->apf_intra_pred_luma_4x4[6] = + ih264_intra_pred_luma_4x4_mode_horz_d; + ps_codec->apf_intra_pred_luma_4x4[7] = + ih264_intra_pred_luma_4x4_mode_vert_l; + ps_codec->apf_intra_pred_luma_4x4[8] = + ih264_intra_pred_luma_4x4_mode_horz_u; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 8x8 */ + ps_codec->apf_intra_pred_luma_8x8[0] = ih264_intra_pred_luma_8x8_mode_vert; + ps_codec->apf_intra_pred_luma_8x8[1] = ih264_intra_pred_luma_8x8_mode_horz; + ps_codec->apf_intra_pred_luma_8x8[2] = ih264_intra_pred_luma_8x8_mode_dc; + ps_codec->apf_intra_pred_luma_8x8[3] = + ih264_intra_pred_luma_8x8_mode_diag_dl; + ps_codec->apf_intra_pred_luma_8x8[4] = + ih264_intra_pred_luma_8x8_mode_diag_dr; + ps_codec->apf_intra_pred_luma_8x8[5] = + ih264_intra_pred_luma_8x8_mode_vert_r; + ps_codec->apf_intra_pred_luma_8x8[6] = + ih264_intra_pred_luma_8x8_mode_horz_d; + ps_codec->apf_intra_pred_luma_8x8[7] = + ih264_intra_pred_luma_8x8_mode_vert_l; + ps_codec->apf_intra_pred_luma_8x8[8] = + ih264_intra_pred_luma_8x8_mode_horz_u; + + ps_codec->pf_intra_pred_ref_filtering = + ih264_intra_pred_luma_8x8_mode_ref_filtering; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_chroma[0] = ih264_intra_pred_chroma_8x8_mode_vert; + ps_codec->apf_intra_pred_chroma[1] = ih264_intra_pred_chroma_8x8_mode_horz; + ps_codec->apf_intra_pred_chroma[2] = ih264_intra_pred_chroma_8x8_mode_dc; + ps_codec->apf_intra_pred_chroma[3] = ih264_intra_pred_chroma_8x8_mode_plane; + + ps_codec->pf_default_weighted_pred_luma = ih264_default_weighted_pred_luma; + ps_codec->pf_default_weighted_pred_chroma = + ih264_default_weighted_pred_chroma; + ps_codec->pf_weighted_pred_luma = ih264_weighted_pred_luma; + ps_codec->pf_weighted_pred_chroma = ih264_weighted_pred_chroma; + ps_codec->pf_weighted_bi_pred_luma = ih264_weighted_bi_pred_luma; + ps_codec->pf_weighted_bi_pred_chroma = ih264_weighted_bi_pred_chroma; + + /* Padding Functions */ + ps_codec->pf_pad_top = ih264_pad_top; + ps_codec->pf_pad_bottom = ih264_pad_bottom; + ps_codec->pf_pad_left_luma = ih264_pad_left_luma; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma; + + ps_codec->pf_iquant_itrans_recon_luma_4x4 = ih264_iquant_itrans_recon_4x4; + ps_codec->pf_iquant_itrans_recon_luma_4x4_dc = + ih264_iquant_itrans_recon_4x4_dc; + ps_codec->pf_iquant_itrans_recon_luma_8x8 = ih264_iquant_itrans_recon_8x8; + ps_codec->pf_iquant_itrans_recon_luma_8x8_dc = + ih264_iquant_itrans_recon_8x8_dc; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = + ih264_iquant_itrans_recon_chroma_4x4; + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = + ih264_iquant_itrans_recon_chroma_4x4_dc; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4; + + /* Init fn ptr luma deblocking */ + ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4; + ps_codec->pf_deblk_luma_vert_bs4_mbaff = ih264_deblk_luma_vert_bs4_mbaff; + ps_codec->pf_deblk_luma_vert_bslt4_mbaff = + ih264_deblk_luma_vert_bslt4_mbaff; + + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4; + + /* Init fn ptr chroma deblocking */ + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4; + ps_codec->pf_deblk_chroma_vert_bs4_mbaff = + ih264_deblk_chroma_vert_bs4_mbaff; + ps_codec->pf_deblk_chroma_vert_bslt4_mbaff = + ih264_deblk_chroma_vert_bslt4_mbaff; + + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4; + + /* Inter pred leaf level functions */ + ps_codec->apf_inter_pred_luma[0] = ih264_inter_pred_luma_copy; + ps_codec->apf_inter_pred_luma[1] = ih264_inter_pred_luma_horz_qpel; + ps_codec->apf_inter_pred_luma[2] = ih264_inter_pred_luma_horz; + ps_codec->apf_inter_pred_luma[3] = ih264_inter_pred_luma_horz_qpel; + ps_codec->apf_inter_pred_luma[4] = ih264_inter_pred_luma_vert_qpel; + ps_codec->apf_inter_pred_luma[5] = + ih264_inter_pred_luma_horz_qpel_vert_qpel; + ps_codec->apf_inter_pred_luma[6] = + ih264_inter_pred_luma_horz_hpel_vert_qpel; + ps_codec->apf_inter_pred_luma[7] = + ih264_inter_pred_luma_horz_qpel_vert_qpel; + ps_codec->apf_inter_pred_luma[8] = ih264_inter_pred_luma_vert; + ps_codec->apf_inter_pred_luma[9] = + ih264_inter_pred_luma_horz_qpel_vert_hpel; + ps_codec->apf_inter_pred_luma[10] = + ih264_inter_pred_luma_horz_hpel_vert_hpel; + ps_codec->apf_inter_pred_luma[11] = + ih264_inter_pred_luma_horz_qpel_vert_hpel; + ps_codec->apf_inter_pred_luma[12] = ih264_inter_pred_luma_vert_qpel; + ps_codec->apf_inter_pred_luma[13] = + ih264_inter_pred_luma_horz_qpel_vert_qpel; + ps_codec->apf_inter_pred_luma[14] = + ih264_inter_pred_luma_horz_hpel_vert_qpel; + ps_codec->apf_inter_pred_luma[15] = + ih264_inter_pred_luma_horz_qpel_vert_qpel; + + ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma; + + return; +} diff --git a/decoder/ih264d_inter_pred.c b/decoder/ih264d_inter_pred.c new file mode 100755 index 0000000..fa818b5 --- /dev/null +++ b/decoder/ih264d_inter_pred.c @@ -0,0 +1,1614 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_inter_pred.c + * + * \brief + * This file contains routines to perform MotionCompensation tasks + * + * Detailed_description + * + * \date + * 20/11/2002 + * + * \author Arvind Raman + ************************************************************************** + */ + +#include <string.h> +#include "ih264d_defs.h" +#include "ih264d_mvpred.h" +#include "ih264d_error_handler.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_inter_pred.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_mb_utils.h" + + +void ih264d_pad_on_demand(pred_info_t *ps_pred, UWORD8 lum_chrom_blk); + + + +void ih264d_copy_multiplex_data(UWORD8 *puc_Source, + UWORD8 *puc_To, + UWORD32 uc_w, + UWORD32 uc_h, + UWORD32 ui16_sourceWidth, + UWORD32 ui16_toWidth) +{ + UWORD8 uc_i, uc_j; + + for(uc_i = 0; uc_i < uc_h; uc_i++) + { + memcpy(puc_To, puc_Source, uc_w); + puc_To += ui16_toWidth; + puc_Source += ui16_sourceWidth; + } +} + + +/*! + ************************************************************************** + * \if Function name : dma_2d1d \endif + * + * \brief + * 2D -> 1D linear DMA into the reference buffers + * + * \return + * None + ************************************************************************** + */ +void ih264d_copy_2d1d(UWORD8 *puc_src, + UWORD8 *puc_dest, + UWORD16 ui16_srcWidth, + UWORD16 ui16_widthToFill, + UWORD16 ui16_heightToFill) +{ + UWORD32 uc_w, uc_h; + for(uc_h = ui16_heightToFill; uc_h != 0; uc_h--) + { + memcpy(puc_dest, puc_src, ui16_widthToFill); + puc_dest += ui16_widthToFill; + puc_src += ui16_srcWidth; + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_fill_pred_info \endif + * + * \brief + * Fills inter prediction related info + * + * \return + * None + ************************************************************************** + */ +void ih264d_fill_pred_info(WORD16 *pi2_mv,WORD32 part_width,WORD32 part_height, WORD32 sub_mb_num, + WORD32 pred_dir,pred_info_pkd_t *ps_pred_pkd,WORD8 i1_buf_id, + WORD8 i1_ref_idx,UWORD32 *pu4_wt_offset,UWORD8 u1_pic_type) +{ + WORD32 insert_bits; + + ps_pred_pkd->i2_mv[0] = pi2_mv[0]; + ps_pred_pkd->i2_mv[1] = pi2_mv[1]; + + insert_bits = sub_mb_num & 3; /*sub mb x*/ + ps_pred_pkd->i1_size_pos_info = insert_bits; + insert_bits = sub_mb_num >> 2;/*sub mb y*/ + ps_pred_pkd->i1_size_pos_info |= insert_bits << 2; + insert_bits = part_width >> 1; + ps_pred_pkd->i1_size_pos_info |= insert_bits << 4; + insert_bits = part_height >> 1; + ps_pred_pkd->i1_size_pos_info |= insert_bits << 6; + + ps_pred_pkd->i1_ref_idx_info = i1_ref_idx; + ps_pred_pkd->i1_ref_idx_info |= (pred_dir << 6); + ps_pred_pkd->i1_buf_id = i1_buf_id; + ps_pred_pkd->pu4_wt_offst = pu4_wt_offset; + ps_pred_pkd->u1_pic_type = u1_pic_type; + + +} + + + + + + + +/*****************************************************************************/ +/* \if Function name : formMbPartInfo \endif */ +/* */ +/* \brief */ +/* Form the Mb partition information structure, to be used by the MC */ +/* routine */ +/* */ +/* \return */ +/* None */ +/* \note */ +/* c_bufx is used to select PredBuffer, */ +/* if it's only Forward/Backward prediction always buffer used is */ +/* puc_MbLumaPredBuffer[0 to X1],pu1_mb_cb_pred_buffer[0 to X1] and */ +/* pu1_mb_cr_pred_buffer[0 to X1] */ +/* */ +/* if it's bidirect for forward ..PredBuffer[0 to X1] buffer is used and */ +/* ..PredBuffer[X2 to X3] for backward prediction. and */ +/* */ +/* Final predicted samples values are the average of ..PredBuffer[0 to X1]*/ +/* and ..PredBuffer[X2 to X3] */ +/* */ +/* X1 is 255 for Luma and 63 for Chroma */ +/* X2 is 256 for Luma and 64 for Chroma */ +/* X3 is 511 for Luma and 127 for Chroma */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 11 05 2005 SWRN Modified to handle pod */ +/*****************************************************************************/ + +WORD32 ih264d_form_mb_part_info_bp(pred_info_pkd_t *ps_pred_pkd, + dec_struct_t * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info) +{ + /* The reference buffer pointer */ + WORD32 i2_frm_x, i2_frm_y; + WORD32 i2_tmp_mv_x, i2_tmp_mv_y; + WORD32 i2_rec_x, i2_rec_y; + + WORD32 u2_pic_ht; + WORD32 u2_frm_wd; + WORD32 u2_rec_wd; + UWORD8 u1_sub_x = 0,u1_sub_y=0 ; + UWORD8 u1_part_wd = 0,u1_part_ht = 0; + WORD16 i2_mv_x,i2_mv_y; + + + + /********************************************/ + /* i1_mc_wd width reqd for mcomp */ + /* u1_dma_ht height reqd for mcomp */ + /* u1_dma_wd width aligned to 4 bytes */ + /* u1_dx fractional part of width */ + /* u1_dx fractional part of height */ + /********************************************/ + WORD32 u1_ofst_in_word; + UWORD32 i1_mc_wd; + + WORD32 u1_dma_ht; + + UWORD32 u1_dma_wd; + UWORD32 u1_dx; + UWORD32 u1_dy; + pred_info_t * ps_pred = ps_dec->ps_pred + ps_dec->u4_pred_info_idx; + dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice; + tfr_ctxt_t *ps_frame_buf; + struct pic_buffer_t *ps_ref_frm; + UWORD8 u1_scale_ref,u1_mbaff,u1_field; + pic_buffer_t **pps_ref_frame; + WORD8 i1_size_pos_info,i1_buf_id; + + PROFILE_DISABLE_MB_PART_INFO() + + UNUSED(ps_cur_mb_info); + i1_size_pos_info = ps_pred_pkd->i1_size_pos_info; + GET_XPOS_PRED(u1_sub_x,i1_size_pos_info); + GET_YPOS_PRED(u1_sub_y,i1_size_pos_info); + GET_WIDTH_PRED(u1_part_wd,i1_size_pos_info); + GET_HEIGHT_PRED(u1_part_ht,i1_size_pos_info); + i2_mv_x = ps_pred_pkd->i2_mv[0]; + i2_mv_y = ps_pred_pkd->i2_mv[1]; + i1_buf_id = ps_pred_pkd->i1_buf_id; + + + ps_ref_frm = ps_dec->apv_buf_id_pic_buf_map[i1_buf_id]; + + + { + ps_frame_buf = &ps_dec->s_tran_addrecon; + } + + + /* Transfer Setup Y */ + { + UWORD8 *pu1_pred, *pu1_rec; + + /* calculating rounded motion vectors and fractional components */ + i2_tmp_mv_x = i2_mv_x; + i2_tmp_mv_y = i2_mv_y; + u1_dx = i2_tmp_mv_x & 0x3; + u1_dy = i2_tmp_mv_y & 0x3; + i2_tmp_mv_x >>= 2; + i2_tmp_mv_y >>= 2; + i1_mc_wd = u1_part_wd << 2; + u1_dma_ht = u1_part_ht << 2; + if(u1_dx) + { + i2_tmp_mv_x -= 2; + i1_mc_wd += 5; + } + if(u1_dy) + { + i2_tmp_mv_y -= 2; + u1_dma_ht += 5; + } + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the reference frame, and subsequent clipping */ + /********************************************************************/ + u2_pic_ht = ps_dec->u2_pic_ht; + u2_frm_wd = ps_dec->u2_frm_wd_y; + i2_rec_x = u1_sub_x << 2; + i2_rec_y = u1_sub_y << 2; + + i2_frm_x = (u2_mb_x << 4) + i2_rec_x + i2_tmp_mv_x; + i2_frm_y = (u2_mb_y << 4) + i2_rec_y + i2_tmp_mv_y; + + i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_X_FRM, (ps_dec->u2_pic_wd - 1), + i2_frm_x); + i2_frm_y = CLIP3(((1 - u1_dma_ht)), (u2_pic_ht - (1)), i2_frm_y); + + pu1_pred = ps_ref_frm->pu1_buf1 + i2_frm_y * u2_frm_wd + i2_frm_x; + + + u1_ofst_in_word = 0; + u1_dma_wd = (i1_mc_wd + u1_ofst_in_word + 3) & 0xFC; + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the recon buffer */ + /********************************************************************/ + /* CHANGED CODE */ + u2_rec_wd = MB_SIZE; + { + u2_rec_wd = ps_dec->u2_frm_wd_y; + i2_rec_x += (mb_index << 4); + pu1_rec = ps_frame_buf->pu1_dest_y + i2_rec_y * u2_rec_wd + + i2_rec_x; + } + + /* CHANGED CODE */ + + /* filling the pred and dma structures for Y */ + u2_frm_wd = ps_dec->u2_frm_wd_y; + + ps_pred->u2_u1_ref_buf_wd = u1_dma_wd; + ps_pred->i1_dma_ht = u1_dma_ht; + ps_pred->i1_mc_wd = i1_mc_wd; + ps_pred->u2_frm_wd = u2_frm_wd; + ps_pred->pu1_rec_y_u = pu1_rec; + ps_pred->u2_dst_stride = u2_rec_wd; + + ps_pred->i1_mb_partwidth = u1_part_wd << 2; + ps_pred->i1_mb_partheight = u1_part_ht << 2; + ps_pred->u1_mc_addr_ofst = u1_ofst_in_word; + ps_pred->u1_dydx = (u1_dy << 2) + u1_dx; + + ps_pred->pu1_y_ref = pu1_pred; + + } + + /* Increment ps_pred index */ + ps_pred++; + + /* Transfer Setup U & V */ + { + WORD32 i4_ref_offset, i4_rec_offset; + UWORD8 *pu1_pred_u, *pu1_pred_v; + + + /* calculating rounded motion vectors and fractional components */ + i2_tmp_mv_x = i2_mv_x; + i2_tmp_mv_y = i2_mv_y; + + /************************************************************************/ + /* Table 8-9: Derivation of the vertical component of the chroma vector */ + /* in field coding mode */ + /************************************************************************/ + + /* Eighth sample of the chroma MV */ + u1_dx = i2_tmp_mv_x & 0x7; + u1_dy = i2_tmp_mv_y & 0x7; + + /********************************************************************/ + /* Calculating the full pel MV for chroma which is 1/2 of the Luma */ + /* MV in full pel units */ + /********************************************************************/ + i2_mv_x = i2_tmp_mv_x; + i2_mv_y = i2_tmp_mv_y; + i2_tmp_mv_x = SIGN_POW2_DIV(i2_tmp_mv_x, 3); + i2_tmp_mv_y = SIGN_POW2_DIV(i2_tmp_mv_y, 3); + i1_mc_wd = u1_part_wd << 1; + u1_dma_ht = u1_part_ht << 1; + if(u1_dx) + { + i2_tmp_mv_x -= (i2_mv_x < 0); + i1_mc_wd++; + } + if(u1_dy != 0) + { + i2_tmp_mv_y -= (i2_mv_y < 0); + u1_dma_ht++; + } + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the reference frame, and subsequent clipping */ + /********************************************************************/ + u2_pic_ht >>= 1; + u2_frm_wd = ps_dec->u2_frm_wd_uv; + i2_rec_x = u1_sub_x << 1; + i2_rec_y = u1_sub_y << 1; + + i2_frm_x = (u2_mb_x << 3) + i2_rec_x + i2_tmp_mv_x; + i2_frm_y = (u2_mb_y << 3) + i2_rec_y + i2_tmp_mv_y; + + i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_UV_FRM, + ((ps_dec->u2_pic_wd >> 1) - 1), i2_frm_x); + i2_frm_y = CLIP3(((1 - u1_dma_ht)), (u2_pic_ht - (1)), i2_frm_y); + + i4_ref_offset = i2_frm_y * u2_frm_wd + i2_frm_x * YUV420SP_FACTOR; + u1_ofst_in_word = 0; + u1_dma_wd = (i1_mc_wd + u1_ofst_in_word + 3) & 0xFC; + i4_ref_offset -= u1_ofst_in_word; + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the recon buffer */ + /********************************************************************/ + /* CHANGED CODE */ + u2_rec_wd = BLK8x8SIZE * YUV420SP_FACTOR; + i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR; + + { + u2_rec_wd = ps_dec->u2_frm_wd_uv; + i2_rec_x += (mb_index << 3); + i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR; + ps_pred->pu1_rec_y_u = ps_frame_buf->pu1_dest_u + i4_rec_offset; + ps_pred->u1_pi1_wt_ofst_rec_v = ps_frame_buf->pu1_dest_v + + i4_rec_offset; + } + + /* CHANGED CODE */ + + /* filling the common pred structures for U */ + u2_frm_wd = ps_dec->u2_frm_wd_uv; + + ps_pred->u2_u1_ref_buf_wd = u1_dma_wd; + ps_pred->i1_dma_ht = u1_dma_ht; + ps_pred->i1_mc_wd = i1_mc_wd; + + ps_pred->u2_frm_wd = u2_frm_wd; + ps_pred->u2_dst_stride = u2_rec_wd; + + ps_pred->i1_mb_partwidth = u1_part_wd << 1; + ps_pred->i1_mb_partheight = u1_part_ht << 1; + ps_pred->u1_mc_addr_ofst = u1_ofst_in_word; + ps_pred->u1_dydx = (u1_dy << 3) + u1_dx; + + pu1_pred_u = ps_ref_frm->pu1_buf2 + i4_ref_offset; + pu1_pred_v = ps_ref_frm->pu1_buf3 + i4_ref_offset; + + /* Copy U & V partitions */ + ps_pred->pu1_u_ref = pu1_pred_u; + + /* Increment the reference buffer Index */ + ps_pred->pu1_v_ref = pu1_pred_v; + } + + /* Increment ps_pred index */ + ps_dec->u4_pred_info_idx += 2; + + return OK; + +} + + +/*****************************************************************************/ +/* \if Function name : formMbPartInfo \endif */ +/* */ +/* \brief */ +/* Form the Mb partition information structure, to be used by the MC */ +/* routine */ +/* */ +/* \return */ +/* None */ +/* \note */ +/* c_bufx is used to select PredBuffer, */ +/* if it's only Forward/Backward prediction always buffer used is */ +/* puc_MbLumaPredBuffer[0 to X1],pu1_mb_cb_pred_buffer[0 to X1] and */ +/* pu1_mb_cr_pred_buffer[0 to X1] */ +/* */ +/* if it's bidirect for forward ..PredBuffer[0 to X1] buffer is used and */ +/* ..PredBuffer[X2 to X3] for backward prediction. and */ +/* */ +/* Final predicted samples values are the average of ..PredBuffer[0 to X1]*/ +/* and ..PredBuffer[X2 to X3] */ +/* */ +/* X1 is 255 for Luma and 63 for Chroma */ +/* X2 is 256 for Luma and 64 for Chroma */ +/* X3 is 511 for Luma and 127 for Chroma */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 11 05 2005 SWRN Modified to handle pod */ +/*****************************************************************************/ +WORD32 ih264d_form_mb_part_info_mp(pred_info_pkd_t *ps_pred_pkd, + dec_struct_t * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info) +{ + /* The reference buffer pointer */ + UWORD8 *pu1_ref_buf; + WORD16 i2_frm_x, i2_frm_y, i2_tmp_mv_x, i2_tmp_mv_y, i2_pod_ht; + WORD16 i2_rec_x, i2_rec_y; + UWORD16 u2_pic_ht, u2_frm_wd, u2_rec_wd; + UWORD8 u1_wght_pred_type, u1_wted_bipred_idc; + UWORD16 u2_tot_ref_scratch_size; + UWORD8 u1_sub_x = 0; + UWORD8 u1_sub_y = 0; + UWORD8 u1_is_bi_dir = 0; + + /********************************************/ + /* i1_mc_wd width reqd for mcomp */ + /* u1_dma_ht height reqd for mcomp */ + /* u1_dma_wd width aligned to 4 bytes */ + /* u1_dx fractional part of width */ + /* u1_dx fractional part of height */ + /********************************************/ + UWORD8 u1_ofst_in_word, i1_mc_wd, u1_dma_ht, u1_dma_wd, u1_dx, u1_dy; + pred_info_t * ps_pred ; + dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice; + const UWORD8 u1_slice_type = ps_cur_slice->u1_slice_type; + UWORD8 u1_pod_bot, u1_pod_top; + + /* load the pictype for pod u4_flag & chroma motion vector derivation */ + UWORD8 u1_ref_pic_type ; + + /* set default value to flags specifying field nature of picture & mb */ + UWORD32 u1_mb_fld = 0, u1_mb_or_pic_fld; + UWORD32 u1_mb_bot = 0, u1_pic_bot = 0, u1_mb_or_pic_bot; + tfr_ctxt_t *ps_frame_buf; + /* calculate flags specifying field nature of picture & mb */ + const UWORD32 u1_pic_fld = ps_cur_slice->u1_field_pic_flag; + WORD8 i1_pred; + WORD8 i1_size_pos_info,i1_buf_id,i1_ref_idx; + UWORD8 u1_part_wd,u1_part_ht; + WORD16 i2_mv_x,i2_mv_y; + struct pic_buffer_t *ps_ref_frm; + UWORD32 *pu4_wt_offset; + UWORD8 *pu1_buf1,*pu1_buf2,*pu1_buf3; + + + PROFILE_DISABLE_MB_PART_INFO() + + ps_pred = ps_dec->ps_pred + ps_dec->u4_pred_info_idx; + + + i1_size_pos_info = ps_pred_pkd->i1_size_pos_info; + GET_XPOS_PRED(u1_sub_x,i1_size_pos_info); + GET_YPOS_PRED(u1_sub_y,i1_size_pos_info); + GET_WIDTH_PRED(u1_part_wd,i1_size_pos_info); + GET_HEIGHT_PRED(u1_part_ht,i1_size_pos_info); + i2_mv_x = ps_pred_pkd->i2_mv[0]; + i2_mv_y = ps_pred_pkd->i2_mv[1]; + i1_ref_idx = ps_pred_pkd->i1_ref_idx_info & 0x3f; + i1_buf_id = ps_pred_pkd->i1_buf_id; + ps_ref_frm = ps_dec->apv_buf_id_pic_buf_map[i1_buf_id]; + + i1_pred = (ps_pred_pkd->i1_ref_idx_info & 0xC0) >> 6; + u1_is_bi_dir = (i1_pred == BI_PRED); + + + u1_ref_pic_type = ps_pred_pkd->u1_pic_type & PIC_MASK; + + pu1_buf1 = ps_ref_frm->pu1_buf1; + pu1_buf2 = ps_ref_frm->pu1_buf2; + pu1_buf3 = ps_ref_frm->pu1_buf3; + + if(u1_ref_pic_type == BOT_FLD) + { + pu1_buf1 += ps_ref_frm->u2_frm_wd_y; + pu1_buf2 += ps_ref_frm->u2_frm_wd_uv; + pu1_buf3 += ps_ref_frm->u2_frm_wd_uv; + + } + + + + if(ps_dec->ps_cur_pps->u1_wted_pred_flag) + { + pu4_wt_offset = (UWORD32*)&ps_dec->pu4_wt_ofsts[2 + * X3(i1_ref_idx)]; + } + + + pu4_wt_offset = ps_pred_pkd->pu4_wt_offst; + + + /* Pointer to the frame buffer */ + { + ps_frame_buf = &ps_dec->s_tran_addrecon; + /* CHANGED CODE */ + } + + if(!u1_pic_fld) + { + u1_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + u1_mb_bot = 1 - ps_cur_mb_info->u1_topmb; + } + else + u1_pic_bot = ps_cur_slice->u1_bottom_field_flag; + + /****************************************************************/ + /* calculating the flags the tell whether to use frame-padding */ + /* or use software pad-on-demand */ + /****************************************************************/ + u1_mb_or_pic_bot = u1_mb_bot | u1_pic_bot; + u1_mb_or_pic_fld = u1_mb_fld | u1_pic_fld; + u1_pod_bot = u1_mb_or_pic_fld && (u1_ref_pic_type == TOP_FLD); + u1_pod_top = u1_mb_or_pic_fld && (u1_ref_pic_type == BOT_FLD); + + /* Weighted Pred additions */ + u1_wted_bipred_idc = ps_dec->ps_cur_pps->u1_wted_bipred_idc; + + if((u1_slice_type == P_SLICE) || (u1_slice_type == SP_SLICE)) + { + /* P Slice only */ + u1_wght_pred_type = ps_dec->ps_cur_pps->u1_wted_pred_flag; + + } + else + { + /* B Slice only */ + u1_wght_pred_type = 1 + u1_is_bi_dir; + if(u1_wted_bipred_idc == 0) + u1_wght_pred_type = 0; + if((u1_wted_bipred_idc == 2) && (!u1_is_bi_dir)) + u1_wght_pred_type = 0; + } + /* load the scratch reference buffer index */ + pu1_ref_buf = ps_dec->pu1_ref_buff + ps_dec->u4_dma_buf_idx; + u2_tot_ref_scratch_size = 0; + + + /* Transfer Setup Y */ + { + UWORD8 *pu1_pred, *pu1_rec; + /* calculating rounded motion vectors and fractional components */ + i2_tmp_mv_x = i2_mv_x; + i2_tmp_mv_y = i2_mv_y; + + u1_dx = i2_tmp_mv_x & 0x3; + u1_dy = i2_tmp_mv_y & 0x3; + i2_tmp_mv_x >>= 2; + i2_tmp_mv_y >>= 2; + i1_mc_wd = u1_part_wd << 2; + u1_dma_ht = u1_part_ht << 2; + if(u1_dx) + { + i2_tmp_mv_x -= 2; + i1_mc_wd += 5; + } + if(u1_dy) + { + i2_tmp_mv_y -= 2; + u1_dma_ht += 5; + } + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the reference frame, and subsequent clipping */ + /********************************************************************/ + u2_pic_ht = ps_dec->u2_pic_ht >> u1_pic_fld; + u2_frm_wd = ps_dec->u2_frm_wd_y << u1_pic_fld; + i2_frm_x = (u2_mb_x << 4) + (u1_sub_x << 2) + i2_tmp_mv_x; + i2_frm_y = ((u2_mb_y + (u1_mb_bot && !u1_mb_fld)) << 4) + + (((u1_sub_y << 2) + i2_tmp_mv_y) << u1_mb_fld); + + i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_X_FRM, (ps_dec->u2_pic_wd - 1), + i2_frm_x); + i2_frm_y = CLIP3(((1 - u1_dma_ht) << u1_mb_fld), + (u2_pic_ht - (1 << u1_mb_fld)), i2_frm_y); + + pu1_pred = pu1_buf1 + i2_frm_y * u2_frm_wd + i2_frm_x; + u1_ofst_in_word = 0; + + u1_dma_wd = (i1_mc_wd + u1_ofst_in_word + 3) & 0xFC; + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the recon buffer */ + /********************************************************************/ + /* CHANGED CODE */ + u2_rec_wd = MB_SIZE; + i2_rec_x = u1_sub_x << 2; + i2_rec_y = u1_sub_y << 2; + { + u2_rec_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld; + i2_rec_x += (mb_index << 4); + pu1_rec = ps_frame_buf->pu1_dest_y + i2_rec_y * u2_rec_wd + + i2_rec_x; + if(u1_mb_bot) + pu1_rec += ps_dec->u2_frm_wd_y << ((u1_mb_fld) ? 0 : 4); + } + + /* CHANGED CODE */ + + /* filling the pred and dma structures for Y */ + u2_frm_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld; + + ps_pred->pu1_dma_dest_addr = pu1_ref_buf; + ps_pred->u2_u1_ref_buf_wd = u1_dma_wd; + ps_pred->u2_frm_wd = u2_frm_wd; + ps_pred->i1_dma_ht = u1_dma_ht; + ps_pred->i1_mc_wd = i1_mc_wd; + ps_pred->pu1_rec_y_u = pu1_rec; + ps_pred->u2_dst_stride = u2_rec_wd; + + ps_pred->i1_mb_partwidth = u1_part_wd << 2; + ps_pred->i1_mb_partheight = u1_part_ht << 2; + ps_pred->u1_mc_addr_ofst = u1_ofst_in_word; + ps_pred->u1_dydx = (u1_dy << 2) + u1_dx; + ps_pred->u1_is_bi_direct = u1_is_bi_dir; + ps_pred->u1_pi1_wt_ofst_rec_v = (UWORD8 *)pu4_wt_offset; + ps_pred->u1_wght_pred_type = u1_wght_pred_type; + ps_pred->i1_pod_ht = 0; + + /* Increment the Reference buffer Indices */ + pu1_ref_buf += u1_dma_wd * u1_dma_ht; + u2_tot_ref_scratch_size += u1_dma_wd * u1_dma_ht; + + /* unrestricted field motion comp for top region outside frame */ + i2_pod_ht = (-i2_frm_y) >> u1_mb_fld; + if((i2_pod_ht > 0) && u1_pod_top) + { + ps_pred->i1_pod_ht = (WORD8)(-i2_pod_ht); + u1_dma_ht -= i2_pod_ht; + pu1_pred += i2_pod_ht * u2_frm_wd; + } + /* unrestricted field motion comp for bottom region outside frame */ + else if(u1_pod_bot) + { + i2_pod_ht = u1_dma_ht + ((i2_frm_y - u2_pic_ht) >> u1_mb_fld); + if(i2_pod_ht > 0) + { + u1_dma_ht -= i2_pod_ht; + ps_pred->i1_pod_ht = (WORD8)i2_pod_ht; + } + } + + /* Copy Y partition */ + + /* + * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data + * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data + */ + if(ps_pred->i1_pod_ht) + { + ps_pred->pu1_pred = pu1_pred; + ps_pred->u1_dma_ht_y = u1_dma_ht; + ps_pred->u1_dma_wd_y = u1_dma_wd; + } + ps_pred->pu1_y_ref = pu1_pred; + } + + + + /* Increment ps_pred index */ + ps_pred++; + + /* Transfer Setup U & V */ + { + WORD32 i4_ref_offset, i4_rec_offset; + UWORD8 *pu1_pred_u, *pu1_pred_v, u1_tmp_dma_ht; + /* CHANGED CODE */ + UWORD8 u1_chroma_cbp = (UWORD8)(ps_cur_mb_info->u1_cbp >> 4); + /* CHANGED CODE */ + + /* calculating rounded motion vectors and fractional components */ + i2_tmp_mv_x = i2_mv_x; + i2_tmp_mv_y = i2_mv_y; + + /************************************************************************/ + /* Table 8-9: Derivation of the vertical component of the chroma vector */ + /* in field coding mode */ + /************************************************************************/ + if(u1_pod_bot && u1_mb_or_pic_bot) + i2_tmp_mv_y += 2; + if(u1_pod_top && !u1_mb_or_pic_bot) + i2_tmp_mv_y -= 2; + + /* Eighth sample of the chroma MV */ + u1_dx = i2_tmp_mv_x & 0x7; + u1_dy = i2_tmp_mv_y & 0x7; + + /********************************************************************/ + /* Calculating the full pel MV for chroma which is 1/2 of the Luma */ + /* MV in full pel units */ + /********************************************************************/ + i2_mv_x = i2_tmp_mv_x; + i2_mv_y = i2_tmp_mv_y; + i2_tmp_mv_x = SIGN_POW2_DIV(i2_tmp_mv_x, 3); + i2_tmp_mv_y = SIGN_POW2_DIV(i2_tmp_mv_y, 3); + i1_mc_wd = u1_part_wd << 1; + u1_dma_ht = u1_part_ht << 1; + if(u1_dx) + { + if(i2_mv_x < 0) + i2_tmp_mv_x -= 1; + i1_mc_wd++; + } + if(u1_dy != 0) + { + if(i2_mv_y < 0) + i2_tmp_mv_y -= 1; + u1_dma_ht++; + } + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the reference frame, and subsequent clipping */ + /********************************************************************/ + u2_pic_ht >>= 1; + u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_pic_fld; + i2_frm_x = (u2_mb_x << 3) + (u1_sub_x << 1) + i2_tmp_mv_x; + i2_frm_y = ((u2_mb_y + (u1_mb_bot && !u1_mb_fld)) << 3) + + (((u1_sub_y << 1) + i2_tmp_mv_y) << u1_mb_fld); + + i2_frm_x = CLIP3(MAX_OFFSET_OUTSIDE_UV_FRM, + ((ps_dec->u2_pic_wd >> 1) - 1), i2_frm_x); + i2_frm_y = CLIP3(((1 - u1_dma_ht) << u1_mb_fld), + (u2_pic_ht - (1 << u1_mb_fld)), i2_frm_y); + + i4_ref_offset = i2_frm_y * u2_frm_wd + i2_frm_x * YUV420SP_FACTOR; + u1_ofst_in_word = 0; + u1_dma_wd = (i1_mc_wd + u1_ofst_in_word + 3) & 0xFC; + i4_ref_offset -= u1_ofst_in_word; + + /********************************************************************/ + /* Calulating the horizontal and the vertical u4_ofst from top left */ + /* edge of the recon buffer */ + /********************************************************************/ + /* CHANGED CODE */ + u2_rec_wd = BLK8x8SIZE * YUV420SP_FACTOR; + i2_rec_x = u1_sub_x << 1; + i2_rec_y = u1_sub_y << 1; + i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR; + { + u2_rec_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld; + + i2_rec_x += (mb_index << 3); + i4_rec_offset = i2_rec_y * u2_rec_wd + i2_rec_x * YUV420SP_FACTOR; + if(u1_mb_bot) + i4_rec_offset += ps_dec->u2_frm_wd_uv << ((u1_mb_fld) ? 0 : 3); + ps_pred->pu1_rec_y_u = ps_frame_buf->pu1_dest_u + i4_rec_offset; + ps_pred->u1_pi1_wt_ofst_rec_v = ps_frame_buf->pu1_dest_v + + i4_rec_offset; + + } + + /* CHANGED CODE */ + + /* filling the common pred structures for U */ + u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld; + u1_tmp_dma_ht = u1_dma_ht; + ps_pred->u2_u1_ref_buf_wd = u1_dma_wd; + ps_pred->u2_frm_wd = u2_frm_wd; + ps_pred->i1_dma_ht = u1_dma_ht; + ps_pred->i1_mc_wd = i1_mc_wd; + ps_pred->u2_dst_stride = u2_rec_wd; + + ps_pred->i1_mb_partwidth = u1_part_wd << 1; + ps_pred->i1_mb_partheight = u1_part_ht << 1; + ps_pred->u1_mc_addr_ofst = u1_ofst_in_word; + ps_pred->u1_dydx = (u1_dy << 3) + u1_dx; + ps_pred->u1_is_bi_direct = u1_is_bi_dir; + ps_pred->u1_wght_pred_type = u1_wght_pred_type; + ps_pred->i1_pod_ht = 0; + + ps_pred->pu1_dma_dest_addr = pu1_ref_buf; + + /* unrestricted field motion comp for top region outside frame */ + i2_pod_ht = (-i2_frm_y) >> u1_mb_fld; + if((i2_pod_ht > 0) && u1_pod_top) + { + i4_ref_offset += i2_pod_ht * u2_frm_wd; + u1_dma_ht -= i2_pod_ht; + ps_pred->i1_pod_ht = (WORD8)(-i2_pod_ht); + } + /* unrestricted field motion comp for bottom region outside frame */ + else if(u1_pod_bot) + { + i2_pod_ht = u1_dma_ht + ((i2_frm_y - u2_pic_ht) >> u1_mb_fld); + if(i2_pod_ht > 0) + { + u1_dma_ht -= i2_pod_ht; + ps_pred->i1_pod_ht = (WORD8)i2_pod_ht; + } + } + + pu1_pred_u = pu1_buf2 + i4_ref_offset; + pu1_pred_v = pu1_buf3 + i4_ref_offset; + + /* Copy U & V partitions */ + if(ps_pred->i1_pod_ht) + { + ps_pred->pu1_pred_u = pu1_pred_u; + ps_pred->u1_dma_ht_uv = u1_dma_ht; + ps_pred->u1_dma_wd_uv = u1_dma_wd; + + } + ps_pred->pu1_u_ref = pu1_pred_u; + + /* Increment the reference buffer Index */ + u2_tot_ref_scratch_size += (u1_dma_wd * u1_tmp_dma_ht) << 1; + + if(ps_pred->i1_pod_ht) + { + ps_pred->pu1_pred_v = pu1_pred_v; + ps_pred->u1_dma_ht_uv = u1_dma_ht; + ps_pred->u1_dma_wd_uv = u1_dma_wd; + } + + ps_pred->pu1_v_ref = pu1_pred_v; + } + + /* Increment ps_pred index */ + ps_dec->u4_pred_info_idx += 2; + + + /* Increment the reference buffer Index */ + ps_dec->u4_dma_buf_idx += u2_tot_ref_scratch_size; + + if(ps_dec->u4_dma_buf_idx > ps_dec->u4_ref_buf_size) + return ERROR_NUM_MV; + + return OK; + + + +} + + +/*! + ************************************************************************** + * \if Function name : MotionCompensate \endif + * + * \brief + * The routine forms predictor blocks for the entire MB and stores it in + * predictor buffers.This function works only for BASELINE profile + * + * \param ps_dec: Pointer to the structure decStruct. This is used to get + * pointers to the current and the reference frame and to the MbParams + * structure. + * + * \return + * None + * + * \note + * The routine forms predictors for all the luma and the chroma MB + * partitions. + ************************************************************************** + */ + +void ih264d_motion_compensate_bp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info) +{ + pred_info_t *ps_pred ; + UWORD8 *puc_ref, *pu1_dest_y; + UWORD8 *pu1_dest_u; + UWORD32 u2_num_pels, u2_ref_wd_y, u2_ref_wd_uv, u2_dst_wd; + + UWORD32 u4_wd_y, u4_ht_y, u4_wd_uv; + UWORD32 u4_ht_uv; + UWORD8 *puc_pred0 = (UWORD8 *)(ps_dec->pi2_pred1); + + + PROFILE_DISABLE_INTER_PRED() + UNUSED(ps_cur_mb_info); + ps_pred = ps_dec->ps_pred ; + + for(u2_num_pels = 0; u2_num_pels < 256;) + { + UWORD32 uc_dx, uc_dy; + /* Pointer to the destination buffer. If the CBPs of all 8x8 blocks in + the MB partition are zero then it would be better to copy the + predictor valus directly to the current frame buffer */ + /* + * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data + * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data + */ + + u2_ref_wd_y = ps_pred->u2_frm_wd; + puc_ref = ps_pred->pu1_y_ref; + if(ps_pred->u1_dydx & 0x3) + puc_ref += 2; + if(ps_pred->u1_dydx >> 2) + puc_ref += 2 * u2_ref_wd_y; + + u4_wd_y = ps_pred->i1_mb_partwidth; + u4_ht_y = ps_pred->i1_mb_partheight; + uc_dx = ps_pred->u1_dydx; + uc_dy = uc_dx >> 2; + uc_dx &= 0x3; + + pu1_dest_y = ps_pred->pu1_rec_y_u; + u2_dst_wd = ps_pred->u2_dst_stride; + + ps_dec->apf_inter_pred_luma[ps_pred->u1_dydx](puc_ref, pu1_dest_y, + u2_ref_wd_y, + u2_dst_wd, + u4_ht_y, + u4_wd_y, puc_pred0, + ps_pred->u1_dydx); + + ps_pred++; + + /* Interpolate samples for the chroma components */ + { + UWORD8 *pu1_ref_u; + + u2_ref_wd_uv = ps_pred->u2_frm_wd; + pu1_ref_u = ps_pred->pu1_u_ref + ps_pred->u1_mc_addr_ofst; + + u4_wd_uv = ps_pred->i1_mb_partwidth; + u4_ht_uv = ps_pred->i1_mb_partheight; + uc_dx = ps_pred->u1_dydx; /* 8*dy + dx */ + uc_dy = uc_dx >> 3; + uc_dx &= 0x7; + + pu1_dest_u = ps_pred->pu1_rec_y_u; + u2_dst_wd = ps_pred->u2_dst_stride; + + ps_pred++; + ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_dest_u, u2_ref_wd_uv, + u2_dst_wd, uc_dx, uc_dy, + u4_ht_uv, u4_wd_uv); + + } + + u2_num_pels += (UWORD8)u4_wd_y * (UWORD8)u4_ht_y; + + } +} + + +/* + ************************************************************************** + * \if Function name : MotionCompensateB \endif + * + * \brief + * The routine forms predictor blocks for the entire MB and stores it in + * predictor buffers. + * + * \param ps_dec: Pointer to the structure decStruct. This is used to get + * pointers to the current and the reference frame and to the MbParams + * structure. + * + * \return + * None + * + * \note + * The routine forms predictors for all the luma and the chroma MB + * partitions. + ************************************************************************** + */ + +void ih264d_motion_compensate_mp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info) +{ + pred_info_t *ps_pred ; + pred_info_t *ps_pred_y_forw, *ps_pred_y_back, *ps_pred_cr_forw; + UWORD8 *puc_ref, *pu1_dest_y, *puc_pred0, *puc_pred1; + UWORD8 *pu1_dest_u, *pu1_dest_v; + WORD16 *pi16_intm; + UWORD32 u2_num_pels, u2_ref_wd_y, u2_ref_wd_uv, u2_dst_wd; + UWORD32 u2_dest_wd_y, u2_dest_wd_uv; + UWORD32 u2_row_buf_wd_y = ps_dec->u2_mb_group_cols_y1; + UWORD32 u2_row_buf_wd_uv = ps_dec->u2_mb_group_cols_cr1; + UWORD32 u2_log2Y_crwd = ps_dec->ps_cur_slice->u2_log2Y_crwd; + UWORD32 u4_wd_y, u4_ht_y, u1_dir, u4_wd_uv; + UWORD32 u4_ht_uv; + UWORD8 *pu1_temp_mc_buffer = ps_dec->pu1_temp_mc_buffer; + WORD32 i2_pod_ht; + UWORD32 u2_pic_ht, u2_frm_wd, u2_rec_wd; + UWORD32 u1_pod_bot, u1_pod_top; + UWORD8 *pu1_pred, *pu1_dma_dst; + UWORD32 u1_dma_wd, u1_dma_ht; + + dec_slice_params_t * const ps_cur_slice = ps_dec->ps_cur_slice; + + /* set default value to flags specifying field nature of picture & mb */ + UWORD32 u1_mb_fld = 0, u1_mb_or_pic_fld; + UWORD32 u1_mb_or_pic_bot; + /* calculate flags specifying field nature of picture & mb */ + const UWORD8 u1_pic_fld = ps_cur_slice->u1_field_pic_flag; + + PROFILE_DISABLE_INTER_PRED() + ps_pred = ps_dec->ps_pred ; + /* Initialize both ps_pred_y_forw an y_back to avoid static analysis warnigns */ + ps_pred_y_forw = ps_pred; + ps_pred_y_back = ps_pred; + + if(ps_dec->u1_separate_parse) + u2_log2Y_crwd = ps_dec->ps_decode_cur_slice->u2_log2Y_crwd; + + if(!u1_pic_fld) + { + u1_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + } + + u1_mb_or_pic_fld = u1_mb_fld | u1_pic_fld; + + pi16_intm = ps_dec->pi2_pred1; + puc_pred0 = (UWORD8 *)pi16_intm; + puc_pred1 = puc_pred0 + MB_SIZE * MB_SIZE; + + for(u2_num_pels = 0; u2_num_pels < 256;) + { + UWORD8 uc_dx, uc_dy; + const UWORD8 u1_is_bi_direct = ps_pred->u1_is_bi_direct; + for(u1_dir = 0; u1_dir <= u1_is_bi_direct; u1_dir++) + { + /* Pointer to the destination buffer. If the CBPs of all 8x8 blocks in + the MB partition are zero then it would be better to copy the + predictor valus directly to the current frame buffer */ + /* + * ps_pred->i1_pod_ht is non zero when MBAFF is present. In case of MBAFF the reference data + * is copied in the Scrath buffer so that the padding_on_demand doesnot corrupt the frame data + */ + + if(ps_pred->i1_pod_ht) + { + u2_ref_wd_y = ps_pred->u2_u1_ref_buf_wd; + puc_ref = ps_pred->pu1_dma_dest_addr; + } + else + { + u2_ref_wd_y = ps_pred->u2_frm_wd; + puc_ref = ps_pred->pu1_y_ref; + + } + + if(ps_pred->u1_dydx & 0x3) + puc_ref += 2; + if(ps_pred->u1_dydx >> 2) + puc_ref += 2 * u2_ref_wd_y; + u4_wd_y = ps_pred->i1_mb_partwidth; + u4_ht_y = ps_pred->i1_mb_partheight; + + if(ps_pred->i1_pod_ht) + { + pu1_pred = ps_pred->pu1_pred; + pu1_dma_dst = ps_pred->pu1_dma_dest_addr; + u1_dma_wd = ps_pred->u1_dma_wd_y; + u1_dma_ht = ps_pred->u1_dma_ht_y; + u2_frm_wd = ps_dec->u2_frm_wd_y << u1_mb_or_pic_fld; + } + + uc_dx = ps_pred->u1_dydx; + uc_dy = uc_dx >> 2; + uc_dx &= 0x3; + if(u1_dir == 0) + { + pu1_dest_y = ps_pred->pu1_rec_y_u; + u2_row_buf_wd_y = ps_pred->u2_dst_stride; + u2_dst_wd = ps_pred->u2_dst_stride; + u2_dest_wd_y = u2_dst_wd; + ps_pred_y_forw = ps_pred; + } + else + { + pu1_dest_y = pu1_temp_mc_buffer; + u2_dst_wd = MB_SIZE; + u2_dest_wd_y = u2_dst_wd; + ps_pred_y_back = ps_pred; + ps_pred_y_back->pu1_rec_y_u = pu1_dest_y; + } + + /* padding on demand (POD) for y done here */ + + if(ps_pred->i1_pod_ht) + { + if(ps_pred->i1_pod_ht < 0) + { + pu1_dma_dst = + pu1_dma_dst + - (ps_pred->i1_pod_ht + * ps_pred->u2_u1_ref_buf_wd); + } + ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd, u1_dma_wd, + u1_dma_ht); + ih264d_pad_on_demand(ps_pred, LUM_BLK); + } + ps_dec->apf_inter_pred_luma[ps_pred->u1_dydx](puc_ref, pu1_dest_y, + u2_ref_wd_y, + u2_dst_wd, + u4_ht_y, + u4_wd_y, + puc_pred0, + ps_pred->u1_dydx); + ps_pred++; + + /* Interpolate samples for the chroma components */ + { + UWORD8 *pu1_ref_u; + UWORD32 u1_dma_ht; + + /* padding on demand (POD) for U and V done here */ + u1_dma_ht = ps_pred->i1_dma_ht; + + if(ps_pred->i1_pod_ht) + { + pu1_pred = ps_pred->pu1_pred_u; + pu1_dma_dst = ps_pred->pu1_dma_dest_addr; + u1_dma_ht = ps_pred->u1_dma_ht_uv; + u1_dma_wd = ps_pred->u1_dma_wd_uv * YUV420SP_FACTOR; + u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld; + if(ps_pred->i1_pod_ht < 0) + { + /*Top POD*/ + pu1_dma_dst -= (ps_pred->i1_pod_ht + * ps_pred->u2_u1_ref_buf_wd + * YUV420SP_FACTOR); + } + + ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd, + u1_dma_wd, u1_dma_ht); + + pu1_dma_dst += (ps_pred->i1_dma_ht + * ps_pred->u2_u1_ref_buf_wd); + pu1_pred = ps_pred->pu1_pred_v; + + ih264d_pad_on_demand(ps_pred, CHROM_BLK); + } + + if(ps_pred->i1_pod_ht) + { + pu1_ref_u = ps_pred->pu1_dma_dest_addr; + + u2_ref_wd_uv = ps_pred->u2_u1_ref_buf_wd + * YUV420SP_FACTOR; + } + else + { + u2_ref_wd_uv = ps_pred->u2_frm_wd; + pu1_ref_u = ps_pred->pu1_u_ref; + + } + + u4_wd_uv = ps_pred->i1_mb_partwidth; + u4_ht_uv = ps_pred->i1_mb_partheight; + uc_dx = ps_pred->u1_dydx; /* 8*dy + dx */ + uc_dy = uc_dx >> 3; + uc_dx &= 0x7; + if(u1_dir == 0) + { + pu1_dest_u = ps_pred->pu1_rec_y_u; + + pu1_dest_v = ps_pred->u1_pi1_wt_ofst_rec_v; + u2_row_buf_wd_uv = ps_pred->u2_dst_stride; + u2_dst_wd = ps_pred->u2_dst_stride; + u2_dest_wd_uv = u2_dst_wd; + ps_pred_cr_forw = ps_pred; + } + else + { + pu1_dest_u = puc_pred0; + + pu1_dest_v = puc_pred1; + u2_dest_wd_uv = BUFFER_WIDTH; + u2_dst_wd = BUFFER_WIDTH; + ps_pred->pu1_rec_y_u = pu1_dest_u; + ps_pred->u1_pi1_wt_ofst_rec_v = pu1_dest_v; + } + + ps_pred++; + ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_dest_u, + u2_ref_wd_uv, u2_dst_wd, + uc_dx, uc_dy, u4_ht_uv, + u4_wd_uv); + + if(ps_cur_mb_info->u1_Mux == 1) + { + /******************************************************************/ + /* padding on demand (POD) for U and V done here */ + /* ps_pred now points to the Y entry of the 0,0 component */ + /* Y need not be checked for POD because Y lies within */ + /* the picture((0,0) mv for Y doesnot get changed. But (0,0) for */ + /* U and V can need POD beacause of cross-field mv adjustments */ + /* (Table 8-9 of standard) */ + /******************************************************************/ + if((ps_pred + 1)->i1_pod_ht) + + { + + pu1_pred = (ps_pred + 1)->pu1_pred_u; + pu1_dma_dst = (ps_pred + 1)->pu1_dma_dest_addr; + u1_dma_ht = (ps_pred + 1)->u1_dma_ht_uv; + u1_dma_wd = (ps_pred + 1)->u1_dma_wd_uv + * YUV420SP_FACTOR; + u2_frm_wd = ps_dec->u2_frm_wd_uv << u1_mb_or_pic_fld; + if((ps_pred + 1)->i1_pod_ht < 0) + { + /*Top POD*/ + pu1_dma_dst -= ((ps_pred + 1)->i1_pod_ht + * (ps_pred + 1)->u2_u1_ref_buf_wd + * YUV420SP_FACTOR); + } + ih264d_copy_2d1d(pu1_pred, pu1_dma_dst, u2_frm_wd, + u1_dma_wd, u1_dma_ht); + pu1_dma_dst += ((ps_pred + 1)->i1_dma_ht + * (ps_pred + 1)->u2_u1_ref_buf_wd); //(u1_dma_ht * u1_dma_wd);// + pu1_pred = (ps_pred + 1)->pu1_pred_v; + ih264d_pad_on_demand(ps_pred + 1, CHROM_BLK); + + } + + ih264d_multiplex_ref_data(ps_dec, ps_pred, pu1_dest_y, + pu1_dest_u, pu1_dest_v, ps_cur_mb_info, + u2_dest_wd_y, u2_dest_wd_uv, + u1_dir); + ps_pred += 2; + } + } + } + if(u1_dir != 0) + u2_ref_wd_y = MB_SIZE; + + u2_num_pels += u4_wd_y * u4_ht_y; + /* if BI_DIRECT, average the two pred's, and put in ..PredBuffer[0] */ + if((u1_is_bi_direct != 0) || (ps_pred_y_forw->u1_wght_pred_type != 0)) + { + + switch(ps_pred_y_forw->u1_wght_pred_type) + { + case 0: + ps_dec->pf_default_weighted_pred_luma( + ps_pred_y_forw->pu1_rec_y_u, pu1_dest_y, + ps_pred_y_forw->pu1_rec_y_u, + u2_row_buf_wd_y, u2_ref_wd_y, + u2_row_buf_wd_y, u4_ht_uv * 2, + u4_wd_uv * 2); + + ps_dec->pf_default_weighted_pred_chroma( + ps_pred_cr_forw->pu1_rec_y_u, pu1_dest_u, + ps_pred_cr_forw->pu1_rec_y_u, + u2_row_buf_wd_uv, u2_dst_wd, + u2_row_buf_wd_uv, u4_ht_uv, + u4_wd_uv); + + break; + case 1: + { + UWORD32 *pu4_weight_ofst = + (UWORD32*)ps_pred_y_forw->u1_pi1_wt_ofst_rec_v; + UWORD32 u4_wt_ofst_u, u4_wt_ofst_v; + UWORD32 u4_wt_ofst_y = + (UWORD32)(pu4_weight_ofst[0]); + WORD32 weight = (WORD16)(u4_wt_ofst_y & 0xffff); + WORD32 ofst = (WORD8)(u4_wt_ofst_y >> 16); + + ps_dec->pf_weighted_pred_luma(ps_pred_y_forw->pu1_rec_y_u, + ps_pred_y_forw->pu1_rec_y_u, + u2_row_buf_wd_y, + u2_row_buf_wd_y, + (u2_log2Y_crwd & 0x0ff), + weight, ofst, u4_ht_y, + u4_wd_y); + + u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[2]); + u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[4]); + weight = ((u4_wt_ofst_v & 0xffff) << 16) + | (u4_wt_ofst_u & 0xffff); + ofst = ((u4_wt_ofst_v >> 16) << 8) + | ((u4_wt_ofst_u >> 16) & 0xFF); + + ps_dec->pf_weighted_pred_chroma( + ps_pred_cr_forw->pu1_rec_y_u, + ps_pred_cr_forw->pu1_rec_y_u, + u2_row_buf_wd_uv, u2_row_buf_wd_uv, + (u2_log2Y_crwd >> 8), weight, ofst, + u4_ht_y >> 1, u4_wd_y >> 1); + } + + break; + case 2: + { + UWORD32 *pu4_weight_ofst = + (UWORD32*)ps_pred_y_forw->u1_pi1_wt_ofst_rec_v; + UWORD32 u4_wt_ofst_u, u4_wt_ofst_v; + UWORD32 u4_wt_ofst_y; + WORD32 weight1, weight2; + WORD32 ofst1, ofst2; + + u4_wt_ofst_y = (UWORD32)(pu4_weight_ofst[0]); + + weight1 = (WORD16)(u4_wt_ofst_y & 0xffff); + ofst1 = (WORD8)(u4_wt_ofst_y >> 16); + + u4_wt_ofst_y = (UWORD32)(pu4_weight_ofst[1]); + weight2 = (WORD16)(u4_wt_ofst_y & 0xffff); + ofst2 = (WORD8)(u4_wt_ofst_y >> 16); + + ps_dec->pf_weighted_bi_pred_luma(ps_pred_y_forw->pu1_rec_y_u, + ps_pred_y_back->pu1_rec_y_u, + ps_pred_y_forw->pu1_rec_y_u, + u2_row_buf_wd_y, + u2_ref_wd_y, + u2_row_buf_wd_y, + (u2_log2Y_crwd & 0x0ff), + weight1, weight2, ofst1, + ofst2, u4_ht_y, + u4_wd_y); + + u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[2]); + u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[4]); + weight1 = ((u4_wt_ofst_v & 0xffff) << 16) + | (u4_wt_ofst_u & 0xffff); + ofst1 = ((u4_wt_ofst_v >> 16) << 8) + | ((u4_wt_ofst_u >> 16) & 0xFF); + + u4_wt_ofst_u = (UWORD32)(pu4_weight_ofst[3]); + u4_wt_ofst_v = (UWORD32)(pu4_weight_ofst[5]); + weight2 = ((u4_wt_ofst_v & 0xffff) << 16) + | (u4_wt_ofst_u & 0xffff); + ofst2 = ((u4_wt_ofst_v >> 16) << 8) + | ((u4_wt_ofst_u >> 16) & 0xFF); + + ps_dec->pf_weighted_bi_pred_chroma( + (ps_pred_y_forw + 1)->pu1_rec_y_u, + (ps_pred_y_back + 1)->pu1_rec_y_u, + (ps_pred_y_forw + 1)->pu1_rec_y_u, + u2_row_buf_wd_uv, u2_dst_wd, + u2_row_buf_wd_uv, (u2_log2Y_crwd >> 8), + weight1, weight2, ofst1, ofst2, + u4_ht_y >> 1, u4_wd_y >> 1); + } + + break; + } + + } + } +} + + +/*! + ************************************************************************** + * \if Function name : ih264d_multiplex_ref_data \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +void ih264d_multiplex_ref_data(dec_struct_t * ps_dec, + pred_info_t *ps_pred, + UWORD8* pu1_dest_y, + UWORD8* pu1_dest_u, + UWORD8* pu1_dest_v, + dec_mb_info_t *ps_cur_mb_info, + UWORD16 u2_dest_wd_y, + UWORD16 u2_dest_wd_uv, + UWORD8 u1_dir) +{ + UWORD16 u2_mask = ps_cur_mb_info->u2_mask[u1_dir]; + UWORD8 *pu1_ref_y, *pu1_ref_u, *pu1_ref_v; + UWORD8 uc_cond, i, j, u1_dydx; + UWORD16 u2_ref_wd_y, u2_ref_wd_uv; + + PROFILE_DISABLE_INTER_PRED() + + if(ps_pred->i1_pod_ht) + { + pu1_ref_y = ps_pred->pu1_dma_dest_addr + ps_pred->u1_mc_addr_ofst; + + u2_ref_wd_y = ps_pred->u2_u1_ref_buf_wd; + } + else + { + pu1_ref_y = ps_pred->pu1_y_ref + ps_pred->u1_mc_addr_ofst; + u2_ref_wd_y = ps_pred->u2_frm_wd; + } + + ps_pred++; + if(ps_pred->i1_pod_ht) + { + pu1_ref_u = ps_pred->pu1_dma_dest_addr + ps_pred->u1_mc_addr_ofst; + pu1_ref_v = pu1_ref_u + ps_pred->u2_u1_ref_buf_wd * ps_pred->i1_dma_ht; + u2_ref_wd_uv = ps_pred->u2_u1_ref_buf_wd * YUV420SP_FACTOR; + + } + else + { + pu1_ref_u = ps_pred->pu1_u_ref + ps_pred->u1_mc_addr_ofst; + pu1_ref_v = ps_pred->pu1_v_ref + ps_pred->u1_mc_addr_ofst; + u2_ref_wd_uv = ps_pred->u2_frm_wd; + + } + + u1_dydx = ps_pred->u1_dydx; + + { + UWORD8 uc_dx, uc_dy; + UWORD8 *pu1_scratch_v, *pu1_scratch_u; + + uc_dx = u1_dydx & 0x3; + uc_dy = u1_dydx >> 3; + if(u1_dydx != 0) + { + pred_info_t * ps_prv_pred = ps_pred - 2; + pu1_scratch_u = ps_prv_pred->pu1_dma_dest_addr + + ps_prv_pred->u1_mc_addr_ofst; + pu1_scratch_v = pu1_scratch_u + + ps_prv_pred->u2_u1_ref_buf_wd + * ps_prv_pred->i1_dma_ht; + ps_dec->pf_inter_pred_chroma(pu1_ref_u, pu1_scratch_u, + u2_ref_wd_uv, 16, uc_dx, uc_dy, 8, + 8); + + /* Modify ref pointer and refWidth to point to scratch */ + /* buffer to be used below in ih264d_copy_multiplex_data functions */ + /* CHANGED CODE */ + pu1_ref_u = pu1_scratch_u; + pu1_ref_v = pu1_scratch_v; + u2_ref_wd_uv = 8 * YUV420SP_FACTOR; + } + } + { + for(i = 0; i < 4; i++) + { + for(j = 0; j < 4; j++) + { + + uc_cond = u2_mask & 1; + u2_mask >>= 1; + if(uc_cond) + { + *(UWORD32 *)(pu1_dest_y + u2_dest_wd_y) = + *(UWORD32 *)(pu1_ref_y + u2_ref_wd_y); + *(UWORD32 *)(pu1_dest_y + 2 * u2_dest_wd_y) = + *(UWORD32 *)(pu1_ref_y + 2 * u2_ref_wd_y); + *(UWORD32 *)(pu1_dest_y + 3 * u2_dest_wd_y) = + *(UWORD32 *)(pu1_ref_y + 3 * u2_ref_wd_y); + { + UWORD32 *dst, *src; + dst = (UWORD32 *)pu1_dest_y; + src = (UWORD32 *)pu1_ref_y; + *dst = *src; + dst++; + src++; + pu1_dest_y = (UWORD8 *)dst; + pu1_ref_y = (UWORD8 *)src; + } + *(UWORD32 *)(pu1_dest_u + u2_dest_wd_uv) = + *(UWORD32 *)(pu1_ref_u + u2_ref_wd_uv); + { + UWORD32 *dst, *src; + dst = (UWORD32 *)pu1_dest_u; + src = (UWORD32 *)pu1_ref_u; + *dst = *src; + dst++; + src++; + pu1_dest_u = (UWORD8 *)dst; + pu1_ref_u = (UWORD8 *)src; + } + + } + else + { + pu1_dest_y += 4; + pu1_ref_y += 4; + pu1_dest_u += 2 * YUV420SP_FACTOR; + pu1_ref_u += 2 * YUV420SP_FACTOR; + pu1_dest_v += 2; + pu1_ref_v += 2; + } + } + pu1_ref_y += 4 * (u2_ref_wd_y - 4); + pu1_ref_u += 2 * (u2_ref_wd_uv - 4 * YUV420SP_FACTOR); + pu1_ref_v += 2 * (u2_ref_wd_uv - 4); + pu1_dest_y += 4 * (u2_dest_wd_y - 4); + pu1_dest_u += 2 * (u2_dest_wd_uv - 4 * YUV420SP_FACTOR); + pu1_dest_v += 2 * (u2_dest_wd_uv - 4); + } + } +} + +void ih264d_pad_on_demand(pred_info_t *ps_pred, UWORD8 lum_chrom_blk) +{ + if(CHROM_BLK == lum_chrom_blk) + { + UWORD32 *pu4_pod_src_u, *pu4_pod_dst_u; + UWORD32 *pu4_pod_src_v, *pu4_pod_dst_v; + WORD32 j, u1_wd_stride; + WORD32 i, u1_dma_ht, i1_ht; + UWORD32 u2_dma_size; + u1_wd_stride = (ps_pred->u2_u1_ref_buf_wd >> 2) * YUV420SP_FACTOR; + u1_dma_ht = ps_pred->i1_dma_ht; + u2_dma_size = u1_wd_stride * u1_dma_ht; + pu4_pod_src_u = (UWORD32 *)ps_pred->pu1_dma_dest_addr; + pu4_pod_dst_u = pu4_pod_src_u; + + pu4_pod_src_v = pu4_pod_src_u + u2_dma_size; + pu4_pod_dst_v = pu4_pod_src_v; + + i1_ht = ps_pred->i1_pod_ht; + pu4_pod_src_u -= u1_wd_stride * i1_ht; + pu4_pod_src_v -= u1_wd_stride * i1_ht; + if(i1_ht < 0) + /* Top POD */ + i1_ht = -i1_ht; + else + { + /* Bottom POD */ + pu4_pod_src_u += (u1_dma_ht - 1) * u1_wd_stride; + pu4_pod_dst_u += (u1_dma_ht - i1_ht) * u1_wd_stride; + pu4_pod_src_v += (u1_dma_ht - 1) * u1_wd_stride; + pu4_pod_dst_v += (u1_dma_ht - i1_ht) * u1_wd_stride; + } + + for(i = 0; i < i1_ht; i++) + for(j = 0; j < u1_wd_stride; j++) + { + *pu4_pod_dst_u++ = *(pu4_pod_src_u + j); + + } + } + else + { + UWORD32 *pu4_pod_src, *pu4_pod_dst; + WORD32 j, u1_wd_stride; + WORD32 i, i1_ht; + pu4_pod_src = (UWORD32 *)ps_pred->pu1_dma_dest_addr; + pu4_pod_dst = pu4_pod_src; + u1_wd_stride = ps_pred->u2_u1_ref_buf_wd >> 2; + i1_ht = ps_pred->i1_pod_ht; + pu4_pod_src -= u1_wd_stride * i1_ht; + if(i1_ht < 0) + /* Top POD */ + i1_ht = -i1_ht; + else + { + /* Bottom POD */ + pu4_pod_src += (ps_pred->i1_dma_ht - 1) * u1_wd_stride; + pu4_pod_dst += (ps_pred->i1_dma_ht - i1_ht) * u1_wd_stride; + } + + for(i = 0; i < i1_ht; i++) + for(j = 0; j < u1_wd_stride; j++) + *pu4_pod_dst++ = *(pu4_pod_src + j); + } +} + diff --git a/decoder/ih264d_inter_pred.h b/decoder/ih264d_inter_pred.h new file mode 100755 index 0000000..52d648a --- /dev/null +++ b/decoder/ih264d_inter_pred.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_INTER_PRED_H_ +#define _IH264D_INTER_PRED_H_ + +/*! + ************************************************************************** + * \file ih264d_inter_pred.h + * + * \brief + * Decalaration for routines defined in MorionCompensate.c + * + * Detailed_description + * + * \date + * creation_date + * + * \author Arvind Raman + ************************************************************************** + */ + +#include "ih264d_structs.h" + +#define BUFFER_WIDTH 16 +/*! + ************************************************************************** + * \brief PRED_BUFFER_WIDTH / HEIGHT + * + * Width and height of the 16 bit (also reused a 2 8 bits buffers). The + * required dimensions for these buffers are 21x21, however to align the + * start of every row to a WORD aligned boundary the width has been increased + * to 24. + ************************************************************************** + */ +//#define PRED_BUFFER_WIDTH 24 +//#define PRED_BUFFER_HEIGHT 21 +#define PRED_BUFFER_WIDTH 24*2 +#define PRED_BUFFER_HEIGHT 24*2 + +void ih264d_fill_pred_info(WORD16 *pi2_mv,WORD32 part_width,WORD32 part_height, WORD32 sub_mb_num, + WORD32 pred_dir,pred_info_pkd_t *ps_pred_pkd,WORD8 i1_buf_id, + WORD8 i1_ref_idx,UWORD32 *pu4_wt_offset,UWORD8 u1_pic_type); + +WORD32 ih264d_form_mb_part_info_bp(pred_info_pkd_t *ps_pred_pkd, + dec_struct_t * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info); + +WORD32 ih264d_form_mb_part_info_mp(pred_info_pkd_t *ps_pred_pkd, + dec_struct_t * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info); + + +void ih264d_motion_compensate_bp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info); +void ih264d_motion_compensate_mp(dec_struct_t * ps_dec, dec_mb_info_t *ps_cur_mb_info); + + +void TransferRefBuffs(dec_struct_t *ps_dec); + +void ih264d_multiplex_ref_data(dec_struct_t * ps_dec, + pred_info_t *ps_pred, + UWORD8* pu1_dest_y, + UWORD8* pu1_dest_u, + UWORD8* pu1_dest_v, + dec_mb_info_t *ps_cur_mb_info, + UWORD16 u2_dest_wd_y, + UWORD16 u2_dest_wd_uv, + UWORD8 u1_dir); +#endif /* _IH264D_INTER_PRED_H_ */ + diff --git a/decoder/ih264d_mb_utils.c b/decoder/ih264d_mb_utils.c new file mode 100755 index 0000000..4cbfca5 --- /dev/null +++ b/decoder/ih264d_mb_utils.c @@ -0,0 +1,1496 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_mb_utils.c + * + * \brief + * Contains utitlity functions needed for Macroblock decoding + * + * \date + * 18/12/2002 + * + * \author AI + ************************************************************************** + */ +#include <string.h> +#include <stdlib.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_mb_utils.h" +#include "ih264d_parse_slice.h" +#include "ih264d_error_handler.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_cabac.h" +#include "ih264d_defs.h" +#include "ih264d_tables.h" + +/*****************************************************************************/ +/* */ +/* Function Name : get_mb_info_cavlc */ +/* */ +/* Description : This function sets the following information of cur MB */ +/* (a) mb_x and mb_y */ +/* (b) Neighbour availablity */ +/* (c) Macroblock location in the frame buffer */ +/* (e) For mbaff predicts field/frame u4_flag for topMb */ +/* and sets the field/frame for botMb. This is */ +/* written in ps_dec->u1_cur_mb_fld_dec_flag */ +/* */ +/* Inputs : pointer to decstruct */ +/* pointer to current mb info */ +/* currentMbaddress */ +/* */ +/* Processing : leftMb and TopMb params are used by DecMbskip and */ +/* DecCtxMbfield modules so that these modules do not */ +/* check for neigbour availability and then find the */ +/* neigbours for context increments */ +/* */ +/* Returns : OK */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_get_mb_info_cavlc_nonmbaff(dec_struct_t *ps_dec, + const UWORD16 u2_cur_mb_address, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run) +{ + UWORD16 u2_mb_x; + UWORD16 u2_mb_y; + UWORD8 u1_mb_ngbr_avail = 0; + UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; + WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; + UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; + UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; + UNUSED(u4_mbskip_run); + /*--------------------------------------------------------------------*/ + /* Calculate values of mb_x and mb_y */ + /*--------------------------------------------------------------------*/ + u2_mb_x = ps_dec->u2_mbx; + u2_mb_y = ps_dec->u2_mby; + + if(ps_dec->u1_separate_parse) + { + ps_dec->u2_cur_mb_addr = u2_cur_mb_address; + } + u2_mb_x++; + + if(u2_mb_x == u2_frm_width_in_mb) + { + u2_mb_x = 0; + u2_mb_y++; + } + if(u2_mb_y > ps_dec->i2_prev_slice_mby) + { + /* if not in the immemdiate row of prev slice end then top + will be available */ + if(u2_mb_y > (ps_dec->i2_prev_slice_mby + 1)) + i2_prev_slice_mbx = -1; + + if(u2_mb_x > i2_prev_slice_mbx) + { + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + } + + if((u2_mb_x > (i2_prev_slice_mbx - 1)) + && (u2_mb_x != (u2_frm_width_in_mb - 1))) + { + u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; + } + + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + + /* Next row Left will be available*/ + i2_prev_slice_mbx = -1; + } + + /* Same row */ + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + } + + { + mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row; + mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row; + + /* copy the parameters of topleft Mb */ + ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype; + /* Neighbour pointer assignments*/ + ps_cur_mb_info->ps_curmb = ps_cur_mb_row + u2_mb_x; + ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + u2_mb_x - 1; + ps_cur_mb_info->ps_top_mb = ps_top_mb_row + u2_mb_x; + ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + u2_mb_x + 1; + + /* Update the parameters of topleftmb*/ + ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type; + } + + ps_dec->u2_mby = u2_mb_y; + ps_dec->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mby = u2_mb_y; + ps_cur_mb_info->u1_topmb = 1; + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag; + ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag; + ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; + ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; + return (OK); + +} + +/*****************************************************************************/ +/* */ +/* Function Name : get_mb_info_cavlc */ +/* */ +/* Description : This function sets the following information of cur MB */ +/* (a) mb_x and mb_y */ +/* (b) Neighbour availablity */ +/* (c) Macroblock location in the frame buffer */ +/* (e) For mbaff predicts field/frame u4_flag for topMb */ +/* and sets the field/frame for botMb. This is */ +/* written in ps_dec->u1_cur_mb_fld_dec_flag */ +/* */ +/* Inputs : pointer to decstruct */ +/* pointer to current mb info */ +/* currentMbaddress */ +/* */ +/* Processing : leftMb and TopMb params are used by DecMbskip and */ +/* DecCtxMbfield modules so that these modules do not */ +/* check for neigbour availability and then find the */ +/* neigbours for context increments */ +/* */ +/* Returns : OK */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_get_mb_info_cavlc_mbaff(dec_struct_t *ps_dec, + const UWORD16 u2_cur_mb_address, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run) +{ + UWORD16 u2_mb_x; + UWORD16 u2_mb_y; + UWORD8 u1_mb_ngbr_avail = 0; + UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; + + UWORD8 u1_top_mb = 1 - (u2_cur_mb_address & 0x01); + WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; + UWORD8 u1_cur_mb_field = 0; + UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; + UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; + + /*--------------------------------------------------------------------*/ + /* Calculate values of mb_x and mb_y */ + /*--------------------------------------------------------------------*/ + u2_mb_x = ps_dec->u2_mbx; + u2_mb_y = ps_dec->u2_mby; + + if(ps_dec->u1_separate_parse) + { + ps_dec->u2_cur_mb_addr = u2_cur_mb_address; + } + + + if(u1_top_mb) + { + u2_mb_x++; + if(u2_mb_x == u2_frm_width_in_mb) + { + u2_mb_x = 0; + u2_mb_y += 2; + } + if(u2_mb_y > ps_dec->i2_prev_slice_mby) + { + /* if not in the immemdiate row of prev slice end then top + will be available */ + if(u2_mb_y > (ps_dec->i2_prev_slice_mby + 2)) + i2_prev_slice_mbx = -1; + if(u2_mb_x > i2_prev_slice_mbx) + { + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u1_cur_mb_field = ps_dec->ps_top_mb_row[u2_mb_x << 1].u1_mb_fld; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + } + if((u2_mb_x > (i2_prev_slice_mbx - 1)) + && (u2_mb_x != (u2_frm_width_in_mb - 1))) + { + u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; + } + + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + + i2_prev_slice_mbx = -1; + } + /* Same row */ + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; + u1_cur_mb_field = + ps_dec->ps_cur_mb_row[(u2_mb_x << 1) - 1].u1_mb_fld; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + } + /* Read u1_cur_mb_field from the bitstream if u4_mbskip_run <= 1*/ + if(u4_mbskip_run <= 1) + u1_cur_mb_field = (UWORD8)ih264d_get_bit_h264(ps_dec->ps_bitstrm); + + ps_dec->u1_cur_mb_fld_dec_flag = u1_cur_mb_field; + ps_dec->u2_top_left_mask = u2_top_left_mask; + ps_dec->u2_top_right_mask = u2_top_right_mask; + } + else + { + u1_mb_ngbr_avail = ps_dec->u1_mb_ngbr_availablity; + u1_cur_mb_field = ps_dec->u1_cur_mb_fld_dec_flag; + u2_top_left_mask = ps_dec->u2_top_left_mask; + u2_top_right_mask = ps_dec->u2_top_right_mask; + + if(!u1_cur_mb_field) + { + /* Top is available */ + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + /* Top Right not available */ + u1_mb_ngbr_avail &= TOP_RT_SUBBLOCK_MASK_MOD; + u2_top_right_mask &= (~TOP_RIGHT_TOPR_AVAILABLE); + + if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + } + } + + ps_dec->u2_mby = u2_mb_y; + ps_dec->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mby = u2_mb_y; + ps_cur_mb_info->u1_topmb = u1_top_mb; + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_field_decodingflag = u1_cur_mb_field; + ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; + ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; + ih264d_get_mbaff_neighbours(ps_dec, ps_cur_mb_info, u1_cur_mb_field); + return (OK); +} + +/*****************************************************************************/ +/* */ +/* Function Name : get_mb_info_cabac */ +/* */ +/* Description : This function sets the following information of cur MB */ +/* (a) mb_x and mb_y */ +/* (b) Neighbour availablity */ +/* (c) Macroblock location in the frame buffer */ +/* (e) leftMb parama and TopMb params of curMB */ +/* (f) For Mbaff case leftMb params and TopMb params of */ +/* bottomMb are also set if curMB is top */ +/* (g) For mbaff predicts field/frame u4_flag for topMb */ +/* and sets the field/frame for botMb. This is */ +/* written in ps_dec->u1_cur_mb_fld_dec_flag */ +/* */ +/* Inputs : pointer to decstruct */ +/* pointer to current mb info */ +/* currentMbaddress */ +/* */ +/* Processing : leftMb and TopMb params are used by DecMbskip and */ +/* DecCtxMbfield modules so that these modules do not */ +/* check for neigbour availability and then find the */ +/* neigbours for context increments */ +/* */ +/* Returns : OK */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_get_mb_info_cabac_nonmbaff(dec_struct_t *ps_dec, + const UWORD16 u2_cur_mb_address, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip) +{ + WORD32 u2_mb_x; + WORD32 u2_mb_y; + UWORD32 u1_mb_ngbr_avail = 0; + UWORD32 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; + UWORD32 u1_top_mb = 1; + WORD32 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; + UWORD32 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; + UWORD32 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; + ctxt_inc_mb_info_t * const p_ctx_inc_mb_map = ps_dec->p_ctxt_inc_mb_map; + + /*--------------------------------------------------------------------*/ + /* Calculate values of mb_x and mb_y */ + /*--------------------------------------------------------------------*/ + u2_mb_x = (WORD16)ps_dec->u2_mbx; + u2_mb_y = ps_dec->u2_mby; + + if(ps_dec->u1_separate_parse) + { + ps_dec->u2_cur_mb_addr = u2_cur_mb_address; + } + + u2_mb_x++; + if((UWORD32)u2_mb_x == u2_frm_width_in_mb) + { + u2_mb_x = 0; + u2_mb_y++; + } + /*********************************************************************/ + /* Cabac Context Initialisations */ + /*********************************************************************/ + ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + u2_mb_x; + ps_dec->p_left_ctxt_mb_info = p_ctx_inc_mb_map - 1; + ps_dec->p_top_ctxt_mb_info = p_ctx_inc_mb_map - 1; + + /********************************************************************/ + /* neighbour availablility */ + /********************************************************************/ + if(u2_mb_y > ps_dec->i2_prev_slice_mby) + { + /* if not in the immemdiate row of prev slice end then top + will be available */ + if(u2_mb_y > (ps_dec->i2_prev_slice_mby + 1)) + i2_prev_slice_mbx = -1; + + if(u2_mb_x > i2_prev_slice_mbx) + { + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + ps_dec->p_top_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info; + } + if((u2_mb_x > (i2_prev_slice_mbx - 1)) + && ((UWORD32)u2_mb_x != (u2_frm_width_in_mb - 1))) + { + u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; + } + + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + /* Next row */ + i2_prev_slice_mbx = -1; + } + /* Same row */ + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + ps_dec->p_left_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info - 1; + } + { + mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row; + mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row; + /* copy the parameters of topleft Mb */ + ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype; + /* Neighbour pointer assignments*/ + ps_cur_mb_info->ps_curmb = ps_cur_mb_row + u2_mb_x; + ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + u2_mb_x - 1; + ps_cur_mb_info->ps_top_mb = ps_top_mb_row + u2_mb_x; + ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + u2_mb_x + 1; + + /* Update the parameters of topleftmb*/ + ps_dec->u1_topleft_mbtype = ps_cur_mb_info->ps_top_mb->u1_mb_type; + } + + ps_dec->u2_mby = u2_mb_y; + ps_dec->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mby = u2_mb_y; + ps_cur_mb_info->u1_topmb = u1_top_mb; + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->ps_curmb->u1_mb_fld = ps_dec->u1_cur_mb_fld_dec_flag; + ps_cur_mb_info->u1_mb_field_decodingflag = ps_dec->u1_cur_mb_fld_dec_flag; + ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; + ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; + + /*********************************************************************/ + /* Assign the neigbours */ + /*********************************************************************/ + if(u4_mbskip) + { + UWORD32 u4_ctx_inc = + 2 + - ((!!(ps_dec->p_top_ctxt_mb_info->u1_mb_type + & CAB_SKIP_MASK)) + + (!!(ps_dec->p_left_ctxt_mb_info->u1_mb_type + & CAB_SKIP_MASK))); + + u4_mbskip = ih264d_decode_bin(u4_ctx_inc, ps_dec->p_mb_skip_flag_t, + ps_dec->ps_bitstrm, &ps_dec->s_cab_dec_env); + + if(!u4_mbskip) + { + if(!(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK)) + { + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + + + *(ps_dec->pu1_left_yuv_dc_csbp) = 0; + MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); + *(UWORD32 *)ps_dec->pi1_left_ref_idx_ctxt_inc = 0; + } + if(!(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK)) + { + MEMSET_16BYTES(ps_dec->ps_curr_ctxt_mb_info->u1_mv, 0); + memset(ps_dec->ps_curr_ctxt_mb_info->i1_ref_idx, 0, 4); + } + } + } + return (u4_mbskip); +} + +/*****************************************************************************/ +/* */ +/* Function Name : get_mb_info_cabac */ +/* */ +/* Description : This function sets the following information of cur MB */ +/* (a) mb_x and mb_y */ +/* (b) Neighbour availablity */ +/* (c) Macroblock location in the frame buffer */ +/* (e) leftMb parama and TopMb params of curMB */ +/* (f) For Mbaff case leftMb params and TopMb params of */ +/* bottomMb are also set if curMB is top */ +/* (g) For mbaff predicts field/frame u4_flag for topMb */ +/* and sets the field/frame for botMb. This is */ +/* written in ps_dec->u1_cur_mb_fld_dec_flag */ +/* */ +/* Inputs : pointer to decstruct */ +/* pointer to current mb info */ +/* currentMbaddress */ +/* */ +/* Processing : leftMb and TopMb params are used by DecMbskip and */ +/* DecCtxMbfield modules so that these modules do not */ +/* check for neigbour availability and then find the */ +/* neigbours for context increments */ +/* */ +/* Returns : OK */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ + +UWORD32 ih264d_get_mb_info_cabac_mbaff(dec_struct_t *ps_dec, + const UWORD16 u2_cur_mb_address, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip) +{ + UWORD16 u2_mb_x; + UWORD16 u2_mb_y; + UWORD8 u1_mb_ngbr_avail = 0; + UWORD16 u2_frm_width_in_mb = ps_dec->u2_frm_wd_in_mbs; + ctxt_inc_mb_info_t * const p_ctx_inc_mb_map = ps_dec->p_ctxt_inc_mb_map; + ctxt_inc_mb_info_t *ps_curr_ctxt, *ps_top_ctxt, *ps_left_ctxt; + mb_neigbour_params_t *ps_cur_mb_row = ps_dec->ps_cur_mb_row; + mb_neigbour_params_t *ps_top_mb_row = ps_dec->ps_top_mb_row; + UWORD32 u4_left_mb_pair_fld = 0; + UWORD32 u4_top_mb_pair_fld = 0; + UWORD8 u1_cur_mb_field = 0; + UWORD8 u1_top_mb = 1 - (u2_cur_mb_address & 0x01); + WORD16 i2_prev_slice_mbx = ps_dec->i2_prev_slice_mbx; + UWORD16 u2_top_right_mask = TOP_RIGHT_DEFAULT_AVAILABLE; + UWORD16 u2_top_left_mask = TOP_LEFT_DEFAULT_AVAILABLE; + + /*--------------------------------------------------------------------*/ + /* Calculate values of mb_x and mb_y */ + /*--------------------------------------------------------------------*/ + u2_mb_x = ps_dec->u2_mbx; + u2_mb_y = ps_dec->u2_mby; + + if(ps_dec->u1_separate_parse) + { + ps_dec->u2_cur_mb_addr = u2_cur_mb_address; + } + + ps_top_ctxt = ps_left_ctxt = p_ctx_inc_mb_map - 1; + + if(u1_top_mb) + { + ctxt_inc_mb_info_t *ps_left_mb_of_bot = ps_left_ctxt; + ctxt_inc_mb_info_t *ps_top_mb_of_bot = ps_top_ctxt; + + u2_mb_x++; + + if(u2_mb_x == u2_frm_width_in_mb) + { + u2_mb_x = 0; + u2_mb_y += 2; + } + + ps_curr_ctxt = p_ctx_inc_mb_map + (u2_mb_x << 1); + if(u2_mb_y > ps_dec->i2_prev_slice_mby) + { + UWORD8 u1_cur_mb_fld_flag_known = 0; + /* Next row */ + if(u2_mb_x > 0) + { + /***********************************************************************/ + /* Left Mb is avialable */ + /***********************************************************************/ + u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; + ps_left_ctxt = ps_curr_ctxt - 2; + ps_left_mb_of_bot = ps_curr_ctxt - 1; + u1_cur_mb_field = u4_left_mb_pair_fld = ps_cur_mb_row[(u2_mb_x + << 1) - 1].u1_mb_fld; + u1_cur_mb_fld_flag_known = 1; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + } + /* if not in the immemdiate row of prev slice end then top + will be available */ + if(u2_mb_y > (ps_dec->i2_prev_slice_mby + 2)) + i2_prev_slice_mbx = -1; + if(u2_mb_x > i2_prev_slice_mbx) + { + /*********************************************************************/ + /* Top Mb is avialable */ + /*********************************************************************/ + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + + /* point to MbAddrB + 1 */ + ps_top_ctxt = ps_curr_ctxt + 1; + u4_top_mb_pair_fld = ps_top_mb_row[(u2_mb_x << 1)].u1_mb_fld; + + u1_cur_mb_field = + u1_cur_mb_fld_flag_known ? + u1_cur_mb_field : + u4_top_mb_pair_fld; + ps_top_mb_of_bot = u1_cur_mb_field ? ps_top_ctxt : ps_curr_ctxt; + + /* MbAddrB */ + ps_top_ctxt -= (u1_cur_mb_field && u4_top_mb_pair_fld); + } + + if((u2_mb_x > (i2_prev_slice_mbx - 1)) + && (u2_mb_x != (u2_frm_width_in_mb - 1))) + { + u1_mb_ngbr_avail |= TOP_RIGHT_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOPR_AVAILABLE; + } + + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + } + else + { + /* Same row */ + if(u2_mb_x > (i2_prev_slice_mbx + 1)) + { + /***************************************************************/ + /* Left Mb is avialable */ + /***************************************************************/ + u1_mb_ngbr_avail |= LEFT_MB_AVAILABLE_MASK; + + u1_cur_mb_field = u4_left_mb_pair_fld = ps_cur_mb_row[(u2_mb_x + << 1) - 1].u1_mb_fld; + ps_left_ctxt = ps_curr_ctxt - 2; + ps_left_mb_of_bot = ps_curr_ctxt - 1; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + } + } + /*********************************************************/ + /* Check whether the call is from I slice or Inter slice */ + /*********************************************************/ + if(u4_mbskip) + { + UWORD32 u4_ctx_inc = 2 + - ((!!(ps_top_ctxt->u1_mb_type & CAB_SKIP_MASK)) + + (!!(ps_left_ctxt->u1_mb_type + & CAB_SKIP_MASK))); + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + decoding_envirnoment_t *ps_cab_dec_env = &ps_dec->s_cab_dec_env; + bin_ctxt_model_t *p_mb_skip_flag_t = ps_dec->p_mb_skip_flag_t; + + ps_dec->u4_next_mb_skip = 0; + u4_mbskip = ih264d_decode_bin(u4_ctx_inc, p_mb_skip_flag_t, + ps_bitstrm, ps_cab_dec_env); + + if(u4_mbskip) + { + UWORD32 u4_next_mbskip; + ps_curr_ctxt->u1_mb_type = CAB_SKIP; + + u4_ctx_inc = + 2 + - ((!!(ps_top_mb_of_bot->u1_mb_type + & CAB_SKIP_MASK)) + + (!!(ps_left_mb_of_bot->u1_mb_type + & CAB_SKIP_MASK))); + + /* Decode the skip u4_flag of bottom Mb */ + u4_next_mbskip = ih264d_decode_bin(u4_ctx_inc, p_mb_skip_flag_t, + ps_bitstrm, + ps_cab_dec_env); + + ps_dec->u4_next_mb_skip = u4_next_mbskip; + + if(!u4_next_mbskip) + { + u4_ctx_inc = u4_top_mb_pair_fld + u4_left_mb_pair_fld; + + u1_cur_mb_field = ih264d_decode_bin( + u4_ctx_inc, ps_dec->p_mb_field_dec_flag_t, + ps_bitstrm, ps_cab_dec_env); + } + } + } + + if(!u4_mbskip) + { + UWORD32 u4_ctx_inc = u4_top_mb_pair_fld + u4_left_mb_pair_fld; + u1_cur_mb_field = ih264d_decode_bin(u4_ctx_inc, + ps_dec->p_mb_field_dec_flag_t, + ps_dec->ps_bitstrm, + &ps_dec->s_cab_dec_env); + } + + ps_dec->u1_cur_mb_fld_dec_flag = u1_cur_mb_field; + ps_dec->u2_top_left_mask = u2_top_left_mask; + ps_dec->u2_top_right_mask = u2_top_right_mask; + ps_dec->u2_mby = u2_mb_y; + ps_dec->u2_mbx = u2_mb_x; + } + else + { + u1_cur_mb_field = ps_dec->u1_cur_mb_fld_dec_flag; + u1_mb_ngbr_avail = ps_dec->u1_mb_ngbr_availablity; + u2_top_left_mask = ps_dec->u2_top_left_mask; + u2_top_right_mask = ps_dec->u2_top_right_mask; + ps_curr_ctxt = p_ctx_inc_mb_map + (u2_mb_x << 1) + 1; + + if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) + { + u4_left_mb_pair_fld = ps_cur_mb_row[(u2_mb_x << 1) - 1].u1_mb_fld; + + /* point to A if top else A+1 */ + ps_left_ctxt = ps_curr_ctxt - 2 + - (u4_left_mb_pair_fld != u1_cur_mb_field); + } + + if(u1_cur_mb_field) + { + if(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK) + { + /* point to MbAddrB + 1 */ + ps_top_ctxt = ps_curr_ctxt; + } + } + else + { + /* Top is available */ + u1_mb_ngbr_avail |= TOP_MB_AVAILABLE_MASK; + u2_top_right_mask |= TOP_RIGHT_TOP_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOP_AVAILABLE; + /* Top Right not available */ + u1_mb_ngbr_avail &= TOP_RT_SUBBLOCK_MASK_MOD; + u2_top_right_mask &= (~TOP_RIGHT_TOPR_AVAILABLE); + + if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) + { + u1_mb_ngbr_avail |= TOP_LEFT_MB_AVAILABLE_MASK; + u2_top_left_mask |= TOP_LEFT_LEFT_AVAILABLE; + u2_top_left_mask |= TOP_LEFT_TOPL_AVAILABLE; + } + + /* CurMbAddr - 1 */ + ps_top_ctxt = ps_curr_ctxt - 1; + } + + if(u4_mbskip) + { + if(ps_curr_ctxt[-1].u1_mb_type & CAB_SKIP_MASK) + { + /* If previous mb is skipped, return value of next mb skip */ + u4_mbskip = ps_dec->u4_next_mb_skip; + + } + else + { + /* If previous mb is not skipped then call DecMbSkip */ + UWORD32 u4_ctx_inc = + 2 + - ((!!(ps_top_ctxt->u1_mb_type + & CAB_SKIP_MASK)) + + (!!(ps_left_ctxt->u1_mb_type + & CAB_SKIP_MASK))); + + u4_mbskip = ih264d_decode_bin(u4_ctx_inc, + ps_dec->p_mb_skip_flag_t, + ps_dec->ps_bitstrm, + &ps_dec->s_cab_dec_env); + } + } + } + + ps_cur_mb_info->u2_mbx = u2_mb_x; + ps_cur_mb_info->u2_mby = u2_mb_y; + ps_cur_mb_info->u1_topmb = u1_top_mb; + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + ps_dec->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_ngbr_availablity = u1_mb_ngbr_avail; + ps_cur_mb_info->u1_mb_field_decodingflag = u1_cur_mb_field; + ps_cur_mb_info->u2_top_left_avail_mask = u2_top_left_mask; + ps_cur_mb_info->u2_top_right_avail_mask = u2_top_right_mask; + + ih264d_get_mbaff_neighbours(ps_dec, ps_cur_mb_info, u1_cur_mb_field); + { + ih264d_get_cabac_context_mbaff(ps_dec, ps_cur_mb_info, u4_mbskip); + } + + { + bin_ctxt_model_t *p_cabac_ctxt_table_t = ps_dec->p_cabac_ctxt_table_t; + + if(u1_cur_mb_field) + { + p_cabac_ctxt_table_t += SIGNIFICANT_COEFF_FLAG_FLD; + } + else + { + p_cabac_ctxt_table_t += SIGNIFICANT_COEFF_FLAG_FRAME; + } + { + bin_ctxt_model_t * * p_significant_coeff_flag_t = + ps_dec->p_significant_coeff_flag_t; + p_significant_coeff_flag_t[0] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_0_OFFSET; + p_significant_coeff_flag_t[1] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_1_OFFSET; + p_significant_coeff_flag_t[2] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_2_OFFSET; + p_significant_coeff_flag_t[3] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_3_OFFSET; + p_significant_coeff_flag_t[4] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_4_OFFSET; + p_significant_coeff_flag_t[5] = p_cabac_ctxt_table_t + + SIG_COEFF_CTXT_CAT_5_OFFSET; + + } + } + return (u4_mbskip); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_cabac_context_mbaff */ +/* */ +/* Description : Gets the current macroblock Cabac Context and sets the */ +/* top and left cabac context ptrs in CtxIncMbMap */ +/* 1. For Coss field left neigbours it alters coded block */ +/* u4_flag , motion vectors, reference indices, cbp of */ +/* the left neigbours which increases the code i4_size */ +/* 2. For Coss field top neigbours it alters motion */ +/* vectors reference indices of the top neigbours */ +/* which further increases the code i4_size */ +/* */ +/* Inputs : 1. dec_struct_t */ +/* 2. CurMbAddr used for Mbaff (only to see if curMB */ +/* is top or bottom) */ +/* 3. uc_curMbFldDecFlag only for Mbaff */ +/* */ +/* Returns : 0 */ +/* */ +/* Issues : code i4_size can be reduced if ui_CodedBlockFlag storage */ +/* structure in context is changed. This change however */ +/* would break the parseResidual4x4Cabac asm routine. */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 18 06 2005 Jay */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_get_cabac_context_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 u4_mbskip) +{ + const UWORD8 u1_mb_ngbr_availablity = ps_dec->u1_mb_ngbr_availablity; + ctxt_inc_mb_info_t * const p_ctx_inc_mb_map = ps_dec->p_ctxt_inc_mb_map; + + UWORD8 (*pu1_left_mv_ctxt_inc_2d)[4] = &ps_dec->pu1_left_mv_ctxt_inc[0]; + WORD8 (*pi1_left_ref_idx_ctxt_inc) = ps_dec->pi1_left_ref_idx_ctxt_inc; + const UWORD8 u1_cur_mb_fld_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + const UWORD8 u1_topmb = ps_cur_mb_info->u1_topmb; + const UWORD8 uc_botMb = 1 - ps_cur_mb_info->u1_topmb; + + ctxt_inc_mb_info_t * ps_leftMB; + + ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + (ps_dec->u2_mbx << 1); + ps_dec->p_top_ctxt_mb_info = ps_dec->ps_curr_ctxt_mb_info; + + if(u1_topmb) + { + pu1_left_mv_ctxt_inc_2d = ps_dec->u1_left_mv_ctxt_inc_arr[0]; + pi1_left_ref_idx_ctxt_inc = &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0]; + ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb; + } + else + { + /* uc_botMb */ + pu1_left_mv_ctxt_inc_2d = ps_dec->u1_left_mv_ctxt_inc_arr[1]; + pi1_left_ref_idx_ctxt_inc = &ps_dec->i1_left_ref_idx_ctx_inc_arr[1][0]; + ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_bot_mb; + ps_dec->ps_curr_ctxt_mb_info += 1; + } + + ps_dec->pu1_left_mv_ctxt_inc = pu1_left_mv_ctxt_inc_2d; + ps_dec->pi1_left_ref_idx_ctxt_inc = pi1_left_ref_idx_ctxt_inc; + + if(u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK) + { + const UWORD8 u1_left_mb_fld_flag = ps_cur_mb_info->ps_left_mb->u1_mb_fld; + + ps_leftMB = ps_dec->ps_curr_ctxt_mb_info - 2; + if(u1_left_mb_fld_flag != u1_cur_mb_fld_flag) + { + ctxt_inc_mb_info_t *ps_tempLeft; + UWORD8 u1_cbp_t, u1_cbp_b; + UWORD8 u1_cr_cpb; + + ps_leftMB -= uc_botMb; + ps_tempLeft = ps_dec->ps_left_mb_ctxt_info; + ps_tempLeft->u1_mb_type = ps_leftMB->u1_mb_type; + ps_tempLeft->u1_intra_chroma_pred_mode = + ps_leftMB->u1_intra_chroma_pred_mode; + + ps_tempLeft->u1_transform8x8_ctxt = ps_leftMB->u1_transform8x8_ctxt; + + u1_cr_cpb = ps_leftMB->u1_cbp; + /*****************************************************************/ + /* reform RefIdx, CBP, MV and CBF ctxInc taking care of A and A+1*/ + /*****************************************************************/ + if(u1_cur_mb_fld_flag) + { + /* current MB is a FLD and left a FRM */ + UWORD8 (* const pu1_left_mv_ctxt_inc_2d_arr_top)[4] = + ps_dec->u1_left_mv_ctxt_inc_arr[0]; + UWORD8 (* const pu1_left_mv_ctxt_inc_2d_arr_bot)[4] = + ps_dec->u1_left_mv_ctxt_inc_arr[1]; + WORD8 (* const i1_left_ref_idx_ctxt_inc_arr_top) = + &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0]; + WORD8 (* const i1_left_ref_idx_ctxt_inc_arr_bot) = + &ps_dec->i1_left_ref_idx_ctx_inc_arr[1][0]; + + u1_cbp_t = ps_leftMB->u1_cbp; + u1_cbp_b = (ps_leftMB + 1)->u1_cbp; + ps_tempLeft->u1_cbp = (u1_cbp_t & 0x02) + | ((u1_cbp_b & 0x02) << 2); + + // set motionvectors as + // 0T = 0T 0B = 0T + // 1T = 2T 1B = 2T + // 2T = 0B 2B = 0B + // 3T = 2B 3B = 2B + if(u1_topmb) + { + /********************************************/ + /* Bottoms DC CBF = Top DC CBF */ + /********************************************/ + ps_dec->u1_yuv_dc_csbp_bot_mb = + ps_dec->u1_yuv_dc_csbp_topmb; + + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[3] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d_arr_bot[2]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[1] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d_arr_top[2]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[2] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d_arr_bot[0]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[0] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d_arr_top[0]; + + i1_left_ref_idx_ctxt_inc_arr_top[1] = + i1_left_ref_idx_ctxt_inc_arr_bot[0]; + i1_left_ref_idx_ctxt_inc_arr_top[3] = + i1_left_ref_idx_ctxt_inc_arr_bot[2]; + + *(UWORD32 *)(i1_left_ref_idx_ctxt_inc_arr_bot) = + *(UWORD32 *)(i1_left_ref_idx_ctxt_inc_arr_top); + + memcpy(pu1_left_mv_ctxt_inc_2d_arr_bot, + pu1_left_mv_ctxt_inc_2d_arr_top, 16); + } + + { + UWORD8 i; + for(i = 0; i < 4; i++) + { + pu1_left_mv_ctxt_inc_2d[i][1] >>= 1; + pu1_left_mv_ctxt_inc_2d[i][3] >>= 1; + } + } + } + else + { + /* current MB is a FRM and left FLD */ + if(u1_topmb) + { + u1_cbp_t = ps_leftMB->u1_cbp; + u1_cbp_t = (u1_cbp_t & 0x02); + ps_tempLeft->u1_cbp = (u1_cbp_t | (u1_cbp_t << 2)); + + /********************************************/ + /* Bottoms DC CBF = Top DC CBF */ + /********************************************/ + ps_dec->u1_yuv_dc_csbp_bot_mb = + ps_dec->u1_yuv_dc_csbp_topmb; + + // set motionvectors as + // 3B = 2B = 3T + // 1B = 0B = 2T + // 3T = 2T = 1T + // 1T = 0T = 0T + + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[7] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[3]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[6] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[3]; + + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[5] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[2]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[4] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[2]; + + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[3] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[1]; + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[2] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[1]; + + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[1] = + *(UWORD32 *)pu1_left_mv_ctxt_inc_2d[0]; + + pi1_left_ref_idx_ctxt_inc[7] = (pi1_left_ref_idx_ctxt_inc[3] + - 1); + pi1_left_ref_idx_ctxt_inc[6] = (pi1_left_ref_idx_ctxt_inc[3] + - 1); + + pi1_left_ref_idx_ctxt_inc[5] = (pi1_left_ref_idx_ctxt_inc[1] + - 1); + pi1_left_ref_idx_ctxt_inc[4] = (pi1_left_ref_idx_ctxt_inc[1] + - 1); + + pi1_left_ref_idx_ctxt_inc[3] = (pi1_left_ref_idx_ctxt_inc[2] + - 1); + pi1_left_ref_idx_ctxt_inc[2] = (pi1_left_ref_idx_ctxt_inc[2] + - 1); + + pi1_left_ref_idx_ctxt_inc[1] = (pi1_left_ref_idx_ctxt_inc[0] + - 1); + pi1_left_ref_idx_ctxt_inc[0] = (pi1_left_ref_idx_ctxt_inc[0] + - 1); + } + else + { + u1_cbp_t = ps_leftMB->u1_cbp; + u1_cbp_t = (u1_cbp_t & 0x08); + ps_tempLeft->u1_cbp = (u1_cbp_t | (u1_cbp_t >> 2)); + } + + { + UWORD8 i; + for(i = 0; i < 4; i++) + { + pu1_left_mv_ctxt_inc_2d[i][1] <<= 1; + pu1_left_mv_ctxt_inc_2d[i][3] <<= 1; + } + } + + } + + ps_tempLeft->u1_cbp = ps_tempLeft->u1_cbp + ((u1_cr_cpb >> 4) << 4); + ps_leftMB = ps_tempLeft; + } + + ps_dec->p_left_ctxt_mb_info = ps_leftMB; + } + else + { + ps_dec->p_left_ctxt_mb_info = p_ctx_inc_mb_map - 1; + if(!u4_mbskip) + { + *(ps_dec->pu1_left_yuv_dc_csbp) = 0; + + MEMSET_16BYTES(&pu1_left_mv_ctxt_inc_2d[0][0], 0); + *(UWORD32 *)pi1_left_ref_idx_ctxt_inc = 0; + } + } + + /*************************************************************************/ + /* Now get the top context mb info */ + /*************************************************************************/ + { + UWORD8 (*u1_top_mv_ctxt_inc_arr_2d)[4] = + ps_dec->ps_curr_ctxt_mb_info->u1_mv; + WORD8 (*pi1_top_ref_idx_ctxt_inc) = + ps_dec->ps_curr_ctxt_mb_info->i1_ref_idx; + UWORD8 uc_topMbFldDecFlag = ps_cur_mb_info->ps_top_mb->u1_mb_fld; + + if(u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK) + { + if(ps_cur_mb_info->i1_offset) + ps_dec->p_top_ctxt_mb_info += 1; + + if(!u4_mbskip) + { + memcpy(u1_top_mv_ctxt_inc_arr_2d, + &ps_dec->p_top_ctxt_mb_info->u1_mv, 16); + memcpy(pi1_top_ref_idx_ctxt_inc, + &ps_dec->p_top_ctxt_mb_info->i1_ref_idx, 4); + if(uc_topMbFldDecFlag ^ u1_cur_mb_fld_flag) + { + UWORD8 i; + if(u1_cur_mb_fld_flag) + { + for(i = 0; i < 4; i++) + { + u1_top_mv_ctxt_inc_arr_2d[i][1] >>= 1; + u1_top_mv_ctxt_inc_arr_2d[i][3] >>= 1; + } + } + else + { + for(i = 0; i < 4; i++) + { + u1_top_mv_ctxt_inc_arr_2d[i][1] <<= 1; + u1_top_mv_ctxt_inc_arr_2d[i][3] <<= 1; + pi1_top_ref_idx_ctxt_inc[i] -= 1; + } + } + } + } + } + else + { + ps_dec->p_top_ctxt_mb_info = p_ctx_inc_mb_map - 1; + if(!u4_mbskip) + { + + MEMSET_16BYTES(&u1_top_mv_ctxt_inc_arr_2d[0][0], 0); + memset(pi1_top_ref_idx_ctxt_inc, 0, 4); + } + } + } + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_update_mbaff_left_nnz */ +/* */ +/* Description : This function updates the left luma and chroma nnz for */ +/* mbaff cases. */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Ittiam Draft */ +/* */ +/*****************************************************************************/ +void ih264d_update_mbaff_left_nnz(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + if(ps_cur_mb_info->u1_topmb) + { + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + ps_dec->u4_n_left_temp_y = *pu4_buf; + + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + ps_dec->u4_n_left_temp_uv = *pu4_buf; + } + else + { + + ps_dec->u4_n_leftY[0] = ps_dec->u4_n_left_temp_y; + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + ps_dec->u4_n_leftY[1] = *pu4_buf; + ps_dec->u4_n_left_cr[0] = ps_dec->u4_n_left_temp_uv; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + ps_dec->u4_n_left_cr[1] = *pu4_buf; + + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_get_mbaff_neighbours \endif + * + * \brief + * Gets the neighbors for the current MB if it is of type MB-AFF + * frame. + * + * \return + * None + * + ************************************************************************** + */ +void ih264d_get_mbaff_neighbours(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 uc_curMbFldDecFlag) +{ + + mb_neigbour_params_t *ps_left_mb; + mb_neigbour_params_t *ps_top_mb; + mb_neigbour_params_t *ps_top_right_mb = NULL; + mb_neigbour_params_t *ps_curmb; + const UWORD8 u1_topmb = ps_cur_mb_info->u1_topmb; + const UWORD8 uc_botMb = 1 - u1_topmb; + const UWORD32 u4_mb_x = ps_cur_mb_info->u2_mbx; + + /* Current MbParams location in top row buffer */ + ps_curmb = ps_dec->ps_cur_mb_row + (u4_mb_x << 1) + uc_botMb; + ps_left_mb = ps_curmb - 2; + /* point to A if top else A+1 */ + if(uc_botMb && (ps_left_mb->u1_mb_fld != uc_curMbFldDecFlag)) + { + /* move from A + 1 to A */ + ps_left_mb--; + } + ps_cur_mb_info->i1_offset = 0; + if((uc_curMbFldDecFlag == 0) && uc_botMb) + { + mb_neigbour_params_t *ps_topleft_mb; + /* CurMbAddr - 1 */ + ps_top_mb = ps_curmb - 1; + + /* Mark Top right Not available */ + /* point to A */ + ps_topleft_mb = ps_curmb - 3; + + if(ps_topleft_mb->u1_mb_fld) + { + /* point to A + 1 */ + ps_topleft_mb++; + } + ps_cur_mb_info->u1_topleft_mb_fld = ps_topleft_mb->u1_mb_fld; + ps_cur_mb_info->u1_topleft_mbtype = ps_topleft_mb->u1_mb_type; + } + else + { + /* Top = B + 1 */ + ps_top_mb = ps_dec->ps_top_mb_row + (u4_mb_x << 1) + 1; + ps_top_right_mb = ps_top_mb + 2; + ps_cur_mb_info->i1_offset = 4; + /* TopRight = C + 1 */ + + /* TopLeft = D+1 */ + ps_cur_mb_info->u1_topleft_mb_fld = ps_dec->u1_topleft_mb_fld_bot; + ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype_bot; + + if(uc_curMbFldDecFlag && u1_topmb) + { + if(ps_top_mb->u1_mb_fld) + { + /* MbAddrB */ + ps_top_mb--; + ps_cur_mb_info->i1_offset = 0; + } + /* If topright is field then point to C */ + ps_top_right_mb -= ps_top_right_mb->u1_mb_fld ? 1 : 0; + if(ps_cur_mb_info->u1_topleft_mb_fld) + { + /* TopLeft = D */ + ps_cur_mb_info->u1_topleft_mb_fld = ps_dec->u1_topleft_mb_fld; + ps_cur_mb_info->u1_topleft_mbtype = ps_dec->u1_topleft_mbtype; + } + } + } + if(u1_topmb) + { + /* Update the parameters of topleftmb*/ + ps_dec->u1_topleft_mb_fld = ps_top_mb->u1_mb_fld; + ps_dec->u1_topleft_mbtype = ps_top_mb->u1_mb_type; + /* Set invscan and dequantMatrixScan*/ + if(uc_curMbFldDecFlag) + { + ps_dec->pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_fld; + } + else + { + ps_dec->pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + } + ps_dec->pu2_quant_scale_y = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_y_rem6]; + ps_dec->pu2_quant_scale_u = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_u_rem6]; + ps_dec->pu2_quant_scale_v = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_v_rem6]; + + } + else + { + /* Update the parameters of topleftmb*/ + mb_neigbour_params_t *ps_top_mb_temp = ps_dec->ps_top_mb_row + + (u4_mb_x << 1) + 1; + ps_dec->u1_topleft_mb_fld_bot = ps_top_mb_temp->u1_mb_fld; + ps_dec->u1_topleft_mbtype_bot = ps_top_mb_temp->u1_mb_type; + } + + ps_cur_mb_info->ps_left_mb = ps_left_mb; + ps_cur_mb_info->ps_top_mb = ps_top_mb; + ps_cur_mb_info->ps_top_right_mb = ps_top_right_mb; + ps_cur_mb_info->ps_curmb = ps_curmb; + ps_curmb->u1_mb_fld = uc_curMbFldDecFlag; + + { + /* Form Left NNZ */ + UWORD8 u1_is_left_mb_fld = ps_left_mb->u1_mb_fld; + UWORD8 *pu1_left_mb_pair_nnz_y = (UWORD8 *)&ps_dec->u4_n_leftY[0]; + UWORD8 *pu1_left_mb_pair_nnz_uv = (UWORD8 *)&ps_dec->u4_n_left_cr[0]; + UWORD8 *pu1_left_nnz_y = ps_dec->pu1_left_nnz_y; + UWORD8 *pu1_left_nnz_uv = ps_dec->pu1_left_nnz_uv; + + if(uc_curMbFldDecFlag == u1_is_left_mb_fld) + { + *(UWORD32 *)pu1_left_nnz_y = *(UWORD32 *)(pu1_left_mb_pair_nnz_y + + (uc_botMb << 2)); + *(UWORD32 *)pu1_left_nnz_uv = *(UWORD32 *)(pu1_left_mb_pair_nnz_uv + + (uc_botMb << 2)); + } + else if((uc_curMbFldDecFlag == 0) && u1_topmb && u1_is_left_mb_fld) + { + /* 0 0 1 1 of u4_n_leftY[0], 0 0 2 2 of u4_n_left_cr[0] */ + pu1_left_nnz_y[0] = pu1_left_nnz_y[1] = pu1_left_mb_pair_nnz_y[0]; + pu1_left_nnz_y[2] = pu1_left_nnz_y[3] = pu1_left_mb_pair_nnz_y[1]; + pu1_left_nnz_uv[0] = pu1_left_nnz_uv[1] = + pu1_left_mb_pair_nnz_uv[0]; + pu1_left_nnz_uv[2] = pu1_left_nnz_uv[3] = + pu1_left_mb_pair_nnz_uv[2]; + } + else if((uc_curMbFldDecFlag == 0) && uc_botMb && u1_is_left_mb_fld) + { + /* 2 2 3 3 of u4_n_leftY[0] , 1 1 3 3 of u4_n_left_cr[0] */ + pu1_left_nnz_y[0] = pu1_left_nnz_y[1] = pu1_left_mb_pair_nnz_y[2]; + pu1_left_nnz_y[2] = pu1_left_nnz_y[3] = pu1_left_mb_pair_nnz_y[3]; + pu1_left_nnz_uv[0] = pu1_left_nnz_uv[1] = + pu1_left_mb_pair_nnz_uv[1]; + pu1_left_nnz_uv[2] = pu1_left_nnz_uv[3] = + pu1_left_mb_pair_nnz_uv[3]; + } + else + { + /* 0 2 0 2 of u4_n_leftY[0], u4_n_leftY[1] */ + pu1_left_nnz_y[0] = pu1_left_mb_pair_nnz_y[0]; + pu1_left_nnz_y[1] = pu1_left_mb_pair_nnz_y[2]; + pu1_left_nnz_y[2] = pu1_left_mb_pair_nnz_y[4 + 0]; + pu1_left_nnz_y[3] = pu1_left_mb_pair_nnz_y[4 + 2]; + + /* 0 of u4_n_left_cr[0] and 0 u4_n_left_cr[1] + 2 of u4_n_left_cr[0] and 2 u4_n_left_cr[1] */ + pu1_left_nnz_uv[0] = pu1_left_mb_pair_nnz_uv[0]; + pu1_left_nnz_uv[1] = pu1_left_mb_pair_nnz_uv[4 + 0]; + pu1_left_nnz_uv[2] = pu1_left_mb_pair_nnz_uv[2]; + pu1_left_nnz_uv[3] = pu1_left_mb_pair_nnz_uv[4 + 2]; + } + } +} + +/* + ************************************************************************** + * \if Function name : ih264d_transfer_mb_group_data \endif + * + * \brief + * Transfer the Following things + * N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) + * N-Mb Recon Data ( To Ext Frame Buffer ) + * N-Mb Intrapredline Data ( Updated Internally) + * N-Mb MV Data ( To Ext MV Buffer ) + * N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) + * + * \return + * None + * + ************************************************************************** + */ +void ih264d_transfer_mb_group_data(dec_struct_t * ps_dec, + const WORD8 c_numMbs, + const UWORD8 u1_end_of_row, /* Cur n-Mb End of Row Flag */ + const UWORD8 u1_end_of_row_next /* Next n-Mb End of Row Flag */ + ) +{ + dec_mb_info_t *ps_cur_mb_info = ps_dec->ps_nmb_info; + tfr_ctxt_t *ps_trns_addr = &ps_dec->s_tran_addrecon; + UWORD16 u2_mb_y; + UWORD32 y_offset; + UWORD32 u4_frame_stride; + mb_neigbour_params_t *ps_temp; + const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UNUSED(u1_end_of_row_next); + + ps_trns_addr->pu1_dest_y += ps_trns_addr->u4_inc_y[u1_end_of_row]; + ps_trns_addr->pu1_dest_u += ps_trns_addr->u4_inc_uv[u1_end_of_row]; + ps_trns_addr->pu1_dest_v += ps_trns_addr->u4_inc_uv[u1_end_of_row]; + + /* Swap top and current pointers */ + if(u1_end_of_row) + { + + if(ps_dec->u1_separate_parse) + { + u2_mb_y = ps_dec->i2_dec_thread_mb_y; + } + else + { + ps_temp = ps_dec->ps_cur_mb_row; + ps_dec->ps_cur_mb_row = ps_dec->ps_top_mb_row; + ps_dec->ps_top_mb_row = ps_temp; + + u2_mb_y = ps_dec->u2_mby + (1 + u1_mbaff); + } + + u4_frame_stride = ps_dec->u2_frm_wd_y + << ps_dec->ps_cur_slice->u1_field_pic_flag; + y_offset = (u2_mb_y * u4_frame_stride) << 4; + ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + y_offset; + + u4_frame_stride = ps_dec->u2_frm_wd_uv + << ps_dec->ps_cur_slice->u1_field_pic_flag; + y_offset = (u2_mb_y * u4_frame_stride) << 3; + ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + y_offset; + ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + y_offset; + + ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y; + ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u; + ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v; + } + + /* + * The Slice boundary is also a valid condition to transfer. So recalculate + * the Left increment, in case the number of MBs is lesser than the + * N MB value. c_numMbs will be equal to N of N MB if the entire N Mb is + * decoded. + */ + ps_dec->s_tran_addrecon.u2_mv_left_inc = ((c_numMbs >> u1_mbaff) - 1) + << (4 + u1_mbaff); + ps_dec->s_tran_addrecon.u2_mv_top_left_inc = (c_numMbs << 2) - 1 + - (u1_mbaff << 2); + + if(ps_dec->u1_separate_parse == 0) + { + /* reassign left MV and cur MV pointers */ + ps_dec->ps_mv_left = ps_dec->ps_mv_cur + + ps_dec->s_tran_addrecon.u2_mv_left_inc; + + ps_dec->ps_mv_cur += (c_numMbs << 4); + } + + /* Increment deblock parameters pointer in external memory */ + + if(ps_dec->u1_separate_parse == 1) + { + ps_dec->ps_deblk_mbn_dec_thrd += c_numMbs; + } + else + { + if(ps_dec->u4_mb_level_deblk == 0) + ps_dec->ps_deblk_mbn += c_numMbs; + else + { + deblk_mb_t *temp; + + /*swap previous and curr pointers*/ + ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_mbn_prev; + temp = ps_dec->ps_deblk_mbn_curr; + ps_dec->ps_deblk_mbn_curr = ps_dec->ps_deblk_mbn_prev; + ps_dec->ps_deblk_mbn_prev = temp; + } + } + +} + diff --git a/decoder/ih264d_mb_utils.h b/decoder/ih264d_mb_utils.h new file mode 100755 index 0000000..6e359f5 --- /dev/null +++ b/decoder/ih264d_mb_utils.h @@ -0,0 +1,293 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_MB_UTILS_H_ +#define _IH264D_MB_UTILS_H_ +/*! + ************************************************************************** + * \file ih264d_mb_utils.h + * + * \brief + * Contains declarations of the utility functions needed to decode MB + * + * \date + * 18/12/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" + +/*--------------------------------------------------------------------*/ +/* Macros to get raster scan position of a block[8x8] / sub block[4x4]*/ +/*--------------------------------------------------------------------*/ + +#define GET_BLK_RASTER_POS_X(x) ((x & 0x01) << 1) +#define GET_BLK_RASTER_POS_Y(y) ((y >> 1) << 1) +#define GET_SUB_BLK_RASTER_POS_X(x) ((x & 0x01)) +#define GET_SUB_BLK_RASTER_POS_Y(y) ((y >> 1)) + +/*--------------------------------------------------------------------*/ +/* Masks used in decoding of Macroblock */ +/*--------------------------------------------------------------------*/ + +#define LEFT_MB_AVAILABLE_MASK 0x01 +#define TOP_LEFT_MB_AVAILABLE_MASK 0x02 +#define TOP_MB_AVAILABLE_MASK 0x04 +#define TOP_RIGHT_MB_AVAILABLE_MASK 0x08 + +#define TOP_RT_SUBBLOCK_MASK_MOD 0xFFF7 + +#define TOP_RIGHT_DEFAULT_AVAILABLE 0x5750 +#define TOP_RIGHT_TOPR_AVAILABLE 0x0008 +#define TOP_RIGHT_TOP_AVAILABLE 0x0007 + +#define TOP_LEFT_DEFAULT_AVAILABLE 0xEEE0 +#define TOP_LEFT_TOPL_AVAILABLE 0x0001 +#define TOP_LEFT_TOP_AVAILABLE 0x000E +#define TOP_LEFT_LEFT_AVAILABLE 0x1110 + +#define CHECK_MB_MAP(u4_mb_num, mb_map, u4_cond) \ +{ \ + UWORD32 u4_bit_number; \ + volatile UWORD8 *pu1_mb_flag; \ + \ + u4_bit_number = u4_mb_num & 0x07; \ + pu1_mb_flag = (UWORD8 *)mb_map + (u4_mb_num >> 3); \ + \ + u4_cond = CHECKBIT((*pu1_mb_flag), u4_bit_number); \ +} + +#define CHECK_MB_MAP_BYTE(u4_mb_num, mb_map, u4_cond) \ +{ \ + volatile UWORD8 *pu1_mb_flag; \ + \ + pu1_mb_flag = (UWORD8 *)mb_map + (u4_mb_num ); \ + \ + u4_cond = (*pu1_mb_flag); \ +} + +#define UPDATE_MB_MAP(u2_frm_wd_in_mbs, u2_mbx, u2_mby, mb_map, mb_count) \ +{ \ + UWORD32 u4_bit_number; \ + UWORD32 u4_mb_number; \ + \ + u4_mb_number = u2_frm_wd_in_mbs * (u2_mby >> u1_mbaff) + u2_mbx; \ + \ + u4_bit_number = u4_mb_number & 0x07; \ + /* \ + * In case of MbAff, update the mb_map only if the entire MB is done. We can check that \ + * by checking if Y is odd, implying that this is the second row in the MbAff MB \ + */ \ + SET_BIT(mb_map[u4_mb_number >> 3], u4_bit_number); \ + \ + if (1 == u1_mbaff) \ + { \ + /* \ + * If MBAFF u4_flag is set, set this MB and the MB just below this. \ + * So, add frame width to the MB number and set that bit. \ + */ \ + /* \ + u4_mb_number += u2_frm_wd_in_mbs; \ + \ + u4_bit_number = u4_mb_number & 0x07; \ + \ + SET_BIT(mb_map[u4_mb_number >> 3], u4_bit_number); \ + */ \ + } \ + \ + /*H264_DEC_DEBUG_PRINT("SETBIT: %d\n", u4_mb_number);*/ \ + mb_count++; \ +} + +#define UPDATE_MB_MAP_MBNUM(mb_map, u4_mb_number) \ +{ \ + UWORD32 u4_bit_number; \ + volatile UWORD8 *pu1_mb_flag; \ + \ + u4_bit_number = u4_mb_number & 0x07; \ + pu1_mb_flag = (UWORD8 *)mb_map + (u4_mb_number >> 3); \ + /* \ + * In case of MbAff, update the mb_map only if the entire MB is done. We can check that \ + * by checking if Y is odd, implying that this is the second row in the MbAff MB \ + */ \ + SET_BIT((*pu1_mb_flag), u4_bit_number); \ +} + +#define UPDATE_MB_MAP_MBNUM_BYTE(mb_map, u4_mb_number) \ +{ \ + volatile UWORD8 *pu1_mb_flag; \ + \ + pu1_mb_flag = (UWORD8 *)mb_map + (u4_mb_number); \ + /* \ + * In case of MbAff, update the mb_map only if the entire MB is done. We can check that \ + * by checking if Y is odd, implying that this is the second row in the MbAff MB \ + */ \ + (*pu1_mb_flag) = 1; \ +} + +#define UPDATE_SLICE_NUM_MAP(slice_map, u4_mb_number,u2_slice_num) \ +{ \ + volatile UWORD16 *pu2_slice_map; \ + \ + pu2_slice_map = (UWORD16 *)slice_map + (u4_mb_number); \ + (*pu2_slice_map) = u2_slice_num; \ +} + +#define GET_SLICE_NUM_MAP(slice_map, mb_number,u2_slice_num) \ +{ \ + volatile UWORD16 *pu2_slice_map; \ + \ + pu2_slice_map = (UWORD16 *)slice_map + (mb_number); \ + u2_slice_num = (*pu2_slice_map) ; \ +} + + +#define GET_XPOS_PRED(u1_out,pkd_info) \ +{ \ + WORD32 bit_field; \ + bit_field = pkd_info & 0x3; \ + u1_out = bit_field; \ +} + + +#define GET_YPOS_PRED(u1_out,pkd_info) \ +{ \ + WORD32 bit_field; \ + bit_field = pkd_info >> 2; \ + u1_out = bit_field & 0x3; \ +} + + + +#define GET_WIDTH_PRED(u1_out,pkd_info) \ +{ \ + WORD32 bit_field; \ + bit_field = pkd_info >> 4; \ + bit_field = (bit_field & 0x3) << 1 ; \ + u1_out = (bit_field == 0)?1:bit_field; \ + } + +#define GET_HEIGHT_PRED(u1_out,pkd_info) \ +{ \ + WORD32 bit_field; \ + bit_field = pkd_info >> 6; \ + bit_field = (bit_field & 0x3) << 1 ; \ + u1_out = (bit_field == 0)?1:bit_field; \ +} + +/*! + ************************************************************************** + * \brief Masks for elements present in the first column but not on the + * first row. + ************************************************************************** + */ +#define FIRST_COL_NOT_FIRST_ROW 0xFAFB +#define FIRST_ROW_MASK 0xFFCC +/*! + ************************************************************************** + * \brief Mask for elements presen in the first row but not in the + * last column. + ************************************************************************** + */ +#define FIRST_ROW_NOT_LAST_COL 0xFFEC +/*! + ************************************************************************** + * \brief Mask for elements presen in the first row but not in the + * first column. + ************************************************************************** + */ +#define FIRST_ROW_NOT_FIRST_COL 0xFFCD +/*! + ************************************************************************** + * \brief Masks for the top right subMB of a 4x4 block + ************************************************************************** + */ +#define TOP_RT_SUBBLOCK_MASK 0xFFDF +/*! + ************************************************************************** + * \brief Masks for the top left subMB of a 4x4 block + ************************************************************************** + */ +#define TOP_LT_SUBBLOCK_MASK 0xFFFE +/*! + ************************************************************************** + * \brief Indicates if a subMB has a top right subMB available + ************************************************************************** + */ +#define TOP_RT_SUBBLOCK_MB_MASK 0x5F4C + +#define FIRST_COL_MASK 0xFAFA + +/*--------------------------------------------------------------------*/ +/* Macros to calculate the current position of a MB wrt picture */ +/*--------------------------------------------------------------------*/ +#define MB_LUMA_PIC_OFFSET(mb_x,mb_y,frmWidthY) (((mb_y)*(frmWidthY) + (mb_x))<<4) +#define MB_CHROMA_PIC_OFFSET(mb_x,mb_y,frmWidthUV) (((mb_y)*(frmWidthUV) + (mb_x))<<3) + +/*--------------------------------------------------------------------*/ +/* Macros to calculate the current position of a MB wrt N[ Num coeff] Array */ +/*--------------------------------------------------------------------*/ +#define MB_PARAM_OFFSET(mb_x,mb_y,frmWidthInMbs,u1_mbaff,u1_topmb) \ + ((mb_x << u1_mbaff) + (1 - u1_topmb) + (mb_y * frmWidthInMbs)) + +UWORD32 ih264d_get_mb_info_cavlc_mbaff(dec_struct_t * ps_dec, + const UWORD16 ui16_curMbAddress, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run); +UWORD32 ih264d_get_mb_info_cavlc_nonmbaff(dec_struct_t * ps_dec, + const UWORD16 ui16_curMbAddress, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run); + +UWORD32 ih264d_get_mb_info_cabac_mbaff(dec_struct_t * ps_dec, + const UWORD16 ui16_curMbAddress, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run); + +UWORD32 ih264d_get_mb_info_cabac_nonmbaff(dec_struct_t * ps_dec, + const UWORD16 ui16_curMbAddress, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run); + +UWORD8 get_cabac_context_non_mbaff(dec_struct_t * ps_dec, UWORD16 u2_mbskip); + +UWORD32 ih264d_get_cabac_context_mbaff(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip); + +WORD32 PutMbToFrame(dec_struct_t * ps_dec); +void ih264d_get_mbaff_neighbours(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 uc_curMbFldDecFlag); + +void ih264d_update_mbaff_left_nnz(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_transfer_mb_group_data(dec_struct_t * ps_dec, + const WORD8 c_numMbs, + const UWORD8 u1_end_of_row, /* Cur n-Mb End of Row Flag */ + const UWORD8 u1_end_of_row_next /* Next n-Mb End of Row Flag */ + ); + +//void FillRandomData(UWORD8 *pu1_buf, WORD32 u4_bufSize); + +#endif /* _MB_UTILS_H_ */ diff --git a/decoder/ih264d_mem_request.h b/decoder/ih264d_mem_request.h new file mode 100755 index 0000000..3c60c72 --- /dev/null +++ b/decoder/ih264d_mem_request.h @@ -0,0 +1,82 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_MEM_REQUEST_H_ +#define _IH264D_MEM_REQUEST_H_ +/*! + *************************************************************************** + * \file ih264d_mem_request.h + * + * \brief + * This file contains declarations and data structures of the API's which + * required to interact with Picture Buffer. + * + * + * \date + * 11/12/2002 + * + * \author NS + ***************************************************************************/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_defs.h" +#include "ih264d_structs.h" + +#define MAX_MEM_BLOCKS 64 + 8 + +struct MemBlock +{ + void ** v_memLocation; /** memory location where address of allocated memory should be stored*/ + UWORD32 u4_mem_size; /** Size of the memory block */ +}; + +struct MemReq +{ + UWORD32 u4_num_memBlocks; /** Number of memory blocks */ + struct MemBlock s_memBlock[MAX_MEM_BLOCKS]; /** Pointer to the first memory block */ +}; + +struct PicMemBlock +{ + void * buf1; /** memory location for buf1 */ + void * buf2; /** memory location for buf2 */ + void * buf3; /** memory location for buf3 */ +}; + +struct PicMemReq +{ + WORD32 i4_num_pic_memBlocks; /** Number of memory blocks */ + UWORD32 u4_size1; /** Size of the buf1 in PicMemBlock */ + UWORD32 u4_size2; /** Size of the buf2 in PicMemBlock */ + UWORD32 u4_size3; /** Size of the buf3 in PicMemBlock */ + struct PicMemBlock s_PicMemBlock[MAX_DISP_BUFS_NEW]; +}; + +WORD32 ih264d_create_pic_buffers(UWORD8 u1_num_of_buf, + dec_struct_t *ps_dec); + +WORD32 ih264d_create_mv_bank(void * pv_codec_handle, + UWORD32 u4_wd, + UWORD32 u4_ht); +WORD16 ih264d_get_memory_dec_params(dec_struct_t * ps_dec); + + +#endif /* _IH264D_MEM_REQUEST_H_ */ diff --git a/decoder/ih264d_mvpred.c b/decoder/ih264d_mvpred.c new file mode 100755 index 0000000..fb4932f --- /dev/null +++ b/decoder/ih264d_mvpred.c @@ -0,0 +1,1193 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_mvpred.c + * + * \brief + * This file contains function specific to decoding Motion vector. + * + * Detailed_description + * + * \date + * 10-12-2002 + * + * \author Arvind Raman + ************************************************************************** + */ +#include <string.h> +#include "ih264d_parse_cavlc.h" +#include "ih264d_error_handler.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_mb_utils.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_process_bslice.h" +#include "ih264d_mvpred.h" +#include "ih264d_inter_pred.h" +#include "ih264d_tables.h" + +/*! + ************************************************************************** + * \if ih264d_get_motion_vector_predictor name : Name \endif + * + * \brief + * The routine calculates the motion vector predictor for a given block, + * given the candidate MV predictors. + * + * \param ps_mv_pred: Candidate predictors for the current block + * \param ps_currMv: Pointer to the left top edge of the current block in + * the MV bank + * + * \return + * _mvPred: The x & y components of the MV predictor. + * + * \note + * The code implements the logic as described in sec 8.4.1.2.1. Given + * the candidate predictors and the pointer to the top left edge of the + * block in the MV bank. + * + ************************************************************************** + */ + +void ih264d_get_motion_vector_predictor(mv_pred_t * ps_result, + mv_pred_t **ps_mv_pred, + UWORD8 u1_ref_idx, + UWORD8 u1_B, + const UWORD8 *pu1_mv_pred_condition) +{ + WORD8 c_temp; + UWORD8 uc_B2 = (u1_B << 1); + + /* If only one of the candidate blocks has a reference frame equal to + the current block then use the same block as the final predictor */ + c_temp = + (ps_mv_pred[LEFT]->i1_ref_frame[u1_B] == u1_ref_idx) + | ((ps_mv_pred[TOP]->i1_ref_frame[u1_B] + == u1_ref_idx) << 1) + | ((ps_mv_pred[TOP_R]->i1_ref_frame[u1_B] + == u1_ref_idx) << 2); + c_temp = pu1_mv_pred_condition[c_temp]; + + if(c_temp != -1) + { + /* Case when only when one of the cadidate block has the same + reference frame as the current block */ + ps_result->i2_mv[uc_B2 + 0] = ps_mv_pred[c_temp]->i2_mv[uc_B2 + 0]; + ps_result->i2_mv[uc_B2 + 1] = ps_mv_pred[c_temp]->i2_mv[uc_B2 + 1]; + } + else + { + WORD32 D0, D1; + D0 = MIN(ps_mv_pred[0]->i2_mv[uc_B2 + 0], + ps_mv_pred[1]->i2_mv[uc_B2 + 0]); + D1 = MAX(ps_mv_pred[0]->i2_mv[uc_B2 + 0], + ps_mv_pred[1]->i2_mv[uc_B2 + 0]); + D1 = MIN(D1, ps_mv_pred[2]->i2_mv[uc_B2 + 0]); + ps_result->i2_mv[uc_B2 + 0] = (WORD16)(MAX(D0, D1)); + + D0 = MIN(ps_mv_pred[0]->i2_mv[uc_B2 + 1], + ps_mv_pred[1]->i2_mv[uc_B2 + 1]); + D1 = MAX(ps_mv_pred[0]->i2_mv[uc_B2 + 1], + ps_mv_pred[1]->i2_mv[uc_B2 + 1]); + D1 = MIN(D1, ps_mv_pred[2]->i2_mv[uc_B2 + 1]); + ps_result->i2_mv[uc_B2 + 1] = (WORD16)(MAX(D0, D1)); + + } +} + +/*! + ************************************************************************** + * \if ih264d_mbaff_mv_pred name : Name \endif + * + * \brief + * The routine calculates the motion vector predictor for a given block, + * given the candidate MV predictors. + * + * \param ps_mv_pred: Candidate predictors for the current block + * \param ps_currMv: Pointer to the left top edge of the current block in + * the MV bank + * + * \return + * _mvPred: The x & y components of the MV predictor. + * + * \note + * The code implements the logic as described in sec 8.4.1.2.1. Given + * the candidate predictors and the pointer to the top left edge of the + * block in the MV bank. + * + ************************************************************************** + */ + +void ih264d_mbaff_mv_pred(mv_pred_t **ps_mv_pred, + UWORD8 u1_sub_mb_num, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + dec_struct_t *ps_dec, + UWORD8 uc_mb_part_width, + dec_mb_info_t *ps_cur_mb_info, + UWORD8* pu0_scale) +{ + UWORD16 u2_a_in = 0, u2_b_in = 0, u2_c_in = 0, u2_d_in = 0; + mv_pred_t *ps_mvpred_l, *ps_mvpred_tmp; + UWORD8 u1_sub_mb_x = (u1_sub_mb_num & 3), uc_sub_mb_y = (u1_sub_mb_num >> 2); + UWORD8 u1_is_cur_mb_fld, u1_is_left_mb_fld, u1_is_top_mb_fld; + UWORD8 u1_is_cur_mb_top; + + u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + u1_is_cur_mb_top = ps_cur_mb_info->u1_topmb; + + u1_is_left_mb_fld = ps_cur_mb_info->ps_left_mb->u1_mb_fld; + u1_is_top_mb_fld = ps_cur_mb_info->ps_top_mb->u1_mb_fld; + + /* Checking in the subMB exists, calculating their motion vectors to be + used as predictors and the reference frames of those subMBs */ + ps_mv_pred[LEFT] = &ps_dec->s_default_mv_pred; + ps_mv_pred[TOP] = &(ps_dec->s_default_mv_pred); + ps_mv_pred[TOP_R] = &(ps_dec->s_default_mv_pred); + + /* Check if the left subMb is available */ + if(u1_sub_mb_x) + { + u2_a_in = 1; + ps_mv_pred[LEFT] = (ps_mv_nmb - 1); + } + else + { + UWORD8 uc_temp; + u2_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK); + if(u2_a_in) + { + ps_mvpred_l = (ps_dec->u4_num_pmbair) ? + ps_mv_nmb : + (ps_dec->ps_mv_left + (uc_sub_mb_y << 2) + 48 + - (u1_is_cur_mb_top << 4)); + uc_temp = 29; + if(u1_is_cur_mb_fld ^ u1_is_left_mb_fld) + { + if(u1_is_left_mb_fld) + { + uc_temp += + (((uc_sub_mb_y & 1) << 2) + + ((uc_sub_mb_y & 2) << 1)); + uc_temp += ((u1_is_cur_mb_top) ? 0 : 8); + } + else + { + uc_temp = uc_temp - (uc_sub_mb_y << 2); + uc_temp += ((u1_is_cur_mb_top) ? 0 : 16); + } + } + ps_mv_pred[LEFT] = (ps_mvpred_l - uc_temp); + pu0_scale[LEFT] = u1_is_cur_mb_fld - u1_is_left_mb_fld; + } + } + + /* Check if the top subMB is available */ + if((uc_sub_mb_y > 0) || ((u1_is_cur_mb_top | u1_is_cur_mb_fld) == 0)) + { + u2_b_in = 1; + ps_mv_pred[TOP] = ps_mv_nmb - 4; + } + else + { + u2_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK); + if(u2_b_in) + { + /* CHANGED CODE */ + + if(u1_is_top_mb_fld && u1_is_cur_mb_fld) + ps_mvpred_tmp = ps_mv_ntop; + else + { + ps_mvpred_tmp = ps_mv_ntop; + if(u1_is_cur_mb_top) + ps_mvpred_tmp += 16; + } + + ps_mv_pred[TOP] = ps_mvpred_tmp; + pu0_scale[TOP] = u1_is_cur_mb_fld - u1_is_top_mb_fld; + } + } + + /* Check if the top right subMb is available. The top right subMb is + defined as the top right subMb at the top right corner of the MB + partition. The top right subMb index starting from the top left + corner of the MB partition is given by + TopRightSubMbIndx = TopLeftSubMbIndx + (WidthOfMbPartition - 6) / 2 + */ + u2_c_in = CHECKBIT(ps_cur_mb_info->u2_top_right_avail_mask, + (u1_sub_mb_num + uc_mb_part_width - 1)); + if(u2_c_in) + { + ps_mv_pred[TOP_R] = ps_mv_pred[TOP] + uc_mb_part_width; + pu0_scale[TOP_R] = pu0_scale[TOP]; + if((uc_sub_mb_y == 0) && ((u1_sub_mb_x + uc_mb_part_width) > 3)) + { + UWORD8 uc_isTopRtMbFld; + uc_isTopRtMbFld = ps_cur_mb_info->ps_top_right_mb->u1_mb_fld; + /* CHANGED CODE */ + ps_mvpred_tmp = ps_mv_ntop + uc_mb_part_width + 12; + ps_mvpred_tmp += (u1_is_cur_mb_top) ? 16 : 0; + ps_mvpred_tmp += (u1_is_cur_mb_fld && u1_is_cur_mb_top && uc_isTopRtMbFld) ? + 0 : 16; + ps_mv_pred[TOP_R] = ps_mvpred_tmp; + pu0_scale[TOP_R] = u1_is_cur_mb_fld - uc_isTopRtMbFld; + } + } + else + { + u2_d_in = CHECKBIT(ps_cur_mb_info->u2_top_left_avail_mask, u1_sub_mb_num); + + /* Check if the the top left subMB is available */ + if(u2_d_in) + { + UWORD8 uc_isTopLtMbFld; + + ps_mv_pred[TOP_R] = ps_mv_pred[TOP] - 1; + pu0_scale[TOP_R] = pu0_scale[TOP]; + + if(u1_sub_mb_x == 0) + { + if((uc_sub_mb_y > 0) || ((u1_is_cur_mb_top | u1_is_cur_mb_fld) == 0)) + { + uc_isTopLtMbFld = u1_is_left_mb_fld; + ps_mvpred_tmp = ps_mv_pred[LEFT] - 4; + + if((u1_is_cur_mb_fld == 0) && uc_isTopLtMbFld) + { + ps_mvpred_tmp = ps_mv_pred[LEFT] + 16; + ps_mvpred_tmp -= (uc_sub_mb_y & 1) ? 0 : 4; + } + } + else + { + UWORD32 u4_cond = ps_dec->u4_num_pmbair; + uc_isTopLtMbFld = ps_cur_mb_info->u1_topleft_mb_fld; + + /* CHANGED CODE */ + ps_mvpred_tmp = ps_mv_ntop - 29; + ps_mvpred_tmp += (u1_is_cur_mb_top) ? 16 : 0; + if(u1_is_cur_mb_fld && u1_is_cur_mb_top) + ps_mvpred_tmp -= (uc_isTopLtMbFld) ? 16 : 0; + } + ps_mv_pred[TOP_R] = ps_mvpred_tmp; + pu0_scale[TOP_R] = u1_is_cur_mb_fld - uc_isTopLtMbFld; + } + } + else if(u2_b_in == 0) + { + /* If all the subMBs B, C, D are all out of the frame then their MV + and their reference picture is equal to that of A */ + ps_mv_pred[TOP] = ps_mv_pred[LEFT]; + ps_mv_pred[TOP_R] = ps_mv_pred[LEFT]; + pu0_scale[TOP] = pu0_scale[LEFT]; + pu0_scale[TOP_R] = pu0_scale[LEFT]; + } + } +} + +/*! + ************************************************************************** + * \if ih264d_non_mbaff_mv_pred name : Name \endif + * + * \brief + * The routine calculates the motion vector predictor for a given block, + * given the candidate MV predictors. + * + * \param ps_mv_pred: Candidate predictors for the current block + * \param ps_currMv: Pointer to the left top edge of the current block in + * the MV bank + * + * \return + * _mvPred: The x & y components of the MV predictor. + * + * \note + * The code implements the logic as described in sec 8.4.1.2.1. Given + * the candidate predictors and the pointer to the top left edge of the + * block in the MV bank. + * + ************************************************************************** + */ +#if(!MVPRED_NONMBAFF) +void ih264d_non_mbaff_mv_pred(mv_pred_t **ps_mv_pred, + UWORD8 u1_sub_mb_num, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + dec_struct_t *ps_dec, + UWORD8 uc_mb_part_width, + dec_mb_info_t *ps_cur_mb_info) +{ + UWORD16 u2_b_in = 0, u2_c_in = 0, u2_d_in = 0; + UWORD8 u1_sub_mb_x = (u1_sub_mb_num & 3), uc_sub_mb_y = (u1_sub_mb_num >> 2); + + /* Checking in the subMB exists, calculating their motion vectors to be + used as predictors and the reference frames of those subMBs */ + + ps_mv_pred[LEFT] = &ps_dec->s_default_mv_pred; + ps_mv_pred[TOP] = &(ps_dec->s_default_mv_pred); + ps_mv_pred[TOP_R] = &(ps_dec->s_default_mv_pred); + /* Check if the left subMb is available */ + + if(u1_sub_mb_x) + { + ps_mv_pred[LEFT] = (ps_mv_nmb - 1); + } + else + { + if(ps_cur_mb_info->u1_mb_ngbr_availablity & LEFT_MB_AVAILABLE_MASK) + { + ps_mv_pred[LEFT] = (ps_mv_nmb - 13); + } + } + + /* Check if the top subMB is available */ + if(uc_sub_mb_y) + { + u2_b_in = 1; + ps_mv_ntop = ps_mv_nmb - 4; + ps_mv_pred[TOP] = ps_mv_ntop; + + } + else + { + u2_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & TOP_MB_AVAILABLE_MASK); + if(u2_b_in) + { + ps_mv_pred[TOP] = ps_mv_ntop; + } + } + + /* Check if the top right subMb is available. The top right subMb is + defined as the top right subMb at the top right corner of the MB + partition. The top right subMb index starting from the top left + corner of the MB partition is given by + TopRightSubMbIndx = TopLeftSubMbIndx + (WidthOfMbPartition - 6) / 2 + */ + u2_c_in = CHECKBIT(ps_cur_mb_info->u2_top_right_avail_mask, + (u1_sub_mb_num + uc_mb_part_width - 1)); + if(u2_c_in) + { + ps_mv_pred[TOP_R] = (ps_mv_ntop + uc_mb_part_width); + + if(uc_sub_mb_y == 0) + { + /* CHANGED CODE */ + if((u1_sub_mb_x + uc_mb_part_width) > 3) + ps_mv_pred[TOP_R] += 12; + } + } + else + { + u2_d_in = CHECKBIT(ps_cur_mb_info->u2_top_left_avail_mask, u1_sub_mb_num); + /* Check if the the top left subMB is available */ + if(u2_d_in) + { + /* CHANGED CODE */ + ps_mv_pred[TOP_R] = (ps_mv_ntop - 1); + if(u1_sub_mb_x == 0) + { + if(uc_sub_mb_y) + { + ps_mv_pred[TOP_R] = (ps_mv_nmb - 17); + } + else + { + /* CHANGED CODE */ + ps_mv_pred[TOP_R] -= 12; + } + } + } + else if(u2_b_in == 0) + { + /* If all the subMBs B, C, D are all out of the frame then their MV + and their reference picture is equal to that of A */ + ps_mv_pred[TOP] = ps_mv_pred[LEFT]; + ps_mv_pred[TOP_R] = ps_mv_pred[LEFT]; + } + } +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_mvpred_nonmbaffB */ +/* */ +/* Description : This function calculates the motion vector predictor, */ +/* for B-Slices */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : None */ +/* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */ +/* and based on the type of Mb the prediction is */ +/* appropriately done */ +/* Outputs : populates ps_mv_final_pred structure */ +/* Returns : u1_direct_zero_pred_flag which is used only in */ +/* decodeSpatialdirect() */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 03 05 2005 TA First Draft */ +/* */ +/*****************************************************************************/ +#if(!MVPRED_NONMBAFF) +UWORD8 ih264d_mvpred_nonmbaffB(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode) +{ + UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3; + mv_pred_t *ps_mv_pred[3]; + UWORD8 uc_B2, uc_lx, u1_ref_idx; + UWORD8 u1_direct_zero_pred_flag = 0; + + ih264d_non_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop, + ps_dec, uc_mb_part_width, ps_cur_mb_info); + + for(uc_lx = u1_lx_start; uc_lx < u1_lxend; uc_lx++) + { + u1_ref_idx = ps_mv_final_pred->i1_ref_frame[uc_lx]; + uc_B2 = (uc_lx << 1); + switch(u1_mb_mc_mode) + { + case PRED_16x8: + /* Directional prediction for a 16x8 MB partition */ + if(u1_sub_mb_num == 0) + { + /* Calculating the MV pred for the top 16x8 block */ + if(ps_mv_pred[TOP]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the top subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the top + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[TOP]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[TOP]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case PRED_8x16: + /* Directional prediction for a 8x16 MB partition */ + if(u1_sub_mb_num == 0) + { + if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[TOP_R]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the top right subMB is same as + the reference frame used by the current block then MV + predictor to be used for the current block is same as the MV + of the left subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case B_DIRECT_SPATIAL: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0]; + + ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1]; + + ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + if((ps_mv_final_pred->i1_ref_frame[0] < 0) + && (ps_mv_final_pred->i1_ref_frame[1] < 0)) + { + u1_direct_zero_pred_flag = 1; + ps_mv_final_pred->i1_ref_frame[0] = 0; + ps_mv_final_pred->i1_ref_frame[1] = 0; + } + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[0], 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[1], 1, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + break; + case MB_SKIP: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + LEFT_MB_AVAILABLE_MASK); + u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + TOP_MB_AVAILABLE_MASK); + if(((u1_a_in * u1_b_in) == 0) + || ((ps_mv_pred[LEFT]->i2_mv[0] + | ps_mv_pred[LEFT]->i2_mv[1] + | ps_mv_pred[LEFT]->i1_ref_frame[0]) + == 0) + || ((ps_mv_pred[TOP]->i2_mv[0] + | ps_mv_pred[TOP]->i2_mv[1] + | ps_mv_pred[TOP]->i1_ref_frame[0]) + == 0)) + { + ps_mv_final_pred->i2_mv[0] = 0; + ps_mv_final_pred->i2_mv[1] = 0; + break; + } + /* If the condition above is not true calculate the MV predictor + according to the process defined in sec 8.4.1.2.1 */ + default: + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, u1_ref_idx, uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + break; + } + } + return (u1_direct_zero_pred_flag); +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_mvpred_nonmbaff */ +/* */ +/* Description : This function calculates the motion vector predictor, */ +/* for all the slice types other than B_SLICE */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : None */ +/* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */ +/* and based on the type of Mb the prediction is */ +/* appropriately done */ +/* Outputs : populates ps_mv_final_pred structure */ +/* Returns : u1_direct_zero_pred_flag which is used only in */ +/* decodeSpatialdirect() */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 03 05 2005 TA First Draft */ +/* */ +/*****************************************************************************/ +#if(!MVPRED_NONMBAFF) +UWORD8 ih264d_mvpred_nonmbaff(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode) +{ + UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3; + mv_pred_t *ps_mv_pred[3]; + UWORD8 u1_ref_idx; + UWORD8 u1_direct_zero_pred_flag = 0; + UNUSED(u1_lx_start); + UNUSED(u1_lxend); + ih264d_non_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop, + ps_dec, uc_mb_part_width, ps_cur_mb_info); + + u1_ref_idx = ps_mv_final_pred->i1_ref_frame[0]; + + switch(u1_mb_mc_mode) + { + case PRED_16x8: + /* Directional prediction for a 16x8 MB partition */ + if(u1_sub_mb_num == 0) + { + /* Calculating the MV pred for the top 16x8 block */ + if(ps_mv_pred[TOP]->i1_ref_frame[0] == u1_ref_idx) + { + /* If the reference frame used by the top subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the top + subMB */ + + ps_mv_final_pred->i2_mv[0] = ps_mv_pred[TOP]->i2_mv[0]; + ps_mv_final_pred->i2_mv[1] = ps_mv_pred[TOP]->i2_mv[1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[LEFT]->i1_ref_frame[0] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + + ps_mv_final_pred->i2_mv[0] = ps_mv_pred[LEFT]->i2_mv[0]; + ps_mv_final_pred->i2_mv[1] = ps_mv_pred[LEFT]->i2_mv[1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case PRED_8x16: + /* Directional prediction for a 8x16 MB partition */ + if(u1_sub_mb_num == 0) + { + if(ps_mv_pred[LEFT]->i1_ref_frame[0] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + + ps_mv_final_pred->i2_mv[0] = ps_mv_pred[LEFT]->i2_mv[0]; + ps_mv_final_pred->i2_mv[1] = ps_mv_pred[LEFT]->i2_mv[1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[TOP_R]->i1_ref_frame[0] == u1_ref_idx) + { + /* If the reference frame used by the top right subMB is same as + the reference frame used by the current block then MV + predictor to be used for the current block is same as the MV + of the left subMB */ + + ps_mv_final_pred->i2_mv[0] = ps_mv_pred[TOP_R]->i2_mv[0]; + ps_mv_final_pred->i2_mv[1] = ps_mv_pred[TOP_R]->i2_mv[1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case B_DIRECT_SPATIAL: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0]; + + ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1]; + + ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + if((ps_mv_final_pred->i1_ref_frame[0] < 0) + && (ps_mv_final_pred->i1_ref_frame[1] < 0)) + { + u1_direct_zero_pred_flag = 1; + ps_mv_final_pred->i1_ref_frame[0] = 0; + ps_mv_final_pred->i1_ref_frame[1] = 0; + } + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[0], 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[1], 1, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + break; + case MB_SKIP: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + LEFT_MB_AVAILABLE_MASK); + u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + TOP_MB_AVAILABLE_MASK); + if(((u1_a_in * u1_b_in) == 0) + || ((ps_mv_pred[LEFT]->i2_mv[0] + | ps_mv_pred[LEFT]->i2_mv[1] + | ps_mv_pred[LEFT]->i1_ref_frame[0]) + == 0) + || ((ps_mv_pred[TOP]->i2_mv[0] + | ps_mv_pred[TOP]->i2_mv[1] + | ps_mv_pred[TOP]->i1_ref_frame[0]) + == 0)) + { + + ps_mv_final_pred->i2_mv[0] = 0; + ps_mv_final_pred->i2_mv[1] = 0; + break; + } + /* If the condition above is not true calculate the MV predictor + according to the process defined in sec 8.4.1.2.1 */ + default: + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, u1_ref_idx, 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + break; + } + + return (u1_direct_zero_pred_flag); +} +#endif + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_mvpred_mbaff */ +/* */ +/* Description : This function calculates the motion vector predictor, */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : None */ +/* Processing : The neighbours A(Left),B(Top),C(TopRight) are calculated */ +/* and based on the type of Mb the prediction is */ +/* appropriately done */ +/* Outputs : populates ps_mv_final_pred structure */ +/* Returns : u1_direct_zero_pred_flag which is used only in */ +/* decodeSpatialdirect() */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 03 05 2005 TA First Draft */ +/* */ +/*****************************************************************************/ + +UWORD8 ih264d_mvpred_mbaff(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode) +{ + UWORD8 u1_a_in, u1_b_in, uc_temp1, uc_temp2, uc_temp3; + mv_pred_t *ps_mv_pred[3], s_mvPred[3]; + UWORD8 uc_B2, pu0_scale[3], i, uc_lx, u1_ref_idx; + UWORD8 u1_direct_zero_pred_flag = 0; + + pu0_scale[0] = pu0_scale[1] = pu0_scale[2] = 0; + ih264d_mbaff_mv_pred(ps_mv_pred, u1_sub_mb_num, ps_mv_nmb, ps_mv_ntop, ps_dec, + uc_mb_part_width, ps_cur_mb_info, pu0_scale); + for(i = 0; i < 3; i++) + { + if(pu0_scale[i] != 0) + { + memcpy(&s_mvPred[i], ps_mv_pred[i], sizeof(mv_pred_t)); + if(pu0_scale[i] == 1) + { + s_mvPred[i].i1_ref_frame[0] = s_mvPred[i].i1_ref_frame[0] << 1; + s_mvPred[i].i1_ref_frame[1] = s_mvPred[i].i1_ref_frame[1] << 1; + s_mvPred[i].i2_mv[1] = SIGN_POW2_DIV(s_mvPred[i].i2_mv[1], 1); + s_mvPred[i].i2_mv[3] = SIGN_POW2_DIV(s_mvPred[i].i2_mv[3], 1); + } + else + { + s_mvPred[i].i1_ref_frame[0] = s_mvPred[i].i1_ref_frame[0] >> 1; + s_mvPred[i].i1_ref_frame[1] = s_mvPred[i].i1_ref_frame[1] >> 1; + s_mvPred[i].i2_mv[1] = s_mvPred[i].i2_mv[1] << 1; + s_mvPred[i].i2_mv[3] = s_mvPred[i].i2_mv[3] << 1; + } + ps_mv_pred[i] = &s_mvPred[i]; + } + } + + for(uc_lx = u1_lx_start; uc_lx < u1_lxend; uc_lx++) + { + u1_ref_idx = ps_mv_final_pred->i1_ref_frame[uc_lx]; + uc_B2 = (uc_lx << 1); + switch(u1_mb_mc_mode) + { + case PRED_16x8: + /* Directional prediction for a 16x8 MB partition */ + if(u1_sub_mb_num == 0) + { + /* Calculating the MV pred for the top 16x8 block */ + if(ps_mv_pred[TOP]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the top subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the top + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[TOP]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[TOP]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case PRED_8x16: + /* Directional prediction for a 8x16 MB partition */ + if(u1_sub_mb_num == 0) + { + if(ps_mv_pred[LEFT]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the left subMB is same as the + reference frame used by the current block then MV predictor to + be used for the current block is same as the MV of the left + subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[LEFT]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + else + { + if(ps_mv_pred[TOP_R]->i1_ref_frame[uc_lx] == u1_ref_idx) + { + /* If the reference frame used by the top right subMB is same as + the reference frame used by the current block then MV + predictor to be used for the current block is same as the MV + of the left subMB */ + ps_mv_final_pred->i2_mv[uc_B2 + 0] = + ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 0]; + ps_mv_final_pred->i2_mv[uc_B2 + 1] = + ps_mv_pred[TOP_R]->i2_mv[uc_B2 + 1]; + } + else + { + /* The MV predictor is calculated according to the process + defined in 8.4.1.2.1 */ + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, + ps_mv_pred, + u1_ref_idx, + uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + } + } + break; + case B_DIRECT_SPATIAL: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[0]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[0]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[0]; + + ps_mv_final_pred->i1_ref_frame[0] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + uc_temp1 = (UWORD8)ps_mv_pred[LEFT]->i1_ref_frame[1]; + uc_temp2 = (UWORD8)ps_mv_pred[TOP]->i1_ref_frame[1]; + uc_temp3 = (UWORD8)ps_mv_pred[TOP_R]->i1_ref_frame[1]; + + ps_mv_final_pred->i1_ref_frame[1] = MIN(uc_temp1, + MIN(uc_temp2, uc_temp3)); + + /* If the reference indices are negative clip the scaled reference indices to -1 */ + /* i.e invalid reference index */ + + /*if(ps_mv_final_pred->i1_ref_frame[0] < 0) + ps_mv_final_pred->i1_ref_frame[0] = -1; + + if(ps_mv_final_pred->i1_ref_frame[1] < 0) + ps_mv_final_pred->i1_ref_frame[1] = -1; */ + + if((ps_mv_final_pred->i1_ref_frame[0] < 0) + && (ps_mv_final_pred->i1_ref_frame[1] < 0)) + { + u1_direct_zero_pred_flag = 1; + ps_mv_final_pred->i1_ref_frame[0] = 0; + ps_mv_final_pred->i1_ref_frame[1] = 0; + } + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[0], 0, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, + ps_mv_final_pred->i1_ref_frame[1], 1, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + + break; + case MB_SKIP: + /* Case when the MB has been skipped */ + /* If either of left or the top subMB is not present + OR + If both the MV components of either the left or the top subMB are + zero and their reference frame pointer pointing to 0 + then MV for the skipped MB is zero + else the Median of the mv_pred_t is used */ + u1_a_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + LEFT_MB_AVAILABLE_MASK); + u1_b_in = (ps_cur_mb_info->u1_mb_ngbr_availablity & + TOP_MB_AVAILABLE_MASK); + if(((u1_a_in * u1_b_in) == 0) + || ((ps_mv_pred[LEFT]->i2_mv[0] + | ps_mv_pred[LEFT]->i2_mv[1] + | ps_mv_pred[LEFT]->i1_ref_frame[0]) + == 0) + || ((ps_mv_pred[TOP]->i2_mv[0] + | ps_mv_pred[TOP]->i2_mv[1] + | ps_mv_pred[TOP]->i1_ref_frame[0]) + == 0)) + { + ps_mv_final_pred->i2_mv[0] = 0; + ps_mv_final_pred->i2_mv[1] = 0; + break; + } + /* If the condition above is not true calculate the MV predictor + according to the process defined in sec 8.4.1.2.1 */ + default: + ih264d_get_motion_vector_predictor( + ps_mv_final_pred, ps_mv_pred, u1_ref_idx, uc_lx, + (const UWORD8 *)gau1_ih264d_mv_pred_condition); + break; + } + } + return (u1_direct_zero_pred_flag); +} + + + + +void ih264d_rep_mv_colz(dec_struct_t *ps_dec, + mv_pred_t *ps_mv_pred_src, + mv_pred_t *ps_mv_pred_dst, + UWORD8 u1_sub_mb_num, + UWORD8 u1_colz, + UWORD8 u1_ht, + UWORD8 u1_wd) +{ + + UWORD8 k, m; + UWORD8 *pu1_colz = ps_dec->pu1_col_zero_flag + ps_dec->i4_submb_ofst + + u1_sub_mb_num; + + for(k = 0; k < u1_ht; k++) + { + for(m = 0; m < u1_wd; m++) + { + *(ps_mv_pred_dst + m) = *(ps_mv_pred_src); + *(pu1_colz + m) = u1_colz; + + } + pu1_colz += SUB_BLK_WIDTH; + ps_mv_pred_dst += SUB_BLK_WIDTH; + } +} + diff --git a/decoder/ih264d_mvpred.h b/decoder/ih264d_mvpred.h new file mode 100755 index 0000000..66366ca --- /dev/null +++ b/decoder/ih264d_mvpred.h @@ -0,0 +1,153 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_MVPRED_H_ +#define _IH264D_MVPRED_H_ + +/** +************************************************************************** +* \file ih264d_mvpred.h +* +* \brief +* This file contains declarations of functions specific to decoding +* Motion vector. +* +* Detailed_description +* +* \date +* 10-12-2002 +* +* \author Arvind Raman +************************************************************************** +*/ +#include "ih264d_structs.h" +#include "ih264d_defs.h" +//#include "structs.h" + +/** Reference number that is not valid */ +#define OUT_OF_RANGE_REF -1 + +#define ONE_TO_ONE 0 +#define FRM_TO_FLD 1 +#define FLD_TO_FRM 2 + +/** +************************************************************************** +* \brief POSITION_IN_MVBANK +* +* a: Pointer to the top left subMb of the MB in the MV bank array +* b: Horiz posn in terms of subMbs +* c: Vert posn in terms of subMbs +* d: subMb number +************************************************************************** +*/ +#define POSITION_IN_MVBANK(a, b, c, d) (a) + (c) * (d) + (b) + + + +/** +************************************************************************** +* \brief col4x4_t +* +* Container to return the information related to the co-located 4x4 +* sub-macroblock. +************************************************************************** +*/ +typedef struct +{ + mv_pred_t *ps_mv; /** Ptr to the Mv bank */ + UWORD16 u2_mb_addr_col; /** Addr of the co-located MB */ + WORD16 i2_mv[2]; /** Mv of the colocated MB */ + WORD8 i1_ref_idx_col; /** Ref idx of the co-located picture */ + UWORD8 u1_col_pic; /** Idx of the colocated pic */ + UWORD8 u1_yM; /** "y" coord of the colocated MB addr */ + UWORD8 u1_vert_mv_scale; /** as defined in sec 8.4.1.2.1 */ +} col4x4_t; + + + + + +void ih264d_update_nnz_for_skipmb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_entrpy); + +void ih264d_get_motion_vector_predictor(mv_pred_t * ps_result, + mv_pred_t **ps_mv_pred, + UWORD8 u1_ref_idx, + UWORD8 u1_B, + const UWORD8 *pu1_mv_pred_condition); +void ih264d_mbaff_mv_pred(mv_pred_t **ps_mv_pred, + UWORD8 u1_sub_mb_num, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + dec_struct_t *ps_dec, + UWORD8 uc_mb_part_width, + dec_mb_info_t *ps_cur_mb_info, + UWORD8* pu0_scale); +void ih264d_non_mbaff_mv_pred(mv_pred_t **ps_mv_pred, + UWORD8 u1_sub_mb_num, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + dec_struct_t *ps_dec, + UWORD8 uc_mb_part_width, + dec_mb_info_t *ps_cur_mb_info); +UWORD8 ih264d_mvpred_nonmbaff(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode); + +UWORD8 ih264d_mvpred_nonmbaffB(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode); + +UWORD8 ih264d_mvpred_mbaff(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + mv_pred_t *ps_mv_final_pred, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 u1_lx_start, + UWORD8 u1_lxend, + UWORD8 u1_mb_mc_mode); + +void ih264d_rep_mv_colz(dec_struct_t *ps_dec, + mv_pred_t *ps_mv_pred_src, + mv_pred_t *ps_mv_pred_dst, + UWORD8 u1_sub_mb_num, + UWORD8 u1_colz, + UWORD8 u1_ht, + UWORD8 u1_wd); + +#endif /* _IH264D_MVPRED_H_ */ diff --git a/decoder/ih264d_nal.c b/decoder/ih264d_nal.c new file mode 100755 index 0000000..48450c8 --- /dev/null +++ b/decoder/ih264d_nal.c @@ -0,0 +1,393 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_nal.c + * + * \brief NAL parsing routines + * + * Detailed_description + * + * \author + * - AI 19 11 2002 Creation + ************************************************************************** + */ +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_defs.h" +#define NUM_OF_ZERO_BYTES_BEFORE_START_CODE 2 +#define EMULATION_PREVENTION_BYTE 0x03 + +#define NAL_FIRST_BYTE_SIZE 1 + +/*! + ************************************************************************** + * \if Function name : ih264d_find_start_code \endif + * + * \brief + * This function searches for the Start Code Prefix. + * + * \param pu1_buf : Pointer to char buffer which contains bitstream. + * \param u4_cur_pos : Current position in the buffer. + * \param u4_max_ofst : Number of bytes in Buffer. + * \param pu4_length_of_start_code : Poiter to length of Start Code. + * + * \return + * Returns 0 on success and -1 on error. + * + ************************************************************************** + */ +#define START_CODE_NOT_FOUND -1 +#define END_OF_STREAM_BUFFER -2 +#define END_OF_STREAM -1 + +void ih264d_check_if_aud(UWORD8 *pu1_buf, + UWORD32 u4_cur_pos, + UWORD32 u4_max_ofst, + UWORD32 *pu4_next_is_aud) +{ + UWORD8 u1_first_byte, u1_nal_unit_type; + if(u4_cur_pos + 1 < u4_max_ofst) + { + u1_first_byte = pu1_buf[u4_cur_pos + 1]; + u1_nal_unit_type = NAL_UNIT_TYPE(u1_first_byte); + + if(u1_nal_unit_type == ACCESS_UNIT_DELIMITER_RBSP) + { + *pu4_next_is_aud = 1; + } + } + +} +WORD32 ih264d_find_start_code(UWORD8 *pu1_buf, + UWORD32 u4_cur_pos, + UWORD32 u4_max_ofst, + UWORD32 *pu4_length_of_start_code, + UWORD32 *pu4_next_is_aud) +{ + WORD32 zero_byte_cnt = 0; + UWORD32 ui_curPosTemp; + + *pu4_length_of_start_code = 0; + /*Find first start code */ + while(u4_cur_pos < u4_max_ofst) + { + if(pu1_buf[u4_cur_pos] == 0) + zero_byte_cnt++; + else if(pu1_buf[u4_cur_pos] + == 0x01 && zero_byte_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE) + { + /* Found the start code */ + u4_cur_pos++; + break; + } + else + { + zero_byte_cnt = 0; + } + u4_cur_pos++; + } + /*Find Next Start Code */ + *pu4_length_of_start_code = u4_cur_pos; + zero_byte_cnt = 0; + ui_curPosTemp = u4_cur_pos; + while(u4_cur_pos < u4_max_ofst) + { + + if(pu1_buf[u4_cur_pos] == 0) + zero_byte_cnt++; + else if(pu1_buf[u4_cur_pos] + == 0x01 && zero_byte_cnt >= NUM_OF_ZERO_BYTES_BEFORE_START_CODE) + { + /* Found the start code */ + ih264d_check_if_aud(pu1_buf, u4_cur_pos, u4_max_ofst, + pu4_next_is_aud); + return (u4_cur_pos - zero_byte_cnt - ui_curPosTemp); + } + else + { + zero_byte_cnt = 0; + } + u4_cur_pos++; + } + + return (u4_cur_pos - zero_byte_cnt - ui_curPosTemp); //(START_CODE_NOT_FOUND); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_get_next_nal_unit \endif + * + * \brief + * This function reads one NAl unit. + * + * \param ps_nalStream : Poiter to NalUnitStream structure. + * \param ps_nalUnit : Pointer to NalUnit. + * + * \return + * Returns 0 on success and -1 on error. + * + ************************************************************************** + */ +WORD32 ih264d_get_next_nal_unit(UWORD8 *pu1_buf, + UWORD32 u4_cur_pos, + UWORD32 u4_max_ofst, + UWORD32 *pu4_length_of_start_code) +{ + + WORD32 i_length_of_nal_unit = 0; + UWORD32 u4_next_is_aud; + + /* NAL Thread starts */ + + ih264d_find_start_code(pu1_buf, u4_cur_pos, u4_max_ofst, + pu4_length_of_start_code, &u4_next_is_aud); + + return (i_length_of_nal_unit); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_process_nal_unit \endif + * + * \brief + * This function removes emulation byte "0x03" from bitstream (EBSP to RBSP). + * It also converts bytestream format into 32 bit little-endian format. + * + * \param ps_bitstrm : Poiter to dec_bit_stream_t structure. + * \param pu1_nal_unit : Pointer to char buffer of NalUnit. + * \param u4_numbytes_in_nal_unit : Number bytes in NalUnit buffer. + * + * \return + * Returns number of bytes in RBSP ps_bitstrm. + * + * \note + * This function is same as nal_unit() of 7.3.1. Apart from nal_unit() + * implementation it converts char buffer into 32 bit Buffer. This + * facilitates efficient access of bitstream. This has been done taking + * into account present processor architectures. + * + ************************************************************************** + */ +WORD32 ih264d_process_nal_unit(dec_bit_stream_t *ps_bitstrm, + UWORD8 *pu1_nal_unit, + UWORD32 u4_numbytes_in_nal_unit) +{ + UWORD32 u4_num_bytes_in_rbsp; + UWORD8 u1_cur_byte; + WORD32 i = 0; + WORD8 c_count; + UWORD32 ui_word; + UWORD32 *puc_bitstream_buffer = (UWORD32*)pu1_nal_unit; + ps_bitstrm->pu4_buffer = puc_bitstream_buffer; + + /*--------------------------------------------------------------------*/ + /* First Byte of the NAL Unit */ + /*--------------------------------------------------------------------*/ + + ui_word = *pu1_nal_unit++; + + /*--------------------------------------------------------------------*/ + /* Convertion of the EBSP to RBSP */ + /* ie Remove the emulation_prevention_byte [equal to 0x03] */ + /*--------------------------------------------------------------------*/ + u4_num_bytes_in_rbsp = 0; + c_count = 0; + +//first iteration + + u1_cur_byte = *pu1_nal_unit++; + + ui_word = ((ui_word << 8) | u1_cur_byte); + + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + +//second iteration + + u1_cur_byte = *pu1_nal_unit++; + + ui_word = ((ui_word << 8) | u1_cur_byte); + u4_num_bytes_in_rbsp = 2; + + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + + if(u4_numbytes_in_nal_unit > 2) + { + i = ((u4_numbytes_in_nal_unit - 3)); + } + + for(; i > 8; i -= 4) + { + +// loop 0 + u1_cur_byte = *pu1_nal_unit++; + + if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE + && u1_cur_byte == EMULATION_PREVENTION_BYTE) + { + c_count = 0; + u1_cur_byte = *pu1_nal_unit++; + i--; + } + + ui_word = ((ui_word << 8) | u1_cur_byte); + *puc_bitstream_buffer = ui_word; + puc_bitstream_buffer++; + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + +// loop 1 + u1_cur_byte = *pu1_nal_unit++; + + if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE + && u1_cur_byte == EMULATION_PREVENTION_BYTE) + { + c_count = 0; + u1_cur_byte = *pu1_nal_unit++; + i--; + } + ui_word = ((ui_word << 8) | u1_cur_byte); + + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + +// loop 2 + u1_cur_byte = *pu1_nal_unit++; + + if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE + && u1_cur_byte == EMULATION_PREVENTION_BYTE) + { + c_count = 0; + u1_cur_byte = *pu1_nal_unit++; + i--; + } + + ui_word = ((ui_word << 8) | u1_cur_byte); + + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + +// loop 3 + u1_cur_byte = *pu1_nal_unit++; + + if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE + && u1_cur_byte == EMULATION_PREVENTION_BYTE) + { + c_count = 0; + u1_cur_byte = *pu1_nal_unit++; + i--; + } + + ui_word = ((ui_word << 8) | u1_cur_byte); + + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + + u4_num_bytes_in_rbsp += 4; + + } + + for(; i > 0; i--) + { + u1_cur_byte = *pu1_nal_unit++; + + if(c_count == NUM_OF_ZERO_BYTES_BEFORE_START_CODE + && u1_cur_byte == EMULATION_PREVENTION_BYTE) + { + c_count = 0; + i--; + u1_cur_byte = *pu1_nal_unit++; + } + + ui_word = ((ui_word << 8) | u1_cur_byte); + u4_num_bytes_in_rbsp++; + + if((u4_num_bytes_in_rbsp & 0x03) == 0x03) + { + *puc_bitstream_buffer = ui_word; + puc_bitstream_buffer++; + } + c_count++; + if(u1_cur_byte != 0x00) + c_count = 0; + + } + + *puc_bitstream_buffer = (ui_word + << ((3 - (((u4_num_bytes_in_rbsp << 30) >> 30))) << 3)); + ps_bitstrm->u4_ofst = 0; + ps_bitstrm->u4_max_ofst = ((u4_num_bytes_in_rbsp + NAL_FIRST_BYTE_SIZE) << 3); + + return (u4_num_bytes_in_rbsp); +} + + +/*! + ************************************************************************** + * \if Function name : ih264d_rbsp_to_sodb \endif + * + * \brief + * This function converts RBSP to SODB. + * + * \param ps_bitstrm : Poiter to dec_bit_stream_t structure. + * + * \return + * None. + * + ************************************************************************** + */ +void ih264d_rbsp_to_sodb(dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 ui_lastWord; + UWORD32 ui_word; + UWORD8 uc_lastByte; + WORD8 i; + + ui_lastWord = (ps_bitstrm->u4_max_ofst >> 5); + i = (ps_bitstrm->u4_max_ofst >> 3) & 0x03; + + if(i) + { + ui_word = ps_bitstrm->pu4_buffer[ui_lastWord]; + uc_lastByte = ((ui_word << ((i - 1) << 3)) >> 24); + } + else + { + ui_word = ps_bitstrm->pu4_buffer[ui_lastWord - 1]; + uc_lastByte = ((ui_word << 24) >> 24); + } + /*--------------------------------------------------------------------*/ + /* Find out the rbsp_stop_bit position in the last byte of rbsp */ + /*--------------------------------------------------------------------*/ + for(i = 0; (i < 8) && !CHECKBIT(uc_lastByte, i); ++i) + ; + ps_bitstrm->u4_max_ofst = ps_bitstrm->u4_max_ofst - (i + 1); +} diff --git a/decoder/ih264d_nal.h b/decoder/ih264d_nal.h new file mode 100755 index 0000000..3778881 --- /dev/null +++ b/decoder/ih264d_nal.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_NAL_H_ +#define _IH264D_NAL_H_ + +/*! +************************************************************************* +* \file ih264d_nal.h +* +* \brief +* short_description +* +* Detailed_description +* +* \date +* 21/11/2002 +* +* \author AI +************************************************************************* +*/ +#include <stdio.h> +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" + +WORD32 ih264d_process_nal_unit(dec_bit_stream_t *ps_bitstrm, + UWORD8 *pu1_nal_unit, + UWORD32 u4_numbytes_in_nal_unit); +void ih264d_rbsp_to_sodb(dec_bit_stream_t *ps_bitstrm); +WORD32 ih264d_find_start_code(UWORD8 *pu1_buf, + UWORD32 u4_cur_pos, + UWORD32 u4_max_ofst, + UWORD32 *pu4_length_of_start_code, + UWORD32 *pu4_next_is_aud); + + +#endif /* _IH264D_NAL_H_ */ diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c new file mode 100755 index 0000000..89cf5ed --- /dev/null +++ b/decoder/ih264d_parse_bslice.c @@ -0,0 +1,1696 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_bslice.c + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ + +#include <string.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_parse_slice.h" +#include "ih264d_process_intra_mb.h" +#include "ih264d_mvpred.h" +#include "ih264d_parse_islice.h" +#include "ih264d_inter_pred.h" +#include "ih264d_process_pslice.h" +#include "ih264d_process_bslice.h" +#include "ih264d_deblocking.h" +#include "ih264d_cabac.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_error_handler.h" +#include "ih264d_mvpred.h" +#include "ih264d_cabac.h" +#include "ih264d_utils.h" + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec); + +/*! + ************************************************************************** + * \if Function name : ParseMb_SubMb_PredBCav\endif + * + * \brief + * Implements sub_mb_pred() of 7.3.5.2. & mb_pred() of 7.3.5.1 + * + * \return + * None. + * + ************************************************************************** + */ +WORD32 ih264d_parse_bmb_non_direct_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD8 * pu1_sub_mb_pred_modes = (UWORD8 *)(gau1_ih264d_submb_pred_modes) + 4; + const UWORD8 (*pu1_mb_pred_modes)[32] = + (const UWORD8 (*)[32])gau1_ih264d_mb_pred_modes; + const UWORD8 * pu1_num_mb_part = (const UWORD8 *)gau1_ih264d_num_mb_part; + const UWORD8 * pu1_sub_mb_mc_mode = (const UWORD8 *)(gau1_ih264d_submb_mc_mode) + + 4; + + parse_pmbarams_t * ps_parse_mb_data = ps_dec->ps_parse_mb_data + + u1_num_mbsNby2; + UWORD8 * pu1_col_info = ps_parse_mb_data->u1_col_info; + WORD8 (*pi1_ref_idx)[MAX_REFIDX_INFO_PER_MB] = ps_parse_mb_data->i1_ref_idx; + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD8 u1_mb_mc_mode, u1_num_mb_part, u1_sub_mb = !(u1_mb_type ^ B_8x8); + UWORD32 u4_mb_mc_mode = 0, u4_mb_pred_mode = 0; + WORD32 ret; + + if(u1_sub_mb) + { + UWORD8 uc_i; + u1_mb_mc_mode = 0; + u1_num_mb_part = 4; + /* Reading the subMB type */ + for(uc_i = 0; uc_i < 4; uc_i++) + { + + UWORD32 ui_sub_mb_mode; + +//Inlined ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + ui_sub_mb_mode = ((1 << u4_ldz) + u4_word - 1); +//Inlined ih264d_uev + + if(ui_sub_mb_mode > 12) + return ERROR_SUB_MB_TYPE; + else + { + UWORD8 u1_subMbPredMode = pu1_sub_mb_pred_modes[ui_sub_mb_mode]; + u4_mb_mc_mode = (u4_mb_mc_mode << 8) + | pu1_sub_mb_mc_mode[ui_sub_mb_mode]; + u4_mb_pred_mode = (u4_mb_pred_mode << 8) | u1_subMbPredMode; + pi1_ref_idx[0][uc_i] = ((u1_subMbPredMode & PRED_L0) - 1) >> 1; + pi1_ref_idx[1][uc_i] = ((u1_subMbPredMode & PRED_L1) - 1) >> 1; + COPYTHECONTEXT("sub_mb_type", u1_subMbPredMode); + } + /* Storing collocated Mb and SubMb mode information */ + *pu1_col_info++ = ((PRED_8x8) << 6) + | ((pu1_sub_mb_mc_mode[ui_sub_mb_mode] << 4)); + if(ui_sub_mb_mode != B_DIRECT_8x8) + { + if(ui_sub_mb_mode > B_BI_8x8) + { + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0; + } + } + else if(!ps_dec->s_high_profile.u1_direct_8x8_inference_flag) + { + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0; + } + } + } + else + { + UWORD8 u1_mb_pred_mode_idx = 5 + u1_mb_type; + UWORD8 u1_mb_pred_mode_part0 = pu1_mb_pred_modes[0][u1_mb_pred_mode_idx]; + UWORD8 u1_mb_pred_mode_part1 = pu1_mb_pred_modes[1][u1_mb_pred_mode_idx]; + u1_mb_mc_mode = ps_cur_mb_info->u1_mb_mc_mode; + u1_num_mb_part = pu1_num_mb_part[u1_mb_mc_mode]; + + pi1_ref_idx[0][0] = ((u1_mb_pred_mode_part0 & PRED_L0) - 1) >> 1; + pi1_ref_idx[1][0] = ((u1_mb_pred_mode_part0 & PRED_L1) - 1) >> 1; + pi1_ref_idx[0][1] = ((u1_mb_pred_mode_part1 & PRED_L0) - 1) >> 1; + pi1_ref_idx[1][1] = ((u1_mb_pred_mode_part1 & PRED_L1) - 1) >> 1; + + u4_mb_pred_mode = (u1_mb_pred_mode_part0 << 8) | u1_mb_pred_mode_part1; + u4_mb_mc_mode = u1_mb_mc_mode | (u1_mb_mc_mode << 8); + u4_mb_mc_mode <<= 16; + u4_mb_pred_mode <<= 16; + + /* Storing collocated Mb and SubMb mode information */ + *pu1_col_info++ = (u1_mb_mc_mode << 6); + if(u1_mb_mc_mode) + *pu1_col_info++ = (u1_mb_mc_mode << 6); + } + + { + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 *pu1_num_ref_idx_lx_active = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active; + const UWORD8 u1_mbaff_field = (u1_mbaff & uc_field); + UWORD8 u4_num_ref_idx_lx_active; + + u4_num_ref_idx_lx_active = (pu1_num_ref_idx_lx_active[0] + << u1_mbaff_field) - 1; + + if(u4_num_ref_idx_lx_active) + { + if(1 == u4_num_ref_idx_lx_active) + ih264d_parse_bmb_ref_index_cavlc_range1( + u1_num_mb_part, ps_bitstrm, pi1_ref_idx[0], + u4_num_ref_idx_lx_active); + else + { + ret = ih264d_parse_bmb_ref_index_cavlc(u1_num_mb_part, ps_bitstrm, + pi1_ref_idx[0], + u4_num_ref_idx_lx_active); + if(ret != OK) + return ret; + } + } + + u4_num_ref_idx_lx_active = (pu1_num_ref_idx_lx_active[1] + << u1_mbaff_field) - 1; + + if(u4_num_ref_idx_lx_active) + { + if(1 == u4_num_ref_idx_lx_active) + ih264d_parse_bmb_ref_index_cavlc_range1( + u1_num_mb_part, ps_bitstrm, pi1_ref_idx[1], + u4_num_ref_idx_lx_active); + else + { + ret = ih264d_parse_bmb_ref_index_cavlc(u1_num_mb_part, ps_bitstrm, + pi1_ref_idx[1], + u4_num_ref_idx_lx_active); + if(ret != OK) + return ret; + } + } + } + + /* Read MotionVectors */ + { + const UWORD8 * pu1_top_left_sub_mb_indx; + + const UWORD8 * pu1_sub_mb_indx_mod = + (const UWORD8 *)(gau1_ih264d_submb_indx_mod) + + (u1_sub_mb * 6); + const UWORD8 * pu1_sub_mb_partw = (const UWORD8 *)gau1_ih264d_submb_partw; + const UWORD8 * pu1_sub_mb_parth = (const UWORD8 *)gau1_ih264d_submb_parth; + const UWORD8 * pu1_num_sub_mb_part = + (const UWORD8 *)gau1_ih264d_num_submb_part; + const UWORD8 * pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + const UWORD8 * pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + UWORD8 u1_p_idx = 0, u1_num_submb_part, uc_lx; + parse_part_params_t * ps_part; + mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4); + UWORD8 u1_mb_part_wd, u1_mb_part_ht; + + /* Initialisations */ + ps_part = ps_dec->ps_part; + /* Default Initialization for Non subMb Case Mode */ + u1_mb_part_wd = pu1_mb_partw[u1_mb_mc_mode]; + u1_mb_part_ht = pu1_mb_parth[u1_mb_mc_mode]; + u1_num_submb_part = 1; + + /* Decoding the MV for the subMB */ + for(uc_lx = 0; uc_lx < 2; uc_lx++) + { + UWORD8 u1_sub_mb_num = 0, u1_pred_mode, uc_i; + UWORD32 u4_mb_mc_mode_tmp = u4_mb_mc_mode; + UWORD32 u4_mb_pred_mode_tmp = u4_mb_pred_mode; + UWORD16 u2_sub_mb_num = 0x028A; // for sub mb case + UWORD8 u1_b2 = uc_lx << 1; + u1_pred_mode = (uc_lx) ? PRED_L1 : PRED_L0; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode << 1); + + for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++) + { + UWORD8 u1_mb_mc_mode, uc_j; + UWORD8 i1_pred = u4_mb_pred_mode_tmp >> 24; + u1_mb_mc_mode = u4_mb_mc_mode_tmp >> 24; + u4_mb_pred_mode_tmp <<= 8; + u4_mb_mc_mode_tmp <<= 8; + /* subMb prediction mode */ + if(u1_sub_mb) + { + + u1_mb_part_wd = pu1_sub_mb_partw[u1_mb_mc_mode]; + u1_mb_part_ht = pu1_sub_mb_parth[u1_mb_mc_mode]; + u1_sub_mb_num = u2_sub_mb_num >> 12; + u1_num_submb_part = pu1_num_sub_mb_part[u1_mb_mc_mode]; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + + (u1_mb_mc_mode << 1); + u2_sub_mb_num <<= 4; + } + for(uc_j = 0; uc_j < u1_num_submb_part; + uc_j++, pu1_top_left_sub_mb_indx++) + { + mv_pred_t * ps_mv; + u1_sub_mb_num = u1_sub_mb_num + *pu1_top_left_sub_mb_indx; + ps_mv = ps_mv_start + u1_sub_mb_num; + + /* Storing Info for partitions, writing only once */ + if(uc_lx) + { + ps_part->u1_is_direct = (!i1_pred); + ps_part->u1_pred_mode = i1_pred; + ps_part->u1_sub_mb_num = u1_sub_mb_num; + ps_part->u1_partheight = u1_mb_part_ht; + ps_part->u1_partwidth = u1_mb_part_wd; + /* Increment partition Index */ + u1_p_idx++; + ps_part++; + } + + if(i1_pred & u1_pred_mode) + { + WORD16 i2_mvx, i2_mvy; + +//inlining ih264d_sev + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf, u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i2_mvx = (-(WORD32)u4_abs_val); + else + i2_mvx = (u4_abs_val); + } +//inlinined ih264d_sev + +//inlining ih264d_sev + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf, u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i2_mvy = (-(WORD32)u4_abs_val); + else + i2_mvy = (u4_abs_val); + } +//inlinined ih264d_sev + + /* Storing Mv residuals */ + ps_mv->i2_mv[u1_b2] = i2_mvx; + ps_mv->i2_mv[u1_b2 + 1] = i2_mvy; + } + } + } + } + /* write back to the scratch partition info */ + ps_dec->ps_part = ps_part; + ps_parse_mb_data->u1_num_part = u1_sub_mb ? u1_p_idx : u1_num_mb_part; + + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ParseMb_SubMb_PredBCab\endif + * + * \brief + * Implements sub_mb_pred() of 7.3.5.2. & mb_pred() of 7.3.5.1 + * + * \return + * None. + * + ************************************************************************** + */ + +WORD32 ih264d_parse_bmb_non_direct_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + /* Loads from ps_dec */ + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + parse_pmbarams_t * ps_parse_mb_data = ps_dec->ps_parse_mb_data + + u1_num_mbsNby2; + + /* table pointer loads */ + const UWORD8 * pu1_sub_mb_pred_modes = (UWORD8 *)(gau1_ih264d_submb_pred_modes) + + 4; + const UWORD8 (*pu1_mb_pred_modes)[32] = + (const UWORD8 (*)[32])gau1_ih264d_mb_pred_modes; + const UWORD8 *pu1_num_mb_part = (const UWORD8 *)gau1_ih264d_num_mb_part; + const UWORD8 *pu1_sub_mb_mc_mode = (UWORD8 *)(gau1_ih264d_submb_mc_mode) + 4; + + const UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD8 * pu1_col_info = ps_parse_mb_data->u1_col_info; + WORD8 *pi1_ref_idx_l0 = &ps_parse_mb_data->i1_ref_idx[0][0]; + WORD8 *pi1_ref_idx_l1 = &ps_parse_mb_data->i1_ref_idx[1][0]; + UWORD8 u1_dec_ref_l0, u1_dec_ref_l1; + + UWORD8 u1_num_mb_part, u1_mb_mc_mode, u1_sub_mb, u1_mbpred_mode = 5 + + u1_mb_type; + UWORD32 u4_mb_mc_mode = 0, u4_mb_pred_mode = 0; + WORD32 ret; + + p_curr_ctxt->u1_mb_type = CAB_NON_BD16x16; + u1_sub_mb = !(u1_mb_type ^ B_8x8); + + { + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD8 *pu1_num_ref_idx_lx_active = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active; + UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 u1_mbaff_field = (u1_mbaff & uc_field); + u1_dec_ref_l0 = (pu1_num_ref_idx_lx_active[0] << u1_mbaff_field) - 1; + u1_dec_ref_l1 = (pu1_num_ref_idx_lx_active[1] << u1_mbaff_field) - 1; + } + + if(u1_sub_mb) + { + const UWORD8 u1_colz = ((PRED_8x8) << 6); + UWORD8 uc_i; + u1_mb_mc_mode = 0; + u1_num_mb_part = 4; + /* Reading the subMB type */ + for(uc_i = 0; uc_i < 4; uc_i++) + { + UWORD8 u1_sub_mb_mode, u1_subMbPredModes; + u1_sub_mb_mode = ih264d_parse_submb_type_cabac( + 1, ps_cab_env, ps_bitstrm, + ps_dec->p_sub_mb_type_t); + + if(u1_sub_mb_mode > 12) + return ERROR_SUB_MB_TYPE; + + u1_subMbPredModes = pu1_sub_mb_pred_modes[u1_sub_mb_mode]; + u4_mb_mc_mode = (u4_mb_mc_mode << 8) | pu1_sub_mb_mc_mode[u1_sub_mb_mode]; + u4_mb_pred_mode = (u4_mb_pred_mode << 8) | u1_subMbPredModes; + *pi1_ref_idx_l0++ = + (u1_subMbPredModes & PRED_L0) ? u1_dec_ref_l0 : -1; + *pi1_ref_idx_l1++ = + (u1_subMbPredModes & PRED_L1) ? u1_dec_ref_l1 : -1; + COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode); + /* Storing collocated Mb and SubMb mode information */ + *pu1_col_info++ = + (u1_colz | (pu1_sub_mb_mc_mode[u1_sub_mb_mode] << 4)); + if(u1_sub_mb_mode != B_DIRECT_8x8) + { + if(u1_sub_mb_mode > B_BI_8x8) + { + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0; + } + } + else if(!ps_dec->s_high_profile.u1_direct_8x8_inference_flag) + { + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 0; + } + } + pi1_ref_idx_l0 -= 4; + pi1_ref_idx_l1 -= 4; + } + else + { + UWORD8 u1_mb_pred_mode_part0 = pu1_mb_pred_modes[0][u1_mbpred_mode]; + UWORD8 u1_mb_pred_mode_part1 = pu1_mb_pred_modes[1][u1_mbpred_mode]; + u1_mb_mc_mode = ps_cur_mb_info->u1_mb_mc_mode; + u1_num_mb_part = pu1_num_mb_part[u1_mb_mc_mode]; + /* Storing collocated Mb and SubMb mode information */ + *pu1_col_info++ = (u1_mb_mc_mode << 6); + if(u1_mb_mc_mode) + *pu1_col_info++ = (u1_mb_mc_mode << 6); + u4_mb_mc_mode = u1_mb_mc_mode | (u1_mb_mc_mode << 8); + u4_mb_mc_mode <<= 16; + u4_mb_pred_mode = ((u1_mb_pred_mode_part0 << 8) | u1_mb_pred_mode_part1) << 16; + + *pi1_ref_idx_l0++ = (u1_mb_pred_mode_part0 & PRED_L0) ? u1_dec_ref_l0 : -1; + *pi1_ref_idx_l0-- = (u1_mb_pred_mode_part1 & PRED_L0) ? u1_dec_ref_l0 : -1; + *pi1_ref_idx_l1++ = (u1_mb_pred_mode_part0 & PRED_L1) ? u1_dec_ref_l1 : -1; + *pi1_ref_idx_l1-- = (u1_mb_pred_mode_part1 & PRED_L1) ? u1_dec_ref_l1 : -1; + } + { + WORD8 *pi1_lft_cxt = ps_dec->pi1_left_ref_idx_ctxt_inc; + WORD8 *pi1_top_cxt = p_curr_ctxt->i1_ref_idx; + + ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 0, u1_dec_ref_l0, + u1_mb_mc_mode, pi1_ref_idx_l0, pi1_lft_cxt, + pi1_top_cxt, ps_cab_env, ps_bitstrm, + ps_dec->p_ref_idx_t); + if(ret != OK) + return ret; + + ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 2, u1_dec_ref_l1, + u1_mb_mc_mode, pi1_ref_idx_l1, pi1_lft_cxt, + pi1_top_cxt, ps_cab_env, ps_bitstrm, + ps_dec->p_ref_idx_t); + if(ret != OK) + return ret; + } + /* Read MotionVectors */ + { + const UWORD8 *pu1_top_left_sub_mb_indx; + UWORD8 uc_j, uc_lx; + UWORD8 u1_mb_part_wd, u1_mb_part_ht; + + const UWORD8 *pu1_sub_mb_indx_mod = + (const UWORD8 *)gau1_ih264d_submb_indx_mod + + (u1_sub_mb * 6); + const UWORD8 *pu1_sub_mb_partw = (const UWORD8 *)gau1_ih264d_submb_partw; + const UWORD8 *pu1_sub_mb_parth = (const UWORD8 *)gau1_ih264d_submb_parth; + const UWORD8 *pu1_num_sub_mb_part = + (const UWORD8 *)gau1_ih264d_num_submb_part; + const UWORD8 *pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + const UWORD8 *pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + + UWORD8 u1_p_idx = 0; + UWORD8 u1_num_submb_part; + parse_part_params_t *ps_part; + /* Initialisations */ + mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4); + ps_part = ps_dec->ps_part; + + /* Default initialization for non subMb case */ + u1_mb_part_wd = pu1_mb_partw[u1_mb_mc_mode]; + u1_mb_part_ht = pu1_mb_parth[u1_mb_mc_mode]; + u1_num_submb_part = 1; + + /* Decoding the MV for the subMB */ + for(uc_lx = 0; uc_lx < 2; uc_lx++) + { + UWORD8 u1_sub_mb_num = 0; + UWORD32 u4_mb_pred_mode_tmp = u4_mb_pred_mode; + UWORD32 u4_mb_mc_mode_tmp = u4_mb_mc_mode; + UWORD8 u1_mb_mc_mode_1, u1_pred_mode, uc_i; + UWORD16 u2_sub_mb_num = 0x028A; + UWORD8 u1_b2 = uc_lx << 1; + u1_pred_mode = (uc_lx) ? PRED_L1 : PRED_L0; + /* Default for Cabac */ + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode << 1); + for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++) + { + + WORD8 i1_pred = (UWORD8)(u4_mb_pred_mode_tmp >> 24); + u1_mb_mc_mode_1 = (UWORD8)(u4_mb_mc_mode_tmp >> 24); + u4_mb_pred_mode_tmp <<= 8; + u4_mb_mc_mode_tmp <<= 8; + + /* subMb prediction mode */ + if(u1_sub_mb) + { + u1_mb_part_wd = pu1_sub_mb_partw[u1_mb_mc_mode_1]; + u1_mb_part_ht = pu1_sub_mb_parth[u1_mb_mc_mode_1]; + u1_sub_mb_num = u2_sub_mb_num >> 12; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_mc_mode_1 << 1); + u1_num_submb_part = pu1_num_sub_mb_part[u1_mb_mc_mode_1]; + u2_sub_mb_num = u2_sub_mb_num << 4; + } + + for(uc_j = 0; uc_j < u1_num_submb_part; + uc_j++, pu1_top_left_sub_mb_indx++) + { + mv_pred_t *ps_mv; + u1_sub_mb_num = u1_sub_mb_num + *pu1_top_left_sub_mb_indx; + ps_mv = ps_mv_start + u1_sub_mb_num; + + /* Storing Info for partitions, writing only once */ + if(uc_lx) + { + ps_part->u1_is_direct = (!i1_pred); + ps_part->u1_pred_mode = i1_pred; + ps_part->u1_sub_mb_num = u1_sub_mb_num; + ps_part->u1_partheight = u1_mb_part_ht; + ps_part->u1_partwidth = u1_mb_part_wd; + + /* Increment partition Index */ + u1_p_idx++; + ps_part++; + } + + ih264d_get_mvd_cabac(u1_sub_mb_num, u1_b2, u1_mb_part_wd, + u1_mb_part_ht, + (UWORD8)(i1_pred & u1_pred_mode), ps_dec, + ps_mv); + } + } + } + /* write back to the scratch partition info */ + + ps_dec->ps_part = ps_part; + ps_parse_mb_data->u1_num_part = u1_sub_mb ? u1_p_idx : u1_num_mb_part; + + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_bmb_cabac \endif + * + * \brief + * This function parses CABAC syntax of a B MB. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_bmb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + UWORD8 u1_cbp; + deblk_mb_t * ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_mb_num; + const UWORD8 *puc_mb_mc_mode = (const UWORD8 *)gau1_ih264d_mb_mc_mode; + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + + WORD32 ret; + UWORD8 u1_Bdirect_tranform_read = 1; + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 1; + + ps_cur_mb_info->u1_mb_mc_mode = puc_mb_mc_mode[5 + u1_mb_type]; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + ps_cur_deblk_mb->u1_mb_type |= D_B_SLICE; + if(u1_mb_type != B_DIRECT) + { + ret = ih264d_parse_bmb_non_direct_cabac(ps_dec, ps_cur_mb_info, u1_mb_num, + u1_num_mbsNby2); + if(ret != OK) + return ret; + } + else + { + + /************ STORING PARTITION INFO ***********/ + parse_part_params_t * ps_part_info; + ps_part_info = ps_dec->ps_part; + ps_part_info->u1_is_direct = PART_DIRECT_16x16; + ps_part_info->u1_sub_mb_num = 0; + ps_dec->ps_part++; + p_curr_ctxt->u1_mb_type = CAB_BD16x16; + + MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); + memset(ps_dec->pi1_left_ref_idx_ctxt_inc, 0, 4); + MEMSET_16BYTES(p_curr_ctxt->u1_mv, 0); + memset(p_curr_ctxt->i1_ref_idx, 0, 4); + + /* check whether transform8x8 u4_flag to be read or not */ + u1_Bdirect_tranform_read = + ps_dec->s_high_profile.u1_direct_8x8_inference_flag; + } + + /* Read the Coded block pattern */ + u1_cbp = (WORD8)ih264d_parse_ctx_cbp_cabac(ps_dec); + p_curr_ctxt->u1_cbp = u1_cbp; + ps_cur_mb_info->u1_cbp = u1_cbp; + + if(u1_cbp > 47) + return ERROR_CBP; + + COPYTHECONTEXT("coded_block_pattern", u1_cbp); + + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + if((ps_dec->s_high_profile.u1_transform8x8_present) && (u1_cbp & (0xf)) + && (ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag) + && (u1_Bdirect_tranform_read)) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_parse_transform8x8flag_cabac( + ps_dec, ps_cur_mb_info); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8; + } + else + { + p_curr_ctxt->u1_transform8x8_ctxt = 0; + } + + p_curr_ctxt->u1_intra_chroma_pred_mode = 0; + p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE; + ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6; + + /* Read mb_qp_delta */ + if(u1_cbp) + { + WORD8 c_temp; + ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &c_temp); + if(ret != OK) + return ret; + COPYTHECONTEXT("mb_qp_delta", c_temp); + if(c_temp) + { + ret = ih264d_update_qp(ps_dec, c_temp); + if(ret != OK) + return ret; + } + } + else + ps_dec->i1_prev_mb_qp_delta = 0; + + ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, 0); + if(EXCEED_OFFSET(ps_dec->ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + return OK; +} +/*! + ************************************************************************** + * \if Function name : ih264d_parse_bmb_cavlc \endif + * + * \brief + * This function parses CAVLC syntax of a B MB. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_bmb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + UWORD32 u4_cbp; + deblk_mb_t * ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_mb_num; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 * pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + const UWORD8 *puc_mb_mc_mode = (const UWORD8 *)gau1_ih264d_mb_mc_mode; + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + + WORD32 ret; + UWORD8 u1_Bdirect_tranform_read = 1; + ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag = 1; + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + ps_cur_mb_info->u1_mb_mc_mode = puc_mb_mc_mode[5 + u1_mb_type]; + + ps_cur_deblk_mb->u1_mb_type |= D_B_SLICE; + if(u1_mb_type != B_DIRECT) + { + ret = ih264d_parse_bmb_non_direct_cavlc(ps_dec, ps_cur_mb_info, u1_mb_num, + u1_num_mbsNby2); + if(ret != OK) + return ret; + } + else + { + /************ STORING PARTITION INFO ***********/ + parse_part_params_t * ps_part_info; + ps_part_info = ps_dec->ps_part; + ps_part_info->u1_is_direct = PART_DIRECT_16x16; + ps_part_info->u1_sub_mb_num = 0; + ps_dec->ps_part++; + /* check whether transform8x8 u4_flag to be read or not */ + u1_Bdirect_tranform_read = + ps_dec->s_high_profile.u1_direct_8x8_inference_flag; + } + + /* Read the Coded block pattern */ + { + const UWORD8 * puc_CbpInter = gau1_ih264d_cbp_inter; +//Inlined ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_cbp = ((1 << u4_ldz) + u4_word - 1); +//Inlined ih264d_uev + if(u4_cbp > 47) + return ERROR_CBP; + u4_cbp = puc_CbpInter[u4_cbp]; + + if((ps_dec->s_high_profile.u1_transform8x8_present) && (u4_cbp & (0xf)) + && (ps_dec->s_high_profile.u1_no_submb_part_size_lt8x8_flag) + && (u1_Bdirect_tranform_read)) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + } + + } + + COPYTHECONTEXT("coded_block_pattern", u4_cbp); + ps_cur_mb_info->u1_cbp = u4_cbp; + + /* Read mb_qp_delta */ + if(u4_cbp) + { + WORD32 i_temp; +//inlining ih264d_sev + + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i_temp = (-(WORD32)u4_abs_val); + else + i_temp = (u4_abs_val); + + if(i_temp < -26 || i_temp > 25) + return ERROR_INV_RANGE_QP_T; +//inlinined ih264d_sev + COPYTHECONTEXT("mb_qp_delta", i_temp); + if(i_temp) + { + ret = ih264d_update_qp(ps_dec, (WORD8)i_temp); + if(ret != OK) + return ret; + } + + ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, 0); + if(ret != OK) + return ret; + if(EXCEED_OFFSET(ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + } + else + { + ps_dec->i1_prev_mb_qp_delta = 0; + ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC); + } + + return OK; +} + +WORD32 ih264d_mv_pred_ref_tfr_nby2_bmb(dec_struct_t * ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs) +{ + parse_pmbarams_t * ps_mb_part_info; + parse_part_params_t * ps_part; + mv_pred_t *ps_mv_nmb, *ps_mv_nmb_start, *ps_mv_ntop, *ps_mv_ntop_start; + pic_buffer_t * ps_ref_frame; + UWORD8 u1_direct_mode_width; + UWORD8 i, j; + dec_mb_info_t * ps_cur_mb_info; + const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD8 u1_field; + WORD32 ret = 0; + + ps_dec->i4_submb_ofst -= (u1_num_mbs - u1_mb_idx) << 4; + ps_mb_part_info = ps_dec->ps_parse_mb_data; + ps_part = ps_dec->ps_parse_part_params; + + /* N/2 Mb MvPred and Transfer Setup Loop */ + for(i = u1_mb_idx; i < u1_num_mbs; i++, ps_mb_part_info++) + { + UWORD8 u1_colz = 0; + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + /* Restore the slice scratch MbX and MbY context */ + ps_cur_mb_info = ps_dec->ps_nmb_info + i; + ps_dec->u2_wait_id = i; + + u1_field = ps_cur_mb_info->u1_mb_field_decodingflag; + + ps_mv_nmb_start = ps_dec->ps_mv_cur + (i << 4); + ps_dec->u2_mbx = ps_cur_mb_info->u2_mbx; + ps_dec->u2_mby = ps_cur_mb_info->u2_mby; + ps_dec->u1_currB_type = 0; + ps_dec->u2_mv_2mb[i & 0x1] = 0; + + /* Look for MV Prediction and Reference Transfer in Non-I Mbs */ + if(!ps_mb_part_info->u1_isI_mb) + { + UWORD8 u1_blk_no; + WORD16 i1_ref_idx, i1_ref_idx1; + UWORD8 u1_pred_mode; + UWORD8 u1_sub_mb_x, u1_sub_mb_y, u1_sub_mb_num; + UWORD8 u1_lx, u1_lx_start, u1_lxend, u1_tmp_lx; + UWORD8 u1_num_part, u1_num_ref, u1_wd, u1_ht; + UWORD32 *pu4_wt_offst; + UWORD8 u1_scale_ref, u4_bot_mb; + deblk_mb_t * ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + i; + WORD8 (*pi1_ref_idx)[MAX_REFIDX_INFO_PER_MB] = + ps_mb_part_info->i1_ref_idx; + WORD8 *pi1_ref_idx0 = pi1_ref_idx[0], + *pi1_ref_idx1 = pi1_ref_idx[1]; + UWORD32 **ppu4_wt_ofst = ps_mb_part_info->pu4_wt_offst; + + /* MB Level initialisations */ + ps_dec->u4_num_pmbair = i >> u1_mbaff; + ps_dec->u1_mb_idx_mv = i; + + /* CHANGED CODE */ + ps_mv_ntop_start = ps_mv_nmb_start + - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12; + + u1_num_part = ps_mb_part_info->u1_num_part; + ps_cur_deblk_mb->u1_mb_type |= (u1_num_part > 1) << 1; + u1_direct_mode_width = (1 == ps_mb_part_info->u1_num_part) ? 16 : 8; + + + ps_cur_mb_info->u4_pred_info_pkd_idx = ps_dec->u4_pred_info_pkd_idx; + ps_cur_mb_info->u1_num_pred_parts = 0; + + /****************************************************/ + /* weighted u4_ofst pointer calculations, this loop */ + /* runs maximum 4 times, even in direct cases */ + /****************************************************/ + u1_scale_ref = u1_mbaff & ps_cur_mb_info->u1_mb_field_decodingflag; + u4_bot_mb = 1 - ps_cur_mb_info->u1_topmb; + if(ps_dec->ps_cur_pps->u1_wted_bipred_idc) + { + u1_num_ref = MIN(u1_num_part, 4); + if(PART_DIRECT_16x16 != ps_part->u1_is_direct) + { + for(u1_blk_no = 0; u1_blk_no < u1_num_ref; u1_blk_no++) + { + i1_ref_idx = MAX(pi1_ref_idx0[u1_blk_no], 0); + if(u1_scale_ref) + i1_ref_idx >>= 1; + i1_ref_idx *= + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + if(u1_scale_ref) + i1_ref_idx += + (MAX(pi1_ref_idx1[u1_blk_no], 0) + >> 1); + else + i1_ref_idx += MAX(pi1_ref_idx1[u1_blk_no], 0); + pu4_wt_offst = (UWORD32*)&ps_dec->pu4_wt_ofsts[2 + * X3(i1_ref_idx)]; + + if(pi1_ref_idx0[u1_blk_no] < 0) + pu4_wt_offst += 1; + + ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst; + if(u1_scale_ref + && (ps_dec->ps_cur_pps->u1_wted_bipred_idc + == 2)) + { + i1_ref_idx = MAX(pi1_ref_idx0[u1_blk_no], 0); + i1_ref_idx *= + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + i1_ref_idx += MAX(pi1_ref_idx1[u1_blk_no], 0); + if(u4_bot_mb) + { + i1_ref_idx += + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] + << 1) + * (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + } + pu4_wt_offst = (UWORD32*)&ps_dec->pu4_mbaff_wt_mat[2 + * X3(i1_ref_idx)]; + ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst; + } + } + } + } + + /**************************************************/ + /* Loop on Partitions */ + /* direct mode is reflected as a single partition */ + /**************************************************/ + ps_dec->u4_dma_buf_idx = 0; + for(j = 0; j < u1_num_part; j++, ps_part++) + { + u1_sub_mb_num = ps_part->u1_sub_mb_num; + ps_dec->u1_sub_mb_num = u1_sub_mb_num; + + if(PART_NOT_DIRECT != ps_part->u1_is_direct) + { + /**************************************************/ + /* Direct Mode, Call DecodeSpatial/TemporalDirect */ + /* only (those will in turn call FormMbPartInfo) */ + /**************************************************/ + ret = ps_dec->ps_cur_slice->pf_decodeDirect(ps_dec, + u1_direct_mode_width, + ps_cur_mb_info, i); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_type |= (ps_dec->u1_currB_type << 1); + + } + else + { + mv_pred_t s_mvPred; + /**************************************************/ + /* Non Direct Mode, Call Motion Vector Predictor */ + /* and FormMbpartInfo */ + /**************************************************/ + u1_sub_mb_x = u1_sub_mb_num & 0x03; + u1_sub_mb_y = u1_sub_mb_num >> 2; + u1_blk_no = + (u1_num_part < 4) ? + j : + (((u1_sub_mb_y >> 1) << 1) + + (u1_sub_mb_x + >> 1)); + + ps_mv_ntop = ps_mv_ntop_start + u1_sub_mb_x; + ps_mv_nmb = ps_mv_nmb_start + u1_sub_mb_num; + + u1_pred_mode = ps_part->u1_pred_mode; + u1_wd = ps_part->u1_partwidth; + u1_ht = ps_part->u1_partheight; + + u1_lx_start = 0; + u1_lxend = 2; + if( PRED_L0 == u1_pred_mode) + { + s_mvPred.i2_mv[2] = 0; + s_mvPred.i2_mv[3] = 0; + u1_lxend = 1; + } + if( PRED_L1 == u1_pred_mode) + { + s_mvPred.i2_mv[0] = 0; + s_mvPred.i2_mv[1] = 0; + u1_lx_start = 1; + } + + /* Populate the colpic info and reference frames */ + s_mvPred.i1_ref_frame[0] = pi1_ref_idx0[u1_blk_no]; + s_mvPred.i1_ref_frame[1] = pi1_ref_idx1[u1_blk_no]; + + ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb, ps_mv_ntop, + &s_mvPred, u1_sub_mb_num, u1_wd, + u1_lx_start, u1_lxend, + ps_cur_mb_info->u1_mb_mc_mode); + + /**********************************************************/ + /* Loop on number of predictors, 1 Each for Forw Backw */ + /* Loop 2 times for BiDirect mode */ + /**********************************************************/ + for(u1_lx = u1_lx_start; u1_lx < u1_lxend; u1_lx++) + { + WORD16 i2_mv_x, i2_mv_y; + + /********************************************************/ + /* Predict Mv */ + /* Add Mv Residuals and store back */ + /********************************************************/ + i1_ref_idx = s_mvPred.i1_ref_frame[u1_lx]; + u1_tmp_lx = (u1_lx << 1); + + i2_mv_x = ps_mv_nmb->i2_mv[u1_tmp_lx]; + i2_mv_y = ps_mv_nmb->i2_mv[u1_tmp_lx + 1]; + + i2_mv_x += s_mvPred.i2_mv[u1_tmp_lx]; + i2_mv_y += s_mvPred.i2_mv[u1_tmp_lx + 1]; + s_mvPred.i2_mv[u1_tmp_lx] = i2_mv_x; + s_mvPred.i2_mv[u1_tmp_lx + 1] = i2_mv_y; + + /********************************************************/ + /* Transfer setup call */ + /* convert RefIdx if it is MbAff */ + /* Pass Weight Offset and refFrame */ + /********************************************************/ + i1_ref_idx1 = i1_ref_idx >> u1_scale_ref; + if(u1_scale_ref && ((i1_ref_idx & 0x01) != u4_bot_mb)) + i1_ref_idx1 += MAX_REF_BUFS; + ps_ref_frame = + ps_dec->ps_ref_pic_buf_lx[u1_lx][i1_ref_idx1]; + + /* Storing Colocated-Zero u4_flag */ + if(u1_lx == u1_lx_start) + { + /* Fill colocated info in MvPred structure */ + s_mvPred.u1_col_ref_pic_idx = + ps_ref_frame->u1_mv_buf_id; + s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type; + + /* Calculating colocated zero information */ + u1_colz = + (u1_field << 1) + | ((i1_ref_idx == 0) + && (ABS(i2_mv_x) + <= 1) + && (ABS(i2_mv_y) + <= 1)); + u1_colz |= ps_mb_part_info->u1_col_info[u1_blk_no]; + } + + pu4_wt_offst = ppu4_wt_ofst[u1_blk_no]; + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + + i2_mv[0] = i2_mv_x; + i2_mv[1] = i2_mv_y; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,u1_wd,u1_ht,u1_sub_mb_num,u1_pred_mode, + ps_pred_pkd,ps_ref_frame->u1_pic_buf_id,i1_ref_idx,pu4_wt_offst, + ps_ref_frame->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + } + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb, + u1_sub_mb_num, u1_colz, u1_ht, + u1_wd); + } + } + + } + else + { + /* Set zero values in case of Intra Mbs */ + mv_pred_t s_mvPred = + { + { 0, 0, 0, 0 }, + { -1, -1 }, 0, 0}; + /* Storing colocated zero information */ + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, + (UWORD8)(u1_field << 1), 4, 4); + } + + /*if num _cores is set to 3 ,compute bs will be done in another thread*/ + if(ps_dec->u4_num_cores < 3) + { + if(ps_dec->u4_app_disable_deblk_frm == 0) + ps_dec->pf_compute_bs(ps_dec, ps_cur_mb_info, + (UWORD16)(i >> u1_mbaff)); + } + } + return OK; +} +/*! + ************************************************************************** + * \if Function name : ih264d_get_implicit_weights \endif + * + * \brief + * Calculates Implicit Weights. + * + * \return + * None + * + ************************************************************************** + */ +void ih264d_get_implicit_weights(dec_struct_t *ps_dec) +{ + UWORD32 *pu4_iwt_ofst; + UWORD8 i, j; + struct pic_buffer_t *ps_pic_buff0, *ps_pic_buff1; + WORD16 i2_dist_scale_factor; + WORD16 i16_tb, i16_td, i16_tx; + UWORD32 u4_poc0, u4_poc1; + UWORD32 ui_temp0, ui_temp1; + UWORD8 uc_num_ref_idx_l0_active, uc_num_ref_idx_l1_active; + + pu4_iwt_ofst = ps_dec->pu4_wts_ofsts_mat; + uc_num_ref_idx_l0_active = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + uc_num_ref_idx_l1_active = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + + for(i = 0; i < uc_num_ref_idx_l0_active; i++) + { + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][i]; + u4_poc0 = ps_pic_buff0->i4_avg_poc; + for(j = 0; j < uc_num_ref_idx_l1_active; j++) + { + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][j]; + u4_poc1 = ps_pic_buff1->i4_avg_poc; + + if(u4_poc1 != u4_poc0) + { + i16_tb = ps_dec->ps_cur_pic->i4_poc - u4_poc0; + i16_tb = CLIP3(-128, 127, i16_tb); + i16_td = u4_poc1 - u4_poc0; + i16_td = CLIP3(-128, 127, i16_td); + i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i2_dist_scale_factor = CLIP3(-1024, 1023, + (((i16_tb * i16_tx) + 32) >> 6)); + + if(/*((u4_poc1 - u4_poc0) == 0) ||*/ + (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) + || ((i2_dist_scale_factor >> 2) < -64) + || ((i2_dist_scale_factor >> 2) > 128)) + { + /* same for forward and backward, wt=32 and Offset = 0 */ + ui_temp0 = 0x00000020; + ui_temp1 = 0x00000020; + } + else + { + ui_temp0 = 64 - (i2_dist_scale_factor >> 2); + ui_temp1 = (i2_dist_scale_factor >> 2); + } + } + else + { + ui_temp0 = 0x00000020; + ui_temp1 = 0x00000020; + } + pu4_iwt_ofst[0] = pu4_iwt_ofst[2] = pu4_iwt_ofst[4] = ui_temp0; + pu4_iwt_ofst[1] = pu4_iwt_ofst[3] = pu4_iwt_ofst[5] = ui_temp1; + pu4_iwt_ofst += 6; + } + } + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + UWORD8 k; + WORD32 i4_cur_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + UWORD32* pu4_wt_mat = ps_dec->pu4_mbaff_wt_mat; + /* Form the Implicit Weighted prediction matrix for field MBs also */ + for(k = 0; k < 2; k++) + { + for(i = 0; i < (uc_num_ref_idx_l0_active << 1); i++) + { + UWORD16 u2_l0_idx; + + /*u2_l0_idx = (i >= uc_num_ref_idx_l0_active) + ?(MAX_REF_BUFS + i - uc_num_ref_idx_l0_active) : (i) ;*/ + + u2_l0_idx = i >> 1; + if((i & 0x01) != k) + { + u2_l0_idx += MAX_REF_BUFS; + } + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][u2_l0_idx]; + u4_poc0 = ps_pic_buff0->i4_poc; + for(j = 0; j < (uc_num_ref_idx_l1_active << 1); j++) + { + UWORD16 u2_l1_idx; + /*u2_l1_idx = (j >= uc_num_ref_idx_l1_active) + ? (MAX_REF_BUFS + j - uc_num_ref_idx_l1_active ) : (j) ;*/ + + u2_l1_idx = j >> 1; + if((j & 0x01) != k) + { + u2_l1_idx += MAX_REF_BUFS; + } + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][u2_l1_idx]; + u4_poc1 = ps_pic_buff1->i4_poc; + if(u4_poc1 != u4_poc0) + { + i16_tb = i4_cur_poc - u4_poc0; + i16_tb = CLIP3(-128, 127, i16_tb); + i16_td = u4_poc1 - u4_poc0; + i16_td = CLIP3(-128, 127, i16_td); + i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) + / i16_td; + i2_dist_scale_factor = CLIP3( + -1024, 1023, + (((i16_tb * i16_tx) + 32) >> 6)); + + if(/*((u4_poc1 - u4_poc0) == 0) ||*/ + (!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short)) + || ((i2_dist_scale_factor >> 2) < -64) + || ((i2_dist_scale_factor >> 2) > 128)) + { + /* same for forward and backward, wt=32 and Offset = 0 */ + ui_temp0 = 0x00000020; + ui_temp1 = 0x00000020; + } + else + { + ui_temp0 = 64 - (i2_dist_scale_factor >> 2); + ui_temp1 = (i2_dist_scale_factor >> 2); + } + } + else + { + ui_temp0 = 0x00000020; + ui_temp1 = 0x00000020; + } + /* Store in the weight matrix */ + *pu4_wt_mat++ = ui_temp0; + *pu4_wt_mat++ = ui_temp1; + *pu4_wt_mat++ = ui_temp0; + *pu4_wt_mat++ = ui_temp1; + *pu4_wt_mat++ = ui_temp0; + *pu4_wt_mat++ = ui_temp1; + + } + } + i4_cur_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + } + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_bslice \endif + * + * \brief + * Decodes a B Slice + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, UWORD16 u2_first_mb_in_slice) +{ + dec_pic_params_t * ps_pps = ps_dec->ps_cur_pps; + dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + UWORD8 u1_ref_idx_re_flag_lx; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + + UWORD32 u4_temp, ui_temp1; + WORD32 i_temp; + WORD32 ret; + + /*--------------------------------------------------------------------*/ + /* Read remaining contents of the slice header */ + /*--------------------------------------------------------------------*/ + { + WORD8 *pi1_buf; + WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv; + WORD32 *pi4_mv = (WORD32*)pi2_mv; + WORD16 *pi16_refFrame; + pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame; + pi16_refFrame = (WORD16*)pi1_buf; + *pi4_mv = 0; + *(pi4_mv + 1) = 0; + *pi16_refFrame = OUT_OF_RANGE_REF; + ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8)-1; + ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8)-1; + } + + ps_slice->u1_num_ref_idx_active_override_flag = ih264d_get_bit_h264( + ps_bitstrm); + COPYTHECONTEXT("SH: num_ref_idx_override_flag", + ps_slice->u1_num_ref_idx_active_override_flag); + + u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; + ui_temp1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1]; + if(ps_slice->u1_num_ref_idx_active_override_flag) + { + u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", + u4_temp - 1); + ui_temp1 = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SH: num_ref_idx_l1_active_minus1", + ui_temp1 - 1); + } + + { + UWORD8 u1_max_ref_idx = MAX_FRAMES; + if(ps_slice->u1_field_pic_flag) + { + u1_max_ref_idx = MAX_FRAMES << 1; + } + if((u4_temp > u1_max_ref_idx) || (ui_temp1 > u1_max_ref_idx)) + { + return ERROR_NUM_REF; + } + ps_slice->u1_num_ref_idx_lx_active[0] = u4_temp; + ps_slice->u1_num_ref_idx_lx_active[1] = ui_temp1; + } + /* Initialize the Reference list once in Picture if the slice type */ + /* of first slice is between 5 to 9 defined in table 7.3 of standard */ + /* If picture contains both P & B slices then Initialize the Reference*/ + /* List only when it switches from P to B and B to P */ + + { + UWORD8 init_idx_flg = (ps_dec->u1_pr_sl_type + != ps_dec->ps_cur_slice->u1_slice_type); + if(ps_dec->u1_first_pb_nal_in_pic + || (init_idx_flg & !ps_dec->u1_sl_typ_5_9) + || ps_dec->u1_num_ref_idx_lx_active_prev + != ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]) + ih264d_init_ref_idx_lx_b(ps_dec); + if(ps_dec->u1_first_pb_nal_in_pic & ps_dec->u1_sl_typ_5_9) + ps_dec->u1_first_pb_nal_in_pic = 0; + } + /* Store the value for future slices in the same picture */ + ps_dec->u1_num_ref_idx_lx_active_prev = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + + u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l0",u1_ref_idx_re_flag_lx); + + /* Modified temporarily */ + if(u1_ref_idx_re_flag_lx) + { + WORD8 ret; + ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0]; + ret = ih264d_ref_idx_reordering(ps_dec, 0); + if(ret == -1) + return ERROR_REFIDX_ORDER_T; + } + else + ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_init_dpb[0]; + + u1_ref_idx_re_flag_lx = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l1",u1_ref_idx_re_flag_lx); + + /* Modified temporarily */ + if(u1_ref_idx_re_flag_lx) + { + WORD8 ret; + ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_mod_dpb[1]; + ret = ih264d_ref_idx_reordering(ps_dec, 1); + if(ret == -1) + return ERROR_REFIDX_ORDER_T; + } + else + ps_dec->ps_ref_pic_buf_lx[1] = ps_dec->ps_dpb_mgr->ps_init_dpb[1]; + + /* Create refIdx to POC mapping */ + { + void **ppv_map_ref_idx_to_poc_lx; + WORD8 idx; + struct pic_buffer_t *ps_pic; + + ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0; + ppv_map_ref_idx_to_poc_lx[0] = 0; + ppv_map_ref_idx_to_poc_lx++; + for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + idx++) + { + ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx]; + ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1); + } + + ppv_map_ref_idx_to_poc_lx = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1; + + ppv_map_ref_idx_to_poc_lx[0] = 0; + ppv_map_ref_idx_to_poc_lx++; + for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + idx++) + { + ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx]; + ppv_map_ref_idx_to_poc_lx[idx] = (ps_pic->pu1_buf1); + } + + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b; + + ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + + TOP_LIST_FLD_L0; + ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + + BOT_LIST_FLD_L0; + + ppv_map_ref_idx_to_poc_lx_t[0] = 0; + ppv_map_ref_idx_to_poc_lx_t++; + ppv_map_ref_idx_to_poc_lx_b[0] = 0; + ppv_map_ref_idx_to_poc_lx_b++; + for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + idx++) + { + ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx]; + ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1); + ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1); + + ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1; + ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1; + + ppv_map_ref_idx_to_poc_lx_t += 2; + ppv_map_ref_idx_to_poc_lx_b += 2; + } + + ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + + TOP_LIST_FLD_L1; + ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + + BOT_LIST_FLD_L1; + + ppv_map_ref_idx_to_poc_lx_t[0] = 0; + ppv_map_ref_idx_to_poc_lx_t++; + ppv_map_ref_idx_to_poc_lx_b[0] = 0; + ppv_map_ref_idx_to_poc_lx_b++; + for(idx = 0; idx < ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + idx++) + { + UWORD8 u1_tmp_idx = idx << 1; + ps_pic = ps_dec->ps_ref_pic_buf_lx[1][idx]; + ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx] = (ps_pic->pu1_buf1); + ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx + 1] = (ps_pic->pu1_buf1); + + ppv_map_ref_idx_to_poc_lx_b[u1_tmp_idx] = (ps_pic->pu1_buf1) + 1; + ppv_map_ref_idx_to_poc_lx_t[u1_tmp_idx + 1] = (ps_pic->pu1_buf1) + 1; + + } + } + + if(ps_dec->u4_num_cores >= 3) + { + WORD32 num_entries; + WORD32 size; + + num_entries = MIN(MAX_FRAMES, ps_dec->u4_num_ref_frames_at_init); + num_entries = 2 * ((2 * num_entries) + 1); + + size = num_entries * sizeof(void *); + size += PAD_MAP_IDX_POC * sizeof(void *); + + memcpy((void *)ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc, + ps_dec->ppv_map_ref_idx_to_poc, + size); + } + + } + + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag + && (ps_dec->ps_cur_slice->u1_field_pic_flag == 0)) + { + ih264d_convert_frm_mbaff_list(ps_dec); + } + + if(ps_pps->u1_wted_bipred_idc == 1) + { + ret = ih264d_parse_pred_weight_table(ps_slice, ps_bitstrm); + if(ret != OK) + return ret; + ih264d_form_pred_weight_matrix(ps_dec); + ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat; + } + else if(ps_pps->u1_wted_bipred_idc == 2) + { + /* Implicit Weighted prediction */ + ps_slice->u2_log2Y_crwd = 0x0505; + ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat; + ih264d_get_implicit_weights(ps_dec); + } + else + ps_dec->ps_cur_slice->u2_log2Y_crwd = 0; + + ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = + ps_dec->ps_cur_slice->u2_log2Y_crwd; + + /* G050 */ + if(ps_slice->u1_nal_ref_idc != 0) + { + if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read) + ps_dec->u4_bitoffset = ih264d_read_mmco_commands(ps_dec); + else + ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset; + } + /* G050 */ + + if(ps_pps->u1_entropy_coding_mode == CABAC) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > MAX_CABAC_INIT_IDC) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->u1_cabac_init_idc = u4_temp; + COPYTHECONTEXT("SH: cabac_init_idc",ps_slice->u1_cabac_init_idc); + } + + /* Read slice_qp_delta */ + i_temp = ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i_temp < 0) || (i_temp > 51)) + { + return ERROR_INV_RANGE_QP_T; + } + ps_slice->u1_slice_qp = i_temp; + COPYTHECONTEXT("SH: slice_qp_delta", + (WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp)); + + if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED) + { + return ERROR_INV_SLICE_HDR_T; + } COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp); + ps_slice->u1_disable_dblk_filter_idc = u4_temp; + if(u4_temp != 1) + { + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->i1_slice_alpha_c0_offset = i_temp; + COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2", + ps_slice->i1_slice_alpha_c0_offset >> 1); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->i1_slice_beta_offset = i_temp; + COPYTHECONTEXT("SH: slice_beta_offset_div2", + ps_slice->i1_slice_beta_offset >> 1); + + } + else + { + ps_slice->i1_slice_alpha_c0_offset = 0; + ps_slice->i1_slice_beta_offset = 0; + } + } + else + { + ps_slice->u1_disable_dblk_filter_idc = 0; + ps_slice->i1_slice_alpha_c0_offset = 0; + ps_slice->i1_slice_beta_offset = 0; + } + + + /*set slice header cone to 2 ,to indicate correct header*/ + DATA_SYNC(); + + ps_dec->ps_parse_cur_slice->slice_header_done = 2; + + if(ps_pps->u1_entropy_coding_mode) + { + SWITCHOFFTRACE; SWITCHONTRACECABAC; + ps_dec->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac; + ps_dec->pf_parse_inter_mb = ih264d_parse_bmb_cabac; + ih264d_init_cabac_contexts(B_SLICE, ps_dec); + + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff; + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff; + } + else + { + SWITCHONTRACE; SWITCHOFFTRACECABAC; + ps_dec->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc; + ps_dec->pf_parse_inter_mb = ih264d_parse_bmb_cavlc; + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff; + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff; + } + + ret = ih264d_cal_col_pic(ps_dec); + if(ret != OK) + return ret; + ps_dec->u1_B = 1; + ps_dec->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_bmb; + ret = ps_dec->pf_parse_inter_slice(ps_dec, ps_slice, u2_first_mb_in_slice); + if(ret != OK) + return ret; + return OK; +} + diff --git a/decoder/ih264d_parse_cabac.c b/decoder/ih264d_parse_cabac.c new file mode 100755 index 0000000..9d58f33 --- /dev/null +++ b/decoder/ih264d_parse_cabac.c @@ -0,0 +1,1607 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_cabac.c + * + * \brief + * This file contains cabac Residual decoding routines. + * + * \date + * 20/03/2003 + * + * \author NS + *************************************************************************** + */ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_defs.h" +#include "ih264d_structs.h" + +#include "ih264d_cabac.h" +#include "ih264d_bitstrm.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_error_handler.h" +#include "ih264d_parse_cabac.h" +#include "ih264d_parse_slice.h" +#include "ih264d_tables.h" +#include "ih264d_mb_utils.h" +#include "ih264d_utils.h" + +/*! + ******************************************************************************** + * \if Function name : ih264d_read_coeff4x4_cabac \endif + * + * \brief This function encodes residual_block_cabac as defined in 7.3.5.3.2. + * + * \return + * Returns the index of last significant coeff. + * + ******************************************************************************** + */ + +UWORD8 ih264d_read_coeff4x4_cabac(dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_ctxcat, + bin_ctxt_model_t *ps_ctxt_sig_coeff, + dec_struct_t *ps_dec, /*!< pointer to access global variables*/ + bin_ctxt_model_t *ps_ctxt_coded) +{ + + decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env; + UWORD32 u4_coded_flag; + UWORD32 u4_offset, *pu4_buffer; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + WORD16 *pi2_coeff_data; + WORD32 num_sig_coeffs = 0; + + /*loading from strcuctures*/ + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + u4_offset = ps_bitstrm->u4_ofst; + pu4_buffer = ps_bitstrm->pu4_buffer; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + { + + /*inilined DecodeDecision_onebin begins*/ + + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + + UWORD32 table_lookup; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (ps_ctxt_coded->u1_mps_state); + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + table_lookup = + pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) + { + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, + u4_offset, pu4_buffer) + } + + ps_ctxt_coded->u1_mps_state = u1_mps_state; + u4_coded_flag = u4_symbol; + + /*inilined DecodeDecision_onebin ends*/ + + } + + } + + if(u4_coded_flag) + { + + { + bin_ctxt_model_t *p_binCtxt_last, *p_binCtxt_last_org; + UWORD32 uc_last_coeff_idx; + UWORD32 uc_bin; + UWORD32 i; + WORD32 first_coeff_offset = 0; + + if((u4_ctxcat == CHROMA_AC_CTXCAT) || (u4_ctxcat == LUMA_AC_CTXCAT)) + { + first_coeff_offset = 1; + } + + i = 0; + if(u4_ctxcat == CHROMA_DC_CTXCAT) + { + uc_last_coeff_idx = 3; + } + else + { + UWORD32 u4_start; + u4_start = (u4_ctxcat & 1) + (u4_ctxcat >> 2); + uc_last_coeff_idx = 15 - u4_start; + } + p_binCtxt_last_org = ps_ctxt_sig_coeff + + LAST_COEFF_CTXT_MINUS_SIG_COEFF_CTXT; + + do + { + + /*inilined DecodeDecision_onebin begins*/ + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (ps_ctxt_sig_coeff->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, + u4_symbol, u4_int_range_lps, u1_mps_state, + table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_14) + { + + UWORD32 read_bits, u4_clz; + u4_clz = CLZ(u4_code_int_range); + NEXTBITS(read_bits, (u4_offset + 23), pu4_buffer, + u4_clz) + FLUSHBITS(u4_offset, (u4_clz)) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst << u4_clz) + | read_bits; + } + + INC_BIN_COUNT( + ps_cab_env) + + ps_ctxt_sig_coeff->u1_mps_state = u1_mps_state; + uc_bin = u4_symbol; + + } + /*incrementing pointer to point to the context of the next bin*/ + ps_ctxt_sig_coeff++; + + /*inilined DecodeDecision_onebin ends*/ + + if(uc_bin) + { + num_sig_coeffs++; + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, (i + first_coeff_offset)); + + p_binCtxt_last = p_binCtxt_last_org + i; + + /*inilined DecodeDecision_onebin begins*/ + + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (p_binCtxt_last->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) + & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps + << (23 - u4_clz); + + u4_code_int_range = u4_code_int_range + - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, + u4_symbol, u4_int_range_lps, + u1_mps_state, table_lookup) + + INC_BIN_COUNT(ps_cab_env) + + p_binCtxt_last->u1_mps_state = u1_mps_state; + uc_bin = u4_symbol; + + } + + /*inilined DecodeDecision_onebin ends*/ + if(uc_bin == 1) + goto label_read_levels; + + } + + i = i + 1; + + } + while(i < uc_last_coeff_idx); + + num_sig_coeffs++; + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, (i + first_coeff_offset)); + + label_read_levels: ; + + } + + /// VALUE of No of Coeff in BLOCK = i + 1 for second case else i; + + /* Decode coeff_abs_level_minus1 and coeff_sign_flag */ + { + + WORD32 i2_abs_lvl; + UWORD32 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0; + + UWORD32 u4_ctx_inc; + UWORD32 ui_prefix; + bin_ctxt_model_t *p_ctxt_abs_level; + + + p_ctxt_abs_level = ps_dec->p_coeff_abs_level_minus1_t[u4_ctxcat]; + u4_ctx_inc = ((0x51)); + + /*****************************************************/ + /* Main Loop runs for no. of Significant coefficient */ + /*****************************************************/ + + + do + { + + { + INC_SYM_COUNT(&(ps_dec.s_cab_dec_env)); + + /*****************************************************/ + /* inilining a modified ih264d_decode_bins_unary */ + /*****************************************************/ + + { + UWORD32 u4_value; + UWORD32 u4_symbol; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_ctx_Inc; + + u4_value = 0; + + u4_ctx_Inc = u4_ctx_inc & 0xf; + ps_bin_ctxt = p_ctxt_abs_level + u4_ctx_Inc; + + do + { + + { + + UWORD32 u4_qnt_int_range, + u4_int_range_lps; + UWORD32 u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range + << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range + >> 29) & 0x3; + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps + << (23 - u4_clz); + u4_code_int_range = u4_code_int_range + - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, + u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, + table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + + RENORM_RANGE_OFFSET(u4_code_int_range, + u4_code_int_val_ofst, + u4_offset, pu4_buffer) + } + + INC_BIN_COUNT(ps_cab_env); + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + } + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value++; + ps_bin_ctxt = p_ctxt_abs_level + (u4_ctx_inc >> 4); + + } + while(u4_symbol && (u4_value < UCOFF_LEVEL)); + + ui_prefix = u4_value - 1 + u4_symbol; + + } + + if(ui_prefix == UCOFF_LEVEL) + { + UWORD32 ui16_sufS = 0; + UWORD32 u1_max_bins; + UWORD32 u4_value; + + i2_abs_lvl = UCOFF_LEVEL; + /*inlining ih264d_decode_bypass_bins_unary begins*/ + + { + UWORD32 uc_bin; + UWORD32 bits_to_flush; + UWORD32 max_bits = 32; + + bits_to_flush = 0; + /*renormalize to ensure there 23 bits more in the u4_code_int_val_ofst*/ + { + UWORD32 u4_clz, read_bits; + + u4_clz = CLZ(u4_code_int_range); + FLUSHBITS(u4_offset, u4_clz) + NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst + << u4_clz) | read_bits; + + } + + do + { + bits_to_flush++; + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + uc_bin = 1; + u4_code_int_val_ofst -= u4_code_int_range; + } + else + { + /* S=0 */ + uc_bin = 0; + } + + INC_BIN_COUNT( + ps_cab_env);INC_BYPASS_BINS(ps_cab_env); + + } + while(uc_bin && (bits_to_flush < max_bits)); + + u4_value = (bits_to_flush - 1); + + } + /*inlining ih264d_decode_bypass_bins_unary ends*/ + + ui16_sufS = (1 << u4_value); + u1_max_bins = u4_value; + + if(u4_value > 0) + { + + /*inline bypassbins_flc begins*/ + + if(u4_value > 10) + { + UWORD32 u4_clz, read_bits; + + u4_clz = CLZ(u4_code_int_range); + FLUSHBITS(u4_offset, u4_clz) + NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst + << u4_clz) | read_bits; + } + + { + UWORD32 ui_bins; + UWORD32 uc_bin; + UWORD32 bits_to_flush; + + ui_bins = 0; + bits_to_flush = 0; + + do + { + bits_to_flush++; + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst + >= u4_code_int_range) + { + /* S=1 */ + uc_bin = 1; + u4_code_int_val_ofst -= + u4_code_int_range; + } + else + { + /* S=0 */ + uc_bin = 0; + } + + INC_BIN_COUNT( + ps_cab_env);INC_BYPASS_BINS(ps_cab_env); + + ui_bins = ((ui_bins << 1) | uc_bin); + + } + while(bits_to_flush < u1_max_bins); + + u4_value = ui_bins; + } + + /*inline bypassbins_flc ends*/ + + } + + //Value of K + ui16_sufS += u4_value; + i2_abs_lvl += ui16_sufS; + + } + else + i2_abs_lvl = 1 + ui_prefix; + + if(i2_abs_lvl > 1) + { + u1_abs_level_gt1++; + } + if(!u1_abs_level_gt1) + { + u1_abs_level_equal1++; + u4_ctx_inc = (5 << 4) + MIN(u1_abs_level_equal1, 4); + } + else + u4_ctx_inc = (5 + MIN(u1_abs_level_gt1, 4)) << 4; + + /*u4_ctx_inc = g_table_temp[u1_abs_level_gt1][u1_abs_level_equal1];*/ + + /* encode coeff_sign_flag[i] */ + + { + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= (u4_code_int_range)) + { + /* S=1 */ + u4_code_int_val_ofst -= u4_code_int_range; + i2_abs_lvl = (-i2_abs_lvl); + } + + } + num_sig_coeffs--; + *pi2_coeff_data++ = i2_abs_lvl; + } + } + while(num_sig_coeffs > 0); + } + } + + if(u4_coded_flag) + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + + /*updating structures*/ + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_bitstrm->u4_ofst = u4_offset; + return (u4_coded_flag); +} +/*! + ******************************************************************************** + * \if Function name : ih264d_read_coeff8x8_cabac \endif + * + * \brief This function encodes residual_block_cabac as defined in 7.3.5.3.2. + when transform_8x8_flag = 1 + * + * \return + * Returns the index of last significant coeff. + * + ******************************************************************************** + */ + +void ih264d_read_coeff8x8_cabac(dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec, /*!< pointer to access global variables*/ + dec_mb_info_t *ps_cur_mb_info) +{ + decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env; + UWORD32 u4_offset, *pu4_buffer; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + + /* High profile related declarations */ + UWORD8 u1_field_coding_flag = ps_cur_mb_info->ps_curmb->u1_mb_fld; + const UWORD8 *pu1_lastcoeff_context_inc = + (UWORD8 *)gau1_ih264d_lastcoeff_context_inc; + const UWORD8 *pu1_sigcoeff_context_inc; + bin_ctxt_model_t *ps_ctxt_sig_coeff; + WORD32 num_sig_coeffs = 0; + tu_blk8x8_coeff_data_t *ps_tu_8x8; + WORD16 *pi2_coeff_data; + + /*loading from strcuctures*/ + + ps_tu_8x8 = (tu_blk8x8_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_8x8->au4_sig_coeff_map[0] = 0; + ps_tu_8x8->au4_sig_coeff_map[1] = 0; + pi2_coeff_data = &ps_tu_8x8->ai2_level[0]; + + + if(!u1_field_coding_flag) + { + pu1_sigcoeff_context_inc = + (UWORD8 *)gau1_ih264d_sigcoeff_context_inc_frame; + + /*******************************************************************/ + /* last coefficient context is derived from significant coeff u4_flag */ + /* only significant coefficient matrix need to be initialized */ + /*******************************************************************/ + ps_ctxt_sig_coeff = ps_dec->s_high_profile.ps_sigcoeff_8x8_frame; + } + else + { + pu1_sigcoeff_context_inc = + (UWORD8 *)gau1_ih264d_sigcoeff_context_inc_field; + + /*******************************************************************/ + /* last coefficient context is derived from significant coeff u4_flag */ + /* only significant coefficient matrix need to be initialized */ + /*******************************************************************/ + ps_ctxt_sig_coeff = ps_dec->s_high_profile.ps_sigcoeff_8x8_field; + } + + /*loading from strcuctures*/ + + u4_offset = ps_bitstrm->u4_ofst; + pu4_buffer = ps_bitstrm->pu4_buffer; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + { + { + bin_ctxt_model_t *p_binCtxt_last, *p_binCtxt_last_org, + *p_ctxt_sig_coeff_org; + UWORD32 uc_last_coeff_idx; + UWORD32 uc_bin; + UWORD32 i; + + i = 0; + + uc_last_coeff_idx = 63; + + p_binCtxt_last_org = ps_ctxt_sig_coeff + + LAST_COEFF_CTXT_MINUS_SIG_COEFF_CTXT_8X8; + + p_ctxt_sig_coeff_org = ps_ctxt_sig_coeff; + + do + { + /*inilined DecodeDecision_onebin begins*/ + { + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (ps_ctxt_sig_coeff->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, + u4_symbol, u4_int_range_lps, u1_mps_state, + table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_14) + { + UWORD32 read_bits, u4_clz; + u4_clz = CLZ(u4_code_int_range); + NEXTBITS(read_bits, (u4_offset + 23), pu4_buffer, + u4_clz) + FLUSHBITS(u4_offset, (u4_clz)) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst << u4_clz) + | read_bits; + } + + ps_ctxt_sig_coeff->u1_mps_state = u1_mps_state; + uc_bin = u4_symbol; + } + /*incrementing pointer to point to the context of the next bin*/ + ps_ctxt_sig_coeff = p_ctxt_sig_coeff_org + + pu1_sigcoeff_context_inc[i + 1]; + + /*inilined DecodeDecision_onebin ends*/ + if(uc_bin) + { + num_sig_coeffs++; + SET_BIT(ps_tu_8x8->au4_sig_coeff_map[i>31], (i > 31 ? i - 32:i)); + + p_binCtxt_last = p_binCtxt_last_org + + pu1_lastcoeff_context_inc[i]; + + /*inilined DecodeDecision_onebin begins*/ + + { + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (p_binCtxt_last->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) + & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps + << (23 - u4_clz); + + u4_code_int_range = u4_code_int_range + - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, + u4_symbol, u4_int_range_lps, + u1_mps_state, table_lookup) + + p_binCtxt_last->u1_mps_state = u1_mps_state; + uc_bin = u4_symbol; + } + + /*inilined DecodeDecision_onebin ends*/ + if(uc_bin == 1) + goto label_read_levels; + + } + + i = i + 1; + + } + while(i < uc_last_coeff_idx); + + num_sig_coeffs++; + SET_BIT(ps_tu_8x8->au4_sig_coeff_map[i>31], (i > 31 ? i - 32:i)); + + label_read_levels: ; + } + + /// VALUE of No of Coeff in BLOCK = i + 1 for second case else i; + + /* Decode coeff_abs_level_minus1 and coeff_sign_flag */ + { + WORD32 i2_abs_lvl; + UWORD32 u1_abs_level_equal1 = 1, u1_abs_level_gt1 = 0; + + UWORD32 u4_ctx_inc; + UWORD32 ui_prefix; + bin_ctxt_model_t *p_ctxt_abs_level; + + p_ctxt_abs_level = + ps_dec->p_coeff_abs_level_minus1_t[LUMA_8X8_CTXCAT]; + u4_ctx_inc = ((0x51)); + + /*****************************************************/ + /* Main Loop runs for no. of Significant coefficient */ + /*****************************************************/ + do + { + { + + /*****************************************************/ + /* inilining a modified ih264d_decode_bins_unary */ + /*****************************************************/ + + { + UWORD32 u4_value; + UWORD32 u4_symbol; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_ctx_Inc; + u4_value = 0; + + u4_ctx_Inc = u4_ctx_inc & 0xf; + ps_bin_ctxt = p_ctxt_abs_level + u4_ctx_Inc; + + do + { + { + UWORD32 u4_qnt_int_range, + u4_int_range_lps; + UWORD32 u1_mps_state; + UWORD32 table_lookup; + const UWORD32 *pu4_table = + (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range + << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range + >> 29) & 0x3; + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps + << (23 - u4_clz); + u4_code_int_range = u4_code_int_range + - u4_int_range_lps; + u4_symbol = ((u1_mps_state >> 6) & 0x1); + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, + u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, + table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + + RENORM_RANGE_OFFSET(u4_code_int_range, + u4_code_int_val_ofst, + u4_offset, pu4_buffer) + } + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + } + + u4_value++; + ps_bin_ctxt = p_ctxt_abs_level + (u4_ctx_inc >> 4); + + } + while(u4_symbol && (u4_value < UCOFF_LEVEL)); + + ui_prefix = u4_value - 1 + u4_symbol; + } + + if(ui_prefix == UCOFF_LEVEL) + { + UWORD32 ui16_sufS = 0; + UWORD32 u1_max_bins; + UWORD32 u4_value; + + i2_abs_lvl = UCOFF_LEVEL; + /*inlining ih264d_decode_bypass_bins_unary begins*/ + + { + UWORD32 uc_bin; + UWORD32 bits_to_flush; + UWORD32 max_bits = 32; + + bits_to_flush = 0; + /*renormalize to ensure there 23 bits more in the u4_code_int_val_ofst*/ + { + UWORD32 u4_clz, read_bits; + + u4_clz = CLZ(u4_code_int_range); + FLUSHBITS(u4_offset, u4_clz) + NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst + << u4_clz) | read_bits; + } + + do + { + bits_to_flush++; + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + uc_bin = 1; + u4_code_int_val_ofst -= u4_code_int_range; + } + else + { + /* S=0 */ + uc_bin = 0; + } + + } + while(uc_bin && (bits_to_flush < max_bits)); + + u4_value = (bits_to_flush - 1); + } + /*inlining ih264d_decode_bypass_bins_unary ends*/ + + ui16_sufS = (1 << u4_value); + u1_max_bins = u4_value; + + if(u4_value > 0) + { + /*inline bypassbins_flc begins*/ + + if(u4_value > 10) + { + UWORD32 u4_clz, read_bits; + + u4_clz = CLZ(u4_code_int_range); + FLUSHBITS(u4_offset, u4_clz) + NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst + << u4_clz) | read_bits; + } + + { + UWORD32 ui_bins; + UWORD32 uc_bin; + UWORD32 bits_to_flush; + + ui_bins = 0; + bits_to_flush = 0; + + do + { + bits_to_flush++; + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst + >= u4_code_int_range) + { + /* S=1 */ + uc_bin = 1; + u4_code_int_val_ofst -= + u4_code_int_range; + } + else + { + /* S=0 */ + uc_bin = 0; + } + + ui_bins = ((ui_bins << 1) | uc_bin); + + } + while(bits_to_flush < u1_max_bins); + + u4_value = ui_bins; + } + /*inline bypassbins_flc ends*/ + } + + //Value of K + ui16_sufS += u4_value; + i2_abs_lvl += ui16_sufS; + } + else + { + i2_abs_lvl = 1 + ui_prefix; + } + + if(i2_abs_lvl > 1) + { + u1_abs_level_gt1++; + } + if(!u1_abs_level_gt1) + { + u1_abs_level_equal1++; + u4_ctx_inc = (5 << 4) + MIN(u1_abs_level_equal1, 4); + } + else + { + u4_ctx_inc = (5 + MIN(u1_abs_level_gt1, 4)) << 4; + } + + /*u4_ctx_inc = g_table_temp[u1_abs_level_gt1][u1_abs_level_equal1];*/ + + /* encode coeff_sign_flag[i] */ + + { + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= (u4_code_int_range)) + { + /* S=1 */ + u4_code_int_val_ofst -= u4_code_int_range; + i2_abs_lvl = (-i2_abs_lvl); + } + } + + *pi2_coeff_data++ = i2_abs_lvl; + num_sig_coeffs--; + } + } + while(num_sig_coeffs > 0); + } + } + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_8x8; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + /*updating structures*/ + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_bitstrm->u4_ofst = u4_offset; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cabac_parse_8x8block */ +/* */ +/* Description : This function does the residual parsing of 4 subblocks */ +/* in a 8x8 block. */ +/* */ +/* Inputs : pi2_coeff_block : pointer to residual block where */ +/* decoded and inverse scan coefficients are updated */ +/* */ +/* u4_sub_block_strd : indicates the number of sublocks */ +/* in a row. It is 4 for luma and 2 for chroma. */ +/* */ +/* u4_ctx_cat : inidicates context category for residual */ +/* decoding. */ +/* */ +/* ps_dec : pointer to Decstruct (decoder context) */ +/* */ +/* pu1_top_nnz : top nnz pointer */ +/* */ +/* pu1_left_nnz : left nnz pointer */ +/* */ +/* Globals : No */ +/* Processing : Parsing for four subblocks in unrolled, top and left nnz */ +/* are updated on the fly. csbp is set in accordance to */ +/* decoded numcoeff for the subblock index in raster order */ +/* */ +/* Outputs : The updated residue buffer, nnzs and csbp current block */ +/* */ +/* Returns : Returns the coded sub block pattern csbp for the block */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 09 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_cabac_parse_8x8block(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_ctx_cat, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz) +{ + UWORD32 u4_ctxinc, u4_subblock_coded; + UWORD32 u4_top0, u4_top1; + UWORD32 u4_csbp = 0; + UWORD32 u4_idx = 0; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + bin_ctxt_model_t * const ps_cbf = ps_dec->p_cbf_t[u4_ctx_cat]; + bin_ctxt_model_t *ps_src_bin_ctxt; + bin_ctxt_model_t * const ps_sig_coeff_flag = + ps_dec->p_significant_coeff_flag_t[u4_ctx_cat]; + + UWORD8 *pu1_inv_scan = ps_dec->pu1_inv_scan; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 0 */ + /*------------------------------------------------------*/ + u4_ctxinc = ((!!pu1_top_nnz[0]) << 1) + (!!pu1_left_nnz[0]); + + ps_src_bin_ctxt = ps_cbf + u4_ctxinc; + + u4_top0 = ih264d_read_coeff4x4_cabac( ps_bitstrm, + u4_ctx_cat, ps_sig_coeff_flag, ps_dec, + ps_src_bin_ctxt); + + INSERT_BIT(u4_csbp, u4_idx, u4_top0); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 1 */ + /*------------------------------------------------------*/ + u4_idx++; + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + u4_ctxinc = ((!!pu1_top_nnz[1]) << 1) + u4_top0; + + ps_src_bin_ctxt = ps_cbf + u4_ctxinc; + + u4_top1 = ih264d_read_coeff4x4_cabac(ps_bitstrm, + u4_ctx_cat, ps_sig_coeff_flag, ps_dec, + ps_src_bin_ctxt); + + INSERT_BIT(u4_csbp, u4_idx, u4_top1); + pu1_left_nnz[0] = u4_top1; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 2 */ + /*------------------------------------------------------*/ + u4_idx += (u4_sub_block_strd - 1); + pi2_coeff_block += ((u4_sub_block_strd - 1) * NUM_COEFFS_IN_4x4BLK); + u4_ctxinc = (u4_top0 << 1) + (!!pu1_left_nnz[1]); + + ps_src_bin_ctxt = ps_cbf + u4_ctxinc; + + u4_subblock_coded = ih264d_read_coeff4x4_cabac(ps_bitstrm, u4_ctx_cat, + ps_sig_coeff_flag, ps_dec, + ps_src_bin_ctxt); + + INSERT_BIT(u4_csbp, u4_idx, u4_subblock_coded); + pu1_top_nnz[0] = u4_subblock_coded; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 3 */ + /*------------------------------------------------------*/ + u4_idx++; + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + u4_ctxinc = (u4_top1 << 1) + u4_subblock_coded; + + ps_src_bin_ctxt = ps_cbf + u4_ctxinc; + + u4_subblock_coded = ih264d_read_coeff4x4_cabac(ps_bitstrm, u4_ctx_cat, + ps_sig_coeff_flag, ps_dec, + ps_src_bin_ctxt); + + INSERT_BIT(u4_csbp, u4_idx, u4_subblock_coded); + pu1_top_nnz[1] = pu1_left_nnz[1] = u4_subblock_coded; + + return (u4_csbp); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_residual4x4_cabac \endif + * + * \brief + * This function parses CABAC syntax of a Luma and Chroma AC Residuals. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_parse_residual4x4_cabac(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_offset) +{ + UWORD8 u1_cbp = ps_cur_mb_info->u1_cbp; + UWORD16 ui16_csbp = 0; + WORD16 *pi2_residual_buf; + UWORD8 uc_ctx_cat; + UWORD8 *pu1_top_nnz = ps_cur_mb_info->ps_curmb->pu1_nnz_y; + UWORD8 *pu1_left_nnz = ps_dec->pu1_left_nnz_y; + UWORD8 *pu1_top_nnz_uv = ps_cur_mb_info->ps_curmb->pu1_nnz_uv; + ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + ctxt_inc_mb_info_t *ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 u4_nbr_avail = ps_dec->u1_mb_ngbr_availablity; + WORD16 *pi2_coeff_block = NULL; + bin_ctxt_model_t *ps_src_bin_ctxt; + + UWORD8 u1_top_dc_csbp = (ps_top_ctxt->u1_yuv_dc_csbp) >> 1; + UWORD8 u1_left_dc_csbp = (ps_dec->pu1_left_yuv_dc_csbp[0]) >> 1; + + + if(!(u4_nbr_avail & TOP_MB_AVAILABLE_MASK)) + { + if(p_curr_ctxt->u1_mb_type & CAB_INTRA_MASK) + { + *(UWORD32 *)pu1_top_nnz = 0; + u1_top_dc_csbp = 0; + *(UWORD32 *)pu1_top_nnz_uv = 0; + } + else + { + *(UWORD32 *)pu1_top_nnz = 0x01010101; + u1_top_dc_csbp = 0x3; + *(UWORD32 *)pu1_top_nnz_uv = 0x01010101; + } + } + else + { + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + pu1_buf = ps_cur_mb_info->ps_top_mb->pu1_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *(UWORD32 *)(pu1_top_nnz) = *pu4_buf; + + pu1_buf = ps_cur_mb_info->ps_top_mb->pu1_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *(UWORD32 *)(pu1_top_nnz_uv) = *pu4_buf; + + } + + if(!(u4_nbr_avail & LEFT_MB_AVAILABLE_MASK)) + { + if(p_curr_ctxt->u1_mb_type & CAB_INTRA_MASK) + { + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + *(UWORD32 *)pu1_left_nnz = 0; + u1_left_dc_csbp = 0; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + } + else + { + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + *(UWORD32 *)pu1_left_nnz = 0x01010101; + u1_left_dc_csbp = 0x3; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x01010101; + } + } + + uc_ctx_cat = u1_offset ? LUMA_AC_CTXCAT : LUMA_4X4_CTXCAT; + + ps_cur_mb_info->u1_qp_div6 = ps_dec->u1_qp_y_div6; + ps_cur_mb_info->u1_qpc_div6 = ps_dec->u1_qp_u_div6; + ps_cur_mb_info->u1_qp_rem6 = ps_dec->u1_qp_y_rem6; + ps_cur_mb_info->u1_qpc_rem6 = ps_dec->u1_qp_u_rem6; + // CHECK_THIS + ps_cur_mb_info->u1_qpcr_div6 = ps_dec->u1_qp_v_div6; + ps_cur_mb_info->u1_qpcr_rem6 = ps_dec->u1_qp_v_rem6; + + if(u1_cbp & 0x0f) + { + if(ps_cur_mb_info->u1_tran_form8x8 == 0) + { + /*******************************************************************/ + /* Block 0 residual decoding, check cbp and proceed (subblock = 0) */ + /*******************************************************************/ + if(!(u1_cbp & 0x1)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + } + else + { + ui16_csbp = ih264d_cabac_parse_8x8block(pi2_coeff_block, 4, + uc_ctx_cat, ps_dec, + pu1_top_nnz, + pu1_left_nnz); + } + + /*******************************************************************/ + /* Block 1 residual decoding, check cbp and proceed (subblock = 2) */ + /*******************************************************************/ + pi2_coeff_block += (2 * NUM_COEFFS_IN_4x4BLK); + if(!(u1_cbp & 0x2)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + } + else + { + UWORD32 u4_temp = ih264d_cabac_parse_8x8block(pi2_coeff_block, + 4, uc_ctx_cat, + ps_dec, + (pu1_top_nnz + 2), + pu1_left_nnz); + ui16_csbp |= (u4_temp << 2); + } + + /*******************************************************************/ + /* Block 2 residual decoding, check cbp and proceed (subblock = 8) */ + /*******************************************************************/ + pi2_coeff_block += (6 * NUM_COEFFS_IN_4x4BLK); + if(!(u1_cbp & 0x4)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + UWORD32 u4_temp = ih264d_cabac_parse_8x8block( + pi2_coeff_block, 4, uc_ctx_cat, ps_dec, + pu1_top_nnz, (pu1_left_nnz + 2)); + ui16_csbp |= (u4_temp << 8); + } + + /*******************************************************************/ + /* Block 3 residual decoding, check cbp and proceed (subblock = 10)*/ + /*******************************************************************/ + pi2_coeff_block += (2 * NUM_COEFFS_IN_4x4BLK); + if(!(u1_cbp & 0x8)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + UWORD32 u4_temp = ih264d_cabac_parse_8x8block( + pi2_coeff_block, 4, uc_ctx_cat, ps_dec, + (pu1_top_nnz + 2), (pu1_left_nnz + 2)); + ui16_csbp |= (u4_temp << 10); + } + + } + else + { + ui16_csbp = 0; + + /*******************************************************************/ + /* Block 0 residual decoding, check cbp and proceed (subblock = 0) */ + /*******************************************************************/ + if(!(u1_cbp & 0x1)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + } + else + { + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + + ih264d_read_coeff8x8_cabac( ps_bitstrm, + ps_dec, ps_cur_mb_info); + + pu1_left_nnz[0] = 1; + pu1_left_nnz[1] = 1; + + pu1_top_nnz[0] = 1; + pu1_top_nnz[1] = 1; + + /* added to be used by BS computation module */ + ui16_csbp |= 0x0033; + } + + /*******************************************************************/ + /* Block 1 residual decoding, check cbp and proceed (subblock = 2) */ + /*******************************************************************/ + pi2_coeff_block += 64; + + if(!(u1_cbp & 0x2)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + } + else + { + + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + + ih264d_read_coeff8x8_cabac(ps_bitstrm, + ps_dec, ps_cur_mb_info); + + pu1_left_nnz[0] = 1; + pu1_left_nnz[1] = 1; + + pu1_top_nnz[2] = 1; + pu1_top_nnz[3] = 1; + + /* added to be used by BS computation module */ + ui16_csbp |= 0x00CC; + + } + + /*******************************************************************/ + /* Block 2 residual decoding, check cbp and proceed (subblock = 8) */ + /*******************************************************************/ + pi2_coeff_block += 64; + if(!(u1_cbp & 0x4)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + + ih264d_read_coeff8x8_cabac(ps_bitstrm, + ps_dec, ps_cur_mb_info); + + pu1_left_nnz[2] = 1; + pu1_left_nnz[3] = 1; + + pu1_top_nnz[0] = 1; + pu1_top_nnz[1] = 1; + + /* added to be used by BS computation module */ + ui16_csbp |= 0x3300; + } + + /*******************************************************************/ + /* Block 3 residual decoding, check cbp and proceed (subblock = 10)*/ + /*******************************************************************/ + pi2_coeff_block += 64; + + if(!(u1_cbp & 0x8)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + + ih264d_read_coeff8x8_cabac(ps_bitstrm, + ps_dec, ps_cur_mb_info); + + pu1_left_nnz[2] = 1; + pu1_left_nnz[3] = 1; + + pu1_top_nnz[2] = 1; + pu1_top_nnz[3] = 1; + + /* added to be used by BS computation module */ + ui16_csbp |= 0xCC00; + } + } + } + else + { + *(UWORD32 *)(pu1_top_nnz) = 0; + *(UWORD32 *)(pu1_left_nnz) = 0; + } + /*--------------------------------------------------------------------*/ + /* Store the last row of N values to top row */ + /*--------------------------------------------------------------------*/ + ps_cur_mb_info->u2_luma_csbp = ui16_csbp; + ps_cur_mb_info->ps_curmb->u2_luma_csbp = ui16_csbp; + { + WORD8 i; + UWORD16 u2_chroma_csbp = 0; + ps_cur_mb_info->u2_chroma_csbp = 0; + + u1_cbp >>= 4; + pu1_top_nnz = pu1_top_nnz_uv; + pu1_left_nnz = ps_dec->pu1_left_nnz_uv; + /*--------------------------------------------------------------------*/ + /* if Chroma Component not present OR no ac values present */ + /* Set the values of N to zero */ + /*--------------------------------------------------------------------*/ + if(u1_cbp == CBPC_ALLZERO) + { + ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x1; + *(UWORD32 *)(pu1_top_nnz) = 0; + *(UWORD32 *)(pu1_left_nnz) = 0; + p_curr_ctxt->u1_yuv_dc_csbp &= 0x1; + return (0); + } + + /*--------------------------------------------------------------------*/ + /* Decode Chroma DC values */ + /*--------------------------------------------------------------------*/ + for(i = 0; i < 2; i++) + { + UWORD8 uc_a = 1, uc_b = 1; + UWORD32 u4_ctx_inc; + UWORD8 uc_codedBlockFlag; + UWORD8 pu1_inv_scan[4] = + { 0, 1, 2, 3 }; + WORD32 u4_scale; + WORD32 i4_mb_inter_inc; + tu_sblk4x4_coeff_data_t *ps_tu_4x4 = + (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + WORD16 *pi2_coeff_data = + (WORD16 *)ps_dec->pv_parse_tu_coeff_data; + WORD16 ai2_dc_coef[4]; + + INC_SYM_COUNT(&(ps_dec->s_cab_dec_env)); + u4_scale = (i) ? + (ps_dec->pu2_quant_scale_v[0] + << ps_dec->u1_qp_v_div6) : + (ps_dec->pu2_quant_scale_u[0] + << ps_dec->u1_qp_u_div6); + + /*--------------------------------------------------------------------*/ + /* Decode Bitstream to get the DC coeff */ + /*--------------------------------------------------------------------*/ + uc_a = (u1_left_dc_csbp >> i) & 0x01; + uc_b = (u1_top_dc_csbp >> i) & 0x01; + u4_ctx_inc = (uc_a + (uc_b << 1)); + + ps_src_bin_ctxt = (ps_dec->p_cbf_t[CHROMA_DC_CTXCAT]) + u4_ctx_inc; + + uc_codedBlockFlag = + ih264d_read_coeff4x4_cabac(ps_bitstrm, + CHROMA_DC_CTXCAT, + ps_dec->p_significant_coeff_flag_t[CHROMA_DC_CTXCAT], + ps_dec, ps_src_bin_ctxt); + + i4_mb_inter_inc = (!((ps_cur_mb_info->ps_curmb->u1_mb_type == I_4x4_MB) + || (ps_cur_mb_info->ps_curmb->u1_mb_type == I_16x16_MB))) + * 3; + + if(ps_dec->s_high_profile.u1_scaling_present) + { + u4_scale *= + ps_dec->s_high_profile.i2_scalinglist4x4[i4_mb_inter_inc + + 1 + i][0]; + + } + else + { + u4_scale <<= 4; + } + + if(uc_codedBlockFlag) + { + WORD32 i_z0, i_z1, i_z2, i_z3; + WORD32 *pi4_scale; + + SET_BIT(u1_top_dc_csbp, i); + SET_BIT(u1_left_dc_csbp, i); + + ai2_dc_coef[0] = 0; + ai2_dc_coef[1] = 0; + ai2_dc_coef[2] = 0; + ai2_dc_coef[3] = 0; + + ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, + ai2_dc_coef, + pu1_inv_scan); + i_z0 = (ai2_dc_coef[0] + ai2_dc_coef[2]); + i_z1 = (ai2_dc_coef[0] - ai2_dc_coef[2]); + i_z2 = (ai2_dc_coef[1] - ai2_dc_coef[3]); + i_z3 = (ai2_dc_coef[1] + ai2_dc_coef[3]); + + /*-----------------------------------------------------------*/ + /* Scaling and storing the values back */ + /*-----------------------------------------------------------*/ + *pi2_coeff_data++ = ((i_z0 + i_z3) * u4_scale) >> 5; + *pi2_coeff_data++ = ((i_z0 - i_z3) * u4_scale) >> 5; + *pi2_coeff_data++ = ((i_z1 + i_z2) * u4_scale) >> 5; + *pi2_coeff_data++ = ((i_z1 - i_z2) * u4_scale) >> 5; + + ps_dec->pv_parse_tu_coeff_data = (void *)pi2_coeff_data; + + SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag,(i+1)); + } + else + { + CLEARBIT(u1_top_dc_csbp, i); + CLEARBIT(u1_left_dc_csbp, i); + } + } + + /*********************************************************************/ + /* Update the DC csbp */ + /*********************************************************************/ + ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x1; + p_curr_ctxt->u1_yuv_dc_csbp &= 0x1; + ps_dec->pu1_left_yuv_dc_csbp[0] |= (u1_left_dc_csbp << 1); + p_curr_ctxt->u1_yuv_dc_csbp |= (u1_top_dc_csbp << 1); + if(u1_cbp == CBPC_ACZERO) + { + *(UWORD32 *)(pu1_top_nnz) = 0; + *(UWORD32 *)(pu1_left_nnz) = 0; + return (0); + } + /*--------------------------------------------------------------------*/ + /* Decode Chroma AC values */ + /*--------------------------------------------------------------------*/ + { + UWORD32 u4_temp; + /*****************************************************************/ + /* U Block residual decoding, check cbp and proceed (subblock=0)*/ + /*****************************************************************/ + u2_chroma_csbp = ih264d_cabac_parse_8x8block(pi2_coeff_block, 2, + CHROMA_AC_CTXCAT, + ps_dec, pu1_top_nnz, + pu1_left_nnz); + + pi2_coeff_block += MB_CHROM_SIZE; + /*****************************************************************/ + /* V Block residual decoding, check cbp and proceed (subblock=1)*/ + /*****************************************************************/ + u4_temp = ih264d_cabac_parse_8x8block(pi2_coeff_block, 2, + CHROMA_AC_CTXCAT, + ps_dec, (pu1_top_nnz + 2), + (pu1_left_nnz + 2)); + u2_chroma_csbp |= (u4_temp << 4); + } + /*********************************************************************/ + /* Update the AC csbp */ + /*********************************************************************/ + ps_cur_mb_info->u2_chroma_csbp = u2_chroma_csbp; + } + + return (0); +} + diff --git a/decoder/ih264d_parse_cabac.h b/decoder/ih264d_parse_cabac.h new file mode 100755 index 0000000..eb66e8c --- /dev/null +++ b/decoder/ih264d_parse_cabac.h @@ -0,0 +1,60 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_cabac.h + * + * \brief + * This file contains cabac Residual decoding routines. + * + * \date + * 20/03/2003 + * + * \author NS + *************************************************************************** + */ +#ifndef _IH264D_PARSE_CABAC_H_ +#define _IH264D_PARSE_CABAC_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" + +#define UCOFF_LEVEL 14 + + +UWORD8 ih264d_read_coeff4x4_cabac(dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_ctxcat, + bin_ctxt_model_t *ps_ctxt_sig_coeff, + dec_struct_t *ps_dec, + bin_ctxt_model_t *ps_ctxt_coded); + +void ih264d_read_coeff8x8_cabac(dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info); + +UWORD32 cabac_parse_8x8block_transform8x8_set(WORD16 *pi2_coeff_block, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + dec_mb_info_t *ps_cur_mb_info); + +#endif /* _IH264D_PARSE_CABAC_H_ */ diff --git a/decoder/ih264d_parse_cavlc.c b/decoder/ih264d_parse_cavlc.c new file mode 100755 index 0000000..a3f345c --- /dev/null +++ b/decoder/ih264d_parse_cavlc.c @@ -0,0 +1,2694 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_cavlc.c + * + * \brief + * This file contains UVLC related functions. + * + * \date + * 20/11/2002 + * + * \author NS + *************************************************************************** + */ + +#include <string.h> +#include <stdio.h> + +#include "ih264d_bitstrm.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_error_handler.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_cabac.h" +#include "ih264d_structs.h" +#include "ih264d_tables.h" +#include "ih264d_tables.h" +#include "ih264d_mb_utils.h" + +void ih264d_unpack_coeff4x4_dc_4x4blk(tu_sblk4x4_coeff_data_t *ps_tu_4x4, + WORD16 *pi2_out_coeff_data, + UWORD8 *pu1_inv_scan); + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_uev */ +/* */ +/* Description : Reads the unsigned Exp Golomb codec syntax from the */ +/* ps_bitstrm as specified in section 9.1 of H264 standard */ +/* It also increases bitstream u4_ofst by the number of bits */ +/* parsed for UEV decode operation */ +/* */ +/* Inputs : bitstream base pointer and bitsream u4_ofst in bits */ +/* Globals : None */ +/* Processing : */ +/* Outputs : UEV decoded syntax element and incremented ps_bitstrm u4_ofst */ +/* Returns : UEV decoded syntax element */ +/* */ +/* Issues : Does not check if ps_bitstrm u4_ofst exceeds max ps_bitstrm i4_size */ +/* for performamce. Caller might have to do error resilence */ +/* check for bitstream overflow */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_uev(UWORD32 *pu4_bitstrm_ofst, UWORD32 *pu4_bitstrm_buf) +{ + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + return ((1 << u4_ldz) + u4_word - 1); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_sev */ +/* */ +/* Description : Reads the signed Exp Golomb codec syntax from the ps_bitstrm */ +/* as specified in section 9.1 of H264 standard. */ +/* It also increases bitstream u4_ofst by the number of bits */ +/* parsed for SEV decode operation */ +/* */ +/* Inputs : bitstream base pointer and bitsream u4_ofst in bits */ +/* Globals : None */ +/* Processing : */ +/* Outputs : SEV decoded syntax element and incremented ps_bitstrm u4_ofst */ +/* Returns : SEV decoded syntax element */ +/* */ +/* Issues : Does not check if ps_bitstrm u4_ofst exceeds max ps_bitstrm i4_size */ +/* for performamce. Caller might have to do error resilence */ +/* check for bitstream overflow */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_sev(UWORD32 *pu4_bitstrm_ofst, UWORD32 *pu4_bitstrm_buf) +{ + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + return (-(WORD32)u4_abs_val); + else + return (u4_abs_val); +} + +/*****************************************************************************/ +/* */ +/* Function Name : get_tev_range_1 */ +/* */ +/* Description : Reads the TEV Exp Golomb codec syntax from the ps_bitstrm */ +/* as specified in section 9.1 of H264 standard. This will */ +/* called only when the input range is 1 for TEV decode. */ +/* If range is more than 1, then UEV decode is done */ +/* */ +/* Inputs : bitstream base pointer and bitsream u4_ofst in bits */ +/* Globals : None */ +/* Processing : */ +/* Outputs : TEV decoded syntax element and incremented ps_bitstrm u4_ofst */ +/* Returns : TEV decoded syntax element */ +/* */ +/* Issues : Does not check if ps_bitstrm u4_ofst exceeds max ps_bitstrm i4_size */ +/* for performamce. Caller might have to do error resilence */ +/* check for bitstream overflow */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +UWORD32 ih264d_tev_range1(UWORD32 *pu4_bitstrm_ofst, UWORD32 *pu4_bitstrm_buf) +{ + UWORD32 u4_code; + GETBIT(u4_code, *pu4_bitstrm_ofst, pu4_bitstrm_buf); + return (!u4_code); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_uvlc \endif + * + * \brief + * + * Reads the unsigned/signed/truncated integer Exp-Golomb-coded syntax element + * with the left bit first. The parsing process for this descriptor is specified + * in subclause 9.1. + * + * \param ps_bitstrm : Pointer to Bitstream Structure . + * \param u4_range : Range value in case of Truncated Exp-Golomb-code + * \param pi_bitstrm_ofst : Pointer to the local copy of Bitstream u4_ofst + * \param u1_flag : Flag indicating the case of UEV,SEV or TEV + * \param u4_bitstrm_ofst : Local copy of Bitstream u4_ofst + * \param pu4_bitstrm_buf : Pointer to the Bitstream buffer + * + * \return + * Returns Code Value. + * + ************************************************************************** + */ + +WORD32 ih264d_uvlc(dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_range, + UWORD32 *pi_bitstrm_ofst, + UWORD8 u1_flag, + UWORD32 u4_bitstrm_ofst, + UWORD32 *pu4_bitstrm_buf) +{ + UWORD32 word, word2, cur_bit, cur_word, code_val, code_num, clz; + + SWITCHOFFTRACE; + cur_bit = u4_bitstrm_ofst & 0x1F; + cur_word = u4_bitstrm_ofst >> 5; + word = pu4_bitstrm_buf[cur_word]; + word2 = pu4_bitstrm_buf[cur_word + 1]; + + if(cur_bit != 0) + { + word <<= cur_bit; + word2 >>= (32 - cur_bit); + word |= word2; + } + + if(u1_flag == TEV && u4_range == 1) + { + word >>= 31; + word = 1 - word; + (*pi_bitstrm_ofst)++; + ps_bitstrm->u4_ofst = *pi_bitstrm_ofst; + return (WORD32)word; + } + + //finding clz + { + UWORD32 ui32_code, ui32_mask; + + ui32_code = word; + ui32_mask = 0x80000000; + clz = 0; + + /* DSP implements this with LMBD instruction */ + /* so there we don't need to break the loop */ + while(!(ui32_code & ui32_mask)) + { + clz++; + ui32_mask >>= 1; + if(0 == ui32_mask) + break; + } + } + + if(clz == 0) + { + *pi_bitstrm_ofst = *pi_bitstrm_ofst + (2 * clz) + 1; + ps_bitstrm->u4_ofst = *pi_bitstrm_ofst; + return 0; + } + + word <<= (clz + 1); + word >>= (32 - clz); + code_num = (1 << clz) + word - 1; + *pi_bitstrm_ofst = *pi_bitstrm_ofst + (2 * clz) + 1; + ps_bitstrm->u4_ofst = *pi_bitstrm_ofst; + + if(u1_flag == TEV || u1_flag == UEV) + return (WORD32)code_num; + + code_val = (code_num + 1) >> 1; + if(!(code_num & 0x01)) + return -((WORD32)code_val); + return (WORD32)code_val; + +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_4x4res_block_totalcoeff_1 */ +/* */ +/* Description : This function does cavlc decoding of 4x4 block residual */ +/* coefficient when total coeff is equal to 1. The parsing */ +/* is done as defined in section 9.2.2 and 9.2.3 of the */ +/* H264 standard. */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_1(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm) +{ + + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_trailing_ones = u4_total_coeff_trail_one & 0xFFFF; + WORD32 i2_level; + UWORD32 u4_tot_zero, u4_ldz, u4_scan_pos; + + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + WORD16 *pi2_coeff_data; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + + if(u4_trailing_ones) + { + UWORD32 u4_sign; + /****************************************************************/ + /* Decode Trailing One as in section 9.2.2 */ + /****************************************************************/ + GETBIT(u4_sign, u4_bitstream_offset, pu4_bitstrm_buf); + i2_level = u4_sign ? -1 : 1; + } + else + { + /****************************************************************/ + /* Decoding Level based on prefix and suffix as in 9.2.2 */ + /****************************************************************/ + UWORD32 u4_lev_suffix, u4_lev_suffix_size; + WORD32 u2_lev_code, u2_abs_value; + UWORD32 u4_lev_prefix; + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + u2_lev_code = (2 + MIN(u4_lev_prefix, 15)); + + if(14 == u4_lev_prefix) + u4_lev_suffix_size = 4; + else if(15 <= u4_lev_prefix) + { + u2_lev_code += 15; + u4_lev_suffix_size = u4_lev_prefix - 3; + } + else + u4_lev_suffix_size = 0; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + if(u4_lev_suffix_size) + { + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code += u4_lev_suffix; + } + + u2_abs_value = (u2_lev_code + 2) >> 1; + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level = (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + } + + /****************************************************************/ + /* Decoding total zeros as in section 9.2.3, table 9.7 */ + /****************************************************************/ + FIND_ONE_IN_STREAM_LEN(u4_ldz, u4_bitstream_offset, pu4_bitstrm_buf, 8); + + if(u4_ldz) + { + GETBIT(u4_tot_zero, u4_bitstream_offset, pu4_bitstrm_buf); + u4_tot_zero = (u4_ldz << 1) - u4_tot_zero; + } + else + u4_tot_zero = 0; + + /***********************************************************************/ + /* Inverse scan and store residual coeff. Update the bitstream u4_ofst */ + /***********************************************************************/ + u4_scan_pos = u4_tot_zero + u4_isdc; + if(u4_scan_pos > 15) + return -1; + + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level; + + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + ps_bitstrm->u4_ofst = u4_bitstream_offset; + return 0; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_4x4res_block_totalcoeff_2to10 */ +/* */ +/* Description : This function does cavlc decoding of 4x4 block residual */ +/* coefficient when total coeffs are between two and ten */ +/* inclusive. Parsing is done as defined in section 9.2.2 */ +/* and 9.2.3 the H264 standard. */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_2to10(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, /*!<TotalCoefficients<<16+trailingones*/ + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 u4_total_zeroes; + WORD32 i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_trailing_ones = u4_total_coeff_trail_one & 0xFFFF; + UWORD32 u4_total_coeff = u4_total_coeff_trail_one >> 16; + WORD16 i2_level_arr[16]; + + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + WORD16 *pi2_coeff_data; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + i = u4_total_coeff - 1; + + if(u4_trailing_ones) + { + /*********************************************************************/ + /* Decode Trailing Ones */ + /* read the sign of T1's and put them in level array */ + /*********************************************************************/ + UWORD32 u4_signs, u4_cnt = u4_trailing_ones; + WORD16 (*ppi2_trlone_lkup)[3] = + (WORD16 (*)[3])gai2_ih264d_trailing_one_level; + WORD16 *pi2_trlone_lkup; + + GETBITS(u4_signs, u4_bitstream_offset, pu4_bitstrm_buf, u4_cnt); + + pi2_trlone_lkup = ppi2_trlone_lkup[(1 << u4_cnt) - 2 + u4_signs]; + + while(u4_cnt--) + i2_level_arr[i--] = *pi2_trlone_lkup++; + } + + /****************************************************************/ + /* Decoding Levels Begins */ + /****************************************************************/ + if(i >= 0) + { + /****************************************************************/ + /* First level is decoded outside the loop as it has lot of */ + /* special cases. */ + /****************************************************************/ + UWORD32 u4_lev_suffix, u4_suffix_len, u4_lev_suffix_size; + WORD32 u2_lev_code, u2_abs_value; + UWORD32 u4_lev_prefix; + + /***************************************************************/ + /* u4_suffix_len = 0, Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + /*********************************************************/ + /* Special decoding case when trailing ones are 3 */ + /*********************************************************/ + u2_lev_code = MIN(15, u4_lev_prefix); + + u2_lev_code += (3 == u4_trailing_ones) ? 0 : 2; + + if(14 == u4_lev_prefix) + u4_lev_suffix_size = 4; + else if(15 <= u4_lev_prefix) + { + u2_lev_code += 15; + u4_lev_suffix_size = u4_lev_prefix - 3; + } + else + u4_lev_suffix_size = 0; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + if(u4_lev_suffix_size) + { + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code += u4_lev_suffix; + } + + u2_abs_value = (u2_lev_code + 2) >> 1; + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + u4_suffix_len = (u2_abs_value > 3) ? 2 : 1; + + /*********************************************************/ + /* Now loop over the remaining levels */ + /*********************************************************/ + while(i >= 0) + { + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + u4_lev_suffix_size = + (15 <= u4_lev_prefix) ? + (u4_lev_prefix - 3) : u4_suffix_len; + + /*********************************************************/ + /* Compute level code using prefix and suffix */ + /*********************************************************/ + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code = (MIN(15,u4_lev_prefix) << u4_suffix_len) + + u4_lev_suffix; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + u2_abs_value = (u2_lev_code + 2) >> 1; + + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = + (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + /*********************************************************/ + /* Increment suffix length if required */ + /*********************************************************/ + u4_suffix_len += + (u4_suffix_len < 6) ? + (u2_abs_value + > (3 + << (u4_suffix_len + - 1))) : + 0; + } + + /****************************************************************/ + /* Decoding Levels Ends */ + /****************************************************************/ + } + + /****************************************************************/ + /* Decoding total zeros as in section 9.2.3, table 9.7 */ + /****************************************************************/ + { + UWORD32 u4_index; + const UWORD8 (*ppu1_total_zero_lkup)[64] = + (const UWORD8 (*)[64])gau1_ih264d_table_total_zero_2to10; + + NEXTBITS(u4_index, u4_bitstream_offset, pu4_bitstrm_buf, 6); + u4_total_zeroes = ppu1_total_zero_lkup[u4_total_coeff - 2][u4_index]; + + FLUSHBITS(u4_bitstream_offset, (u4_total_zeroes >> 4)); + u4_total_zeroes &= 0xf; + } + + /**************************************************************/ + /* Decode the runs and form the coefficient buffer */ + /**************************************************************/ + { + const UWORD8 *pu1_table_runbefore; + UWORD32 u4_run; + WORD32 k; + UWORD32 u4_scan_pos = u4_total_coeff + u4_total_zeroes - 1 + u4_isdc; + WORD32 u4_zeroes_left = u4_total_zeroes; + k = u4_total_coeff - 1; + + /**************************************************************/ + /* Decoding Runs Begin for zeros left > 6 */ + /**************************************************************/ + while((u4_zeroes_left > 6) && k) + { + UWORD32 u4_code; + + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 3); + + if(u4_code != 0) + { + FLUSHBITS(u4_bitstream_offset, 3); + u4_run = (7 - u4_code); + } + else + { + + FIND_ONE_IN_STREAM_LEN(u4_code, u4_bitstream_offset, + pu4_bitstrm_buf, 11); + u4_run = (4 + u4_code); + } + + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[k--]; + u4_zeroes_left -= u4_run; + u4_scan_pos -= (u4_run + 1); + } + + /**************************************************************/ + /* Decoding Runs for 0 < zeros left <=6 */ + /**************************************************************/ + pu1_table_runbefore = (UWORD8 *)gau1_ih264d_table_run_before; + while((u4_zeroes_left > 0) && k) + { + UWORD32 u4_code; + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 3); + + u4_code = pu1_table_runbefore[u4_code + (u4_zeroes_left << 3)]; + u4_run = u4_code >> 2; + + FLUSHBITS(u4_bitstream_offset, (u4_code & 0x03)); + + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[k--]; + u4_zeroes_left -= u4_run; + u4_scan_pos -= (u4_run + 1); + } + /**************************************************************/ + /* Decoding Runs End */ + /**************************************************************/ + + /**************************************************************/ + /* Copy the remaining coefficients */ + /**************************************************************/ + if(u4_zeroes_left < 0) + return -1; + while(k >= 0) + { + + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[k--]; + u4_scan_pos--; + } + } + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + ps_bitstrm->u4_ofst = u4_bitstream_offset; + return 0; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_4x4res_block_totalcoeff_11to16 */ +/* */ +/* Description : This function does cavlc decoding of 4x4 block residual */ +/* coefficient when total coeffs are greater than ten. */ +/* Parsing is done as defined in section 9.2.2 and 9.2.3 of */ +/* the H264 standard. */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_11to16(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, /*!<TotalCoefficients<<16+trailingones*/ + dec_bit_stream_t *ps_bitstrm ) +{ + UWORD32 u4_total_zeroes; + WORD32 i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_trailing_ones = u4_total_coeff_trail_one & 0xFFFF; + UWORD32 u4_total_coeff = u4_total_coeff_trail_one >> 16; + WORD16 i2_level_arr[16]; + + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + WORD16 *pi2_coeff_data; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + i = u4_total_coeff - 1; + if(u4_trailing_ones) + { + /*********************************************************************/ + /* Decode Trailing Ones */ + /* read the sign of T1's and put them in level array */ + /*********************************************************************/ + UWORD32 u4_signs, u4_cnt = u4_trailing_ones; + WORD16 (*ppi2_trlone_lkup)[3] = + (WORD16 (*)[3])gai2_ih264d_trailing_one_level; + WORD16 *pi2_trlone_lkup; + + GETBITS(u4_signs, u4_bitstream_offset, pu4_bitstrm_buf, u4_cnt); + + pi2_trlone_lkup = ppi2_trlone_lkup[(1 << u4_cnt) - 2 + u4_signs]; + + while(u4_cnt--) + i2_level_arr[i--] = *pi2_trlone_lkup++; + } + + /****************************************************************/ + /* Decoding Levels Begins */ + /****************************************************************/ + if(i >= 0) + { + /****************************************************************/ + /* First level is decoded outside the loop as it has lot of */ + /* special cases. */ + /****************************************************************/ + UWORD32 u4_lev_suffix, u4_suffix_len, u4_lev_suffix_size; + UWORD16 u2_lev_code, u2_abs_value; + UWORD32 u4_lev_prefix; + + if(u4_trailing_ones < 3) + { + /*********************************************************/ + /* u4_suffix_len = 1 */ + /*********************************************************/ + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + u4_lev_suffix_size = + (15 <= u4_lev_prefix) ? (u4_lev_prefix - 3) : 1; + + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code = 2 + (MIN(u4_lev_prefix,15) << 1) + u4_lev_suffix; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + } + else + { + /*********************************************************/ + /*u4_suffix_len = 0 */ + /*********************************************************/ + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + /*********************************************************/ + /* Special decoding case when trailing ones are 3 */ + /*********************************************************/ + u2_lev_code = MIN(15, u4_lev_prefix); + + u2_lev_code += (3 == u4_trailing_ones) ? 0 : (2); + + if(14 == u4_lev_prefix) + u4_lev_suffix_size = 4; + else if(15 <= u4_lev_prefix) + { + u2_lev_code += 15; + u4_lev_suffix_size = (u4_lev_prefix - 3); + } + else + u4_lev_suffix_size = 0; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + if(u4_lev_suffix_size) + { + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code += u4_lev_suffix; + } + } + + u2_abs_value = (u2_lev_code + 2) >> 1; + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + u4_suffix_len = (u2_abs_value > 3) ? 2 : 1; + + /*********************************************************/ + /* Now loop over the remaining levels */ + /*********************************************************/ + while(i >= 0) + { + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + u4_lev_suffix_size = + (15 <= u4_lev_prefix) ? + (u4_lev_prefix - 3) : u4_suffix_len; + + /*********************************************************/ + /* Compute level code using prefix and suffix */ + /*********************************************************/ + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code = (MIN(15,u4_lev_prefix) << u4_suffix_len) + + u4_lev_suffix; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + u2_abs_value = (u2_lev_code + 2) >> 1; + + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = + (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + /*********************************************************/ + /* Increment suffix length if required */ + /*********************************************************/ + u4_suffix_len += + (u4_suffix_len < 6) ? + (u2_abs_value + > (3 + << (u4_suffix_len + - 1))) : + 0; + } + + /****************************************************************/ + /* Decoding Levels Ends */ + /****************************************************************/ + } + + if(u4_total_coeff < (16 - u4_isdc)) + { + UWORD32 u4_index; + const UWORD8 (*ppu1_total_zero_lkup)[16] = + (const UWORD8 (*)[16])gau1_ih264d_table_total_zero_11to15; + + NEXTBITS(u4_index, u4_bitstream_offset, pu4_bitstrm_buf, 4); + u4_total_zeroes = ppu1_total_zero_lkup[u4_total_coeff - 11][u4_index]; + + FLUSHBITS(u4_bitstream_offset, (u4_total_zeroes >> 4)); + u4_total_zeroes &= 0xf; + } + else + u4_total_zeroes = 0; + + /**************************************************************/ + /* Decode the runs and form the coefficient buffer */ + /**************************************************************/ + { + const UWORD8 *pu1_table_runbefore; + UWORD32 u4_run; + WORD32 k; + UWORD32 u4_scan_pos = u4_total_coeff + u4_total_zeroes - 1 + u4_isdc; + WORD32 u4_zeroes_left = u4_total_zeroes; + k = u4_total_coeff - 1; + + /**************************************************************/ + /* Decoding Runs for 0 < zeros left <=6 */ + /**************************************************************/ + pu1_table_runbefore = (UWORD8 *)gau1_ih264d_table_run_before; + while((u4_zeroes_left > 0) && k) + { + UWORD32 u4_code; + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 3); + + u4_code = pu1_table_runbefore[u4_code + (u4_zeroes_left << 3)]; + u4_run = u4_code >> 2; + + FLUSHBITS(u4_bitstream_offset, (u4_code & 0x03)); + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[k--]; + u4_zeroes_left -= u4_run; + u4_scan_pos -= (u4_run + 1); + } + /**************************************************************/ + /* Decoding Runs End */ + /**************************************************************/ + + /**************************************************************/ + /* Copy the remaining coefficients */ + /**************************************************************/ + if(u4_zeroes_left < 0) + return -1; + while(k >= 0) + { + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[k--]; + u4_scan_pos--; + } + } + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + ps_bitstrm->u4_ofst = u4_bitstream_offset; + return 0; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_rest_of_residual_cav_chroma_dc_block */ +/* */ +/* Description : This function does the Cavlc parsing of the bitstream */ +/* for chroma dc coefficients */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 15 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_rest_of_residual_cav_chroma_dc_block(UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 u4_total_zeroes; + WORD16 i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_trailing_ones = u4_total_coeff_trail_one & 0xFFFF; + UWORD32 u4_total_coeff = u4_total_coeff_trail_one >> 16; + WORD16 i2_level_arr[4]; + + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + WORD16 *pi2_coeff_data; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + i = u4_total_coeff - 1; + if(u4_trailing_ones) + { + /*********************************************************************/ + /* Decode Trailing Ones */ + /* read the sign of T1's and put them in level array */ + /*********************************************************************/ + UWORD32 u4_signs, u4_cnt = u4_trailing_ones; + WORD16 (*ppi2_trlone_lkup)[3] = + (WORD16 (*)[3])gai2_ih264d_trailing_one_level; + WORD16 *pi2_trlone_lkup; + + GETBITS(u4_signs, u4_bitstream_offset, pu4_bitstrm_buf, u4_cnt); + + pi2_trlone_lkup = ppi2_trlone_lkup[(1 << u4_cnt) - 2 + u4_signs]; + + while(u4_cnt--) + i2_level_arr[i--] = *pi2_trlone_lkup++; + } + + /****************************************************************/ + /* Decoding Levels Begins */ + /****************************************************************/ + if(i >= 0) + { + /****************************************************************/ + /* First level is decoded outside the loop as it has lot of */ + /* special cases. */ + /****************************************************************/ + UWORD32 u4_lev_suffix, u4_suffix_len, u4_lev_suffix_size; + UWORD16 u2_lev_code, u2_abs_value; + UWORD32 u4_lev_prefix; + + /***************************************************************/ + /* u4_suffix_len = 0, Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + /*********************************************************/ + /* Special decoding case when trailing ones are 3 */ + /*********************************************************/ + u2_lev_code = MIN(15, u4_lev_prefix); + + u2_lev_code += (3 == u4_trailing_ones) ? 0 : (2); + + if(14 == u4_lev_prefix) + u4_lev_suffix_size = 4; + else if(15 <= u4_lev_prefix) + { + u2_lev_code += 15; + u4_lev_suffix_size = u4_lev_prefix - 3; + } + else + u4_lev_suffix_size = 0; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + if(u4_lev_suffix_size) + { + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code += u4_lev_suffix; + } + + u2_abs_value = (u2_lev_code + 2) >> 1; + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + u4_suffix_len = (u2_abs_value > 3) ? 2 : 1; + + /*********************************************************/ + /* Now loop over the remaining levels */ + /*********************************************************/ + while(i >= 0) + { + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + FIND_ONE_IN_STREAM_32(u4_lev_prefix, u4_bitstream_offset, + pu4_bitstrm_buf); + + u4_lev_suffix_size = + (15 <= u4_lev_prefix) ? + (u4_lev_prefix - 3) : u4_suffix_len; + + /*********************************************************/ + /* Compute level code using prefix and suffix */ + /*********************************************************/ + GETBITS(u4_lev_suffix, u4_bitstream_offset, pu4_bitstrm_buf, + u4_lev_suffix_size); + u2_lev_code = (MIN(u4_lev_prefix,15) << u4_suffix_len) + + u4_lev_suffix; + + //HP_LEVEL_PREFIX + if(16 <= u4_lev_prefix) + { + u2_lev_code += ((1 << (u4_lev_prefix - 3)) - 4096); + } + u2_abs_value = (u2_lev_code + 2) >> 1; + + /*********************************************************/ + /* If Level code is odd, level is negative else positive */ + /*********************************************************/ + i2_level_arr[i--] = + (u2_lev_code & 1) ? -u2_abs_value : u2_abs_value; + + /*********************************************************/ + /* Increment suffix length if required */ + /*********************************************************/ + u4_suffix_len += (u2_abs_value > (3 << (u4_suffix_len - 1))); + } + + /****************************************************************/ + /* Decoding Levels Ends */ + /****************************************************************/ + } + + if(u4_total_coeff < 4) + { + UWORD32 u4_max_ldz = (4 - u4_total_coeff); + FIND_ONE_IN_STREAM_LEN(u4_total_zeroes, u4_bitstream_offset, + pu4_bitstrm_buf, u4_max_ldz); + } + else + u4_total_zeroes = 0; + + /**************************************************************/ + /* Decode the runs and form the coefficient buffer */ + /**************************************************************/ + { + const UWORD8 *pu1_table_runbefore; + UWORD32 u4_run; + UWORD32 u4_scan_pos = (u4_total_coeff + u4_total_zeroes - 1); + UWORD32 u4_zeroes_left = u4_total_zeroes; + i = u4_total_coeff - 1; + + /**************************************************************/ + /* Decoding Runs for 0 < zeros left <=6 */ + /**************************************************************/ + pu1_table_runbefore = (UWORD8 *)gau1_ih264d_table_run_before; + while(u4_zeroes_left && i) + { + UWORD32 u4_code; + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 3); + + u4_code = pu1_table_runbefore[u4_code + (u4_zeroes_left << 3)]; + u4_run = u4_code >> 2; + + FLUSHBITS(u4_bitstream_offset, (u4_code & 0x03)); + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[i--]; + u4_zeroes_left -= u4_run; + u4_scan_pos -= (u4_run + 1); + } + /**************************************************************/ + /* Decoding Runs End */ + /**************************************************************/ + + /**************************************************************/ + /* Copy the remaining coefficients */ + /**************************************************************/ + while(i >= 0) + { + SET_BIT(ps_tu_4x4->u2_sig_coeff_map, u4_scan_pos); + *pi2_coeff_data++ = i2_level_arr[i--]; + u4_scan_pos--; + } + } + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_parse_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_parse_tu_coeff_data + offset); + } + + ps_bitstrm->u4_ofst = u4_bitstream_offset; +} + +/*! + ************************************************************************** + * \if Function name : CavlcParsingInvScanInvQuant \endif + * + * \brief + * This function do cavlc parsing of coefficient tokens for any block + * type except chromDc and depending + * on whenther any coefficients to be parsed calls module + * RestOfResidualBlockCavlc. + * + * \return + * Returns total number of non-zero coefficients. + * + ************************************************************************** + */ + +WORD32 ih264d_cavlc_parse4x4coeff_n0to7(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, /* is it a DC block */ + WORD32 u4_n, + dec_struct_t *ps_dec, + UWORD32 *pu4_total_coeff) +{ + dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_code, u4_index, u4_ldz; + const UWORD16 *pu2_code = (const UWORD16*)gau2_ih264d_code_gx; + const UWORD16 *pu2_offset_num_vlc = + (const UWORD16 *)gau2_ih264d_offset_num_vlc_tab; + UWORD32 u4_offset_num_vlc = pu2_offset_num_vlc[u4_n]; + + + UNUSED(pi2_coeff_block); + *pu4_total_coeff = 0; + FIND_ONE_IN_STREAM_32(u4_ldz, u4_bitstream_offset, pu4_bitstrm_buf); + NEXTBITS(u4_index, u4_bitstream_offset, pu4_bitstrm_buf, 3); + u4_index += (u4_ldz << 3); + u4_index += u4_offset_num_vlc; + + u4_index = MIN(u4_index, 303); + u4_code = pu2_code[u4_index]; + + FLUSHBITS(u4_bitstream_offset, (u4_code & 0x03)); + ps_bitstrm->u4_ofst = u4_bitstream_offset; + *pu4_total_coeff = (u4_code >> 4); + + if(*pu4_total_coeff) + { + UWORD32 u4_trailing_ones, u4_offset, u4_total_coeff_tone; + const UWORD8 *pu1_offset = + (UWORD8 *)gau1_ih264d_total_coeff_fn_ptr_offset; + WORD32 ret; + u4_trailing_ones = ((u4_code >> 2) & 0x03); + u4_offset = pu1_offset[*pu4_total_coeff - 1]; + u4_total_coeff_tone = (*pu4_total_coeff << 16) | u4_trailing_ones; + + ret = ps_dec->pf_cavlc_4x4res_block[u4_offset](u4_isdc, + u4_total_coeff_tone, + ps_bitstrm); + if(ret != 0) + return ERROR_CAVLC_NUM_COEFF_T; + } + + return OK; +} + +WORD32 ih264d_cavlc_parse4x4coeff_n8(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, /* is it a DC block */ + WORD32 u4_n, + dec_struct_t *ps_dec, + UWORD32 *pu4_total_coeff) +{ + + dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + UWORD32 u4_code; + UNUSED(u4_n); + UNUSED(pi2_coeff_block); + GETBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 6); + ps_bitstrm->u4_ofst = u4_bitstream_offset; + *pu4_total_coeff = 0; + + if(u4_code != 3) + { + UWORD8 *pu1_offset = (UWORD8 *)gau1_ih264d_total_coeff_fn_ptr_offset; + UWORD32 u4_trailing_ones, u4_offset, u4_total_coeff_tone; + + *pu4_total_coeff = (u4_code >> 2) + 1; + u4_trailing_ones = u4_code & 0x03; + u4_offset = pu1_offset[*pu4_total_coeff - 1]; + u4_total_coeff_tone = (*pu4_total_coeff << 16) | u4_trailing_ones; + + ps_dec->pf_cavlc_4x4res_block[u4_offset](u4_isdc, + u4_total_coeff_tone, + ps_bitstrm); + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_cavlc_parse_chroma_dc \endif + * + * \brief + * This function do cavlc parsing of coefficient tokens chromDc block + * and depending on whenther any coefficients to be parsed calls module + * ih264d_rest_of_residual_cav_chroma_dc_block. + * + * \return + * Returns total number of non-zero coefficients. + * + ************************************************************************** + */ + +void ih264d_cavlc_parse_chroma_dc(dec_mb_info_t *ps_cur_mb_info, + WORD16 *pi2_coeff_block, + dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_scale_u, + UWORD32 u4_scale_v, + WORD32 i4_mb_inter_inc) +{ + UWORD32 u4_total_coeff, u4_trailing_ones, u4_total_coeff_tone, u4_code; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 u4_bitstream_offset = ps_bitstrm->u4_ofst; + const UWORD8 *pu1_cav_chromdc = (const UWORD8*)gau1_ih264d_cav_chromdc_vld; + UNUSED(i4_mb_inter_inc); + /******************************************************************/ + /* Chroma DC Block for U component */ + /******************************************************************/ + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 8); + + u4_code = pu1_cav_chromdc[u4_code]; + + FLUSHBITS(u4_bitstream_offset, ((u4_code & 0x7) + 1)); + ps_bitstrm->u4_ofst = u4_bitstream_offset; + + u4_total_coeff = (u4_code >> 5); + + if(u4_total_coeff) + { + WORD32 i_z0, i_z1, i_z2, i_z3; + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + WORD16 ai2_dc_coef[4]; + UWORD8 pu1_inv_scan[4] = + { 0, 1, 2, 3 }; + WORD16 *pi2_coeff_data = + (WORD16 *)ps_dec->pv_parse_tu_coeff_data; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + + u4_trailing_ones = ((u4_code >> 3) & 0x3); + u4_total_coeff_tone = (u4_total_coeff << 16) | u4_trailing_ones; + ih264d_rest_of_residual_cav_chroma_dc_block(u4_total_coeff_tone, + ps_bitstrm); + + ai2_dc_coef[0] = 0; + ai2_dc_coef[1] = 0; + ai2_dc_coef[2] = 0; + ai2_dc_coef[3] = 0; + + ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, + ai2_dc_coef, + pu1_inv_scan); + /*-------------------------------------------------------------------*/ + /* Inverse 2x2 transform and scaling of chroma DC */ + /*-------------------------------------------------------------------*/ + i_z0 = (ai2_dc_coef[0] + ai2_dc_coef[2]); + i_z1 = (ai2_dc_coef[0] - ai2_dc_coef[2]); + i_z2 = (ai2_dc_coef[1] - ai2_dc_coef[3]); + i_z3 = (ai2_dc_coef[1] + ai2_dc_coef[3]); + + /*-----------------------------------------------------------*/ + /* Scaling and storing the values back */ + /*-----------------------------------------------------------*/ + *pi2_coeff_data++ = ((i_z0 + i_z3) * u4_scale_u) >> 5; + *pi2_coeff_data++ = ((i_z0 - i_z3) * u4_scale_u) >> 5; + *pi2_coeff_data++ = ((i_z1 + i_z2) * u4_scale_u) >> 5; + *pi2_coeff_data++ = ((i_z1 - i_z2) * u4_scale_u) >> 5; + + ps_dec->pv_parse_tu_coeff_data = (void *)pi2_coeff_data; + + SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag,1); + } + + /******************************************************************/ + /* Chroma DC Block for V component */ + /******************************************************************/ + pi2_coeff_block += 64; + u4_bitstream_offset = ps_bitstrm->u4_ofst; + + NEXTBITS(u4_code, u4_bitstream_offset, pu4_bitstrm_buf, 8); + + u4_code = pu1_cav_chromdc[u4_code]; + + FLUSHBITS(u4_bitstream_offset, ((u4_code & 0x7) + 1)); + ps_bitstrm->u4_ofst = u4_bitstream_offset; + + u4_total_coeff = (u4_code >> 5); + + if(u4_total_coeff) + { + WORD32 i_z0, i_z1, i_z2, i_z3; + tu_sblk4x4_coeff_data_t *ps_tu_4x4; + dec_struct_t *ps_dec = (dec_struct_t *)ps_bitstrm->pv_codec_handle; + WORD16 ai2_dc_coef[4]; + UWORD8 pu1_inv_scan[4] = + { 0, 1, 2, 3 }; + WORD16 *pi2_coeff_data = + (WORD16 *)ps_dec->pv_parse_tu_coeff_data; + + ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + + u4_trailing_ones = ((u4_code >> 3) & 0x3); + u4_total_coeff_tone = (u4_total_coeff << 16) | u4_trailing_ones; + ih264d_rest_of_residual_cav_chroma_dc_block(u4_total_coeff_tone, + ps_bitstrm); + + ai2_dc_coef[0] = 0; + ai2_dc_coef[1] = 0; + ai2_dc_coef[2] = 0; + ai2_dc_coef[3] = 0; + + ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, + ai2_dc_coef, + pu1_inv_scan); + + /*-------------------------------------------------------------------*/ + /* Inverse 2x2 transform and scaling of chroma DC */ + /*-------------------------------------------------------------------*/ + i_z0 = (ai2_dc_coef[0] + ai2_dc_coef[2]); + i_z1 = (ai2_dc_coef[0] - ai2_dc_coef[2]); + i_z2 = (ai2_dc_coef[1] - ai2_dc_coef[3]); + i_z3 = (ai2_dc_coef[1] + ai2_dc_coef[3]); + + /*-----------------------------------------------------------*/ + /* Scaling and storing the values back */ + /*-----------------------------------------------------------*/ + *pi2_coeff_data++ = ((i_z0 + i_z3) * u4_scale_v) >> 5; + *pi2_coeff_data++ = ((i_z0 - i_z3) * u4_scale_v) >> 5; + *pi2_coeff_data++ = ((i_z1 + i_z2) * u4_scale_v) >> 5; + *pi2_coeff_data++ = ((i_z1 - i_z2) * u4_scale_v) >> 5; + + ps_dec->pv_parse_tu_coeff_data = (void *)pi2_coeff_data; + + SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag,2); + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_pmb_ref_index_cavlc_range1 */ +/* */ +/* Description : This function does the Cavlc TEV range =1 parsing of */ +/* reference index for a P MB. Range is 1 when */ +/* num_ref_idx_active_minus1 is 0 */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_parse_pmb_ref_index_cavlc_range1(UWORD32 u4_num_part, /* Number of partitions in MB */ + dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */ + WORD8 *pi1_ref_idx, /* pointer to reference index array */ + UWORD32 u4_num_ref_idx_active_minus1 /* Not used for range 1 */ + ) +{ + UWORD32 u4_i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst; + UNUSED(u4_num_ref_idx_active_minus1); + for(u4_i = 0; u4_i < u4_num_part; u4_i++) + { + UWORD32 u4_ref_idx; + u4_ref_idx = ih264d_tev_range1(pu4_bitstream_off, pu4_bitstrm_buf); + + /* Storing Reference Idx Information */ + pi1_ref_idx[u4_i] = (WORD8)u4_ref_idx; + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_pmb_ref_index_cavlc */ +/* */ +/* Description : This function does the Cavlc TEV range > 1 parsing of */ +/* reference index for a P MB. */ +/* Range > 1 when num_ref_idx_active_minus1 > 0 */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_pmb_ref_index_cavlc(UWORD32 u4_num_part, /* Number of partitions in MB */ + dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */ + WORD8 *pi1_ref_idx, /* pointer to reference index array */ + UWORD32 u4_num_ref_idx_active_minus1 /* Number of active references - 1 */ + ) +{ + UWORD32 u4_i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst; + + for(u4_i = 0; u4_i < u4_num_part; u4_i++) + { + UWORD32 u4_ref_idx; +//Inlined ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstream_off; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + *pu4_bitstream_off = u4_bitstream_offset; + u4_ref_idx = ((1 << u4_ldz) + u4_word - 1); +//Inlined ih264d_uev + + if(u4_ref_idx > u4_num_ref_idx_active_minus1) + return ERROR_REF_IDX; + + /* Storing Reference Idx Information */ + pi1_ref_idx[u4_i] = (WORD8)u4_ref_idx; + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_bmb_ref_index_cavlc_range1 */ +/* */ +/* Description : This function does the Cavlc TEV range =1 parsing of */ +/* reference index for a B MB. Range is 1 when */ +/* num_ref_idx_active_minus1 is 0 */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_parse_bmb_ref_index_cavlc_range1(UWORD32 u4_num_part, /* Number of partitions in MB */ + dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */ + WORD8 *pi1_ref_idx, /* pointer to reference index array */ + UWORD32 u4_num_ref_idx_active_minus1 /* Not used for range 1 */ + ) +{ + UWORD32 u4_i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst; + UNUSED(u4_num_ref_idx_active_minus1); + for(u4_i = 0; u4_i < u4_num_part; u4_i++) + { + if(pi1_ref_idx[u4_i] > -1) + { + UWORD32 u4_ref_idx; + + u4_ref_idx = ih264d_tev_range1(pu4_bitstream_off, pu4_bitstrm_buf); + + /* Storing Reference Idx Information */ + pi1_ref_idx[u4_i] = (WORD8)u4_ref_idx; + } + } +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_bmb_ref_index_cavlc */ +/* */ +/* Description : This function does the Cavlc TEV range > 1 parsing of */ +/* reference index for a B MB. */ +/* Range > 1 when num_ref_idx_active_minus1 > 0 */ +/* */ +/* Inputs : <What inputs does the function take?> */ +/* Globals : <Does it use any global variables?> */ +/* Processing : <Describe how the function operates - include algorithm */ +/* description> */ +/* Outputs : <What does the function produce?> */ +/* Returns : <What does the function return?> */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 09 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_bmb_ref_index_cavlc(UWORD32 u4_num_part, /* Number of partitions in MB */ + dec_bit_stream_t *ps_bitstrm, /* Pointer to bitstream Structure. */ + WORD8 *pi1_ref_idx, /* pointer to reference index array */ + UWORD32 u4_num_ref_idx_active_minus1 /* Number of active references - 1 */ + ) +{ + UWORD32 u4_i; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstream_off = &ps_bitstrm->u4_ofst; + + for(u4_i = 0; u4_i < u4_num_part; u4_i++) + { + if(pi1_ref_idx[u4_i] > -1) + { + UWORD32 u4_ref_idx; +//inlining ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstream_off; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + *pu4_bitstream_off = u4_bitstream_offset; + u4_ref_idx = ((1 << u4_ldz) + u4_word - 1); +//inlining ih264d_uev + if(u4_ref_idx > u4_num_ref_idx_active_minus1) + return ERROR_REF_IDX; + + /* Storing Reference Idx Information */ + pi1_ref_idx[u4_i] = (WORD8)u4_ref_idx; + } + } + return OK; +} +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_parse_8x8block_both_available */ +/* */ +/* Description : This function does the residual parsing of 4 subblocks */ +/* in a 8x8 block when both top and left are available */ +/* */ +/* Inputs : pi2_coeff_block : pointer to residual block where */ +/* decoded and inverse scan coefficients are updated */ +/* */ +/* u4_sub_block_strd : indicates the number of sublocks */ +/* in a row. It is 4 for luma and 2 for chroma. */ +/* */ +/* u4_isdc : required to indicate 4x4 parse modules if the */ +/* current Mb is I_16x16/chroma DC coded. */ +/* */ +/* ps_dec : pointer to Decstruct (decoder context) */ +/* */ +/* pu1_top_nnz : top nnz pointer */ +/* */ +/* pu1_left_nnz : left nnz pointer */ +/* */ +/* Globals : No */ +/* Processing : Parsing for four subblocks in unrolled, top and left nnz */ +/* are updated on the fly. csbp is set in accordance to */ +/* decoded numcoeff for the subblock index in raster order */ +/* */ +/* Outputs : The updated residue buffer, nnzs and csbp current block */ +/* */ +/* Returns : Returns the coded sub block pattern csbp for the block */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 09 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_cavlc_parse_8x8block_both_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp) +{ + UWORD32 u4_num_coeff, u4_n, u4_subblock_coded; + UWORD32 u4_top0, u4_top1; + UWORD32 *pu4_dummy; + WORD32 (**pf_cavlc_parse4x4coeff)(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + struct _DecStruct *ps_dec, + UWORD32 *pu4_dummy) = + ps_dec->pf_cavlc_parse4x4coeff; + UWORD32 u4_idx = 0; + UWORD8 *puc_temp; + WORD32 ret; + + *pu4_csbp = 0; + /* need to change the inverse scan matrices here */ + puc_temp = ps_dec->pu1_inv_scan; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 0 */ + /*------------------------------------------------------*/ + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[0]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[0]; + } + } + u4_n = (pu1_top_nnz[0] + pu1_left_nnz[0] + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top0 = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 1 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[1]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[1]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (pu1_top_nnz[1] + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top1 = pu1_left_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 2 */ + /*------------------------------------------------------*/ + u4_idx += (u4_sub_block_strd - 1); + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[2]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[2]; + } + } + else + { + pi2_coeff_block += ((u4_sub_block_strd - 1) * NUM_COEFFS_IN_4x4BLK); + } + u4_n = (u4_top0 + pu1_left_nnz[1] + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 3 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[3]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[3]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (u4_top1 + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[1] = pu1_left_nnz[1] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + ps_dec->pu1_inv_scan = puc_temp; + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_parse_8x8block_left_available */ +/* */ +/* Description : This function does the residual parsing of 4 subblocks */ +/* in a 8x8 block when only left is available for block */ +/* */ +/* Inputs : pi2_coeff_block : pointer to residual block where */ +/* decoded and inverse scan coefficients are updated */ +/* */ +/* u4_sub_block_strd : indicates the number of sublocks */ +/* in a row. It is 4 for luma and 2 for chroma. */ +/* */ +/* u4_isdc : required to indicate 4x4 parse modules if the */ +/* current Mb is I_16x16/chroma DC coded. */ +/* */ +/* ps_dec : pointer to Decstruct (decoder context) */ +/* */ +/* pu1_top_nnz : top nnz pointer */ +/* */ +/* pu1_left_nnz : left nnz pointer */ +/* */ +/* Globals : No */ +/* Processing : Parsing for four subblocks in unrolled, top and left nnz */ +/* are updated on the fly. csbp is set in accordance to */ +/* decoded numcoeff for the subblock index in raster order */ +/* */ +/* Outputs : The updated residue buffer, nnzs and csbp current block */ +/* */ +/* Returns : Returns the coded sub block pattern csbp for the block */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 09 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_cavlc_parse_8x8block_left_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp) +{ + UWORD32 u4_num_coeff, u4_n, u4_subblock_coded; + UWORD32 u4_top0, u4_top1; + UWORD32 *pu4_dummy; + WORD32 (**pf_cavlc_parse4x4coeff)(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + struct _DecStruct *ps_dec, + UWORD32 *pu4_dummy) = + ps_dec->pf_cavlc_parse4x4coeff; + UWORD32 u4_idx = 0; + UWORD8 *puc_temp; + WORD32 ret; + + *pu4_csbp = 0; + puc_temp = ps_dec->pu1_inv_scan; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 0 */ + /*------------------------------------------------------*/ + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[0]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[0]; + } + } + u4_n = pu1_left_nnz[0]; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top0 = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 1 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[1]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[1]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = u4_num_coeff; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top1 = pu1_left_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 2 */ + /*------------------------------------------------------*/ + u4_idx += (u4_sub_block_strd - 1); + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[2]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[2]; + } + } + else + { + pi2_coeff_block += ((u4_sub_block_strd - 1) * NUM_COEFFS_IN_4x4BLK); + } + u4_n = (u4_top0 + pu1_left_nnz[1] + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 3 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[3]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[3]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (u4_top1 + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[1] = pu1_left_nnz[1] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + ps_dec->pu1_inv_scan = puc_temp; + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_parse_8x8block_top_available */ +/* */ +/* Description : This function does the residual parsing of 4 subblocks */ +/* in a 8x8 block when only top is available for block */ +/* */ +/* Inputs : pi2_coeff_block : pointer to residual block where */ +/* decoded and inverse scan coefficients are updated */ +/* */ +/* u4_sub_block_strd : indicates the number of sublocks */ +/* in a row. It is 4 for luma and 2 for chroma. */ +/* */ +/* u4_isdc : required to indicate 4x4 parse modules if the */ +/* current Mb is I_16x16/chroma DC coded. */ +/* */ +/* ps_dec : pointer to Decstruct (decoder context) */ +/* */ +/* pu1_top_nnz : top nnz pointer */ +/* */ +/* pu1_left_nnz : left nnz pointer */ +/* */ +/* Globals : No */ +/* Processing : Parsing for four subblocks in unrolled, top and left nnz */ +/* are updated on the fly. csbp is set in accordance to */ +/* decoded numcoeff for the subblock index in raster order */ +/* */ +/* Outputs : The updated residue buffer, nnzs and csbp current block */ +/* */ +/* Returns : Returns the coded sub block pattern csbp for the block */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 09 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_cavlc_parse_8x8block_top_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp) +{ + UWORD32 u4_num_coeff, u4_n, u4_subblock_coded; + UWORD32 u4_top0, u4_top1; + UWORD32 *pu4_dummy; + WORD32 (**pf_cavlc_parse4x4coeff)(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + struct _DecStruct *ps_dec, + UWORD32 *pu4_dummy) = + ps_dec->pf_cavlc_parse4x4coeff; + UWORD32 u4_idx = 0; + UWORD8 *puc_temp; + WORD32 ret; + + *pu4_csbp = 0; + puc_temp = ps_dec->pu1_inv_scan; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 0 */ + /*------------------------------------------------------*/ + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[0]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[0]; + } + } + u4_n = pu1_top_nnz[0]; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top0 = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 1 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[1]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[1]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (pu1_top_nnz[1] + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top1 = pu1_left_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 2 */ + /*------------------------------------------------------*/ + u4_idx += (u4_sub_block_strd - 1); + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[2]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[2]; + } + } + else + { + pi2_coeff_block += ((u4_sub_block_strd - 1) * NUM_COEFFS_IN_4x4BLK); + } + u4_n = u4_top0; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 3 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[3]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[3]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (u4_top1 + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[1] = pu1_left_nnz[1] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + ps_dec->pu1_inv_scan = puc_temp; + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_cavlc_parse_8x8block_none_available */ +/* */ +/* Description : This function does the residual parsing of 4 subblocks */ +/* in a 8x8 block when none of the neigbours are available */ +/* */ +/* Inputs : pi2_coeff_block : pointer to residual block where */ +/* decoded and inverse scan coefficients are updated */ +/* */ +/* u4_sub_block_strd : indicates the number of sublocks */ +/* in a row. It is 4 for luma and 2 for chroma. */ +/* */ +/* u4_isdc : required to indicate 4x4 parse modules if the */ +/* current Mb is I_16x16/chroma DC coded. */ +/* */ +/* ps_dec : pointer to Decstruct (decoder context) */ +/* */ +/* pu1_top_nnz : top nnz pointer */ +/* */ +/* pu1_left_nnz : left nnz pointer */ +/* */ +/* Globals : No */ +/* Processing : Parsing for four subblocks in unrolled, top and left nnz */ +/* are updated on the fly. csbp is set in accordance to */ +/* decoded numcoeff for the subblock index in raster order */ +/* */ +/* Outputs : The updated residue buffer, nnzs and csbp current block */ +/* */ +/* Returns : Returns the coded sub block pattern csbp for the block */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 09 10 2008 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_cavlc_parse_8x8block_none_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp) +{ + UWORD32 u4_num_coeff, u4_n, u4_subblock_coded; + UWORD32 u4_top0, u4_top1; + UWORD32 *pu4_dummy; + WORD32 (**pf_cavlc_parse4x4coeff)(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + struct _DecStruct *ps_dec, + UWORD32 *pu4_dummy) = + ps_dec->pf_cavlc_parse4x4coeff; + UWORD32 u4_idx = 0; + UWORD8 *puc_temp; + WORD32 ret; + + *pu4_csbp = 0; + puc_temp = ps_dec->pu1_inv_scan; + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 0 */ + /*------------------------------------------------------*/ + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[0]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[0]; + } + } + ret = pf_cavlc_parse4x4coeff[0](pi2_coeff_block, u4_isdc, 0, + ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top0 = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 1 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[1]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[1]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = u4_num_coeff; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + u4_top1 = pu1_left_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 2 */ + /*------------------------------------------------------*/ + u4_idx += (u4_sub_block_strd - 1); + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[2]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[2]; + } + } + else + { + pi2_coeff_block += ((u4_sub_block_strd - 1) * NUM_COEFFS_IN_4x4BLK); + } + u4_n = u4_top0; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[0] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + /*------------------------------------------------------*/ + /* Residual 4x4 decoding: SubBlock 3 */ + /*------------------------------------------------------*/ + u4_idx++; + if(u1_tran_form8x8) + { + if(!u1_mb_field_decodingflag) + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[3]; + } + else + { + ps_dec->pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[3]; + } + } + else + { + pi2_coeff_block += NUM_COEFFS_IN_4x4BLK; + } + u4_n = (u4_top1 + u4_num_coeff + 1) >> 1; + ret = pf_cavlc_parse4x4coeff[(u4_n > 7)](pi2_coeff_block, u4_isdc, + u4_n, ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + pu1_top_nnz[1] = pu1_left_nnz[1] = u4_num_coeff; + u4_subblock_coded = (u4_num_coeff != 0); + INSERT_BIT(*pu4_csbp, u4_idx, u4_subblock_coded); + + ps_dec->pu1_inv_scan = puc_temp; + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_residual4x4_cavlc \endif + * + * \brief + * This function parses CAVLC syntax of a Luma and Chroma AC Residuals. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_parse_residual4x4_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_offset) +{ + UWORD8 u1_cbp = ps_cur_mb_info->u1_cbp; + UWORD16 ui16_csbp = 0; + UWORD32 u4_nbr_avl; + WORD16 *pi2_residual_buf; + + UWORD8 u1_is_top_mb_avail; + UWORD8 u1_is_left_mb_avail; + + UWORD8 *pu1_top_nnz = ps_cur_mb_info->ps_curmb->pu1_nnz_y; + UWORD8 *pu1_left_nnz = ps_dec->pu1_left_nnz_y; + WORD16 *pi2_coeff_block = NULL; + UWORD32 *pu4_dummy; + WORD32 ret; + + WORD32 (**pf_cavlc_parse_8x8block)(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + struct _DecStruct *ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_dummy) = ps_dec->pf_cavlc_parse_8x8block; + + + { + UWORD8 uc_temp = ps_dec->u1_mb_ngbr_availablity; + u1_is_top_mb_avail = BOOLEAN(uc_temp & TOP_MB_AVAILABLE_MASK); + u1_is_left_mb_avail = BOOLEAN(uc_temp & LEFT_MB_AVAILABLE_MASK); + u4_nbr_avl = (u1_is_top_mb_avail << 1) | u1_is_left_mb_avail; + } + + ps_cur_mb_info->u1_qp_div6 = ps_dec->u1_qp_y_div6; + ps_cur_mb_info->u1_qp_rem6 = ps_dec->u1_qp_y_rem6; + ps_cur_mb_info->u1_qpc_div6 = ps_dec->u1_qp_u_div6; + ps_cur_mb_info->u1_qpc_rem6 = ps_dec->u1_qp_u_rem6; + ps_cur_mb_info->u1_qpcr_div6 = ps_dec->u1_qp_v_div6; + ps_cur_mb_info->u1_qpcr_rem6 = ps_dec->u1_qp_v_rem6; + + if(u1_cbp & 0xf) + { + pu1_top_nnz[0] = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[0]; + pu1_top_nnz[1] = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[1]; + pu1_top_nnz[2] = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[2]; + pu1_top_nnz[3] = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[3]; + + /*******************************************************************/ + /* Block 0 residual decoding, check cbp and proceed (subblock = 0) */ + /*******************************************************************/ + if(!(u1_cbp & 0x1)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + + } + else + { + UWORD32 u4_temp; + ret = pf_cavlc_parse_8x8block[u4_nbr_avl]( + pi2_coeff_block, 4, u1_offset, ps_dec, pu1_top_nnz, + pu1_left_nnz, ps_cur_mb_info->u1_tran_form8x8, + ps_cur_mb_info->u1_mb_field_decodingflag, &u4_temp); + if(ret != OK) + return ret; + ui16_csbp = u4_temp; + } + + /*******************************************************************/ + /* Block 1 residual decoding, check cbp and proceed (subblock = 2) */ + /*******************************************************************/ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pi2_coeff_block += 64; + } + else + { + pi2_coeff_block += (2 * NUM_COEFFS_IN_4x4BLK); + } + + if(!(u1_cbp & 0x2)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz) = 0; + } + else + { + UWORD32 u4_temp = (u4_nbr_avl | 0x1); + ret = pf_cavlc_parse_8x8block[u4_temp]( + pi2_coeff_block, 4, u1_offset, ps_dec, + (pu1_top_nnz + 2), pu1_left_nnz, + ps_cur_mb_info->u1_tran_form8x8, + ps_cur_mb_info->u1_mb_field_decodingflag, &u4_temp); + if(ret != OK) + return ret; + ui16_csbp |= (u4_temp << 2); + } + + /*******************************************************************/ + /* Block 2 residual decoding, check cbp and proceed (subblock = 8) */ + /*******************************************************************/ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pi2_coeff_block += 64; + } + else + { + pi2_coeff_block += (6 * NUM_COEFFS_IN_4x4BLK); + } + + if(!(u1_cbp & 0x4)) + { + *(UWORD16 *)(pu1_top_nnz) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + UWORD32 u4_temp = (u4_nbr_avl | 0x2); + ret = pf_cavlc_parse_8x8block[u4_temp]( + pi2_coeff_block, 4, u1_offset, ps_dec, pu1_top_nnz, + (pu1_left_nnz + 2), ps_cur_mb_info->u1_tran_form8x8, + ps_cur_mb_info->u1_mb_field_decodingflag, &u4_temp); + if(ret != OK) + return ret; + ui16_csbp |= (u4_temp << 8); + } + + /*******************************************************************/ + /* Block 3 residual decoding, check cbp and proceed (subblock = 10)*/ + /*******************************************************************/ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pi2_coeff_block += 64; + } + else + { + pi2_coeff_block += (2 * NUM_COEFFS_IN_4x4BLK); + } + + if(!(u1_cbp & 0x8)) + { + *(UWORD16 *)(pu1_top_nnz + 2) = 0; + *(UWORD16 *)(pu1_left_nnz + 2) = 0; + } + else + { + UWORD32 u4_temp; + ret = pf_cavlc_parse_8x8block[0x3]( + pi2_coeff_block, 4, u1_offset, ps_dec, + (pu1_top_nnz + 2), (pu1_left_nnz + 2), + ps_cur_mb_info->u1_tran_form8x8, + ps_cur_mb_info->u1_mb_field_decodingflag, &u4_temp); + if(ret != OK) + return ret; + ui16_csbp |= (u4_temp << 10); + } + } + else + { + *(UWORD32 *)(pu1_top_nnz) = 0; + *(UWORD32 *)(pu1_left_nnz) = 0; + } + + ps_cur_mb_info->u2_luma_csbp = ui16_csbp; + ps_cur_mb_info->ps_curmb->u2_luma_csbp = ui16_csbp; + + { + UWORD16 u2_chroma_csbp = 0; + ps_cur_mb_info->u2_chroma_csbp = 0; + pu1_top_nnz = ps_cur_mb_info->ps_curmb->pu1_nnz_uv; + pu1_left_nnz = ps_dec->pu1_left_nnz_uv; + + u1_cbp >>= 4; + /*--------------------------------------------------------------------*/ + /* if Chroma Component not present OR no ac values present */ + /* Set the values of N to zero */ + /*--------------------------------------------------------------------*/ + if(u1_cbp == CBPC_ALLZERO || u1_cbp == CBPC_ACZERO) + { + *(UWORD32 *)(pu1_top_nnz) = 0; + *(UWORD32 *)(pu1_left_nnz) = 0; + } + + if(u1_cbp == CBPC_ALLZERO) + { + return (0); + } + /*--------------------------------------------------------------------*/ + /* Decode Chroma DC values */ + /*--------------------------------------------------------------------*/ + { + WORD32 u4_scale_u; + WORD32 u4_scale_v; + WORD32 i4_mb_inter_inc; + u4_scale_u = ps_dec->pu2_quant_scale_u[0] << ps_dec->u1_qp_u_div6; + u4_scale_v = ps_dec->pu2_quant_scale_v[0] << ps_dec->u1_qp_v_div6; + i4_mb_inter_inc = (!((ps_cur_mb_info->ps_curmb->u1_mb_type == I_4x4_MB) + || (ps_cur_mb_info->ps_curmb->u1_mb_type == I_16x16_MB))) + * 3; + + if(ps_dec->s_high_profile.u1_scaling_present) + { + u4_scale_u *= + ps_dec->s_high_profile.i2_scalinglist4x4[i4_mb_inter_inc + + 1][0]; + u4_scale_v *= + ps_dec->s_high_profile.i2_scalinglist4x4[i4_mb_inter_inc + + 2][0]; + + } + else + { + u4_scale_u <<= 4; + u4_scale_v <<= 4; + } + + ih264d_cavlc_parse_chroma_dc(ps_cur_mb_info,pi2_coeff_block, ps_dec->ps_bitstrm, + u4_scale_u, u4_scale_v, + i4_mb_inter_inc); + } + + if(u1_cbp == CBPC_ACZERO) + return (0); + + pu1_top_nnz[0] = ps_cur_mb_info->ps_top_mb->pu1_nnz_uv[0]; + pu1_top_nnz[1] = ps_cur_mb_info->ps_top_mb->pu1_nnz_uv[1]; + pu1_top_nnz[2] = ps_cur_mb_info->ps_top_mb->pu1_nnz_uv[2]; + pu1_top_nnz[3] = ps_cur_mb_info->ps_top_mb->pu1_nnz_uv[3]; + /*--------------------------------------------------------------------*/ + /* Decode Chroma AC values */ + /*--------------------------------------------------------------------*/ + { + UWORD32 u4_temp; + /*****************************************************************/ + /* U Block residual decoding, check cbp and proceed (subblock=0)*/ + /*****************************************************************/ + ret = pf_cavlc_parse_8x8block[u4_nbr_avl]( + pi2_coeff_block, 2, 1, ps_dec, pu1_top_nnz, + pu1_left_nnz, 0, 0, &u4_temp); + if(ret != OK) + return ret; + u2_chroma_csbp = u4_temp; + + pi2_coeff_block += MB_CHROM_SIZE; + /*****************************************************************/ + /* V Block residual decoding, check cbp and proceed (subblock=1)*/ + /*****************************************************************/ + ret = pf_cavlc_parse_8x8block[u4_nbr_avl](pi2_coeff_block, 2, 1, + ps_dec, + (pu1_top_nnz + 2), + (pu1_left_nnz + 2), 0, + 0, &u4_temp); + if(ret != OK) + return ret; + u2_chroma_csbp |= (u4_temp << 4); + } + + ps_cur_mb_info->u2_chroma_csbp = u2_chroma_csbp; + } + return OK; +} diff --git a/decoder/ih264d_parse_cavlc.h b/decoder/ih264d_parse_cavlc.h new file mode 100755 index 0000000..06105a3 --- /dev/null +++ b/decoder/ih264d_parse_cavlc.h @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_PARSE_CAVLC_H_ +#define _IH264D_PARSE_CAVLC_H_ +/*! + ************************************************************************** + * \file ih264d_parse_cavlc.h + * + * \brief + * Declaration of UVLC and CAVLC functions + * + * \date + * 18/12/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" +#include "ih264d_cabac.h" + +enum cavlcTableNum +{ + tableTotalZeroOffset, + tableTotalZero, + tableRunBefore, + codeGx, + chromTab, + offsetNumVlcTab +}; + +WORD32 ih264d_uvlc(dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_range, + UWORD32 *pi_bitstrm_ofst, + UWORD8 u1_flag, + UWORD32 u4_bitstrm_ofst, + UWORD32 *pi_bitstrm_buf); + +UWORD32 ih264d_uev(UWORD32 *pu4_bitstrm_ofst, UWORD32 *pu4_bitstrm_buf); + +WORD32 ih264d_sev(UWORD32 *pu4_bitstrm_ofst, UWORD32 *pu4_bitstrm_buf); + +UWORD32 ih264d_tev_range1(UWORD32 *pu4_bitstrm_ofst, + UWORD32 *pu4_bitstrm_buf); + +UWORD8 RestOfResidualBlockCavlc(WORD16 *pi2_coeff_block, + UWORD32 u1_ofst_is_dc_max_coef_scale_fact, + UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm, + UWORD8 *pu1_invscan); + +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_1( UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm); + +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_2to10(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm); + +WORD32 ih264d_cavlc_4x4res_block_totalcoeff_11to16(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, + dec_bit_stream_t *ps_bitstrm); + +WORD32 ih264d_cavlc_parse4x4coeff_n0to7(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + dec_struct_t *ps_dec, + UWORD32 *pu4_total_coeff); + +WORD32 ih264d_cavlc_parse4x4coeff_n8(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, + WORD32 u4_n, + dec_struct_t *ps_dec, + UWORD32 *pu4_total_coeff); + +void ih264d_cavlc_parse_chroma_dc(dec_mb_info_t *ps_cur_mb_info, + WORD16 *pi2_coeff_block, + dec_bit_stream_t *ps_bitstrm, + UWORD32 u4_scale_u, + UWORD32 u4_scale_v, + WORD32 i4_mb_inter_inc); + +WORD32 ih264d_cavlc_parse_8x8block_none_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp); + +WORD32 ih264d_cavlc_parse_8x8block_left_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp); + +WORD32 ih264d_cavlc_parse_8x8block_top_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp); + +WORD32 ih264d_cavlc_parse_8x8block_both_available(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + dec_struct_t * ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp); + +WORD8 ResidualBlockChromaDC(WORD16 *pi2_level, dec_bit_stream_t *ps_bitstrm); + +void ih264d_parse_pmb_ref_index_cavlc_range1(UWORD32 u4_num_part, + dec_bit_stream_t *ps_bitstrm, + WORD8 *pi1_ref_idx, + UWORD32 u4_num_ref_idx_active_minus1); + +WORD32 ih264d_parse_pmb_ref_index_cavlc(UWORD32 u4_num_part, + dec_bit_stream_t *ps_bitstrm, + WORD8 *pi1_ref_idx, + UWORD32 u4_num_ref_idx_active_minus1); + +void ih264d_parse_bmb_ref_index_cavlc_range1(UWORD32 u4_num_part, + dec_bit_stream_t *ps_bitstrm, + WORD8 *pi1_ref_idx, + UWORD32 u4_num_ref_idx_active_minus1); + +WORD32 ih264d_parse_bmb_ref_index_cavlc(UWORD32 u4_num_part, + dec_bit_stream_t *ps_bitstrm, + WORD8 *pi1_ref_idx, + UWORD32 u4_num_ref_idx_active_minus1); + +#endif /* _IH264D_PARSE_CAVLC_H_ */ diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c new file mode 100755 index 0000000..9458d6b --- /dev/null +++ b/decoder/ih264d_parse_headers.c @@ -0,0 +1,1204 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_headers.c + * + * \brief + * Contains High level syntax[above slice] parsing routines + * + * \date + * 19/12/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_slice.h" +#include "ih264d_tables.h" +#include "ih264d_utils.h" +#include "ih264d_nal.h" +#include "ih264d_deblocking.h" + +#include "ih264d_mem_request.h" +#include "ih264d_debug.h" +#include "ih264d_error_handler.h" +#include "ih264d_mb_utils.h" +#include "ih264d_sei.h" +#include "ih264d_vui.h" +#include "ih264d_thread_parse_decode.h" +#include "ih264d_thread_compute_bs.h" +#include "ih264d_quant_scaling.h" +#include "ih264d_defs.h" +#include "ivd.h" + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_slice_partition */ +/* */ +/* Description : This function is intended to parse and decode slice part */ +/* itions. Currently it's not implemented. Decoder will */ +/* print a message, skips this NAL and continues */ +/* Inputs : ps_dec Decoder parameters */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : This functionality needs to be implemented */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_slice_partition(dec_struct_t * ps_dec, + dec_bit_stream_t * ps_bitstrm) +{ + H264_DEC_DEBUG_PRINT("\nSlice partition not supported"); + UNUSED(ps_dec); + UNUSED(ps_bitstrm); + return (0); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_sei */ +/* */ +/* Description : This function is intended to parse and decode SEI */ +/* Currently it's not implemented. Decoder will print a */ +/* message, skips this NAL and continues */ +/* Inputs : ps_dec Decoder parameters */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : This functionality needs to be implemented */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_sei(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) +{ + UNUSED(ps_dec); + UNUSED(ps_bitstrm); + return (0); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_filler_data */ +/* */ +/* Description : This function is intended to parse and decode filler */ +/* data NAL. Currently it's not implemented. Decoder will */ +/* print a message, skips this NAL and continues */ +/* Inputs : ps_dec Decoder parameters */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : This functionality needs to be implemented */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_filler_data(dec_struct_t * ps_dec, + dec_bit_stream_t * ps_bitstrm) +{ + UNUSED(ps_dec); + UNUSED(ps_bitstrm); + return (0); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_end_of_stream */ +/* */ +/* Description : This function is intended to parse and decode end of */ +/* sequence. Currently it's not implemented. Decoder will */ +/* print a message, skips this NAL and continues */ +/* Inputs : ps_dec Decoder parameters */ +/* Globals : None */ +/* Processing : This functionality needs to be implemented */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +void ih264d_parse_end_of_stream(dec_struct_t * ps_dec) +{ + UNUSED(ps_dec); + return; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_pps \endif + * + * \brief + * Decodes Picture Parameter set + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_pps(dec_struct_t * ps_dec, dec_bit_stream_t * ps_bitstrm) +{ + UWORD8 uc_temp; + dec_seq_params_t * ps_sps = NULL; + dec_pic_params_t * ps_pps = NULL; + UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; + + /* Variables used for error resilience checks */ + UWORD32 u4_temp; + WORD32 i_temp; + + /* For High profile related syntax elements */ + UWORD8 u1_more_data_flag; + WORD32 i4_i; + + /*--------------------------------------------------------------------*/ + /* Decode pic_parameter_set_id and find corresponding pic params */ + /*--------------------------------------------------------------------*/ + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_ERR_PIC_SET_ID) + return ERROR_INV_SPS_PPS_T; + ps_pps = ps_dec->pv_scratch_sps_pps; + *ps_pps = ps_dec->ps_pps[u4_temp]; + ps_pps->u1_pic_parameter_set_id = (WORD8)u4_temp; + COPYTHECONTEXT("PPS: pic_parameter_set_id",ps_pps->u1_pic_parameter_set_id); + + /************************************************/ + /* initilization of High profile syntax element */ + /************************************************/ + ps_pps->i4_transform_8x8_mode_flag = 0; + ps_pps->i4_pic_scaling_matrix_present_flag = 0; + + /*--------------------------------------------------------------------*/ + /* Decode seq_parameter_set_id and map it to a seq_parameter_set */ + /*--------------------------------------------------------------------*/ + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_ERR_SEQ_SET_ID) + return ERROR_INV_SPS_PPS_T; + COPYTHECONTEXT("PPS: seq_parameter_set_id",u4_temp); + ps_sps = &ps_dec->ps_sps[u4_temp]; + ps_pps->ps_sps = ps_sps; + + /*--------------------------------------------------------------------*/ + /* Decode entropy_coding_mode */ + /*--------------------------------------------------------------------*/ + ps_pps->u1_entropy_coding_mode = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("PPS: entropy_coding_mode_flag",ps_pps->u1_entropy_coding_mode); + + ps_pps->u1_pic_order_present_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("PPS: pic_order_present_flag",ps_pps->u1_pic_order_present_flag); + + /*--------------------------------------------------------------------*/ + /* Decode num_slice_groups_minus1 */ + /*--------------------------------------------------------------------*/ + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; + if(u4_temp != 1) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_FEATURE_UNAVAIL; + return i4_error_code; + } + ps_pps->u1_num_slice_groups = u4_temp; + COPYTHECONTEXT("PPS: num_slice_groups_minus1",ps_pps->u1_num_slice_groups -1); + + /*--------------------------------------------------------------------*/ + /* Other parameter set values */ + /*--------------------------------------------------------------------*/ + u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > H264_MAX_REF_IDX) + return ERROR_REF_IDX; + ps_pps->u1_num_ref_idx_lx_active[0] = u4_temp; + COPYTHECONTEXT("PPS: num_ref_idx_l0_active_minus1", + ps_pps->u1_num_ref_idx_lx_active[0] - 1); + + u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > H264_MAX_REF_IDX) + return ERROR_REF_IDX; + ps_pps->u1_num_ref_idx_lx_active[1] = u4_temp; + COPYTHECONTEXT("PPS: num_ref_idx_l1_active_minus1", + ps_pps->u1_num_ref_idx_lx_active[1] - 1); + + ps_pps->u1_wted_pred_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("PPS: weighted prediction u4_flag",ps_pps->u1_wted_pred_flag); + uc_temp = ih264d_get_bits_h264(ps_bitstrm, 2); + COPYTHECONTEXT("PPS: weighted_bipred_idc",uc_temp); + ps_pps->u1_wted_bipred_idc = uc_temp; + + if(ps_pps->u1_wted_bipred_idc > MAX_WEIGHT_BIPRED_IDC) + return ERROR_INV_SPS_PPS_T; + + i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if((i_temp < 0) || (i_temp > 51)) + return ERROR_INV_RANGE_QP_T; + + ps_pps->u1_pic_init_qp = i_temp; + COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26); + + i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if((i_temp < 0) || (i_temp > 51)) + return ERROR_INV_RANGE_QP_T; + + ps_pps->u1_pic_init_qs = i_temp; + COPYTHECONTEXT("PPS: pic_init_qs_minus26",ps_pps->u1_pic_init_qs - 26); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i_temp < -12) || (i_temp > 12)) + return ERROR_INV_RANGE_QP_T; + ps_pps->i1_chroma_qp_index_offset = i_temp; + COPYTHECONTEXT("PPS: chroma_qp_index_offset",ps_pps->i1_chroma_qp_index_offset); + + /***************************************************************************/ + /* initialize second_chroma_qp_index_offset to i1_chroma_qp_index_offset if */ + /* second_chroma_qp_index_offset is not present in bit-ps_bitstrm */ + /***************************************************************************/ + ps_pps->i1_second_chroma_qp_index_offset = + ps_pps->i1_chroma_qp_index_offset; + + ps_pps->u1_deblocking_filter_parameters_present_flag = ih264d_get_bit_h264( + ps_bitstrm); + COPYTHECONTEXT("PPS: deblocking_filter_control_present_flag", + ps_pps->u1_deblocking_filter_parameters_present_flag); + ps_pps->u1_constrained_intra_pred_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("PPS: constrained_intra_pred_flag", + ps_pps->u1_constrained_intra_pred_flag); + ps_pps->u1_redundant_pic_cnt_present_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("PPS: redundant_pic_cnt_present_flag", + ps_pps->u1_redundant_pic_cnt_present_flag); + + /* High profile related syntax elements */ + u1_more_data_flag = MORE_RBSP_DATA(ps_bitstrm); + if(u1_more_data_flag && (ps_pps->ps_sps->u1_profile_idc == HIGH_PROFILE_IDC)) + { + /* read transform_8x8_mode_flag */ + ps_pps->i4_transform_8x8_mode_flag = (WORD32)ih264d_get_bit_h264( + ps_bitstrm); + + /* read pic_scaling_matrix_present_flag */ + ps_pps->i4_pic_scaling_matrix_present_flag = + (WORD32)ih264d_get_bit_h264(ps_bitstrm); + + if(ps_pps->i4_pic_scaling_matrix_present_flag) + { + /* read the scaling matrices */ + for(i4_i = 0; + i4_i + < (6 + + (ps_pps->i4_transform_8x8_mode_flag + << 1)); + i4_i++) + { + ps_pps->u1_pic_scaling_list_present_flag[i4_i] = + ih264d_get_bit_h264(ps_bitstrm); + + if(ps_pps->u1_pic_scaling_list_present_flag[i4_i]) + { + if(i4_i < 6) + { + ih264d_scaling_list( + ps_pps->i2_pic_scalinglist4x4[i4_i], + 16, + &ps_pps->u1_pic_use_default_scaling_matrix_flag[i4_i], + ps_bitstrm); + } + else + { + ih264d_scaling_list( + ps_pps->i2_pic_scalinglist8x8[i4_i - 6], + 64, + &ps_pps->u1_pic_use_default_scaling_matrix_flag[i4_i], + ps_bitstrm); + } + } + } + } + + /* read second_chroma_qp_index_offset syntax element */ + ps_pps->i1_second_chroma_qp_index_offset = ih264d_sev( + pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if((ps_pps->i1_second_chroma_qp_index_offset + 12) > 24) + return ERROR_INV_RANGE_QP_T; + } + + ps_pps->u1_is_valid = TRUE; + ps_dec->ps_pps[ps_pps->u1_pic_parameter_set_id] = *ps_pps; + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_sps \endif + * + * \brief + * Decodes Sequence parameter set from the bitstream + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +UWORD32 ih264d_correct_level_idc(UWORD32 u4_level_idc, UWORD32 u4_total_mbs) +{ + UWORD32 u4_max_mbs_allowed; + + switch(u4_level_idc) + { + case H264_LEVEL_1_0: + u4_max_mbs_allowed = MAX_MBS_LEVEL_10; + break; + case H264_LEVEL_1_1: + u4_max_mbs_allowed = MAX_MBS_LEVEL_11; + break; + case H264_LEVEL_1_2: + u4_max_mbs_allowed = MAX_MBS_LEVEL_12; + break; + case H264_LEVEL_1_3: + u4_max_mbs_allowed = MAX_MBS_LEVEL_13; + break; + case H264_LEVEL_2_0: + u4_max_mbs_allowed = MAX_MBS_LEVEL_20; + break; + case H264_LEVEL_2_1: + u4_max_mbs_allowed = MAX_MBS_LEVEL_21; + break; + case H264_LEVEL_2_2: + u4_max_mbs_allowed = MAX_MBS_LEVEL_22; + break; + case H264_LEVEL_3_0: + u4_max_mbs_allowed = MAX_MBS_LEVEL_30; + break; + case H264_LEVEL_3_1: + u4_max_mbs_allowed = MAX_MBS_LEVEL_31; + break; + case H264_LEVEL_3_2: + u4_max_mbs_allowed = MAX_MBS_LEVEL_32; + break; + case H264_LEVEL_4_0: + u4_max_mbs_allowed = MAX_MBS_LEVEL_40; + break; + case H264_LEVEL_4_1: + u4_max_mbs_allowed = MAX_MBS_LEVEL_41; + break; + case H264_LEVEL_4_2: + u4_max_mbs_allowed = MAX_MBS_LEVEL_42; + break; + case H264_LEVEL_5_0: + u4_max_mbs_allowed = MAX_MBS_LEVEL_50; + break; + case H264_LEVEL_5_1: + default: + u4_max_mbs_allowed = MAX_MBS_LEVEL_51; + break; + + } + + /*correct of the level is incorrect*/ + if(u4_total_mbs > u4_max_mbs_allowed) + { + if(u4_total_mbs > MAX_MBS_LEVEL_50) + u4_level_idc = H264_LEVEL_5_1; + else if(u4_total_mbs > MAX_MBS_LEVEL_42) + u4_level_idc = H264_LEVEL_5_0; + else if(u4_total_mbs > MAX_MBS_LEVEL_41) + u4_level_idc = H264_LEVEL_4_2; + else if(u4_total_mbs > MAX_MBS_LEVEL_40) + u4_level_idc = H264_LEVEL_4_1; + else if(u4_total_mbs > MAX_MBS_LEVEL_32) + u4_level_idc = H264_LEVEL_4_0; + else if(u4_total_mbs > MAX_MBS_LEVEL_31) + u4_level_idc = H264_LEVEL_3_2; + else if(u4_total_mbs > MAX_MBS_LEVEL_30) + u4_level_idc = H264_LEVEL_3_1; + else if(u4_total_mbs > MAX_MBS_LEVEL_21) + u4_level_idc = H264_LEVEL_3_0; + else if(u4_total_mbs > MAX_MBS_LEVEL_20) + u4_level_idc = H264_LEVEL_2_1; + else if(u4_total_mbs > MAX_MBS_LEVEL_10) + u4_level_idc = H264_LEVEL_2_0; + } + + return (u4_level_idc); + +} +WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) +{ + UWORD8 i; + dec_seq_params_t *ps_seq = NULL; + UWORD8 u1_profile_idc, u1_level_idc, u1_seq_parameter_set_id; + UWORD16 i2_max_frm_num; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_flag; + + UWORD32 u4_temp; + WORD32 pic_height_in_map_units_minus1 = 0; + UWORD32 u2_pic_wd = 0; + UWORD32 u2_pic_ht = 0; + UWORD32 u2_frm_wd_y = 0; + UWORD32 u2_frm_ht_y = 0; + UWORD32 u2_frm_wd_uv = 0; + UWORD32 u2_frm_ht_uv = 0; + UWORD32 u2_crop_offset_y = 0; + UWORD32 u2_crop_offset_uv = 0; + WORD32 ret; + + /* High profile related syntax element */ + WORD32 i4_i; + /* G050 */ + UWORD8 u1_frame_cropping_flag, u1_frame_cropping_rect_left_ofst, + u1_frame_cropping_rect_right_ofst, + u1_frame_cropping_rect_top_ofst, + u1_frame_cropping_rect_bottom_ofst; + /* G050 */ + /*--------------------------------------------------------------------*/ + /* Decode seq_parameter_set_id and profile and level values */ + /*--------------------------------------------------------------------*/ + SWITCHONTRACE; + u1_profile_idc = ih264d_get_bits_h264(ps_bitstrm, 8); + COPYTHECONTEXT("SPS: profile_idc",u1_profile_idc); + + /* G050 */ + uc_constraint_set0_flag = ih264d_get_bit_h264(ps_bitstrm); + uc_constraint_set1_flag = ih264d_get_bit_h264(ps_bitstrm); + ih264d_get_bit_h264(ps_bitstrm); + + /*****************************************************/ + /* Read 5 bits for uc_constraint_set3_flag (1 bit) */ + /* and reserved_zero_4bits (4 bits) - Sushant */ + /*****************************************************/ + ih264d_get_bits_h264(ps_bitstrm, 5); + /* G050 */ + + /* Check whether particular profile is suported or not */ + /* Check whether particular profile is suported or not */ + if((u1_profile_idc != MAIN_PROFILE_IDC) && + + (u1_profile_idc != BASE_PROFILE_IDC) && + + (u1_profile_idc != HIGH_PROFILE_IDC) + + ) + { + + if((uc_constraint_set1_flag != 1) && (uc_constraint_set0_flag != 1)) + { + if(NULL != ps_dec) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_FEATURE_UNAVAIL; + return i4_error_code; + } + else + { + return (ERROR_FEATURE_UNAVAIL); + } + } + } + + u1_level_idc = ih264d_get_bits_h264(ps_bitstrm, 8); + + /* + if(ps_dec->u4_level_at_init < u1_level_idc) + { + UWORD32 i4_error_code; + H264_DEC_DEBUG_PRINT("\nstream has the level more than the one which is set during init\n"); + i4_error_code = ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT ; + return i4_error_code; + * Here instead of flagging the error, we could have ignored this error + * and went ahead for further decoding, but we are not doing + * so because, at least one header should be healthy to do the + * decoding, and moreover, it may help to avoid the crashes in the erroneous + * streams. + * + + } + */ + COPYTHECONTEXT("SPS: u4_level_idc",u1_level_idc); + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_ERR_SEQ_SET_ID) + return ERROR_INV_SPS_PPS_T; + u1_seq_parameter_set_id = u4_temp; + COPYTHECONTEXT("SPS: seq_parameter_set_id", + u1_seq_parameter_set_id); + + /*--------------------------------------------------------------------*/ + /* Find an seq param entry in seqparam array of decStruct */ + /*--------------------------------------------------------------------*/ + + ps_seq = ps_dec->pv_scratch_sps_pps; + *ps_seq = ps_dec->ps_sps[u1_seq_parameter_set_id]; + ps_seq->u1_profile_idc = u1_profile_idc; + ps_seq->u1_level_idc = u1_level_idc; + ps_seq->u1_seq_parameter_set_id = u1_seq_parameter_set_id; + + /*******************************************************************/ + /* Initializations for high profile - Sushant */ + /*******************************************************************/ + ps_seq->i4_chroma_format_idc = 1; + ps_seq->i4_bit_depth_luma_minus8 = 0; + ps_seq->i4_bit_depth_chroma_minus8 = 0; + ps_seq->i4_qpprime_y_zero_transform_bypass_flag = 0; + ps_seq->i4_seq_scaling_matrix_present_flag = 0; + if(u1_profile_idc == HIGH_PROFILE_IDC) + { + + /* reading chroma_format_idc */ + ps_seq->i4_chroma_format_idc = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + + /* Monochrome is not supported */ + if(ps_seq->i4_chroma_format_idc != 1) + { + return ERROR_INV_SPS_PPS_T; + } + + /* reading bit_depth_luma_minus8 */ + ps_seq->i4_bit_depth_luma_minus8 = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + + if(ps_seq->i4_bit_depth_luma_minus8 != 0) + { + return ERROR_INV_SPS_PPS_T; + } + + /* reading bit_depth_chroma_minus8 */ + ps_seq->i4_bit_depth_chroma_minus8 = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + + if(ps_seq->i4_bit_depth_chroma_minus8 != 0) + { + return ERROR_INV_SPS_PPS_T; + } + + /* reading qpprime_y_zero_transform_bypass_flag */ + ps_seq->i4_qpprime_y_zero_transform_bypass_flag = + (WORD32)ih264d_get_bit_h264(ps_bitstrm); + + if(ps_seq->i4_qpprime_y_zero_transform_bypass_flag != 0) + { + return ERROR_INV_SPS_PPS_T; + } + + /* reading seq_scaling_matrix_present_flag */ + ps_seq->i4_seq_scaling_matrix_present_flag = + (WORD32)ih264d_get_bit_h264(ps_bitstrm); + + if(ps_seq->i4_seq_scaling_matrix_present_flag) + { + for(i4_i = 0; i4_i < 8; i4_i++) + { + ps_seq->u1_seq_scaling_list_present_flag[i4_i] = + ih264d_get_bit_h264(ps_bitstrm); + + /* initialize u1_use_default_scaling_matrix_flag[i4_i] to zero */ + /* before calling scaling list */ + ps_seq->u1_use_default_scaling_matrix_flag[i4_i] = 0; + + if(ps_seq->u1_seq_scaling_list_present_flag[i4_i]) + { + if(i4_i < 6) + { + ih264d_scaling_list( + ps_seq->i2_scalinglist4x4[i4_i], + 16, + &ps_seq->u1_use_default_scaling_matrix_flag[i4_i], + ps_bitstrm); + } + else + { + ih264d_scaling_list( + ps_seq->i2_scalinglist8x8[i4_i - 6], + 64, + &ps_seq->u1_use_default_scaling_matrix_flag[i4_i], + ps_bitstrm); + } + } + } + } + } + /*--------------------------------------------------------------------*/ + /* Decode MaxFrameNum */ + /*--------------------------------------------------------------------*/ + u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > MAX_BITS_IN_FRAME_NUM) + { + return ERROR_INV_SPS_PPS_T; + } + ps_seq->u1_bits_in_frm_num = u4_temp; + COPYTHECONTEXT("SPS: log2_max_frame_num_minus4", + (ps_seq->u1_bits_in_frm_num - 4)); + + i2_max_frm_num = (1 << (ps_seq->u1_bits_in_frm_num)); + ps_seq->u2_u4_max_pic_num_minus1 = i2_max_frm_num - 1; + /*--------------------------------------------------------------------*/ + /* Decode picture order count and related values */ + /*--------------------------------------------------------------------*/ + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if(u4_temp > MAX_PIC_ORDER_CNT_TYPE) + { + return ERROR_INV_POC_TYPE_T; + } + ps_seq->u1_pic_order_cnt_type = u4_temp; + COPYTHECONTEXT("SPS: pic_order_cnt_type",ps_seq->u1_pic_order_cnt_type); + + ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1; + if(ps_seq->u1_pic_order_cnt_type == 0) + { + u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > MAX_BITS_IN_POC_LSB) + { + return ERROR_INV_SPS_PPS_T; + } + ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = u4_temp; + ps_seq->i4_max_pic_order_cntLsb = (1 << u4_temp); + COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u4_temp - 4)); + } + else if(ps_seq->u1_pic_order_cnt_type == 1) + { + ps_seq->u1_delta_pic_order_always_zero_flag = ih264d_get_bit_h264( + ps_bitstrm); + COPYTHECONTEXT("SPS: delta_pic_order_always_zero_flag", + ps_seq->u1_delta_pic_order_always_zero_flag); + + ps_seq->i4_ofst_for_non_ref_pic = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: offset_for_non_ref_pic", + ps_seq->i4_ofst_for_non_ref_pic); + + ps_seq->i4_ofst_for_top_to_bottom_field = ih264d_sev( + pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: offset_for_top_to_bottom_field", + ps_seq->i4_ofst_for_top_to_bottom_field); + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > 255) + return ERROR_INV_SPS_PPS_T; + ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = u4_temp; + COPYTHECONTEXT("SPS: num_ref_frames_in_pic_order_cnt_cycle", + ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle); + + for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; i++) + { + ps_seq->i4_ofst_for_ref_frame[i] = ih264d_sev( + pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: offset_for_ref_frame", + ps_seq->i4_ofst_for_ref_frame[i]); + } + } + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if((u4_temp > H264_MAX_REF_PICS)) + { + return ERROR_NUM_REF; + } + ps_seq->u1_num_ref_frames = u4_temp; + COPYTHECONTEXT("SPS: num_ref_frames",ps_seq->u1_num_ref_frames); + + ps_seq->u1_gaps_in_frame_num_value_allowed_flag = ih264d_get_bit_h264( + ps_bitstrm); + COPYTHECONTEXT("SPS: gaps_in_frame_num_value_allowed_flag", + ps_seq->u1_gaps_in_frame_num_value_allowed_flag); + + /*--------------------------------------------------------------------*/ + /* Decode FrameWidth and FrameHeight and related values */ + /*--------------------------------------------------------------------*/ + ps_seq->u2_frm_wd_in_mbs = 1 + + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1", + ps_seq->u2_frm_wd_in_mbs - 1); + u2_pic_wd = (ps_seq->u2_frm_wd_in_mbs << 4); + + pic_height_in_map_units_minus1 = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_seq->u2_frm_ht_in_mbs = 1 + pic_height_in_map_units_minus1; + + u2_pic_ht = (ps_seq->u2_frm_ht_in_mbs << 4); + + /*--------------------------------------------------------------------*/ + /* Get the value of MaxMbAddress and Number of bits needed for it */ + /*--------------------------------------------------------------------*/ + ps_seq->u2_max_mb_addr = (ps_seq->u2_frm_wd_in_mbs + * ps_seq->u2_frm_ht_in_mbs) - 1; + + ps_seq->u2_total_num_of_mbs = ps_seq->u2_max_mb_addr + 1; + + ps_seq->u1_level_idc = ih264d_correct_level_idc( + u1_level_idc, ps_seq->u2_total_num_of_mbs); + + u1_frm = ih264d_get_bit_h264(ps_bitstrm); + ps_seq->u1_frame_mbs_only_flag = u1_frm; + + COPYTHECONTEXT("SPS: frame_mbs_only_flag", u1_frm); + + if(!u1_frm) + { + u2_pic_ht <<= 1; + ps_seq->u1_mb_aff_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SPS: mb_adaptive_frame_field_flag", + ps_seq->u1_mb_aff_flag); + + } + else + ps_seq->u1_mb_aff_flag = 0; + + { + WORD32 frame_height_in_mbs = (2 - ps_seq->u1_frame_mbs_only_flag) + * (pic_height_in_map_units_minus1 + 1); + UWORD32 wdth = (ps_seq->u2_frm_wd_in_mbs) << 4; + UWORD32 hght = (frame_height_in_mbs) << 4; + + if((u2_pic_wd < H264_MIN_FRAME_WIDTH) + || (u2_pic_wd > ps_dec->u4_width_at_init)) + { + ivd_video_decode_op_t *ps_out; + /*set width and height in decode output structure*/ + ps_out = (ivd_video_decode_op_t *)ps_dec->pv_dec_out; + ps_out->u4_pic_wd = u2_pic_wd; + ps_out->u4_pic_ht = u2_pic_ht; + + return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED; + } + + if((u2_pic_ht < H264_MIN_FRAME_HEIGHT) + || (((0 != ps_seq->u1_frame_mbs_only_flag) + && (u2_pic_ht * u2_pic_wd + > ps_dec->u4_height_at_init + * ps_dec->u4_width_at_init)) + || ((0 == ps_seq->u1_frame_mbs_only_flag) + && (ALIGN32(u2_pic_ht) + * u2_pic_wd + > ALIGN32(ps_dec->u4_height_at_init) + * ps_dec->u4_width_at_init)))) + { + ivd_video_decode_op_t *ps_out; + /*set width and height in decode output structure*/ + ps_out = (ivd_video_decode_op_t *)ps_dec->pv_dec_out; + ps_out->u4_pic_wd = u2_pic_wd; + ps_out->u4_pic_ht = u2_pic_ht; + + return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED; + } + + + + + } + + ps_seq->u1_direct_8x8_inference_flag = ih264d_get_bit_h264(ps_bitstrm); + + COPYTHECONTEXT("SPS: direct_8x8_inference_flag", + ps_seq->u1_direct_8x8_inference_flag); + + /* G050 */ + u1_frame_cropping_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SPS: frame_cropping_flag",u1_frame_cropping_flag); + + if(u1_frame_cropping_flag) + { + u1_frame_cropping_rect_left_ofst = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: frame_cropping_rect_left_offset", + u1_frame_cropping_rect_left_ofst); + u1_frame_cropping_rect_right_ofst = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: frame_cropping_rect_right_offset", + u1_frame_cropping_rect_right_ofst); + u1_frame_cropping_rect_top_ofst = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: frame_cropping_rect_top_offset", + u1_frame_cropping_rect_top_ofst); + u1_frame_cropping_rect_bottom_ofst = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SPS: frame_cropping_rect_bottom_offset", + u1_frame_cropping_rect_bottom_ofst); + } + /* G050 */ + + ps_seq->u1_vui_parameters_present_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SPS: vui_parameters_present_flag", + ps_seq->u1_vui_parameters_present_flag); + + u2_frm_wd_y = u2_pic_wd + (UWORD8)(PAD_LEN_Y_H << 1); + if(1 == ps_dec->u4_share_disp_buf) + { + if(ps_dec->u4_app_disp_width > u2_frm_wd_y) + u2_frm_wd_y = ps_dec->u4_app_disp_width; + } + + u2_frm_ht_y = u2_pic_ht + (UWORD8)(PAD_LEN_Y_V << 2); + u2_frm_wd_uv = u2_pic_wd + (UWORD8)(PAD_LEN_UV_H << 2); + u2_frm_wd_uv = MAX(u2_frm_wd_uv, u2_frm_wd_y); + + u2_frm_ht_uv = (u2_pic_ht >> 1) + (UWORD8)(PAD_LEN_UV_V << 2); + u2_frm_ht_uv = MAX(u2_frm_ht_uv, (u2_frm_ht_y >> 1)); + + + /* Calculate display picture width, height and start u4_ofst from YUV420 */ + /* pictute buffers as per cropping information parsed above */ + { + UWORD16 u2_rgt_ofst = 0; + UWORD16 u2_lft_ofst = 0; + UWORD16 u2_top_ofst = 0; + UWORD16 u2_btm_ofst = 0; + UWORD8 u1_frm_mbs_flag; + UWORD8 u1_vert_mult_factor; + WORD32 i4_cropped_ht, i4_cropped_wd; + + if(u1_frame_cropping_flag) + { + /* Calculate right and left u4_ofst for cropped picture */ + u2_rgt_ofst = u1_frame_cropping_rect_right_ofst << 1; + u2_lft_ofst = u1_frame_cropping_rect_left_ofst << 1; + + /* Know frame MBs only u4_flag */ + u1_frm_mbs_flag = (1 == ps_seq->u1_frame_mbs_only_flag); + + /* Simplify the vertical u4_ofst calculation from field/frame */ + u1_vert_mult_factor = (2 - u1_frm_mbs_flag); + + /* Calculate bottom and top u4_ofst for cropped picture */ + u2_btm_ofst = (u1_frame_cropping_rect_bottom_ofst + << u1_vert_mult_factor); + u2_top_ofst = (u1_frame_cropping_rect_top_ofst + << u1_vert_mult_factor); + } + + /* Calculate u4_ofst from start of YUV 420 picture buffer to start of*/ + /* cropped picture buffer */ + u2_crop_offset_y = (u2_frm_wd_y * u2_top_ofst) + (u2_lft_ofst); + u2_crop_offset_uv = (u2_frm_wd_uv * (u2_top_ofst >> 1)) + + (u2_lft_ofst >> 1) * YUV420SP_FACTOR; + /* Calculate the display picture width and height based on crop */ + /* information */ + i4_cropped_ht = u2_pic_ht - (u2_btm_ofst + u2_top_ofst); + i4_cropped_wd = u2_pic_wd - (u2_rgt_ofst + u2_lft_ofst); + + if((i4_cropped_ht < MB_SIZE) || (i4_cropped_wd < MB_SIZE)) + { + return ERROR_INV_SPS_PPS_T; + } + + if((3 == ps_dec->i4_header_decoded) && (ps_dec->u2_pic_wd != u2_pic_wd)) + { + ps_dec->u1_res_changed = 1; + return IVD_RES_CHANGED; + } + if((3 == ps_dec->i4_header_decoded) && (ps_dec->u2_pic_ht != u2_pic_ht)) + { + ps_dec->u1_res_changed = 1; + return IVD_RES_CHANGED; + } + + ps_dec->u2_disp_height = i4_cropped_ht; + + ps_dec->u2_disp_width = i4_cropped_wd; + + } + + ps_seq->u1_is_valid = TRUE; + + if(1 == ps_seq->u1_vui_parameters_present_flag) + { + ret = ih264d_parse_vui_parametres(&ps_seq->s_vui, ps_bitstrm); + if(ret != OK) + return ret; + } + + /* + * Code Add to check for display width. + * This has to be at the end of the SPS parsing, so everything gets + * parsed and the error will not affect decoding. + * */ + if((0 != ps_dec->u4_app_disp_width) + && (ps_dec->u4_app_disp_width < ps_dec->u2_pic_wd)) + { + ps_dec->u4_app_disp_width = ps_dec->u2_pic_wd; + return ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH; + } + + + + ps_dec->u2_pic_wd = u2_pic_wd; + ps_dec->u2_pic_ht = u2_pic_ht; + + /* Added temporarily to give pic height and width as display height */ + /* and width in case some cropping errors occur` */ + /*ps_dec->u2_disp_height = ps_dec->u2_pic_ht; + ps_dec->u2_disp_width = ps_dec->u2_pic_wd;*/ + + /* Determining the Width and Height of Frame from that of Picture */ + + ps_dec->u2_frm_wd_y = u2_frm_wd_y; + ps_dec->u2_frm_ht_y = u2_frm_ht_y; + + ps_dec->u2_frm_wd_uv = u2_frm_wd_uv; + ps_dec->u2_frm_ht_uv = u2_frm_ht_uv; + ps_dec->s_pad_mgr.u1_pad_len_y_v = (UWORD8)(PAD_LEN_Y_V << (1 - u1_frm)); + ps_dec->s_pad_mgr.u1_pad_len_cr_v = (UWORD8)(PAD_LEN_UV_V << (1 - u1_frm)); + + ps_dec->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs; + ps_dec->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs; + + ps_dec->u2_crop_offset_y = u2_crop_offset_y; + ps_dec->u2_crop_offset_uv = u2_crop_offset_uv; + + ps_dec->ps_sps[u1_seq_parameter_set_id] = *ps_seq; + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_end_of_sequence \endif + * + * \brief + * Decodes End of Sequence. + * + * \param ps_bitstrm : Pointer to bit ps_bitstrm containing the NAL unit + * + * \return + * 0 on Success and error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_end_of_sequence(dec_struct_t * ps_dec) +{ + WORD32 ret; + + ret = ih264d_end_of_pic_processing(ps_dec); + return ret; +} + +/*! + ************************************************************************** + * \if Function name : AcessUnitDelimiterRbsp \endif + * + * \brief + * Decodes AcessUnitDelimiterRbsp. + * + * \param ps_bitstrm : Pointer to bit ps_bitstrm containing the NAL unit + * + * \return + * 0 on Success and error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_access_unit_delimiter_rbsp(dec_struct_t * ps_dec) +{ + UWORD8 u1_primary_pic_type; + u1_primary_pic_type = ih264d_get_bits_h264(ps_dec->ps_bitstrm, 3); + switch(u1_primary_pic_type) + { + case I_PIC: + case SI_PIC: + case ISI_PIC: + ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_I; + break; + default: + ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN; + } + return (0); +} +/*! + ************************************************************************** + * \if Function name : ih264d_parse_nal_unit \endif + * + * \brief + * Decodes NAL unit + * + * \return + * 0 on Success and error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_parse_nal_unit(iv_obj_t *dec_hdl, + ivd_video_decode_op_t *ps_dec_op, + UWORD8 *pu1_buf, + UWORD32 u4_length) +{ + + dec_bit_stream_t *ps_bitstrm; + + + dec_struct_t *ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle; + ivd_video_decode_ip_t *ps_dec_in = + (ivd_video_decode_ip_t *)ps_dec->pv_dec_in; + dec_slice_params_t * ps_cur_slice = ps_dec->ps_cur_slice; + UWORD8 u1_first_byte, u1_nal_ref_idc; + UWORD8 u1_nal_unit_type; + WORD32 i_status = OK; + ps_bitstrm = ps_dec->ps_bitstrm; + + if(pu1_buf) + { + if(u4_length) + { + ps_dec_op->u4_frame_decoded_flag = 0; + ih264d_process_nal_unit(ps_dec->ps_bitstrm, pu1_buf, + u4_length); + + SWITCHOFFTRACE; + u1_first_byte = ih264d_get_bits_h264(ps_bitstrm, 8); + + if(NAL_FORBIDDEN_BIT(u1_first_byte)) + { + H264_DEC_DEBUG_PRINT("\nForbidden bit set in Nal Unit, Let's try\n"); + } + u1_nal_unit_type = NAL_UNIT_TYPE(u1_first_byte); + ps_dec->u1_nal_unit_type = u1_nal_unit_type; + u1_nal_ref_idc = (UWORD8)(NAL_REF_IDC(u1_first_byte)); + //Skip all NALUs if SPS and PPS are not decoded + switch(u1_nal_unit_type) + { + case SLICE_DATA_PARTITION_A_NAL: + case SLICE_DATA_PARTITION_B_NAL: + case SLICE_DATA_PARTITION_C_NAL: + if(!ps_dec->i4_decode_header) + ih264d_parse_slice_partition(ps_dec, ps_bitstrm); + + break; + + case IDR_SLICE_NAL: + case SLICE_NAL: + + /* ! */ + DEBUG_THREADS_PRINTF("Decoding a slice NAL\n"); + if(!ps_dec->i4_decode_header) + { + if(ps_dec->i4_header_decoded == 3) + { + /* ! */ + ps_dec->u4_slice_start_code_found = 1; + + ih264d_rbsp_to_sodb(ps_dec->ps_bitstrm); + + i_status = ih264d_parse_decode_slice( + (UWORD8)(u1_nal_unit_type + == IDR_SLICE_NAL), + u1_nal_ref_idc, ps_dec); + + if(i_status != OK) + return i_status; + } + else + { + H264_DEC_DEBUG_PRINT( + "\nSlice NAL Supplied but no header has been supplied\n"); + } + } + break; + + case SEI_NAL: + if(!ps_dec->i4_decode_header) + { + ih264d_rbsp_to_sodb(ps_dec->ps_bitstrm); + i_status = ih264d_parse_sei_message(ps_dec, ps_bitstrm); + if(i_status != OK) + return i_status; + ih264d_parse_sei(ps_dec, ps_bitstrm); + } + break; + case SEQ_PARAM_NAL: + /* ! */ + ih264d_rbsp_to_sodb(ps_dec->ps_bitstrm); + i_status = ih264d_parse_sps(ps_dec, ps_bitstrm); + if(i_status == ERROR_INV_SPS_PPS_T) + return i_status; + if(!i_status) + ps_dec->i4_header_decoded |= 0x1; + break; + + case PIC_PARAM_NAL: + /* ! */ + ih264d_rbsp_to_sodb(ps_dec->ps_bitstrm); + i_status = ih264d_parse_pps(ps_dec, ps_bitstrm); + if(i_status == ERROR_INV_SPS_PPS_T) + return i_status; + if(!i_status) + ps_dec->i4_header_decoded |= 0x2; + break; + case ACCESS_UNIT_DELIMITER_RBSP: + if(!ps_dec->i4_decode_header) + { + ih264d_access_unit_delimiter_rbsp(ps_dec); + } + break; + //Let us ignore the END_OF_SEQ_RBSP NAL and decode even after this NAL + case END_OF_STREAM_RBSP: + if(!ps_dec->i4_decode_header) + { + ih264d_parse_end_of_stream(ps_dec); + } + break; + case FILLER_DATA_NAL: + if(!ps_dec->i4_decode_header) + { + ih264d_parse_filler_data(ps_dec, ps_bitstrm); + } + break; + default: + H264_DEC_DEBUG_PRINT("\nUnknown NAL type %d\n", u1_nal_unit_type); + break; + } + + } + + } + + return i_status; + +} + diff --git a/decoder/ih264d_parse_headers.h b/decoder/ih264d_parse_headers.h new file mode 100755 index 0000000..3c829e7 --- /dev/null +++ b/decoder/ih264d_parse_headers.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_PARSE_HEADERS_H_ +#define _IH264D_PARSE_HEADERS_H_ +/*! +************************************************************************** +* \file ih264d_parse_headers.h +* +* \brief +* Contains declarations high level syntax[above slice] +* parsing routines +* +* \date +* 19/12/2002 +* +* \author AI +************************************************************************** +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" +WORD32 ih264d_parse_nal_unit(iv_obj_t *dec_hdl, + ivd_video_decode_op_t *ps_dec_op, + UWORD8 *pu1_buf, + UWORD32 u4_length); + +#endif /* _IH264D_PARSE_HEADERS_H_ */ diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c new file mode 100755 index 0000000..7851a0b --- /dev/null +++ b/decoder/ih264d_parse_islice.c @@ -0,0 +1,1479 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_islice.c + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ +#include "ih264d_error_handler.h" +#include "ih264d_debug.h" +#include <string.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_deblocking.h" +#include "ih264d_cabac.h" +#include "ih264d_parse_cabac.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_parse_slice.h" +#include "ih264d_process_pslice.h" +#include "ih264d_process_intra_mb.h" +#include "ih264d_parse_islice.h" +#include "ih264d_error_handler.h" +#include "ih264d_mvpred.h" +#include "ih264d_defs.h" +#include "ih264d_thread_parse_decode.h" +#include "ithread.h" +#include "ih264d_parse_mb_header.h" +#include "assert.h" +#include "ih264d_utils.h" +#include "ih264d_format_conv.h" + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec); + +void ih264d_itrans_recon_luma_dc(dec_struct_t *ps_dec, + WORD16* pi2_src, + WORD16* pi2_coeff_block, + const UWORD16 *pu2_weigh_mat); + + + +/*! + ************************************************************************** + * \if Function name : ParseIMb \endif + * + * \brief + * This function parses CAVLC syntax of a I MB. If 16x16 Luma DC transform + * is also done here. Transformed Luma DC values are copied in their + * 0th pixel location of corrosponding CoeffBlock. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_imb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_mb_type) +{ + WORD32 i4_delta_qp; + UWORD32 u4_temp; + UWORD32 ui_is_top_mb_available; + UWORD32 ui_is_left_mb_available; + UWORD32 u4_cbp; + UWORD32 u4_offset; + UWORD32 *pu4_bitstrm_buf; + WORD32 ret; + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UNUSED(u1_mb_num); + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + u4_temp = ps_dec->u1_mb_ngbr_availablity; + ui_is_top_mb_available = BOOLEAN(u4_temp & TOP_MB_AVAILABLE_MASK); + ui_is_left_mb_available = BOOLEAN(u4_temp & LEFT_MB_AVAILABLE_MASK); + + pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + + if(u1_mb_type == I_4x4_MB) + { + ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB; + u4_offset = 0; + + /*--------------------------------------------------------------------*/ + /* Read transform_size_8x8_flag if present */ + /*--------------------------------------------------------------------*/ + if(ps_dec->s_high_profile.u1_transform8x8_present) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + } + + /*--------------------------------------------------------------------*/ + /* Read the IntraPrediction modes for LUMA */ + /*--------------------------------------------------------------------*/ + if (!ps_cur_mb_info->u1_tran_form8x8) + { + ih264d_read_intra_pred_modes(ps_dec, + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data), + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data+16), + ps_cur_mb_info->u1_tran_form8x8); + UWORD8 *pu1_temp = (UWORD8 *)ps_dec->pv_parse_tu_coeff_data; + pu1_temp += 32; + ps_dec->pv_parse_tu_coeff_data = (void *)pu1_temp; + } + else + { + ih264d_read_intra_pred_modes(ps_dec, + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data), + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data+4), + ps_cur_mb_info->u1_tran_form8x8); + UWORD8 *pu1_temp = (UWORD8 *)ps_dec->pv_parse_tu_coeff_data; + pu1_temp += 8; + ps_dec->pv_parse_tu_coeff_data = (void *)pu1_temp; + } + /*--------------------------------------------------------------------*/ + /* Read the IntraPrediction mode for CHROMA */ + /*--------------------------------------------------------------------*/ +//Inlined ih264d_uev + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_temp; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + { + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + } + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_temp = ((1 << u4_ldz) + u4_word - 1); + if(u4_temp > 3) + { + return ERROR_CHROMA_PRED_MODE; + } + ps_cur_mb_info->u1_chroma_pred_mode = u4_temp; + COPYTHECONTEXT("intra_chroma_pred_mode", ps_cur_mb_info->u1_chroma_pred_mode); + } + /*--------------------------------------------------------------------*/ + /* Read the Coded block pattern */ + /*--------------------------------------------------------------------*/ + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + { + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + } + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_cbp = ((1 << u4_ldz) + u4_word - 1); + } + if(u4_cbp > 47) + { + return ERROR_CBP; + } + + u4_cbp = gau1_ih264d_cbp_table[u4_cbp][0]; + COPYTHECONTEXT("coded_block_pattern", u1_cbp); + ps_cur_mb_info->u1_cbp = u4_cbp; + + /*--------------------------------------------------------------------*/ + /* Read mb_qp_delta */ + /*--------------------------------------------------------------------*/ + if(ps_cur_mb_info->u1_cbp) + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + { + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + } + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + { + i4_delta_qp = (-(WORD32)u4_abs_val); + } + else + { + i4_delta_qp = (u4_abs_val); + } + + if((i4_delta_qp < -26) || (i4_delta_qp > 25)) + { + return ERROR_INV_RANGE_QP_T; + } + + COPYTHECONTEXT("mb_qp_delta", i1_delta_qp); + if(i4_delta_qp != 0) + { + ret = ih264d_update_qp(ps_dec, (WORD8)i4_delta_qp); + if(ret != OK) + return ret; + } + } + + } + else + { + u4_offset = 1; + ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB; + /*-------------------------------------------------------------------*/ + /* Read the IntraPrediction mode for CHROMA */ + /*-------------------------------------------------------------------*/ + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + { + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + } + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_temp = ((1 << u4_ldz) + u4_word - 1); + +//Inlined ih264d_uev + + if(u4_temp > 3) + { + return ERROR_CHROMA_PRED_MODE; + } + ps_cur_mb_info->u1_chroma_pred_mode = u4_temp; + COPYTHECONTEXT("intra_chroma_pred_mode", ps_cur_mb_info->u1_chroma_pred_mode); + } + /*-------------------------------------------------------------------*/ + /* Read the Coded block pattern */ + /*-------------------------------------------------------------------*/ + u4_cbp = gau1_ih264d_cbp_tab[(u1_mb_type - 1) >> 2]; + ps_cur_mb_info->u1_cbp = u4_cbp; + + /*-------------------------------------------------------------------*/ + /* Read mb_qp_delta */ + /*-------------------------------------------------------------------*/ + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i4_delta_qp = (-(WORD32)u4_abs_val); + else + i4_delta_qp = (u4_abs_val); + + if((i4_delta_qp < -26) || (i4_delta_qp > 25)) + return ERROR_INV_RANGE_QP_T; + + } +//inlinined ih264d_sev + COPYTHECONTEXT("Delta quant", i1_delta_qp); + + if(i4_delta_qp != 0) + { + ret = ih264d_update_qp(ps_dec, (WORD8)i4_delta_qp); + if(ret != OK) + return ret; + } + + { + WORD16 i_scaleFactor; + UWORD32 ui_N = 0; + WORD16 *pi2_scale_matrix_ptr; + /*******************************************************************/ + /* for luma DC coefficients the scaling is done during the parsing */ + /* to preserve the precision */ + /*******************************************************************/ + if(ps_dec->s_high_profile.u1_scaling_present) + { + pi2_scale_matrix_ptr = + ps_dec->s_high_profile.i2_scalinglist4x4[0]; + } + else + { + i_scaleFactor = 16; + pi2_scale_matrix_ptr = &i_scaleFactor; + } + + /*---------------------------------------------------------------*/ + /* Decode DC coefficients */ + /*---------------------------------------------------------------*/ + /*---------------------------------------------------------------*/ + /* Calculation of N */ + /*---------------------------------------------------------------*/ + if(ui_is_left_mb_available) + { + + if(ui_is_top_mb_available) + { + ui_N = ((ps_cur_mb_info->ps_top_mb->pu1_nnz_y[0] + + ps_dec->pu1_left_nnz_y[0] + 1) >> 1); + } + else + { + ui_N = ps_dec->pu1_left_nnz_y[0]; + } + } + else if(ui_is_top_mb_available) + { + ui_N = ps_cur_mb_info->ps_top_mb->pu1_nnz_y[0]; + } + + { + WORD16 pi2_dc_coef[16]; + WORD32 pi4_tmp[16]; + tu_sblk4x4_coeff_data_t *ps_tu_4x4 = + (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + WORD16 *pi2_coeff_block = + (WORD16 *)ps_dec->pv_parse_tu_coeff_data; + ps_tu_4x4->u2_sig_coeff_map = 0; + UWORD32 u4_num_coeff; + + ret = ps_dec->pf_cavlc_parse4x4coeff[(ui_N > 7)](pi2_dc_coef, 0, ui_N, + ps_dec, &u4_num_coeff); + if(ret != OK) + return ret; + + if(EXCEED_OFFSET(ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + if(ps_tu_4x4->u2_sig_coeff_map) + { + memset(pi2_dc_coef,0,sizeof(pi2_dc_coef)); + ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, + pi2_dc_coef, + ps_dec->pu1_inv_scan); + + PROFILE_DISABLE_IQ_IT_RECON() + ps_dec->pf_ihadamard_scaling_4x4(pi2_dc_coef, + pi2_coeff_block, + ps_dec->pu2_quant_scale_y, + (UWORD16 *)pi2_scale_matrix_ptr, + ps_dec->u1_qp_y_div6, + pi4_tmp); + pi2_coeff_block += 16; + ps_dec->pv_parse_tu_coeff_data = (void *)pi2_coeff_block; + SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag,0); + } + + } + } + } + + + if(u4_cbp) + { + + ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, + (UWORD8)u4_offset); + if(ret != OK) + return ret; + if(EXCEED_OFFSET(ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + + /* Store Left Mb NNZ and TOP chroma NNZ */ + } + else + { + ps_cur_mb_info->u1_qp_div6 = ps_dec->u1_qp_y_div6; + ps_cur_mb_info->u1_qpc_div6 = ps_dec->u1_qp_u_div6; + ps_cur_mb_info->u1_qpcr_div6 = ps_dec->u1_qp_v_div6; + ps_cur_mb_info->u1_qp_rem6 = ps_dec->u1_qp_y_rem6; + ps_cur_mb_info->u1_qpc_rem6 = ps_dec->u1_qp_u_rem6; + ps_cur_mb_info->u1_qpcr_rem6 = ps_dec->u1_qp_v_rem6; + ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC); + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ParseIMbCab \endif + * + * \brief + * This function parses CABAC syntax of a I MB. If 16x16 Luma DC transform + * is also done here. Transformed Luma DC values are copied in their + * 0th pixel location of corrosponding CoeffBlock. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_imb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_type) +{ + WORD8 i1_delta_qp; + UWORD8 u1_cbp; + UWORD8 u1_offset; + /* Variables for handling Cabac contexts */ + ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + ctxt_inc_mb_info_t *ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + bin_ctxt_model_t *p_bin_ctxt; + + UWORD8 u1_intra_chrom_pred_mode; + UWORD8 u1_dc_block_flag = 0; + WORD32 ret; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + if(ps_left_ctxt == ps_dec->ps_def_ctxt_mb_info) + { + ps_dec->pu1_left_yuv_dc_csbp[0] = 0xf; + } + + if(ps_dec->ps_cur_slice->u1_slice_type != I_SLICE) + { + WORD32 *pi4_buf; + WORD8 *pi1_buf; + MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); + *((UWORD32 *)ps_dec->pi1_left_ref_idx_ctxt_inc) = 0; + MEMSET_16BYTES(p_curr_ctxt->u1_mv, 0); + pi1_buf = p_curr_ctxt->i1_ref_idx; + pi4_buf = (WORD32 *)pi1_buf; + *pi4_buf = 0; + } + + if(u1_mb_type == I_4x4_MB) + { + ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB; + p_curr_ctxt->u1_mb_type = CAB_I4x4; + u1_offset = 0; + + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + /*--------------------------------------------------------------------*/ + /* Read transform_size_8x8_flag if present */ + /*--------------------------------------------------------------------*/ + if(ps_dec->s_high_profile.u1_transform8x8_present) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_parse_transform8x8flag_cabac( + ps_dec, ps_cur_mb_info); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + } + else + { + p_curr_ctxt->u1_transform8x8_ctxt = 0; + } + + /*--------------------------------------------------------------------*/ + /* Read the IntraPrediction modes for LUMA */ + /*--------------------------------------------------------------------*/ + if (!ps_cur_mb_info->u1_tran_form8x8) + { + ih264d_read_intra_pred_modes_cabac( + ps_dec, + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data), + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data+16), + ps_cur_mb_info->u1_tran_form8x8); + UWORD8 *pu1_temp = (UWORD8 *)ps_dec->pv_parse_tu_coeff_data; + pu1_temp += 32; + ps_dec->pv_parse_tu_coeff_data = (void *)pu1_temp; + } + else + { + ih264d_read_intra_pred_modes_cabac( + ps_dec, + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data), + ((UWORD8 *)ps_dec->pv_parse_tu_coeff_data+4), + ps_cur_mb_info->u1_tran_form8x8); + UWORD8 *pu1_temp = (UWORD8 *)ps_dec->pv_parse_tu_coeff_data; + pu1_temp += 8; + ps_dec->pv_parse_tu_coeff_data = (void *)pu1_temp; + } + /*--------------------------------------------------------------------*/ + /* Read the IntraPrediction mode for CHROMA */ + /*--------------------------------------------------------------------*/ + u1_intra_chrom_pred_mode = ih264d_parse_chroma_pred_mode_cabac(ps_dec); + COPYTHECONTEXT("intra_chroma_pred_mode", u1_intra_chrom_pred_mode); + p_curr_ctxt->u1_intra_chroma_pred_mode = ps_cur_mb_info->u1_chroma_pred_mode = + u1_intra_chrom_pred_mode; + + /*--------------------------------------------------------------------*/ + /* Read the Coded block pattern */ + /*--------------------------------------------------------------------*/ + u1_cbp = ih264d_parse_ctx_cbp_cabac(ps_dec); + COPYTHECONTEXT("coded_block_pattern", u1_cbp); + ps_cur_mb_info->u1_cbp = u1_cbp; + p_curr_ctxt->u1_cbp = u1_cbp; + + /*--------------------------------------------------------------------*/ + /* Read mb_qp_delta */ + /*--------------------------------------------------------------------*/ + if(ps_cur_mb_info->u1_cbp) + { + ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &i1_delta_qp); + if(ret != OK) + return ret; + COPYTHECONTEXT("mb_qp_delta", i1_delta_qp); + if(i1_delta_qp != 0) + { + ret = ih264d_update_qp(ps_dec, i1_delta_qp); + if(ret != OK) + return ret; + } + } + else + ps_dec->i1_prev_mb_qp_delta = 0; + p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE; + } + else + { + u1_offset = 1; + ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB; + p_curr_ctxt->u1_mb_type = CAB_I16x16; + ps_cur_mb_info->u1_tran_form8x8 = 0; + p_curr_ctxt->u1_transform8x8_ctxt = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + /*--------------------------------------------------------------------*/ + /* Read the IntraPrediction mode for CHROMA */ + /*--------------------------------------------------------------------*/ + u1_intra_chrom_pred_mode = ih264d_parse_chroma_pred_mode_cabac(ps_dec); + if(u1_intra_chrom_pred_mode > 3) + return ERROR_CHROMA_PRED_MODE; + + COPYTHECONTEXT("Chroma intra_chroma_pred_mode pred mode", u1_intra_chrom_pred_mode); + p_curr_ctxt->u1_intra_chroma_pred_mode = ps_cur_mb_info->u1_chroma_pred_mode = + u1_intra_chrom_pred_mode; + + /*--------------------------------------------------------------------*/ + /* Read the Coded block pattern */ + /*--------------------------------------------------------------------*/ + u1_cbp = gau1_ih264d_cbp_tab[(u1_mb_type - 1) >> 2]; + ps_cur_mb_info->u1_cbp = u1_cbp; + p_curr_ctxt->u1_cbp = u1_cbp; + + /*--------------------------------------------------------------------*/ + /* Read mb_qp_delta */ + /*--------------------------------------------------------------------*/ + ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &i1_delta_qp); + if(ret != OK) + return ret; + COPYTHECONTEXT("mb_qp_delta", i1_delta_qp); + if(i1_delta_qp != 0) + { + ret = ih264d_update_qp(ps_dec, i1_delta_qp); + if(ret != OK) + return ret; + } + + { + WORD16 i_scaleFactor; + WORD16* pi2_scale_matrix_ptr; + /*******************************************************************/ + /* for luma DC coefficients the scaling is done during the parsing */ + /* to preserve the precision */ + /*******************************************************************/ + if(ps_dec->s_high_profile.u1_scaling_present) + { + pi2_scale_matrix_ptr = + ps_dec->s_high_profile.i2_scalinglist4x4[0]; + + } + else + { + i_scaleFactor = 16; + pi2_scale_matrix_ptr = &i_scaleFactor; + } + { + ctxt_inc_mb_info_t *ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + UWORD8 uc_a, uc_b; + UWORD32 u4_ctx_inc; + + INC_SYM_COUNT(&(ps_dec->s_cab_dec_env)); + + /* if MbAddrN not available then CondTermN = 1 */ + uc_b = ((ps_top_ctxt->u1_yuv_dc_csbp) & 0x01); + + /* if MbAddrN not available then CondTermN = 1 */ + uc_a = ((ps_dec->pu1_left_yuv_dc_csbp[0]) & 0x01); + + u4_ctx_inc = (uc_a + (uc_b << 1)); + + { + WORD16 pi2_dc_coef[16]; + tu_sblk4x4_coeff_data_t *ps_tu_4x4 = + (tu_sblk4x4_coeff_data_t *)ps_dec->pv_parse_tu_coeff_data; + WORD16 *pi2_coeff_block = + (WORD16 *)ps_dec->pv_parse_tu_coeff_data; + + p_bin_ctxt = (ps_dec->p_cbf_t[LUMA_DC_CTXCAT]) + u4_ctx_inc; + + u1_dc_block_flag = + ih264d_read_coeff4x4_cabac(ps_bitstrm, + LUMA_DC_CTXCAT, + ps_dec->p_significant_coeff_flag_t[LUMA_DC_CTXCAT], + ps_dec, p_bin_ctxt); + + /* Store coded_block_flag */ + p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE; + p_curr_ctxt->u1_yuv_dc_csbp |= u1_dc_block_flag; + if(u1_dc_block_flag) + { + WORD32 pi4_tmp[16]; + memset(pi2_dc_coef,0,sizeof(pi2_dc_coef)); + ih264d_unpack_coeff4x4_dc_4x4blk(ps_tu_4x4, + pi2_dc_coef, + ps_dec->pu1_inv_scan); + + PROFILE_DISABLE_IQ_IT_RECON() + ps_dec->pf_ihadamard_scaling_4x4(pi2_dc_coef, + pi2_coeff_block, + ps_dec->pu2_quant_scale_y, + (UWORD16 *)pi2_scale_matrix_ptr, + ps_dec->u1_qp_y_div6, + pi4_tmp); + pi2_coeff_block += 16; + ps_dec->pv_parse_tu_coeff_data = (void *)pi2_coeff_block; + SET_BIT(ps_cur_mb_info->u1_yuv_dc_block_flag,0); + } + + } + + } + } + } + + ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6; + ps_dec->pu1_left_yuv_dc_csbp[0] |= u1_dc_block_flag; + + ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, u1_offset); + if(EXCEED_OFFSET(ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_islice_data_cavlc */ +/* */ +/* Description : This function parses cabac syntax of a inter slice on */ +/* N MB basis. */ +/* */ +/* Inputs : ps_dec */ +/* sliceparams */ +/* firstMbInSlice */ +/* */ +/* Processing : 1. After parsing syntax for N MBs those N MBs are */ +/* decoded till the end of slice. */ +/* */ +/* Returns : 0 */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 24 06 2005 ARNY Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_islice_data_cavlc(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice) +{ + UWORD8 uc_more_data_flag; + UWORD8 u1_num_mbs, u1_mb_idx; + dec_mb_info_t *ps_cur_mb_info; + deblk_mb_t *ps_cur_deblk_mb; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; + WORD16 i2_cur_mb_addr; + UWORD8 u1_mbaff; + UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb; + WORD32 ret; + + ps_dec->u1_qp = ps_slice->u1_slice_qp; + ret = ih264d_update_qp(ps_dec, 0); + if(ret != OK) + return ret; + u1_mbaff = ps_slice->u1_mbaff_frame_flag; + + /* initializations */ + u1_mb_idx = ps_dec->u1_mb_idx; + u1_num_mbs = u1_mb_idx; + + uc_more_data_flag = 1; + i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff; + + do + { + UWORD8 u1_mb_type; + + if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr) + { + break; + } + + ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs; + ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff); + + ps_cur_mb_info->u1_end_of_slice = 0; + + /***************************************************************/ + /* Get the required information for decoding of MB */ + /* mb_x, mb_y , neighbour availablity, */ + /***************************************************************/ + ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0); + + /***************************************************************/ + /* Set the deblocking parameters for this MB */ + /***************************************************************/ + ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs; + + if(ps_dec->u4_app_disable_deblk_frm == 0) + ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice, + ps_dec->u1_mb_ngbr_availablity, + ps_dec->u1_cur_mb_fld_dec_flag); + + ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type | D_INTRA_MB; + + /**************************************************************/ + /* Macroblock Layer Begins, Decode the u1_mb_type */ + /**************************************************************/ +//Inlined ih264d_uev + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_temp; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_temp = ((1 << u4_ldz) + u4_word - 1); + if(u4_temp > 25) + return ERROR_MB_TYPE; + u1_mb_type = u4_temp; + + } +//Inlined ih264d_uev + ps_cur_mb_info->u1_mb_type = u1_mb_type; + COPYTHECONTEXT("u1_mb_type", u1_mb_type); + + /**************************************************************/ + /* Parse Macroblock data */ + /**************************************************************/ + if(25 == u1_mb_type) + { + /* I_PCM_MB */ + ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB; + ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = 0; + } + else + { + ret = ih264d_parse_imb_cavlc(ps_dec, ps_cur_mb_info, u1_num_mbs, u1_mb_type); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + } + + if(u1_mbaff) + { + ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); + } + /**************************************************************/ + /* Get next Macroblock address */ + /**************************************************************/ + + i2_cur_mb_addr++; + uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm); + + /* Store the colocated information */ + { + mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4); + + mv_pred_t s_mvPred = + { + { 0, 0, 0, 0 }, + { -1, -1 }, 0, 0}; + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, + (UWORD8)(ps_dec->u1_cur_mb_fld_dec_flag << 1), 4, + 4); + } + + /*if num _cores is set to 3,compute bs will be done in another thread*/ + if(ps_dec->u4_num_cores < 3) + { + if(ps_dec->u4_app_disable_deblk_frm == 0) + ps_dec->pf_compute_bs(ps_dec, ps_cur_mb_info, + (UWORD16)(u1_num_mbs >> u1_mbaff)); + } + u1_num_mbs++; + ps_dec->u2_total_mbs_coded++; + + /****************************************************************/ + /* Check for End Of Row */ + /****************************************************************/ + u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1; + u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01))); + u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row + || (!uc_more_data_flag); + ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag); + + /*H264_DEC_DEBUG_PRINT("Pic: %d Mb_X=%d Mb_Y=%d", + ps_slice->i4_poc >> ps_slice->u1_field_pic_flag, + ps_dec->u2_mbx,ps_dec->u2_mby + (1 - ps_cur_mb_info->u1_topmb)); + H264_DEC_DEBUG_PRINT("u1_tfr_n_mb || (!uc_more_data_flag): %d", u1_tfr_n_mb || (!uc_more_data_flag));*/ + if(u1_tfr_n_mb || (!uc_more_data_flag)) + { + + if(ps_dec->u1_separate_parse) + { + ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, u1_end_of_row); + ps_dec->ps_nmb_info += u1_num_mbs; + } + else + { + ret = ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, + u1_end_of_row); + if(ret != OK) + return ret; + } + + if(u1_tfr_n_mb) + u1_num_mbs = 0; + u1_mb_idx = u1_num_mbs; + ps_dec->u1_mb_idx = u1_num_mbs; + + } + } + while(uc_more_data_flag); + + if(ps_dec->u1_separate_parse) + { + ps_dec->ps_parse_cur_slice->end_of_slice = 1; + ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr + - (u2_first_mb_in_slice << u1_mbaff); + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_islice_data_cabac */ +/* */ +/* Description : This function parses cabac syntax of a inter slice on */ +/* N MB basis. */ +/* */ +/* Inputs : ps_dec */ +/* sliceparams */ +/* firstMbInSlice */ +/* */ +/* Processing : 1. After parsing syntax for N MBs those N MBs are */ +/* decoded till the end of slice. */ +/* */ +/* Returns : 0 */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 24 06 2005 ARNY Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_islice_data_cabac(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice) +{ + UWORD8 uc_more_data_flag; + UWORD8 u1_num_mbs, u1_mb_idx; + dec_mb_info_t *ps_cur_mb_info; + deblk_mb_t *ps_cur_deblk_mb; + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; + WORD16 i2_cur_mb_addr; + UWORD8 u1_mbaff; + UWORD8 u1_num_mbs_next, u1_end_of_row, u1_tfr_n_mb; + WORD32 ret; + + ps_dec->u1_qp = ps_slice->u1_slice_qp; + ret = ih264d_update_qp(ps_dec, 0); + if(ret != 0) + return ret; + u1_mbaff = ps_slice->u1_mbaff_frame_flag; + + if(ps_bitstrm->u4_ofst & 0x07) + { + ps_bitstrm->u4_ofst += 8; + ps_bitstrm->u4_ofst &= 0xFFFFFFF8; + } + ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm); + if(ret != OK) + return ret; + ih264d_init_cabac_contexts(I_SLICE, ps_dec); + + ps_dec->i1_prev_mb_qp_delta = 0; + + /* initializations */ + u1_mb_idx = ps_dec->u1_mb_idx; + u1_num_mbs = u1_mb_idx; + + uc_more_data_flag = 1; + i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff; + do + { + UWORD16 u2_mbx; + { + UWORD8 u1_mb_type; + + ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs; + ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff); + + ps_cur_mb_info->u1_end_of_slice = 0; + + /***************************************************************/ + /* Get the required information for decoding of MB */ + /* mb_x, mb_y , neighbour availablity, */ + /***************************************************************/ + ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 0); + u2_mbx = ps_dec->u2_mbx; + + /*********************************************************************/ + /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */ + /*********************************************************************/ + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + /***************************************************************/ + /* Set the deblocking parameters for this MB */ + /***************************************************************/ + ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs; + if(ps_dec->u4_app_disable_deblk_frm == 0) + ih264d_set_deblocking_parameters( + ps_cur_deblk_mb, ps_slice, + ps_dec->u1_mb_ngbr_availablity, + ps_dec->u1_cur_mb_fld_dec_flag); + + ps_cur_deblk_mb->u1_mb_type = ps_cur_deblk_mb->u1_mb_type + | D_INTRA_MB; + + /* Macroblock Layer Begins */ + /* Decode the u1_mb_type */ + u1_mb_type = ih264d_parse_mb_type_intra_cabac(0, ps_dec); + if(u1_mb_type > 25) + return ERROR_MB_TYPE; + ps_cur_mb_info->u1_mb_type = u1_mb_type; + COPYTHECONTEXT("u1_mb_type", u1_mb_type); + + /* Parse Macroblock Data */ + if(25 == u1_mb_type) + { + /* I_PCM_MB */ + ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB; + ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = 0; + } + else + { + ret = ih264d_parse_imb_cabac(ps_dec, ps_cur_mb_info, u1_mb_type); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + } + + if(u1_mbaff) + { + ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); + } + /* Next macroblock information */ + if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr) + return ERROR_MB_ADDRESS_T; + i2_cur_mb_addr++; + + if(ps_cur_mb_info->u1_topmb && u1_mbaff) + uc_more_data_flag = 1; + else + { + uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, + ps_bitstrm); + uc_more_data_flag = !uc_more_data_flag; + COPYTHECONTEXT("Decode Sliceterm",!uc_more_data_flag); + } + /* Store the colocated information */ + { + + mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_num_mbs << 4); + mv_pred_t s_mvPred = + { + { 0, 0, 0, 0 }, + { -1, -1 }, 0, 0}; + ih264d_rep_mv_colz( + ps_dec, &s_mvPred, ps_mv_nmb_start, 0, + (UWORD8)(ps_dec->u1_cur_mb_fld_dec_flag << 1), + 4, 4); + } + /*if num _cores is set to 3,compute bs will be done in another thread*/ + if(ps_dec->u4_num_cores < 3) + { + if(ps_dec->u4_app_disable_deblk_frm == 0) + ps_dec->pf_compute_bs(ps_dec, ps_cur_mb_info, + (UWORD16)(u1_num_mbs >> u1_mbaff)); + } + u1_num_mbs++; + ps_dec->u2_total_mbs_coded++; + + } + + /****************************************************************/ + /* Check for End Of Row */ + /****************************************************************/ + u1_num_mbs_next = i2_pic_wdin_mbs - u2_mbx - 1; + u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01))); + u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row + || (!uc_more_data_flag); + ps_cur_mb_info->u1_end_of_slice = (!uc_more_data_flag); + + if(u1_tfr_n_mb || (!uc_more_data_flag)) + { + + + if(ps_dec->u1_separate_parse) + { + ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, u1_end_of_row); + ps_dec->ps_nmb_info += u1_num_mbs; + } + else + { + ret = ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, + u1_end_of_row); + if(ret != OK) + return ret; + } + + if(u1_tfr_n_mb) + u1_num_mbs = 0; + u1_mb_idx = u1_num_mbs; + ps_dec->u1_mb_idx = u1_num_mbs; + + } + } + while(uc_more_data_flag); + + if(ps_dec->u1_separate_parse) + { + ps_dec->ps_parse_cur_slice->end_of_slice = 1; + ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr + - (u2_first_mb_in_slice << u1_mbaff); + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_ipcm_mb */ +/* */ +/* Description : This function decodes the pixel values of I_PCM Mb. */ +/* */ +/* Inputs : ps_dec, ps_cur_mb_info and mb number */ +/* */ +/* Description : This function reads the luma and chroma pixels directly */ +/* from the bitstream when the mbtype is I_PCM and stores */ +/* them in recon buffer. If the entropy coding mode is */ +/* cabac, decoding engine is re-initialized. The nnzs and */ +/* cabac contexts are appropriately modified. */ +/* Returns : void */ +/* */ +/* Revision History: */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_ipcm_mb(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_mbNum) +{ + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD8 *pu1_y, *pu1_u, *pu1_v; + WORD32 ret; + + UWORD32 u4_rec_width_y, u4_rec_width_uv; + UWORD32 u1_num_mb_pair; + UWORD8 u1_x, u1_y; + /* CHANGED CODE */ + tfr_ctxt_t *ps_frame_buf; + UWORD8 u1_mb_field_decoding_flag; + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + /* CHANGED CODE */ + + if(ps_dec->u1_separate_parse) + { + ps_frame_buf = &ps_dec->s_tran_addrecon_parse; + } + else + { + ps_frame_buf = &ps_dec->s_tran_addrecon; + } + /* align bistream to byte boundary. */ + /* pcm_alignment_zero_bit discarded */ + /* For XX GotoByteBoundary */ + if(ps_bitstrm->u4_ofst & 0x07) + { + ps_bitstrm->u4_ofst += 8; + ps_bitstrm->u4_ofst &= 0xFFFFFFF8; + } + + /* Store left Nnz as 16 for each 4x4 blk */ + + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x10101010; + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x10101010; + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x10101010; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x10101010; + ps_cur_mb_info->u1_cbp = 0xff; + + ps_dec->i1_prev_mb_qp_delta = 0; + /* Get neighbour MB's */ + u1_num_mb_pair = (u1_mbNum >> u1_mbaff); + + /*****************************************************************************/ + /* calculate the RECON buffer YUV pointers for the PCM data */ + /*****************************************************************************/ + /* CHANGED CODE */ + u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + pu1_y = ps_frame_buf->pu1_dest_y + (u1_num_mb_pair << 4); + pu1_u = ps_frame_buf->pu1_dest_u + (u1_num_mb_pair << 4); + pu1_v = pu1_u + 1; + + u4_rec_width_y = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + u4_rec_width_uv = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + /* CHANGED CODE */ + + if(u1_mbaff) + { + UWORD8 u1_top_mb; + + u1_top_mb = ps_cur_mb_info->u1_topmb; + + if(u1_top_mb == 0) + { + pu1_y += (u1_mb_field_decoding_flag ? + (u4_rec_width_y >> 1) : (u4_rec_width_y << 4)); + pu1_u += (u1_mb_field_decoding_flag ? + (u4_rec_width_uv) : (u4_rec_width_uv << 4)); + pu1_v = pu1_u + 1; + } + } + + /* Read Luma samples */ + for(u1_y = 0; u1_y < 16; u1_y++) + { + for(u1_x = 0; u1_x < 16; u1_x++) + pu1_y[u1_x] = ih264d_get_bits_h264(ps_bitstrm, 8); + + pu1_y += u4_rec_width_y; + } + + /* Read Chroma samples */ + for(u1_y = 0; u1_y < 8; u1_y++) + { + for(u1_x = 0; u1_x < 8; u1_x++) + pu1_u[u1_x * YUV420SP_FACTOR] = ih264d_get_bits_h264(ps_bitstrm, 8); + + pu1_u += u4_rec_width_uv; + } + + for(u1_y = 0; u1_y < 8; u1_y++) + { + for(u1_x = 0; u1_x < 8; u1_x++) + pu1_v[u1_x * YUV420SP_FACTOR] = ih264d_get_bits_h264(ps_bitstrm, 8); + + pu1_v += u4_rec_width_uv; + } + + if(CABAC == ps_dec->ps_cur_pps->u1_entropy_coding_mode) + { + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + ctxt_inc_mb_info_t *p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + /* Re-initialize the cabac decoding engine. */ + ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm); + if(ret != OK) + return ret; + /* update the cabac contetxs */ + p_curr_ctxt->u1_mb_type = CAB_I_PCM; + p_curr_ctxt->u1_cbp = 47; + p_curr_ctxt->u1_intra_chroma_pred_mode = 0; + p_curr_ctxt->u1_transform8x8_ctxt = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x01010101; + + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x01010101; + + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x01010101; + + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0x01010101; + + p_curr_ctxt->u1_yuv_dc_csbp = 0x7; + ps_dec->pu1_left_yuv_dc_csbp[0] = 0x7; + if(ps_dec->ps_cur_slice->u1_slice_type != I_SLICE) + { + + MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); + memset(ps_dec->pi1_left_ref_idx_ctxt_inc, 0, 4); + MEMSET_16BYTES(p_curr_ctxt->u1_mv, 0); + memset(p_curr_ctxt->i1_ref_idx, 0, 4); + + } + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_islice \endif + * + * \brief + * Decodes an I Slice + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_islice(dec_struct_t *ps_dec, + UWORD16 u2_first_mb_in_slice) +{ + dec_pic_params_t * ps_pps = ps_dec->ps_cur_pps; + dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice; + UWORD32 *pu4_bitstrm_buf = ps_dec->ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst; + UWORD32 u4_temp; + WORD32 i_temp; + WORD32 ret; + + /*--------------------------------------------------------------------*/ + /* Read remaining contents of the slice header */ + /*--------------------------------------------------------------------*/ + /* dec_ref_pic_marking function */ + /* G050 */ + if(ps_slice->u1_nal_ref_idc != 0) + { + if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read) + ps_dec->u4_bitoffset = ih264d_read_mmco_commands( + ps_dec); + else + ps_dec->ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset; + } + /* G050 */ + + /* Read slice_qp_delta */ + i_temp = ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i_temp < 0) || (i_temp > 51)) + return ERROR_INV_RANGE_QP_T; + ps_slice->u1_slice_qp = i_temp; + COPYTHECONTEXT("SH: slice_qp_delta", + ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp); + + if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp); + + if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->u1_disable_dblk_filter_idc = u4_temp; + if(u4_temp != 1) + { + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->i1_slice_alpha_c0_offset = i_temp; + COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2", + ps_slice->i1_slice_alpha_c0_offset >> 1); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_slice->i1_slice_beta_offset = i_temp; + COPYTHECONTEXT("SH: slice_beta_offset_div2", + ps_slice->i1_slice_beta_offset >> 1); + + } + else + { + ps_slice->i1_slice_alpha_c0_offset = 0; + ps_slice->i1_slice_beta_offset = 0; + } + } + else + { + ps_slice->u1_disable_dblk_filter_idc = 0; + ps_slice->i1_slice_alpha_c0_offset = 0; + ps_slice->i1_slice_beta_offset = 0; + } + + /* Initialization to check if number of motion vector per 2 Mbs */ + /* are exceeding the range or not */ + ps_dec->u2_mv_2mb[0] = 0; + ps_dec->u2_mv_2mb[1] = 0; + + + /*set slice header cone to 2 ,to indicate correct header*/ + DATA_SYNC(); + ps_dec->ps_parse_cur_slice->slice_header_done = 2; + + if(ps_pps->u1_entropy_coding_mode) + { + SWITCHOFFTRACE; SWITCHONTRACECABAC; + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff; + } + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff; + + ret = ih264d_parse_islice_data_cabac(ps_dec, ps_slice, + u2_first_mb_in_slice); + if(ret != OK) + return ret; + SWITCHONTRACE; SWITCHOFFTRACECABAC; + if(ps_dec->ps_parse_cur_slice->u2_error_flag == 1) + return 0; + + } + else + { + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff; + } + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff; + ret = ih264d_parse_islice_data_cavlc(ps_dec, ps_slice, + u2_first_mb_in_slice); + if(ret != OK) + return ret; + } + + return OK; +} diff --git a/decoder/ih264d_parse_islice.h b/decoder/ih264d_parse_islice.h new file mode 100755 index 0000000..6a43d7b --- /dev/null +++ b/decoder/ih264d_parse_islice.h @@ -0,0 +1,113 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_islice.h + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ + +#ifndef _IH264D_PARSE_ISLICE_H_ +#define _IH264D_PARSE_ISLICE_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_tables.h" + +WORD32 ih264d_parse_residual4x4_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_offset); +WORD32 ih264d_parse_residual4x4_cabac(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_offset); +WORD32 ih264d_parse_imb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_mb_type); +WORD32 ih264d_parse_imb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_type); + +WORD32 ih264d_parse_islice_data_cavlc(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); +WORD32 ih264d_parse_islice_data_cabac(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); +WORD32 ih264d_parse_pmb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); +WORD32 ih264d_parse_pmb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); + +WORD32 ih264d_parse_bmb_non_direct_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_mbNumModNBy2); + +WORD32 ih264d_parse_bmb_non_direct_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_mbNumModNBy2); + +WORD32 ih264d_parse_bmb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); + +WORD32 ih264d_parse_bmb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); + +WORD32 ih264d_parse_inter_slice_data_cavlc(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); + +WORD32 ih264d_parse_inter_slice_data_cabac(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); + +WORD32 ParseBMb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); + +WORD32 ih264d_parse_ipcm_mb(dec_struct_t * ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_mbNum); +WORD32 ih264d_parse_islice(dec_struct_t *ps_dec, + UWORD16 u2_first_mb_in_slice); + +#endif /* _IH264D_PARSE_ISLICE_H_ */ diff --git a/decoder/ih264d_parse_mb_header.c b/decoder/ih264d_parse_mb_header.c new file mode 100755 index 0000000..f30ad67 --- /dev/null +++ b/decoder/ih264d_parse_mb_header.c @@ -0,0 +1,1397 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_mb_header.c + * + * \brief + * This file contains context identifier encoding routines. + * + * \date + * 04/02/2003 + * + * \author NS + *************************************************************************** + */ +#include <string.h> +#include "ih264d_structs.h" +#include "ih264d_bitstrm.h" +#include "ih264d_cabac.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_defs.h" +#include "ih264d_error_handler.h" +#include "ih264d_tables.h" +#include "ih264d_debug.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_mb_utils.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_defs.h" + +/*! < CtxtInc index 0 - CtxMbTypeI, CtxMbTypeSISuffix + index 1 - CtxMbTypePSuffix, CtxMbTypeBSuffix + */ + + + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_mb_type_intra_cabac \endif + * + * \brief + * This function decodes MB type using CABAC entropy coding mode. + * + * \return + * MBType. + * + ************************************************************************** + */ +UWORD8 ih264d_parse_mb_type_intra_cabac(UWORD8 u1_inter, + struct _DecStruct * ps_dec) +{ + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + bin_ctxt_model_t *ps_mb_bin_ctxt = ps_dec->p_mb_type_t; + WORD8 u1_mb_type, u1_bin; + UWORD32 u4_cxt_inc; + + u4_cxt_inc = 0; + if(!u1_inter) + { + if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) + u4_cxt_inc += ((ps_left_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0); + if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) + u4_cxt_inc += ((ps_top_ctxt->u1_mb_type != CAB_I4x4) ? 1 : 0); + } + else + { + ps_mb_bin_ctxt = ps_mb_bin_ctxt + 3 + (ps_dec->u1_B << 1); + } + + /* b0 */ + u1_mb_type = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + if(u1_mb_type) + { + /* I16x16 or I_PCM mode */ + /* b1 */ + u1_bin = ih264d_decode_terminate(ps_cab_env, ps_bitstrm); + if(u1_bin == 0) + { + /* I16x16 mode */ + /* Read b2 and b3 */ + u4_cxt_inc = (u1_inter) ? 0x021 : 0x043; + + u1_bin = ih264d_decode_bins(2, u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + + if(u1_bin & 0x01) + u1_mb_type += 4; + + if(u1_bin & 0x02) + u1_mb_type += 12; + + if(u1_bin & 0x01) + { + /* since b3=1, Read three bins */ + u4_cxt_inc = (u1_inter) ? 0x0332 : 0x0765; + u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + + } + else + { + /* Read two bins */ + u4_cxt_inc = (u1_inter) ? 0x033 : 0x076; + u1_bin = (UWORD8)ih264d_decode_bins(2, u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + } + u1_mb_type += u1_bin; + } + else + { + /* I_PCM mode */ + /* b1=1 */ + u1_mb_type = 25; + } + } + return (u1_mb_type); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_mb_type_cabac \endif + * + * \brief + * This function decodes MB type using CABAC entropy coding mode. + * + * \return + * MBType. + * + ************************************************************************** + */ +UWORD32 ih264d_parse_mb_type_cabac(struct _DecStruct * ps_dec) +{ + const UWORD8 uc_slice_type = ps_dec->ps_cur_slice->u1_slice_type; + decoding_envirnoment_t *ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t *ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + ctxt_inc_mb_info_t *ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + WORD8 c_ctxt_inc; + bin_ctxt_model_t *ps_mb_bin_ctxt = ps_dec->p_mb_type_t; + WORD8 u1_mb_type = 0, u1_bin; + UWORD32 u4_cxt_inc; + + INC_SYM_COUNT(ps_cab_env); + + c_ctxt_inc = 0; + + if(uc_slice_type == SI_SLICE) + { + /* b0 */ + if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) + c_ctxt_inc += ((ps_left_ctxt->u1_mb_type != CAB_SI4x4) ? 1 : 0); + if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) + c_ctxt_inc += ((ps_top_ctxt->u1_mb_type != CAB_SI4x4) ? 1 : 0); + + u4_cxt_inc = c_ctxt_inc; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + if(u1_bin == 0) + { + /* SI MB */ + u1_mb_type = 0; + } + else + { + u1_mb_type = 1 + ih264d_parse_mb_type_intra_cabac(0, ps_dec); + } + } + else if(uc_slice_type == P_SLICE) + { + /* P Slice */ + /* b0 */ + u4_cxt_inc = 0; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + if(!u1_bin) + { + /* Inter MB types */ + /* b1 */ + u4_cxt_inc = 0x01; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + /* b2 */ + u4_cxt_inc = u1_bin + 2; + u1_mb_type = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + u1_mb_type = (u1_bin << 1) + u1_mb_type; + if(u1_mb_type) + u1_mb_type = 4 - u1_mb_type; + } + else + { + /* Intra Prefix 1 found */ + /* Intra MB type */ + u1_mb_type = 5 + ih264d_parse_mb_type_intra_cabac(1, ps_dec); + } + } + else if(uc_slice_type == B_SLICE) + { + WORD8 a, b; + /* B Slice */ + /* b0 */ + /* a = b = 0, if B slice and MB is a SKIP or B_DIRECT16x16 */ + a = 0; + b = 0; + u1_mb_type = 0; + if(ps_left_ctxt != ps_dec->ps_def_ctxt_mb_info) + a = ((ps_left_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16); + if(ps_top_ctxt != ps_dec->ps_def_ctxt_mb_info) + b = ((ps_top_ctxt->u1_mb_type & CAB_BD16x16_MASK) != CAB_BD16x16); + + u4_cxt_inc = a + b; + + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + + if(u1_bin) + { + + /* b1 */ + u4_cxt_inc = 0x03; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + + if(!u1_bin) + { + /* b2 */ + u4_cxt_inc = 0x05; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + + u1_mb_type = u1_bin + 1; + } + else + { + u1_mb_type = 3; + /* b2 */ + u4_cxt_inc = 0x04; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + + if(u1_bin) + { + u1_mb_type += 8; + /* b3 */ + u4_cxt_inc = 0x05; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, ps_mb_bin_ctxt, + ps_bitstrm, ps_cab_env); + + if(!u1_bin) + { + u1_mb_type++; + /* b4, b5, b6 */ + u4_cxt_inc = 0x0555; + u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, + ps_mb_bin_ctxt, + ps_bitstrm, + ps_cab_env); + + + + u1_mb_type += u1_bin; + } + else + { + /* b4 */ + u4_cxt_inc = 0x05; + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, + ps_mb_bin_ctxt, + ps_bitstrm, + ps_cab_env); + + if(u1_bin) + { + /* b5 */ + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, + ps_mb_bin_ctxt, + ps_bitstrm, + ps_cab_env); + + u1_mb_type += (u1_bin ? 11 : 0); + } + else + { + u1_mb_type = 20; + /* b5 */ + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, + ps_mb_bin_ctxt, + ps_bitstrm, + ps_cab_env); + + if(!u1_bin) + { + /* b6 */ + u1_bin = (UWORD8)ih264d_decode_bin(u4_cxt_inc, + ps_mb_bin_ctxt, + ps_bitstrm, + ps_cab_env); + + u1_mb_type += u1_bin; + } + else + { + /* Intra Prefix 111101 found */ + /* Intra MB type */ + u1_mb_type = + 23 + + ih264d_parse_mb_type_intra_cabac( + 1, + ps_dec); + } + } + } + } + else + { + /* b3, b4, b5 */ + u4_cxt_inc = 0x0555; + u1_bin = (UWORD8)ih264d_decode_bins(3, u4_cxt_inc, + ps_mb_bin_ctxt, ps_bitstrm, + ps_cab_env); + + + + + u1_mb_type += u1_bin; + } + } + } + } + return ((UWORD32)u1_mb_type); +} + +/*! + ************************************************************************** + * \if Function name : DecSubMBType \endif + * + * \brief + * This function decodes MB type using CABAC entropy coding mode. + * + * \return + * MBType. + * + ************************************************************************** + */ +UWORD32 ih264d_parse_submb_type_cabac(const UWORD8 u1_slc_type_b, + decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t * ps_bitstrm, + bin_ctxt_model_t * ps_sub_mb_cxt) +{ + WORD8 u1_sub_mb_type, u1_bin; + + INC_SYM_COUNT(ps_cab_env); + + u1_sub_mb_type = 0; + u1_bin = (UWORD8)ih264d_decode_bin(0, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + + if(u1_slc_type_b ^ u1_bin) + return 0; + + if(!u1_slc_type_b) + { + /* P Slice */ + u1_sub_mb_type = 1; + u1_bin = (UWORD8)ih264d_decode_bin(1, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + if(u1_bin == 1) + { + u1_bin = (UWORD8)ih264d_decode_bin(2, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + u1_sub_mb_type = (2 + (!u1_bin)); + } + + return u1_sub_mb_type; + } + else + { + /* B Slice */ + + /* b1 */ + u1_bin = (UWORD8)ih264d_decode_bin(1, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + if(u1_bin) + { + /* b2 */ + u1_bin = (UWORD8)ih264d_decode_bin(2, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + if(u1_bin) + { + /* b3 */ + u1_sub_mb_type = 7; + u1_bin = (UWORD8)ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + u1_sub_mb_type += u1_bin << 2; + u1_bin = !u1_bin; + /* b4 */ + if(u1_bin == 0) + { + u1_bin = ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + } + else + { + u1_bin = (UWORD8)ih264d_decode_bins(2, 0x33, ps_sub_mb_cxt, + ps_bitstrm, ps_cab_env); + } + + return (u1_sub_mb_type + u1_bin); + } + else + { + /* b3 */ + u1_bin = (UWORD8)ih264d_decode_bins(2, 0x33, ps_sub_mb_cxt, + ps_bitstrm, ps_cab_env); + return (3 + u1_bin); + } + } + else + { + /* b2 */ + u1_bin = (UWORD8)ih264d_decode_bin(3, ps_sub_mb_cxt, ps_bitstrm, + ps_cab_env); + return (1 + u1_bin); + } + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_ref_idx_cabac \endif + * + * \brief + * This function decodes Reference Index using CABAC entropy coding mode. + * + * \return + * None + * + ************************************************************************** + */ +WORD32 ih264d_parse_ref_idx_cabac(const UWORD8 u1_num_part, + const UWORD8 u1_b2, + const UWORD8 u1_max_ref_minus1, + const UWORD8 u1_mb_mode, + WORD8 * pi1_ref_idx, + WORD8 * const pi1_lft_cxt, + WORD8 * const pi1_top_cxt, + decoding_envirnoment_t * const ps_cab_env, + dec_bit_stream_t * const ps_bitstrm, + bin_ctxt_model_t * const ps_ref_cxt) +{ + UWORD8 u1_a, u1_b; + UWORD32 u4_cxt_inc; + UWORD8 u1_blk_no, u1_i, u1_idx_lft, u1_idx_top; + WORD8 i1_ref_idx; + + for(u1_blk_no = 0, u1_i = 0; u1_i < u1_num_part; u1_i++, pi1_ref_idx++) + { + u1_idx_lft = ((u1_blk_no & 0x02) >> 1) + u1_b2; + u1_idx_top = (u1_blk_no & 0x01) + u1_b2; + i1_ref_idx = *pi1_ref_idx; + + if(i1_ref_idx > 0) + { + u1_a = pi1_lft_cxt[u1_idx_lft] > 0; + u1_b = pi1_top_cxt[u1_idx_top] > 0; + + u4_cxt_inc = u1_a + (u1_b << 1); + u4_cxt_inc = (u4_cxt_inc | 0x55540); + + i1_ref_idx = (WORD8)ih264d_decode_bins_unary(32, u4_cxt_inc, + ps_ref_cxt, ps_bitstrm, + ps_cab_env); + + if((i1_ref_idx > u1_max_ref_minus1) || (i1_ref_idx < 0)) + { + return ERROR_REF_IDX; + } + + *pi1_ref_idx = i1_ref_idx; + + INC_SYM_COUNT(ps_cab_env); + + } + + /* Storing Reference Idx Information */ + pi1_lft_cxt[u1_idx_lft] = i1_ref_idx; + pi1_top_cxt[u1_idx_top] = i1_ref_idx; + u1_blk_no = u1_blk_no + 1 + (u1_mb_mode & 0x01); + } + /* if(!u1_sub_mb) */ + if(u1_num_part != 4) + { + pi1_lft_cxt[(!(u1_mb_mode & 0x1)) + u1_b2] = pi1_lft_cxt[u1_b2]; + pi1_top_cxt[(!(u1_mb_mode & 0x2)) + u1_b2] = pi1_top_cxt[u1_b2]; + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_mb_qp_delta_cabac \endif + * + * \brief + * This function decodes MB Qp delta using CABAC entropy coding mode. + * + * \return + * None + * + ************************************************************************** + */ +WORD32 ih264d_parse_mb_qp_delta_cabac(struct _DecStruct * ps_dec, + WORD8 *pi1_mb_qp_delta) +{ + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + + UWORD8 u1_code_num; + bin_ctxt_model_t *ps_mb_qp_delta_ctxt = ps_dec->p_mb_qp_delta_t; + UWORD32 u4_cxt_inc; + + INC_SYM_COUNT(ps_cab_env); + + u4_cxt_inc = (!(!(ps_dec->i1_prev_mb_qp_delta))); + + u1_code_num = 0; + u4_cxt_inc = (u4_cxt_inc | 0x33320); + /* max number of bins = 53, + since Range for MbQpDelta= -26 to +25 inclusive, UNARY code */ + u1_code_num = ih264d_decode_bins_unary(32, u4_cxt_inc, ps_mb_qp_delta_ctxt, + ps_bitstrm, ps_cab_env); + if(u1_code_num == 32) + { + /* Read remaining 21 bins */ + UWORD8 uc_codeNumX; + u4_cxt_inc = 0x33333; + uc_codeNumX = ih264d_decode_bins_unary(21, u4_cxt_inc, ps_mb_qp_delta_ctxt, + ps_bitstrm, ps_cab_env); + u1_code_num = u1_code_num + uc_codeNumX; + } + + *pi1_mb_qp_delta = (u1_code_num + 1) >> 1; + /* Table 9.3: If code_num is even Syntax Element has -ve value */ + if(!(u1_code_num & 0x01)) + *pi1_mb_qp_delta = -(*pi1_mb_qp_delta); + + /* Range of MbQpDelta= -26 to +25 inclusive */ + if((*pi1_mb_qp_delta < -26) || (*pi1_mb_qp_delta > 25)) + return ERROR_INV_RANGE_QP_T; + ps_dec->i1_prev_mb_qp_delta = *pi1_mb_qp_delta; + return OK; +} +/*! + ************************************************************************** + * \if Function name : ih264d_parse_chroma_pred_mode_cabac \endif + * + * \brief + * This function decodes Chroma Pred mode using CABAC entropy coding mode. + * + * \return + * None + * + ************************************************************************** + */ +WORD8 ih264d_parse_chroma_pred_mode_cabac(struct _DecStruct * ps_dec) +{ + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + WORD8 i1_chroma_pred_mode, a, b; + UWORD32 u4_cxt_inc; + + INC_SYM_COUNT(ps_cab_env); + + /* Binarization is TU and Cmax=3 */ + i1_chroma_pred_mode = 0; + a = 0; + b = 0; + + a = ((ps_left_ctxt->u1_intra_chroma_pred_mode != 0) ? 1 : 0); + + b = ((ps_top_ctxt->u1_intra_chroma_pred_mode != 0) ? 1 : 0); + u4_cxt_inc = a + b; + + u4_cxt_inc = (u4_cxt_inc | 0x330); + + i1_chroma_pred_mode = ih264d_decode_bins_tunary( + 3, u4_cxt_inc, ps_dec->p_intra_chroma_pred_mode_t, + ps_bitstrm, ps_cab_env); + + return (i1_chroma_pred_mode); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_transform8x8flag_cabac */ +/* */ +/* Description : */ +/* Inputs : */ +/* */ +/* */ +/* Returns : */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* Rajasekhar Creation */ +/* */ +/*****************************************************************************/ +UWORD8 ih264d_parse_transform8x8flag_cabac(struct _DecStruct * ps_dec, + dec_mb_info_t * ps_cur_mb_info) +{ + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + UWORD8 u1_transform_8x8flag; + UWORD8 u1_mb_ngbr_avail = ps_cur_mb_info->u1_mb_ngbr_availablity; + + WORD8 a, b; + UWORD32 u4_cxt_inc; + + /* for calculating the context increment for transform8x8 u4_flag */ + /* it reads transform8x8 u4_flag of the neighbors through */ + + /* Binarization is FLC */ + a = 0; + b = 0; + + if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) + { + a = ps_left_ctxt->u1_transform8x8_ctxt; + } + if(u1_mb_ngbr_avail & TOP_MB_AVAILABLE_MASK) + { + b = ps_top_ctxt->u1_transform8x8_ctxt; + + } + + u4_cxt_inc = a + b; + + u1_transform_8x8flag = ih264d_decode_bin( + u4_cxt_inc, ps_dec->s_high_profile.ps_transform8x8_flag, + ps_bitstrm, ps_cab_env); + + return (u1_transform_8x8flag); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_read_intra_pred_modes_cabac \endif + * + * \brief + * Reads the intra pred mode related values of I4x4 MB from bitstream. + * + * This function will read the prev intra pred mode flags and + * stores it in pu1_prev_intra4x4_pred_mode_flag. If the u4_flag + * indicates that most probable mode is not intra pred mode, then + * the rem_intra4x4_pred_mode is read and stored in + * pu1_rem_intra4x4_pred_mode array. + * + * + * \return + * 0 on success and Error code otherwise + * + ************************************************************************** + */ +WORD32 ih264d_read_intra_pred_modes_cabac(dec_struct_t * ps_dec, + UWORD8 * pu1_prev_intra4x4_pred_mode_flag, + UWORD8 * pu1_rem_intra4x4_pred_mode, + UWORD8 u1_tran_form8x8) +{ + WORD32 i4x4_luma_blk_idx = 0; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + bin_ctxt_model_t *ps_ctxt_ipred_luma_mpm, *ps_ctx_ipred_luma_rm; + WORD32 i4_rem_intra4x4_pred_mode; + UWORD32 u4_prev_intra4x4_pred_mode_flag; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + + ps_ctxt_ipred_luma_mpm = ps_dec->p_prev_intra4x4_pred_mode_flag_t; + ps_ctx_ipred_luma_rm = ps_dec->p_rem_intra4x4_pred_mode_t; + SWITCHOFFTRACE; + + i4x4_luma_blk_idx = (0 == u1_tran_form8x8) ? 16 : 4; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + do + { + + DECODE_ONE_BIN_MACRO(ps_ctxt_ipred_luma_mpm, u4_code_int_range, + u4_code_int_val_ofst, pu4_table, ps_bitstrm, + u4_prev_intra4x4_pred_mode_flag) + *pu1_prev_intra4x4_pred_mode_flag = u4_prev_intra4x4_pred_mode_flag; + + i4_rem_intra4x4_pred_mode = -1; + if(!u4_prev_intra4x4_pred_mode_flag) + { + + /*inlining DecodeDecisionBins_FLC*/ + + { + + UWORD8 u1_max_bins = 3; + UWORD32 u4_value; + UWORD32 u4_symbol, i; + + i = 0; + u4_value = 0; + + do + { + + DECODE_ONE_BIN_MACRO(ps_ctx_ipred_luma_rm, u4_code_int_range, + u4_code_int_val_ofst, pu4_table, + ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value = u4_value | (u4_symbol << i); + + i++; + } + while(i < u1_max_bins); + + i4_rem_intra4x4_pred_mode = (u4_value); + + } + + } + + (*pu1_rem_intra4x4_pred_mode) = i4_rem_intra4x4_pred_mode; + + COPYTHECONTEXT("intra4x4_pred_mode", i4_rem_intra4x4_pred_mode); + + pu1_prev_intra4x4_pred_mode_flag++; + pu1_rem_intra4x4_pred_mode++; + + i4x4_luma_blk_idx--; + } + while(i4x4_luma_blk_idx); + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + + return (0); + +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_ctx_cbp_cabac \endif + * + * \brief + * This function decodes CtxCbpLuma and CtxCbpChroma (CBP of a Macroblock). + * using CABAC entropy coding mode. + * + * \return + * CBP of a MB. + * + ************************************************************************** + */ +UWORD32 ih264d_parse_ctx_cbp_cabac(struct _DecStruct * ps_dec) +{ + + UWORD32 u4_cxt_inc; + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + ctxt_inc_mb_info_t * ps_left_ctxt = ps_dec->p_left_ctxt_mb_info; + ctxt_inc_mb_info_t * ps_top_ctxt = ps_dec->p_top_ctxt_mb_info; + bin_ctxt_model_t *ps_ctxt_cbp_luma = ps_dec->p_cbp_luma_t, *ps_bin_ctxt; + WORD8 c_Cbp; //,i,j; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + UWORD32 u4_offset, *pu4_buffer; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + + INC_SYM_COUNT(ps_cab_env); + + + + /* CBP Luma, FL, Cmax = 15, L = 4 */ + u4_cxt_inc = (!((ps_top_ctxt->u1_cbp >> 2) & 0x01)) << 1; + u4_cxt_inc += !((ps_left_ctxt->u1_cbp >> 1) & 0x01); + + u4_offset = ps_bitstrm->u4_ofst; + pu4_buffer = ps_bitstrm->pu4_buffer; + + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + /*renormalize to ensure there 23 bits more in the u4_code_int_val_ofst*/ + { + UWORD32 u4_clz, read_bits; + + u4_clz = CLZ(u4_code_int_range); + FLUSHBITS(u4_offset, u4_clz) + NEXTBITS(read_bits, u4_offset, pu4_buffer, 23) + u4_code_int_range = u4_code_int_range << u4_clz; + u4_code_int_val_ofst = (u4_code_int_val_ofst << u4_clz) | read_bits; + } + + ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; + + /*inlining DecodeDecision_onebin without renorm*/ + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u1_mps_state >> 6) & 0x1); + + /*if mps*/ + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, table_lookup) + + INC_BIN_COUNT(ps_cab_env); + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + + c_Cbp = u4_symbol; + + } + + u4_cxt_inc = (!((ps_top_ctxt->u1_cbp >> 3) & 0x01)) << 1; + u4_cxt_inc += !(c_Cbp & 0x01); + ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; + /*inlining DecodeDecision_onebin without renorm*/ + + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u1_mps_state >> 6) & 0x1); + + /*if mps*/ + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, table_lookup) + + INC_BIN_COUNT(ps_cab_env); + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + + c_Cbp |= u4_symbol << 1; + + } + + u4_cxt_inc = (!(c_Cbp & 0x01)) << 1; + u4_cxt_inc += !((ps_left_ctxt->u1_cbp >> 3) & 0x01); + ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; + /*inlining DecodeDecision_onebin without renorm*/ + + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u1_mps_state >> 6) & 0x1); + + /*if mps*/ + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, table_lookup) + + INC_BIN_COUNT(ps_cab_env); + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + + c_Cbp |= u4_symbol << 2; + + } + + u4_cxt_inc = (!((c_Cbp >> 1) & 0x01)) << 1; + u4_cxt_inc += !((c_Cbp >> 2) & 0x01); + ps_bin_ctxt = ps_ctxt_cbp_luma + u4_cxt_inc; + /*inlining DecodeDecision_onebin without renorm*/ + + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + UWORD32 u4_symbol, u1_mps_state; + UWORD32 table_lookup; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u1_mps_state >> 6) & 0x1); + + /*if mps*/ + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, u4_symbol, + u4_int_range_lps, u1_mps_state, table_lookup) + + INC_BIN_COUNT(ps_cab_env); + + ps_bin_ctxt->u1_mps_state = u1_mps_state; + + c_Cbp |= u4_symbol << 3; + + } + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) + { + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, u4_offset, + pu4_buffer) + + } + + { + UWORD32 u4_cxt_inc; + WORD8 a, b, c, d; + bin_ctxt_model_t *p_CtxtCbpChroma = ps_dec->p_cbp_chroma_t; + + /* CBP Chroma, TU, Cmax = 2 */ + a = 0; + b = 0; + c = 0; + d = 0; + + { + a = (ps_top_ctxt->u1_cbp > 15) ? 2 : 0; + c = (ps_top_ctxt->u1_cbp > 31) ? 2 : 0; + } + + { + b = (ps_left_ctxt->u1_cbp > 15) ? 1 : 0; + d = (ps_left_ctxt->u1_cbp > 31) ? 1 : 0; + } + u4_cxt_inc = a + b; + u4_cxt_inc = (u4_cxt_inc | ((4 + c + d) << 4)); + + /*inlining ih264d_decode_bins_tunary */ + + { + + UWORD8 u1_max_bins = 2; + UWORD32 u4_ctx_inc = u4_cxt_inc; + + UWORD32 u4_value; + UWORD32 u4_symbol; + UWORD8 u4_ctx_Inc; + bin_ctxt_model_t *ps_bin_ctxt; + u4_value = 0; + + do + { + u4_ctx_Inc = u4_ctx_inc & 0xF; + u4_ctx_inc = u4_ctx_inc >> 4; + + ps_bin_ctxt = p_CtxtCbpChroma + u4_ctx_Inc; + /*inlining DecodeDecision_onebin*/ + { + + UWORD32 u4_qnt_int_range, u4_int_range_lps; + + UWORD32 u1_mps_state; + UWORD32 table_lookup; + UWORD32 u4_clz; + + u1_mps_state = (ps_bin_ctxt->u1_mps_state); + + u4_clz = CLZ(u4_code_int_range); + u4_qnt_int_range = u4_code_int_range << u4_clz; + u4_qnt_int_range = (u4_qnt_int_range >> 29) & 0x3; + + table_lookup = pu4_table[(u1_mps_state << 2) + + u4_qnt_int_range]; + u4_int_range_lps = table_lookup & 0xff; + + u4_int_range_lps = u4_int_range_lps << (23 - u4_clz); + u4_code_int_range = u4_code_int_range - u4_int_range_lps; + + u4_symbol = ((u1_mps_state >> 6) & 0x1); + + /*if mps*/ + u1_mps_state = (table_lookup >> 8) & 0x7F; + + CHECK_IF_LPS(u4_code_int_range, u4_code_int_val_ofst, + u4_symbol, u4_int_range_lps, u1_mps_state, + table_lookup) + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_8) + { + RENORM_RANGE_OFFSET(u4_code_int_range, + u4_code_int_val_ofst, u4_offset, + pu4_buffer) + } + ps_bin_ctxt->u1_mps_state = u1_mps_state; + } + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS( + ps_cab_env); + + u4_value++; + } + while((u4_value < u1_max_bins) & (u4_symbol)); + + u4_value = u4_value - 1 + u4_symbol; + + a = (u4_value); + + } + +c_Cbp = (c_Cbp | (a << 4)); +} + +ps_bitstrm->u4_ofst = u4_offset; + +ps_cab_env->u4_code_int_range = u4_code_int_range; +ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + +return (c_Cbp); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_get_mvd_cabac \endif + * + * \brief + * This function decodes Horz and Vert mvd_l0 and mvd_l1 using CABAC entropy + * coding mode as defined in 9.3.2.3. + * + * \return + * None + * + ************************************************************************** + */ +void ih264d_get_mvd_cabac(UWORD8 u1_sub_mb, + UWORD8 u1_b2, + UWORD8 u1_part_wd, + UWORD8 u1_part_ht, + UWORD8 u1_dec_mvd, + dec_struct_t *ps_dec, + mv_pred_t *ps_mv) +{ + UWORD8 u1_abs_mvd_x = 0, u1_abs_mvd_y = 0; + UWORD8 u1_sub_mb_x, u1_sub_mb_y; + UWORD8 *pu1_top_mv_ctxt, *pu1_lft_mv_ctxt; + WORD16 *pi2_mv; + + u1_sub_mb_x = (UWORD8)(u1_sub_mb & 0x03); + u1_sub_mb_y = (UWORD8)(u1_sub_mb >> 2); + pu1_top_mv_ctxt = &ps_dec->ps_curr_ctxt_mb_info->u1_mv[u1_sub_mb_x][u1_b2]; + pu1_lft_mv_ctxt = &ps_dec->pu1_left_mv_ctxt_inc[u1_sub_mb_y][u1_b2]; + pi2_mv = &ps_mv->i2_mv[u1_b2]; + + if(u1_dec_mvd) + { + WORD16 i2_mv_x, i2_mv_y; + WORD32 i2_temp; + { + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + UWORD16 u2_abs_mvd_x_a, u2_abs_mvd_x_b, u2_abs_mvd_y_a, + u2_abs_mvd_y_b; + + u2_abs_mvd_x_b = (UWORD16)pu1_top_mv_ctxt[0]; + u2_abs_mvd_y_b = (UWORD16)pu1_top_mv_ctxt[1]; + u2_abs_mvd_x_a = (UWORD16)pu1_lft_mv_ctxt[0]; + u2_abs_mvd_y_a = (UWORD16)pu1_lft_mv_ctxt[1]; + + i2_temp = u2_abs_mvd_x_a + u2_abs_mvd_x_b; + + i2_mv_x = ih264d_parse_mvd_cabac(ps_bitstrm, ps_cab_env, + ps_dec->p_mvd_x_t, i2_temp); + + i2_temp = u2_abs_mvd_y_a + u2_abs_mvd_y_b; + + i2_mv_y = ih264d_parse_mvd_cabac(ps_bitstrm, ps_cab_env, + ps_dec->p_mvd_y_t, i2_temp); + } + + /***********************************************************************/ + /* Store the abs_mvd_values in cabac contexts */ + /* The follownig code can be easily optimzed if mvX, mvY clip values */ + /* are packed in 16 bits follwed by memcpy */ + /***********************************************************************/ + u1_abs_mvd_x = CLIP3(0, 127, ABS(i2_mv_x)); + u1_abs_mvd_y = CLIP3(0, 127, ABS(i2_mv_y)); + + COPYTHECONTEXT("MVD", i2_mv_x);COPYTHECONTEXT("MVD", i2_mv_y); + + /* Storing Mv residuals */ + pi2_mv[0] = i2_mv_x; + pi2_mv[1] = i2_mv_y; + } + + /***************************************************************/ + /* Store abs_mvd_values cabac contexts */ + /***************************************************************/ +#ifndef ARM + { + UWORD8 u1_i; + for(u1_i = 0; u1_i < u1_part_wd; u1_i++, pu1_top_mv_ctxt += 4) + { + pu1_top_mv_ctxt[0] = u1_abs_mvd_x; + pu1_top_mv_ctxt[1] = u1_abs_mvd_y; + } + + for(u1_i = 0; u1_i < u1_part_ht; u1_i++, pu1_lft_mv_ctxt += 4) + { + pu1_lft_mv_ctxt[0] = u1_abs_mvd_x; + pu1_lft_mv_ctxt[1] = u1_abs_mvd_y; + } + } +#else + /* Optimising the loop, with Little-Endian Assumption */ + { + UWORD16 *pu2_top_cxt = (UWORD16 *)pu1_top_mv_ctxt; + UWORD16 *pu2_lft_cxt = (UWORD16 *)pu1_lft_mv_ctxt; + UWORD16 u2_pack_mvd = (UWORD16)((u1_abs_mvd_y << 8) | u1_abs_mvd_x); + UWORD8 u1_wd = u1_part_wd, u1_ht = u1_part_ht; + + u1_wd--; + *pu2_top_cxt = u2_pack_mvd; + pu2_top_cxt += 2; + if(u1_wd) + { + u1_wd--; + *pu2_top_cxt = u2_pack_mvd; + pu2_top_cxt += 2; + } + if(u1_wd) + { + *pu2_top_cxt = u2_pack_mvd; + pu2_top_cxt += 2; + *pu2_top_cxt = u2_pack_mvd; + } + u1_ht--; + *pu2_lft_cxt = u2_pack_mvd; + pu2_lft_cxt += 2; + if(u1_ht) + { + u1_ht--; + *pu2_lft_cxt = u2_pack_mvd; + pu2_lft_cxt += 2; + } + if(u1_ht) + { + *pu2_lft_cxt = u2_pack_mvd; + pu2_lft_cxt += 2; + *pu2_lft_cxt = u2_pack_mvd; + } + } +#endif +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_mvd_cabac */ +/* */ +/* Description : This cabac function decodes the mvd in a given direction */ +/* direction ( x or y ) as defined in 9.3.2.3. */ +/* */ +/* Inputs : 1. pointer to Bitstream */ +/* 2. pointer to cabac decoding environmnet */ +/* 3. pointer to Mvd context */ +/* 4. abs(Top mvd) = u2_abs_mvd_b */ +/* 5. abs(left mvd)= u2_abs_mvd_a */ +/* */ +/* Processing : see section 9.3.2.3 of the standard */ +/* */ +/* Outputs : i2_mvd */ +/* Returns : i2_mvd */ +/* */ +/* Issues : none */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 16 06 2005 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD16 ih264d_parse_mvd_cabac(dec_bit_stream_t * ps_bitstrm, + decoding_envirnoment_t * ps_cab_env, + bin_ctxt_model_t * p_ctxt_mvd, + UWORD32 i4_temp) + +{ + WORD8 k; + WORD16 i2_suf; + WORD16 i2_mvd; + UWORD16 u2_abs_mvd; + UWORD32 u4_ctx_inc; + UWORD32 u4_prefix; + const UWORD32 *pu4_table = (const UWORD32 *)ps_cab_env->cabac_table; + UWORD32 u4_code_int_range, u4_code_int_val_ofst; + + /* if mvd < 9 */ + /* mvd = Prefix */ + /* else */ + /* mvd = Prefix + Suffix */ + /* decode sign bit */ + /* Prefix TU decoding Cmax =Ucoff and Suffix 3rd order Exp-Golomb */ + + u2_abs_mvd = (UWORD16)i4_temp; + u4_ctx_inc = 1; + + if(u2_abs_mvd < 3) + u4_ctx_inc = 0; + else if(u2_abs_mvd > 32) + u4_ctx_inc = 2; + + u4_ctx_inc = (u4_ctx_inc | 0x65430); + + /*inlining modified version of ih264d_decode_bins_unary*/ + + { + UWORD8 u1_max_bins = 9; + UWORD32 u4_value; + UWORD32 u4_symbol; + bin_ctxt_model_t *ps_bin_ctxt; + UWORD32 u4_ctx_Inc; + + u4_value = 0; + u4_code_int_range = ps_cab_env->u4_code_int_range; + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + + do + { + u4_ctx_Inc = u4_ctx_inc & 0xf; + u4_ctx_inc = u4_ctx_inc >> 4; + + ps_bin_ctxt = p_ctxt_mvd + u4_ctx_Inc; + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, + u4_code_int_val_ofst, pu4_table, ps_bitstrm, + u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + + u4_value++; + + } + while(u4_symbol && u4_value < 5); + + ps_bin_ctxt = p_ctxt_mvd + 6; + + if(u4_symbol && (u4_value < u1_max_bins)) + { + + do + { + + DECODE_ONE_BIN_MACRO(ps_bin_ctxt, u4_code_int_range, + u4_code_int_val_ofst, pu4_table, + ps_bitstrm, u4_symbol) + + INC_BIN_COUNT(ps_cab_env);INC_DECISION_BINS(ps_cab_env); + u4_value++; + } + while(u4_symbol && (u4_value < u1_max_bins)); + + } + + ps_cab_env->u4_code_int_range = u4_code_int_range; + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + u4_value = u4_value - 1 + u4_symbol; + u4_prefix = (u4_value); + } + + i2_mvd = u4_prefix; + + if(i2_mvd == 9) + { + /* Read Suffix */ + k = ih264d_decode_bypass_bins_unary(ps_cab_env, ps_bitstrm); + i2_suf = (1 << k) - 1; + k = k + 3; + i2_suf = (i2_suf << 3); + i2_mvd += i2_suf; + i2_suf = ih264d_decode_bypass_bins(ps_cab_env, k, ps_bitstrm); + i2_mvd += i2_suf; + } + /* Read Sign bit */ + if(!i2_mvd) + return (i2_mvd); + + else + { + UWORD32 u4_code_int_val_ofst, u4_code_int_range; + + u4_code_int_val_ofst = ps_cab_env->u4_code_int_val_ofst; + u4_code_int_range = ps_cab_env->u4_code_int_range; + + if(u4_code_int_range < ONE_RIGHT_SHIFTED_BY_9) + { + UWORD32 *pu4_buffer, u4_offset; + + pu4_buffer = ps_bitstrm->pu4_buffer; + u4_offset = ps_bitstrm->u4_ofst; + + RENORM_RANGE_OFFSET(u4_code_int_range, u4_code_int_val_ofst, + u4_offset, pu4_buffer) + ps_bitstrm->u4_ofst = u4_offset; + } + + u4_code_int_range = u4_code_int_range >> 1; + + if(u4_code_int_val_ofst >= u4_code_int_range) + { + /* S=1 */ + u4_code_int_val_ofst -= u4_code_int_range; + i2_mvd = (-i2_mvd); + } + + ps_cab_env->u4_code_int_val_ofst = u4_code_int_val_ofst; + ps_cab_env->u4_code_int_range = u4_code_int_range; + + return (i2_mvd); + + } +} diff --git a/decoder/ih264d_parse_mb_header.h b/decoder/ih264d_parse_mb_header.h new file mode 100755 index 0000000..63067b9 --- /dev/null +++ b/decoder/ih264d_parse_mb_header.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_mb_header.h + * + * \brief + * This file contains context identifier decoding routines. + * + * \date + * 04/02/2003 + * + * \author NS + *************************************************************************** + */ +#ifndef _IH264D_PARSE_MB_HEADER_H_ +#define _IH264D_PARSE_MB_HEADER_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_cabac.h" + +WORD32 ih264d_read_intra_pred_modes_cabac(dec_struct_t * ps_dec, + UWORD8 * pu1_prev_intra4x4_pred_mode_flag, + UWORD8 * pu1_rem_intra4x4_pred_mode, + UWORD8 u1_tran_form8x8); + +UWORD32 ih264d_parse_mb_type_cabac(struct _DecStruct * ps_dec); +UWORD8 ih264d_parse_mb_type_intra_cabac(UWORD8 u1_inter, + struct _DecStruct * ps_dec); + +UWORD32 ih264d_parse_submb_type_cabac(const UWORD8 u1_slc_type_p, + decoding_envirnoment_t * ps_cab_env, + dec_bit_stream_t * ps_bitstrm, + bin_ctxt_model_t * ps_sub_mb_cxt); +WORD32 ih264d_parse_ref_idx_cabac(const UWORD8 u1_num_part, + const UWORD8 u1_b2, + const UWORD8 u1_max_ref_minus1, + const UWORD8 u1_mb_mode, + WORD8 * pi1_ref_idx, + WORD8 * const pi1_lft_cxt, + WORD8 * const pi1_top_cxt, + decoding_envirnoment_t * const ps_cab_env, + dec_bit_stream_t * const ps_bitstrm, + bin_ctxt_model_t * const ps_ref_cxt); + +WORD32 ih264d_parse_mb_qp_delta_cabac(struct _DecStruct * ps_dec, + WORD8 *pi1_mb_qp_delta); +WORD8 ih264d_parse_chroma_pred_mode_cabac(struct _DecStruct * ps_dec); + +UWORD32 ih264d_parse_ctx_cbp_cabac(struct _DecStruct * ps_dec); + +UWORD8 ih264d_parse_transform8x8flag_cabac(struct _DecStruct * ps_dec, + dec_mb_info_t * ps_cur_mb_info); + +void ih264d_get_mvd_cabac(UWORD8 u1_sub_mb, + UWORD8 u1_b2, + UWORD8 u1_part_wd, + UWORD8 u1_part_ht, + UWORD8 u1_dec_mvd, + dec_struct_t *ps_dec, + mv_pred_t *ps_mv); + +WORD16 ih264d_parse_mvd_cabac(dec_bit_stream_t * ps_bitstrm, + decoding_envirnoment_t * ps_cab_env, + bin_ctxt_model_t * p_ctxt_mvd, + UWORD32 temp); + +#endif /* _IH264D_PARSE_MB_HEADER_H_ */ diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c new file mode 100755 index 0000000..67d1405 --- /dev/null +++ b/decoder/ih264d_parse_pslice.c @@ -0,0 +1,1760 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_pslice.c + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ + +#include <string.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_parse_slice.h" +#include "ih264d_mvpred.h" +#include "ih264d_parse_islice.h" +#include "ih264d_process_intra_mb.h" +#include "ih264d_inter_pred.h" +#include "ih264d_process_pslice.h" +#include "ih264d_deblocking.h" +#include "ih264d_cabac.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_error_handler.h" +#include "ih264d_defs.h" +#include "ih264d_format_conv.h" +#include "ih264d_quant_scaling.h" +#include "ih264d_thread_parse_decode.h" +#include "ih264d_process_bslice.h" +#include "ithread.h" +#include "ih264d_utils.h" +#include "ih264d_format_conv.h" + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec); +void ih264d_deblock_mb_level(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index); + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_pmb_cavlc \endif + * + * \brief + * This function parses CAVLC syntax of a P MB. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_pmb_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + UWORD32 u1_num_mb_part; + UWORD32 uc_sub_mb; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 * const pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + + parse_pmbarams_t * ps_parse_mb_data = ps_dec->ps_parse_mb_data + + u1_num_mbsNby2; + WORD8 * pi1_ref_idx = ps_parse_mb_data->i1_ref_idx[0]; + const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + const UWORD8 * pu1_num_mb_part = (const UWORD8 *)gau1_ih264d_num_mb_part; + UWORD8 * pu1_col_info = ps_parse_mb_data->u1_col_info; + + UWORD32 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD32 u4_sum_mb_mode_pack = 0; + WORD32 ret; + + UWORD8 u1_no_submb_part_size_lt8x8_flag = 1; + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + ps_cur_mb_info->u1_mb_mc_mode = u1_mb_type; + uc_sub_mb = ((u1_mb_type == PRED_8x8) | (u1_mb_type == PRED_8x8R0)); + + /* Reading the subMB type */ + if(uc_sub_mb) + { + WORD32 i; + UWORD8 u1_colz = (PRED_8x8 << 6); + + for(i = 0; i < 4; i++) + { + UWORD32 ui_sub_mb_mode; + + //Inlined ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + ui_sub_mb_mode = ((1 << u4_ldz) + u4_word - 1); + //Inlined ih264d_uev + + if(ui_sub_mb_mode > 3) + { + return ERROR_SUB_MB_TYPE; + } + else + { + u4_sum_mb_mode_pack = (u4_sum_mb_mode_pack << 8) | ui_sub_mb_mode; + /* Storing collocated information */ + *pu1_col_info++ = u1_colz | (UWORD8)(ui_sub_mb_mode << 4); + + COPYTHECONTEXT("sub_mb_type", ui_sub_mb_mode); + } + + /* check if Motion compensation is done below 8x8 */ + if(ui_sub_mb_mode != P_L0_8x8) + { + u1_no_submb_part_size_lt8x8_flag = 0; + } + } + + // + u1_num_mb_part = 4; + } + else + { + *pu1_col_info++ = (u1_mb_type << 6); + if(u1_mb_type) + *pu1_col_info++ = (u1_mb_type << 6); + u1_num_mb_part = pu1_num_mb_part[u1_mb_type]; + + } + + /* Decoding reference index 0: For simple profile the following */ + /* conditions are always true (mb_field_decoding_flag == 0); */ + /* (MbPartPredMode != PredL1) */ + + { + + UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 uc_num_ref_idx_l0_active_minus1 = + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] + << (u1_mbaff & uc_field)) - 1; + + if((uc_num_ref_idx_l0_active_minus1 > 0) & (u1_mb_type != PRED_8x8R0)) + { + if(1 == uc_num_ref_idx_l0_active_minus1) + ih264d_parse_pmb_ref_index_cavlc_range1( + u1_num_mb_part, ps_bitstrm, pi1_ref_idx, + uc_num_ref_idx_l0_active_minus1); + else + { + ret = ih264d_parse_pmb_ref_index_cavlc( + u1_num_mb_part, ps_bitstrm, pi1_ref_idx, + uc_num_ref_idx_l0_active_minus1); + if(ret != OK) + return ret; + } + } + else + { + /* When there exists only a single frame to predict from */ + UWORD8 uc_i; + for(uc_i = 0; uc_i < u1_num_mb_part; uc_i++) + /* Storing Reference Idx Information */ + pi1_ref_idx[uc_i] = 0; + } + } + + { + UWORD8 u1_p_idx, uc_i; + parse_part_params_t * ps_part = ps_dec->ps_part; + UWORD8 u1_sub_mb_mode, u1_num_subpart, u1_mb_part_width, u1_mb_part_height; + UWORD8 u1_sub_mb_num; + const UWORD8 * pu1_top_left_sub_mb_indx; + mv_pred_t * ps_mv, *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4); + /* Loading the table pointers */ + const UWORD8 * pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + const UWORD8 * pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + const UWORD8 * pu1_sub_mb_indx_mod = + (const UWORD8 *)(gau1_ih264d_submb_indx_mod) + + (uc_sub_mb * 6); + const UWORD8 * pu1_sub_mb_partw = (const UWORD8 *)gau1_ih264d_submb_partw; + const UWORD8 * pu1_sub_mb_parth = (const UWORD8 *)gau1_ih264d_submb_parth; + const UWORD8 * pu1_num_sub_mb_part = + (const UWORD8 *)gau1_ih264d_num_submb_part; + + UWORD16 u2_sub_mb_num = 0x028A; + + /*********************************************************/ + /* default initialisations for condition (uc_sub_mb == 0) */ + /* i.e. all are subpartitions of 8x8 */ + /*********************************************************/ + u1_sub_mb_mode = 0; + u1_num_subpart = 1; + u1_mb_part_width = pu1_mb_partw[u1_mb_type]; + u1_mb_part_height = pu1_mb_parth[u1_mb_type]; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_type << 1); + u1_sub_mb_num = 0; + + /* Loop on number of partitions */ + for(uc_i = 0, u1_p_idx = 0; uc_i < u1_num_mb_part; uc_i++) + { + UWORD8 uc_j; + if(uc_sub_mb) + { + u1_sub_mb_mode = u4_sum_mb_mode_pack >> 24; + u1_num_subpart = pu1_num_sub_mb_part[u1_sub_mb_mode]; + u1_mb_part_width = pu1_sub_mb_partw[u1_sub_mb_mode]; + u1_mb_part_height = pu1_sub_mb_parth[u1_sub_mb_mode]; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_sub_mb_mode << 1); + u1_sub_mb_num = u2_sub_mb_num >> 12; + u4_sum_mb_mode_pack <<= 8; + u2_sub_mb_num <<= 4; + } + + /* Loop on Number of sub-partitions */ + for(uc_j = 0; uc_j < u1_num_subpart; uc_j++, pu1_top_left_sub_mb_indx++) + { + WORD16 i2_mvx, i2_mvy; + u1_sub_mb_num += *pu1_top_left_sub_mb_indx; + ps_mv = ps_mv_start + u1_sub_mb_num; + + /* Reading the differential Mv from the bitstream */ + //i2_mvx = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + //inlining ih264d_sev + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, + pu4_bitstrm_buf, u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i2_mvx = (-(WORD32)u4_abs_val); + else + i2_mvx = (u4_abs_val); + } + //inlinined ih264d_sev + COPYTHECONTEXT("MVD", i2_mvx); + i2_mvy = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("MVD", i2_mvy); + + /* Storing Info for partitions */ + ps_part->u1_is_direct = PART_NOT_DIRECT; + ps_part->u1_sub_mb_num = u1_sub_mb_num; + ps_part->u1_partheight = u1_mb_part_height; + ps_part->u1_partwidth = u1_mb_part_width; + + /* Storing Mv residuals */ + ps_mv->i2_mv[0] = i2_mvx; + ps_mv->i2_mv[1] = i2_mvy; + + /* Increment partition Index */ + u1_p_idx++; + ps_part++; + } + } + ps_parse_mb_data->u1_num_part = u1_p_idx; + ps_dec->ps_part = ps_part; + } + + { + UWORD32 u4_cbp; + + /* Read the Coded block pattern */ + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_cbp = ((1 << u4_ldz) + u4_word - 1); + + if(u4_cbp > 47) + return ERROR_CBP; + + u4_cbp = *((UWORD8*)gau1_ih264d_cbp_inter + u4_cbp); + COPYTHECONTEXT("coded_block_pattern", u4_cbp); + ps_cur_mb_info->u1_cbp = u4_cbp; + + /* Read the transform8x8 u4_flag if present */ + if((ps_dec->s_high_profile.u1_transform8x8_present) && (u4_cbp & 0xf) + && u1_no_submb_part_size_lt8x8_flag) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + } + + /* Read mb_qp_delta */ + if(u4_cbp) + { + WORD32 i_temp; + + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_abs_val; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_abs_val = ((1 << u4_ldz) + u4_word) >> 1; + + if(u4_word & 0x1) + i_temp = (-(WORD32)u4_abs_val); + else + i_temp = (u4_abs_val); + + if((i_temp < -26) || (i_temp > 25)) + return ERROR_INV_RANGE_QP_T; + //inlinined ih264d_sev + + COPYTHECONTEXT("mb_qp_delta", i_temp); + if(i_temp) + { + ret = ih264d_update_qp(ps_dec, (WORD8)i_temp); + if(ret != OK) + return ret; + } + + ret = ih264d_parse_residual4x4_cavlc(ps_dec, ps_cur_mb_info, 0); + if(ret != OK) + return ret; + if(EXCEED_OFFSET(ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + } + else + { + ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CAVLC); + } + + + + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_pmb_cabac \endif + * + * \brief + * This function parses CABAC syntax of a P MB. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_pmb_cabac(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2) +{ + UWORD32 u1_num_mb_part; + UWORD32 uc_sub_mb; + parse_pmbarams_t * ps_parse_mb_data = ps_dec->ps_parse_mb_data + + u1_num_mbsNby2; + WORD8 * pi1_ref_idx = ps_parse_mb_data->i1_ref_idx[0]; + const UWORD8 * pu1_num_mb_part = (const UWORD8 *)gau1_ih264d_num_mb_part; + const UWORD32 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD8 * pu1_col_info = ps_parse_mb_data->u1_col_info; + UWORD32 u1_mb_mc_mode = u1_mb_type; + ctxt_inc_mb_info_t * p_curr_ctxt = ps_dec->ps_curr_ctxt_mb_info; + decoding_envirnoment_t * ps_cab_env = &ps_dec->s_cab_dec_env; + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 u4_sub_mb_pack = 0; + WORD32 ret; + + UWORD8 u1_no_submb_part_size_lt8x8_flag = 1; + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + ps_cur_mb_info->u1_yuv_dc_block_flag = 0; + + p_curr_ctxt->u1_mb_type = CAB_P; + ps_cur_mb_info->u1_mb_mc_mode = u1_mb_type; + uc_sub_mb = ((u1_mb_type == PRED_8x8) | (u1_mb_type == PRED_8x8R0)); + + /* Reading the subMB type */ + if(uc_sub_mb) + { + + UWORD8 u1_colz = (PRED_8x8 << 6); + u1_mb_mc_mode = 0; + + { + UWORD8 u1_sub_mb_mode; + u1_sub_mb_mode = ih264d_parse_submb_type_cabac( + 0, ps_cab_env, ps_bitstrm, + ps_dec->p_sub_mb_type_t); + if(u1_sub_mb_mode > 3) + return ERROR_SUB_MB_TYPE; + + u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode; + /* Storing collocated information */ + *pu1_col_info++ = u1_colz | ((UWORD8)(u1_sub_mb_mode << 4)); + COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode); + /* check if Motion compensation is done below 8x8 */ + if(u1_sub_mb_mode != P_L0_8x8) + { + u1_no_submb_part_size_lt8x8_flag = 0; + } + } + { + UWORD8 u1_sub_mb_mode; + u1_sub_mb_mode = ih264d_parse_submb_type_cabac( + 0, ps_cab_env, ps_bitstrm, + ps_dec->p_sub_mb_type_t); + if(u1_sub_mb_mode > 3) + return ERROR_SUB_MB_TYPE; + + u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode; + /* Storing collocated information */ + *pu1_col_info++ = u1_colz | ((UWORD8)(u1_sub_mb_mode << 4)); + COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode); + /* check if Motion compensation is done below 8x8 */ + if(u1_sub_mb_mode != P_L0_8x8) + { + u1_no_submb_part_size_lt8x8_flag = 0; + } + } + { + UWORD8 u1_sub_mb_mode; + u1_sub_mb_mode = ih264d_parse_submb_type_cabac( + 0, ps_cab_env, ps_bitstrm, + ps_dec->p_sub_mb_type_t); + if(u1_sub_mb_mode > 3) + return ERROR_SUB_MB_TYPE; + + u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode; + /* Storing collocated information */ + *pu1_col_info++ = u1_colz | ((UWORD8)(u1_sub_mb_mode << 4)); + COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode); + /* check if Motion compensation is done below 8x8 */ + if(u1_sub_mb_mode != P_L0_8x8) + { + u1_no_submb_part_size_lt8x8_flag = 0; + } + } + { + UWORD8 u1_sub_mb_mode; + u1_sub_mb_mode = ih264d_parse_submb_type_cabac( + 0, ps_cab_env, ps_bitstrm, + ps_dec->p_sub_mb_type_t); + if(u1_sub_mb_mode > 3) + return ERROR_SUB_MB_TYPE; + + u4_sub_mb_pack = (u4_sub_mb_pack << 8) | u1_sub_mb_mode; + /* Storing collocated information */ + *pu1_col_info++ = u1_colz | ((UWORD8)(u1_sub_mb_mode << 4)); + COPYTHECONTEXT("sub_mb_type", u1_sub_mb_mode); + /* check if Motion compensation is done below 8x8 */ + if(u1_sub_mb_mode != P_L0_8x8) + { + u1_no_submb_part_size_lt8x8_flag = 0; + } + } + u1_num_mb_part = 4; + } + else + { + u1_num_mb_part = pu1_num_mb_part[u1_mb_type]; + /* Storing collocated Mb and SubMb mode information */ + *pu1_col_info++ = (u1_mb_type << 6); + if(u1_mb_type) + *pu1_col_info++ = (u1_mb_type << 6); + } + /* Decoding reference index 0: For simple profile the following */ + /* conditions are always true (mb_field_decoding_flag == 0); */ + /* (MbPartPredMode != PredL1) */ + { + WORD8 * pi1_top_ref_idx_ctx_inc_arr = p_curr_ctxt->i1_ref_idx; + WORD8 * pi1_left_ref_idx_ctxt_inc = ps_dec->pi1_left_ref_idx_ctxt_inc; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD8 uc_field = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 uc_num_ref_idx_l0_active_minus1 = + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] + << (u1_mbaff & uc_field)) - 1; + + if((uc_num_ref_idx_l0_active_minus1 > 0) & (u1_mb_type != PRED_8x8R0)) + { + /* force the routine to decode ref idx for each partition */ + *((UWORD32 *)pi1_ref_idx) = 0x01010101; + ret = ih264d_parse_ref_idx_cabac(u1_num_mb_part, 0, + uc_num_ref_idx_l0_active_minus1, + u1_mb_mc_mode, pi1_ref_idx, + pi1_left_ref_idx_ctxt_inc, + pi1_top_ref_idx_ctx_inc_arr, ps_cab_env, + ps_bitstrm, ps_dec->p_ref_idx_t); + if(ret != OK) + return ret; + } + else + { + /* When there exists only a single frame to predict from */ + pi1_left_ref_idx_ctxt_inc[0] = 0; + pi1_left_ref_idx_ctxt_inc[1] = 0; + pi1_top_ref_idx_ctx_inc_arr[0] = 0; + pi1_top_ref_idx_ctx_inc_arr[1] = 0; + *((UWORD32 *)pi1_ref_idx) = 0; + } + } + + { + UWORD8 u1_p_idx, uc_i; + parse_part_params_t * ps_part = ps_dec->ps_part; + UWORD8 u1_sub_mb_mode, u1_num_subpart, u1_mb_part_width, u1_mb_part_height; + UWORD8 u1_sub_mb_num; + const UWORD8 * pu1_top_left_sub_mb_indx; + mv_pred_t *ps_mv_start = ps_dec->ps_mv_cur + (u1_mb_num << 4); + UWORD16 u2_sub_mb_num_pack = 0x028A; + + /* Loading the table pointers */ + const UWORD8 * pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + const UWORD8 * pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + const UWORD8 * pu1_sub_mb_indx_mod = + (const UWORD8 *)(gau1_ih264d_submb_indx_mod) + + (uc_sub_mb * 6); + const UWORD8 * pu1_sub_mb_partw = (const UWORD8 *)gau1_ih264d_submb_partw; + const UWORD8 * pu1_sub_mb_parth = (const UWORD8 *)gau1_ih264d_submb_parth; + const UWORD8 * pu1_num_sub_mb_part = + (const UWORD8 *)gau1_ih264d_num_submb_part; + + /*********************************************************/ + /* default initialisations for condition (uc_sub_mb == 0) */ + /* i.e. all are subpartitions of 8x8 */ + /*********************************************************/ + u1_sub_mb_mode = 0; + u1_num_subpart = 1; + u1_mb_part_width = pu1_mb_partw[u1_mb_type]; + u1_mb_part_height = pu1_mb_parth[u1_mb_type]; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_mb_type << 1); + u1_sub_mb_num = 0; + + /* Loop on number of partitions */ + for(uc_i = 0, u1_p_idx = 0; uc_i < u1_num_mb_part; uc_i++) + { + UWORD8 uc_j; + if(uc_sub_mb) + { + u1_sub_mb_mode = u4_sub_mb_pack >> 24; + u1_num_subpart = pu1_num_sub_mb_part[u1_sub_mb_mode]; + u1_mb_part_width = pu1_sub_mb_partw[u1_sub_mb_mode]; + u1_mb_part_height = pu1_sub_mb_parth[u1_sub_mb_mode]; + pu1_top_left_sub_mb_indx = pu1_sub_mb_indx_mod + (u1_sub_mb_mode << 1); + u1_sub_mb_num = u2_sub_mb_num_pack >> 12; + u4_sub_mb_pack <<= 8; + u2_sub_mb_num_pack <<= 4; + } + /* Loop on Number of sub-partitions */ + for(uc_j = 0; uc_j < u1_num_subpart; uc_j++, pu1_top_left_sub_mb_indx++) + { + mv_pred_t * ps_mv; + + u1_sub_mb_num += *pu1_top_left_sub_mb_indx; + ps_mv = ps_mv_start + u1_sub_mb_num; + + /* Storing Info for partitions */ + ps_part->u1_is_direct = PART_NOT_DIRECT; + ps_part->u1_sub_mb_num = u1_sub_mb_num; + ps_part->u1_partheight = u1_mb_part_height; + ps_part->u1_partwidth = u1_mb_part_width; + + /* Increment partition Index */ + u1_p_idx++; + ps_part++; + + ih264d_get_mvd_cabac(u1_sub_mb_num, 0, u1_mb_part_width, + u1_mb_part_height, 1, ps_dec, ps_mv); + } + } + ps_parse_mb_data->u1_num_part = u1_p_idx; + ps_dec->ps_part = ps_part; + } + { + UWORD8 u1_cbp; + + /* Read the Coded block pattern */ + u1_cbp = (WORD8)ih264d_parse_ctx_cbp_cabac(ps_dec); + COPYTHECONTEXT("coded_block_pattern", u1_cbp); + ps_cur_mb_info->u1_cbp = u1_cbp; + p_curr_ctxt->u1_cbp = u1_cbp; + p_curr_ctxt->u1_intra_chroma_pred_mode = 0; + p_curr_ctxt->u1_yuv_dc_csbp &= 0xFE; + ps_dec->pu1_left_yuv_dc_csbp[0] &= 0x6; + + if(u1_cbp > 47) + return ERROR_CBP; + + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + /* Read the transform8x8 u4_flag if present */ + if((ps_dec->s_high_profile.u1_transform8x8_present) && (u1_cbp & 0xf) + && u1_no_submb_part_size_lt8x8_flag) + { + ps_cur_mb_info->u1_tran_form8x8 = ih264d_parse_transform8x8flag_cabac( + ps_dec, ps_cur_mb_info); + COPYTHECONTEXT("transform_size_8x8_flag", ps_cur_mb_info->u1_tran_form8x8); + p_curr_ctxt->u1_transform8x8_ctxt = ps_cur_mb_info->u1_tran_form8x8; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = ps_cur_mb_info->u1_tran_form8x8; + + } + else + { + p_curr_ctxt->u1_transform8x8_ctxt = 0; + } + + /* Read mb_qp_delta */ + if(u1_cbp) + { + WORD8 c_temp; + ret = ih264d_parse_mb_qp_delta_cabac(ps_dec, &c_temp); + if(ret != OK) + return ret; + COPYTHECONTEXT("mb_qp_delta", c_temp); + if(c_temp != 0) + { + ret = ih264d_update_qp(ps_dec, c_temp); + if(ret != OK) + return ret; + } + } + else + ps_dec->i1_prev_mb_qp_delta = 0; + + + + ih264d_parse_residual4x4_cabac(ps_dec, ps_cur_mb_info, 0); + if(EXCEED_OFFSET(ps_dec->ps_bitstrm)) + return ERROR_EOB_TERMINATE_T; + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : parsePSliceData \endif + * + * \brief + * This function parses CAVLC syntax of N MB's of a P slice. + * 1. After parsing syntax of N MB's, for those N MB's (less than N, incase + * of end of slice or end of row), MB is decoded. This process is carried + * for one complete MB row or till end of slice. + * 2. Bottom one row of current MB is copied to IntraPredLine buffers. + * IntraPredLine buffers are used for Intra prediction of next row. + * 3. Current MB row along with previous 4 rows of Luma (and 2 of Chroma) are + * deblocked. + * 4. 4 rows (2 for Chroma) previous row and 12 rows (6 for Chroma) are + * DMA'ed to picture buffers. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +/*! + ************************************************************************** + * \if Function name : ih264d_update_nnz_for_skipmb \endif + * + * \brief + * + * \return + * None + * + ************************************************************************** + */ +void ih264d_update_nnz_for_skipmb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_entrpy) +{ + UWORD32 *pu4_buf; + UWORD8 *pu1_buf; + UNUSED(u1_entrpy); + pu1_buf = ps_dec->pu1_left_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + pu1_buf = ps_dec->pu1_left_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_y; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + pu1_buf = ps_cur_mb_info->ps_curmb->pu1_nnz_uv; + pu4_buf = (UWORD32 *)pu1_buf; + *pu4_buf = 0; + ps_cur_mb_info->ps_curmb->u2_luma_csbp = 0; + ps_cur_mb_info->u2_luma_csbp = 0; + ps_cur_mb_info->u2_chroma_csbp = 0; +} + + + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_inter_slice_data_cabac */ +/* */ +/* Description : This function parses cabac syntax of a inter slice on */ +/* N MB basis. */ +/* */ +/* Inputs : ps_dec */ +/* sliceparams */ +/* firstMbInSlice */ +/* */ +/* Processing : 1. After parsing syntax for N MBs those N MBs are */ +/* decoded till the end of slice. */ +/* 2. MV prediction and DMA happens on a N/2 MB basis. */ +/* */ +/* Returns : 0 */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_inter_slice_data_cabac(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice) +{ + UWORD32 uc_more_data_flag; + WORD32 i2_cur_mb_addr; + UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx; + UWORD32 u1_mbaff; + UWORD32 u1_num_mbs_next, u1_end_of_row; + const UWORD16 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; + UWORD32 u1_slice_end = 0; + UWORD32 u1_tfr_n_mb = 0; + UWORD32 u1_decode_nmb = 0; + + + deblk_mb_t *ps_cur_deblk_mb; + dec_mb_info_t *ps_cur_mb_info; + + parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data; + UWORD32 u1_inter_mb_skip_type; + UWORD32 u1_inter_mb_type; + UWORD32 u1_deblk_mb_type; + UWORD32 u1_mb_threshold; + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + WORD32 ret; + + /******************************************************/ + /* Initialisations specific to B or P slice */ + /******************************************************/ + if(ps_slice->u1_slice_type == P_SLICE) + { + u1_inter_mb_skip_type = CAB_P_SKIP; + u1_inter_mb_type = P_MB; + u1_deblk_mb_type = D_INTER_MB; + u1_mb_threshold = 5; + } + else // B_SLICE + { + u1_inter_mb_skip_type = CAB_B_SKIP; + u1_inter_mb_type = B_MB; + u1_deblk_mb_type = D_B_SLICE; + u1_mb_threshold = 23; + } + + /******************************************************/ + /* Slice Level Initialisations */ + /******************************************************/ + i2_cur_mb_addr = u2_first_mb_in_slice; + ps_dec->u1_qp = ps_slice->u1_slice_qp; + ret = ih264d_update_qp(ps_dec, 0); + if(ret != OK) + return ret; + u1_mb_idx = ps_dec->u1_mb_idx; + u1_num_mbs = u1_mb_idx; + u1_num_mbsNby2 = 0; + u1_mbaff = ps_slice->u1_mbaff_frame_flag; + i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff; + uc_more_data_flag = 1; + + /* Initialisations specific to cabac */ + if(ps_bitstrm->u4_ofst & 0x07) + { + ps_bitstrm->u4_ofst += 8; + ps_bitstrm->u4_ofst &= 0xFFFFFFF8; + } + + ret = ih264d_init_cabac_dec_envirnoment(&(ps_dec->s_cab_dec_env), ps_bitstrm); + if(ret != OK) + return ret; + + ps_dec->i1_prev_mb_qp_delta = 0; + + while(!u1_slice_end) + { + UWORD8 u1_mb_type; + UWORD32 u4_mb_skip; + + + ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs; + + ps_cur_mb_info->u1_Mux = 0; + ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff); + ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs; + + ps_cur_mb_info->u1_end_of_slice = 0; + + /* Storing Default partition info */ + 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 , neighbour availablity, */ + /***************************************************************/ + u4_mb_skip = ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, 1); + + /*********************************************************************/ + /* initialize u1_tran_form8x8 to zero to aviod uninitialized accesses */ + /*********************************************************************/ + ps_cur_mb_info->u1_tran_form8x8 = 0; + ps_cur_mb_info->ps_curmb->u1_tran_form8x8 = 0; + + /***************************************************************/ + /* Set the deblocking parameters for this MB */ + /***************************************************************/ + if(ps_dec->u4_app_disable_deblk_frm == 0) + ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice, + ps_dec->u1_mb_ngbr_availablity, + ps_dec->u1_cur_mb_fld_dec_flag); + + if(u4_mb_skip) + { + + /* Set appropriate flags in ps_cur_mb_info and ps_dec */ + memset(ps_dec->ps_curr_ctxt_mb_info, 0, sizeof(ctxt_inc_mb_info_t)); + ps_dec->ps_curr_ctxt_mb_info->u1_mb_type = u1_inter_mb_skip_type; + + MEMSET_16BYTES(&ps_dec->pu1_left_mv_ctxt_inc[0][0], 0); + + *((UWORD32 *)ps_dec->pi1_left_ref_idx_ctxt_inc) = 0; + *(ps_dec->pu1_left_yuv_dc_csbp) = 0; + + ps_dec->i1_prev_mb_qp_delta = 0; + ps_cur_mb_info->u1_mb_type = MB_SKIP; + ps_cur_mb_info->u1_cbp = 0; + + { + /* Storing Skip partition info */ + parse_part_params_t *ps_part_info = ps_dec->ps_part; + ps_part_info->u1_is_direct = PART_DIRECT_16x16; + ps_part_info->u1_sub_mb_num = 0; + ps_dec->ps_part++; + } + + /* Update Nnzs */ + ih264d_update_nnz_for_skipmb(ps_dec, ps_cur_mb_info, CABAC); + + ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type; + ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type; + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + + } + else + { + + /* Macroblock Layer Begins */ + /* Decode the u1_mb_type */ + u1_mb_type = ih264d_parse_mb_type_cabac(ps_dec); + ps_cur_mb_info->u1_mb_type = u1_mb_type; + if(u1_mb_type > (25 + u1_mb_threshold)) + return ERROR_MB_TYPE; + + /* Parse Macroblock Data */ + if(u1_mb_type < u1_mb_threshold) + { + ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type; + *(ps_dec->pu1_left_yuv_dc_csbp) &= 0x6; + + ret = ps_dec->pf_parse_inter_mb(ps_dec, ps_cur_mb_info, u1_num_mbs, + u1_num_mbsNby2); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type; + } + else + { + /* Storing Intra partition info */ + ps_parse_mb_data->u1_num_part = 0; + ps_parse_mb_data->u1_isI_mb = 1; + + if((25 + u1_mb_threshold) == u1_mb_type) + { + /* I_PCM_MB */ + ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB; + ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = 0; + } + else + { + if(u1_mb_type == u1_mb_threshold) + ps_cur_mb_info->ps_curmb->u1_mb_type = I_4x4_MB; + else + ps_cur_mb_info->ps_curmb->u1_mb_type = I_16x16_MB; + + ret = ih264d_parse_imb_cabac( + ps_dec, ps_cur_mb_info, + (UWORD8)(u1_mb_type - u1_mb_threshold)); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + } + ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB; + + } + + } + + if(u1_mbaff) + { + ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); + } + /* Next macroblock information */ + if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr) + return ERROR_MB_ADDRESS_T; + i2_cur_mb_addr++; + + if(ps_cur_mb_info->u1_topmb && u1_mbaff) + uc_more_data_flag = 1; + else + { + uc_more_data_flag = ih264d_decode_terminate(&ps_dec->s_cab_dec_env, + ps_bitstrm); + uc_more_data_flag = !uc_more_data_flag; + COPYTHECONTEXT("Decode Sliceterm",!uc_more_data_flag); + } + + u1_num_mbs++; + ps_dec->u2_total_mbs_coded++; + u1_num_mbsNby2++; + 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 */ + /****************************************************************/ + u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1; + u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01))); + u1_slice_end = !uc_more_data_flag; + u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row + || u1_slice_end; + u1_decode_nmb = u1_tfr_n_mb || u1_slice_end; + ps_cur_mb_info->u1_end_of_slice = u1_slice_end; + /*u1_dma_nby2mb = u1_decode_nmb || + (u1_num_mbsNby2 == ps_dec->u1_recon_mb_grp_pair);*/ + +//if(u1_dma_nby2mb) + if(u1_decode_nmb) + { + + ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs); + if(ret != OK) + return ret; + u1_num_mbsNby2 = 0; + + { + ps_parse_mb_data = ps_dec->ps_parse_mb_data; + ps_dec->ps_part = ps_dec->ps_parse_part_params; + } + } + + /*H264_DEC_DEBUG_PRINT("Pic: %d Mb_X=%d Mb_Y=%d", + ps_slice->i4_poc >> ps_slice->u1_field_pic_flag, + ps_dec->u2_mbx,ps_dec->u2_mby + (1 - ps_cur_mb_info->u1_topmb)); + H264_DEC_DEBUG_PRINT("u1_decode_nmb: %d, u1_num_mbs: %d", u1_decode_nmb, u1_num_mbs);*/ + if(u1_decode_nmb) + { + + if(ps_dec->u1_separate_parse) + { + ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, u1_end_of_row); + ps_dec->ps_nmb_info += u1_num_mbs; + } + else + { + ret = ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, + u1_end_of_row); + if(ret != OK) + return ret; + } + + if(u1_tfr_n_mb) + u1_num_mbs = 0; + u1_mb_idx = u1_num_mbs; + ps_dec->u1_mb_idx = u1_num_mbs; + + } + } + + if(ps_dec->u1_separate_parse) + { + ps_dec->ps_parse_cur_slice->end_of_slice = 1; + ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr + - (u2_first_mb_in_slice << u1_mbaff); + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_inter_slice_data_cavlc */ +/* */ +/* Description : This function parses cavlc syntax of a inter slice on */ +/* N MB basis. */ +/* */ +/* Inputs : ps_dec */ +/* sliceparams */ +/* firstMbInSlice */ +/* */ +/* Processing : 1. After parsing syntax for N MBs those N MBs are */ +/* decoded till the end of slice. */ +/* 2. MV prediction and DMA happens on a N/2 MB basis. */ +/* */ +/* Returns : 0 */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_inter_slice_data_cavlc(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice) +{ + UWORD32 uc_more_data_flag; + WORD32 i2_cur_mb_addr; + UWORD32 u1_num_mbs, u1_num_mbsNby2, u1_mb_idx; + UWORD32 i2_mb_skip_run; + UWORD32 u1_read_mb_type; + + UWORD32 u1_mbaff; + UWORD32 u1_num_mbs_next, u1_end_of_row; + const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; + UWORD32 u1_slice_end = 0; + UWORD32 u1_tfr_n_mb = 0; + UWORD32 u1_decode_nmb = 0; + + dec_bit_stream_t * const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + deblk_mb_t *ps_cur_deblk_mb; + dec_mb_info_t *ps_cur_mb_info; + parse_pmbarams_t *ps_parse_mb_data = ps_dec->ps_parse_mb_data; + UWORD32 u1_inter_mb_type; + UWORD32 u1_deblk_mb_type; + UWORD32 u1_mb_threshold; + WORD32 ret; + + /******************************************************/ + /* Initialisations specific to B or P slice */ + /******************************************************/ + + if(ps_slice->u1_slice_type == P_SLICE) + { + u1_inter_mb_type = P_MB; + u1_deblk_mb_type = D_INTER_MB; + u1_mb_threshold = 5; + } + else // B_SLICE + { + u1_inter_mb_type = B_MB; + u1_deblk_mb_type = D_B_SLICE; + u1_mb_threshold = 23; + } + /******************************************************/ + /* Slice Level Initialisations */ + /******************************************************/ + i2_cur_mb_addr = u2_first_mb_in_slice; + ps_dec->u1_qp = ps_slice->u1_slice_qp; + ret = ih264d_update_qp(ps_dec, 0); + if(ret != OK) + return ret; + u1_mb_idx = ps_dec->u1_mb_idx; + u1_num_mbs = u1_mb_idx; + + u1_num_mbsNby2 = 0; + u1_mbaff = ps_slice->u1_mbaff_frame_flag; + i2_cur_mb_addr = u2_first_mb_in_slice << u1_mbaff; + i2_mb_skip_run = 0; + uc_more_data_flag = 1; + u1_read_mb_type = 0; + + while(!u1_slice_end) + { + UWORD8 u1_mb_type; + + if(i2_cur_mb_addr > ps_dec->ps_cur_sps->u2_max_mb_addr) + { + + break; + } + + + ps_cur_mb_info = ps_dec->ps_nmb_info + u1_num_mbs; + + ps_cur_mb_info->u1_Mux = 0; + ps_dec->u4_num_pmbair = (u1_num_mbs >> u1_mbaff); + ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + u1_num_mbs; + + ps_cur_mb_info->u1_end_of_slice = 0; + + /* Storing Default partition info */ + ps_parse_mb_data->u1_num_part = 1; + ps_parse_mb_data->u1_isI_mb = 0; + + if((!i2_mb_skip_run) && (!u1_read_mb_type)) + { + + //Inlined ih264d_uev + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz; + + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + + u4_ldz = CLZ(u4_word); + + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + { + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + } + *pu4_bitstrm_ofst = u4_bitstream_offset; + i2_mb_skip_run = ((1 << u4_ldz) + u4_word - 1); + //Inlined ih264d_uev + COPYTHECONTEXT("mb_skip_run", i2_mb_skip_run); + uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm); + u1_read_mb_type = uc_more_data_flag; + } + + /***************************************************************/ + /* Get the required information for decoding of MB */ + /* mb_x, mb_y , neighbour availablity, */ + /***************************************************************/ + ps_dec->pf_get_mb_info(ps_dec, i2_cur_mb_addr, ps_cur_mb_info, i2_mb_skip_run); + + /***************************************************************/ + /* Set the deblocking parameters for this MB */ + /***************************************************************/ + if(ps_dec->u4_app_disable_deblk_frm == 0) + ih264d_set_deblocking_parameters(ps_cur_deblk_mb, ps_slice, + ps_dec->u1_mb_ngbr_availablity, + ps_dec->u1_cur_mb_fld_dec_flag); + + if(i2_mb_skip_run) + { + /* Set appropriate flags in ps_cur_mb_info and ps_dec */ + ps_dec->i1_prev_mb_qp_delta = 0; + ps_dec->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 */ + parse_part_params_t *ps_part_info = ps_dec->ps_part; + ps_part_info->u1_is_direct = PART_DIRECT_16x16; + ps_part_info->u1_sub_mb_num = 0; + ps_dec->ps_part++; + } + + /* Update Nnzs */ + ih264d_update_nnz_for_skipmb(ps_dec, 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; + + i2_mb_skip_run--; + } + else + { + u1_read_mb_type = 0; + /**************************************************************/ + /* Macroblock Layer Begins, Decode the u1_mb_type */ + /**************************************************************/ + { + UWORD32 u4_bitstream_offset = *pu4_bitstrm_ofst; + UWORD32 u4_word, u4_ldz, u4_temp; + + + //Inlined ih264d_uev + /***************************************************************/ + /* Find leading zeros in next 32 bits */ + /***************************************************************/ + NEXTBITS_32(u4_word, u4_bitstream_offset, pu4_bitstrm_buf); + u4_ldz = CLZ(u4_word); + /* Flush the ps_bitstrm */ + u4_bitstream_offset += (u4_ldz + 1); + /* Read the suffix from the ps_bitstrm */ + u4_word = 0; + if(u4_ldz) + GETBITS(u4_word, u4_bitstream_offset, pu4_bitstrm_buf, + u4_ldz); + *pu4_bitstrm_ofst = u4_bitstream_offset; + u4_temp = ((1 << u4_ldz) + u4_word - 1); + //Inlined ih264d_uev + if(u4_temp > (UWORD32)(25 + u1_mb_threshold)) + return ERROR_MB_TYPE; + u1_mb_type = u4_temp; + COPYTHECONTEXT("u1_mb_type", u1_mb_type); + } + ps_cur_mb_info->u1_mb_type = u1_mb_type; + + /**************************************************************/ + /* Parse Macroblock data */ + /**************************************************************/ + if(u1_mb_type < u1_mb_threshold) + { + ps_cur_mb_info->ps_curmb->u1_mb_type = u1_inter_mb_type; + + ret = ps_dec->pf_parse_inter_mb(ps_dec, ps_cur_mb_info, u1_num_mbs, + u1_num_mbsNby2); + if(ret != OK) + return ret; + ps_cur_deblk_mb->u1_mb_type |= u1_deblk_mb_type; + } + else + { + /* Storing Intra partition info */ + ps_parse_mb_data->u1_num_part = 0; + ps_parse_mb_data->u1_isI_mb = 1; + + if((25 + u1_mb_threshold) == u1_mb_type) + { + /* I_PCM_MB */ + ps_cur_mb_info->ps_curmb->u1_mb_type = I_PCM_MB; + ret = ih264d_parse_ipcm_mb(ps_dec, ps_cur_mb_info, u1_num_mbs); + if(ret != OK) + return ret; + ps_dec->u1_qp = 0; + } + else + { + ret = ih264d_parse_imb_cavlc( + ps_dec, ps_cur_mb_info, u1_num_mbs, + (UWORD8)(u1_mb_type - u1_mb_threshold)); + if(ret != OK) + return ret; + } + + ps_cur_deblk_mb->u1_mb_type |= D_INTRA_MB; + } + uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm); + } + ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + + if(u1_mbaff) + { + ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); + } + /**************************************************************/ + /* Get next Macroblock address */ + /**************************************************************/ + i2_cur_mb_addr++; + + u1_num_mbs++; + ps_dec->u2_total_mbs_coded++; + u1_num_mbsNby2++; + 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 */ + /****************************************************************/ + u1_num_mbs_next = i2_pic_wdin_mbs - ps_dec->u2_mbx - 1; + u1_end_of_row = (!u1_num_mbs_next) && (!(u1_mbaff && (u1_num_mbs & 0x01))); + u1_slice_end = (!(uc_more_data_flag || i2_mb_skip_run)); + u1_tfr_n_mb = (u1_num_mbs == ps_dec->u1_recon_mb_grp) || u1_end_of_row + || u1_slice_end; + u1_decode_nmb = u1_tfr_n_mb || u1_slice_end; + ps_cur_mb_info->u1_end_of_slice = u1_slice_end; + + /*u1_dma_nby2mb = u1_decode_nmb || + (u1_num_mbsNby2 == ps_dec->u1_recon_mb_grp_pair);*/ + +//if(u1_dma_nby2mb) + if(u1_decode_nmb) + { + + ret = ps_dec->pf_mvpred_ref_tfr_nby2mb(ps_dec, u1_mb_idx, u1_num_mbs); + if(ret != OK) + return ret; + u1_num_mbsNby2 = 0; + + { + ps_parse_mb_data = ps_dec->ps_parse_mb_data; + ps_dec->ps_part = ps_dec->ps_parse_part_params; + } + } + + /*H264_DEC_DEBUG_PRINT("Pic: %d Mb_X=%d Mb_Y=%d", + ps_slice->i4_poc >> ps_slice->u1_field_pic_flag, + ps_dec->u2_mbx,ps_dec->u2_mby + (1 - ps_cur_mb_info->u1_topmb)); + H264_DEC_DEBUG_PRINT("u1_decode_nmb: %d", u1_decode_nmb);*/ + if(u1_decode_nmb) + { + + + + if(ps_dec->u1_separate_parse) + { + ih264d_parse_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, u1_end_of_row); + ps_dec->ps_nmb_info += u1_num_mbs; + } + else + { + ret = ih264d_decode_recon_tfr_nmb(ps_dec, u1_mb_idx, u1_num_mbs, + u1_num_mbs_next, u1_tfr_n_mb, + u1_end_of_row); + if(ret != OK) + return ret; + } + + if(u1_tfr_n_mb) + u1_num_mbs = 0; + u1_mb_idx = u1_num_mbs; + ps_dec->u1_mb_idx = u1_num_mbs; + + } +//ps_dec->ps_pred++; + } + + if(ps_dec->u1_separate_parse) + { + ps_dec->ps_parse_cur_slice->end_of_slice = 1; + ps_dec->ps_cur_slice->u4_mbs_in_slice = i2_cur_mb_addr + - (u2_first_mb_in_slice << u1_mbaff); + } + + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_pslice \endif + * + * \brief + * Decodes a P Slice + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, UWORD16 u2_first_mb_in_slice) +{ + dec_pic_params_t * ps_pps = ps_dec->ps_cur_pps; + dec_slice_params_t * ps_cur_slice = ps_dec->ps_cur_slice; + dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; //ps_dec->ps_cur_sps->u1_mb_aff_flag; + UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + + UWORD32 u4_temp; + WORD32 i_temp; + WORD32 ret; + + /*--------------------------------------------------------------------*/ + /* Read remaining contents of the slice header */ + /*--------------------------------------------------------------------*/ + { + WORD8 *pi1_buf; + WORD16 *pi2_mv = ps_dec->s_default_mv_pred.i2_mv; + WORD32 *pi4_mv = (WORD32*)pi2_mv; + WORD16 *pi16_refFrame; + + pi1_buf = ps_dec->s_default_mv_pred.i1_ref_frame; + pi16_refFrame = (WORD16*)pi1_buf; + *pi4_mv = 0; + *(pi4_mv + 1) = 0; + *pi16_refFrame = OUT_OF_RANGE_REF; + ps_dec->s_default_mv_pred.u1_col_ref_pic_idx = (UWORD8)-1; + ps_dec->s_default_mv_pred.u1_pic_type = (UWORD8)-1; + } + + 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); + + u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0]; + if(ps_cur_slice->u1_num_ref_idx_active_override_flag) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1; + } + + { + + + + UWORD8 u1_max_ref_idx = MAX_FRAMES << u1_field_pic_flag; + if(u4_temp > u1_max_ref_idx) + { + return ERROR_NUM_REF; + } + ps_cur_slice->u1_num_ref_idx_lx_active[0] = u4_temp; + COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1", + ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1); + + } + + { + UWORD8 uc_refIdxReFlagL0 = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: ref_pic_list_reordering_flag_l0",uc_refIdxReFlagL0); + + /* Initialize the Reference list once in Picture if the slice type */ + /* of first slice is between 5 to 9 defined in table 7.3 of standard */ + /* If picture contains both P & B slices then Initialize the Reference*/ + /* List only when it switches from P to B and B to P */ + { + UWORD8 init_idx_flg = (ps_dec->u1_pr_sl_type + != ps_dec->ps_cur_slice->u1_slice_type); + if(ps_dec->u1_first_pb_nal_in_pic + || (init_idx_flg & !ps_dec->u1_sl_typ_5_9) + || ps_dec->u1_num_ref_idx_lx_active_prev + != ps_cur_slice->u1_num_ref_idx_lx_active[0]) + { + ih264d_init_ref_idx_lx_p(ps_dec); + } + if(ps_dec->u1_first_pb_nal_in_pic & ps_dec->u1_sl_typ_5_9) + ps_dec->u1_first_pb_nal_in_pic = 0; + } + /* Store the value for future slices in the same picture */ + ps_dec->u1_num_ref_idx_lx_active_prev = + ps_cur_slice->u1_num_ref_idx_lx_active[0]; + + /* Modified temporarily */ + if(uc_refIdxReFlagL0) + { + WORD8 ret; + ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0]; + ret = ih264d_ref_idx_reordering(ps_dec, 0); + if(ret == -1) + return ERROR_REFIDX_ORDER_T; + ps_dec->ps_ref_pic_buf_lx[0] = ps_dec->ps_dpb_mgr->ps_mod_dpb[0]; + } + else + ps_dec->ps_ref_pic_buf_lx[0] = + ps_dec->ps_dpb_mgr->ps_init_dpb[0]; + } + /* Create refIdx to POC mapping */ + { + void **pui_map_ref_idx_to_poc_lx0, **pui_map_ref_idx_to_poc_lx1; + WORD8 idx; + struct pic_buffer_t *ps_pic; + + pui_map_ref_idx_to_poc_lx0 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L0; + pui_map_ref_idx_to_poc_lx0[0] = 0; //For ref_idx = -1 + pui_map_ref_idx_to_poc_lx0++; + for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++) + { + ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx]; + pui_map_ref_idx_to_poc_lx0[idx] = (ps_pic->pu1_buf1); + } + + /* Bug Fix Deblocking */ + pui_map_ref_idx_to_poc_lx1 = ps_dec->ppv_map_ref_idx_to_poc + FRM_LIST_L1; + pui_map_ref_idx_to_poc_lx1[0] = 0; + + if(u1_mbaff) + { + void **ppv_map_ref_idx_to_poc_lx_t, **ppv_map_ref_idx_to_poc_lx_b; + void **ppv_map_ref_idx_to_poc_lx_t1, **ppv_map_ref_idx_to_poc_lx_b1; + ppv_map_ref_idx_to_poc_lx_t = ps_dec->ppv_map_ref_idx_to_poc + + TOP_LIST_FLD_L0; + ppv_map_ref_idx_to_poc_lx_b = ps_dec->ppv_map_ref_idx_to_poc + + BOT_LIST_FLD_L0; + + ppv_map_ref_idx_to_poc_lx_t[0] = 0; // For ref_idx = -1 + ppv_map_ref_idx_to_poc_lx_t++; + ppv_map_ref_idx_to_poc_lx_b[0] = 0; // For ref_idx = -1 + ppv_map_ref_idx_to_poc_lx_b++; + + idx = 0; + for(idx = 0; idx < ps_cur_slice->u1_num_ref_idx_lx_active[0]; idx++) + { + ps_pic = ps_dec->ps_ref_pic_buf_lx[0][idx]; + ppv_map_ref_idx_to_poc_lx_t[0] = (ps_pic->pu1_buf1); + ppv_map_ref_idx_to_poc_lx_b[1] = (ps_pic->pu1_buf1); + + ppv_map_ref_idx_to_poc_lx_b[0] = (ps_pic->pu1_buf1) + 1; + ppv_map_ref_idx_to_poc_lx_t[1] = (ps_pic->pu1_buf1) + 1; + + ppv_map_ref_idx_to_poc_lx_t += 2; + ppv_map_ref_idx_to_poc_lx_b += 2; + } + ppv_map_ref_idx_to_poc_lx_t1 = ps_dec->ppv_map_ref_idx_to_poc + + TOP_LIST_FLD_L1; + ppv_map_ref_idx_to_poc_lx_t1[0] = 0; + ppv_map_ref_idx_to_poc_lx_b1 = ps_dec->ppv_map_ref_idx_to_poc + + BOT_LIST_FLD_L1; + ppv_map_ref_idx_to_poc_lx_b1[0] = 0; + + } + + if(ps_dec->u4_num_cores >= 3) + { + WORD32 num_entries; + WORD32 size; + + num_entries = MIN(MAX_FRAMES, ps_dec->u4_num_ref_frames_at_init); + num_entries = 2 * ((2 * num_entries) + 1); + + size = num_entries * sizeof(void *); + size += PAD_MAP_IDX_POC * sizeof(void *); + + memcpy((void *)ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc, + ps_dec->ppv_map_ref_idx_to_poc, + size); + } + + + } + if(ps_pps->u1_wted_pred_flag) + { + ret = ih264d_parse_pred_weight_table(ps_cur_slice, ps_bitstrm); + if(ret != OK) + return ret; + ih264d_form_pred_weight_matrix(ps_dec); + ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat; + } + else + { + ps_dec->ps_cur_slice->u2_log2Y_crwd = 0; + ps_dec->pu4_wt_ofsts = ps_dec->pu4_wts_ofsts_mat; + } + + ps_dec->ps_parse_cur_slice->u2_log2Y_crwd = + ps_dec->ps_cur_slice->u2_log2Y_crwd; + + if(u1_mbaff && (u1_field_pic_flag == 0)) + { + ih264d_convert_frm_mbaff_list(ps_dec); + } + + /* G050 */ + if(ps_cur_slice->u1_nal_ref_idc != 0) + { + if(!ps_dec->ps_dpb_cmds->u1_dpb_commands_read) + ps_dec->u4_bitoffset = ih264d_read_mmco_commands(ps_dec); + else + ps_bitstrm->u4_ofst += ps_dec->u4_bitoffset; + + } + /* G050 */ + + if(ps_pps->u1_entropy_coding_mode == CABAC) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if(u4_temp > MAX_CABAC_INIT_IDC) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_cur_slice->u1_cabac_init_idc = u4_temp; + COPYTHECONTEXT("SH: cabac_init_idc",ps_cur_slice->u1_cabac_init_idc); + } + + /* Read slice_qp_delta */ + i_temp = ps_pps->u1_pic_init_qp + + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if((i_temp < 0) || (i_temp > 51)) + { + return ERROR_INV_RANGE_QP_T; + } + ps_cur_slice->u1_slice_qp = i_temp; + COPYTHECONTEXT("SH: slice_qp_delta", + (WORD8)(ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp)); + + if(ps_pps->u1_deblocking_filter_parameters_present_flag == 1) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > SLICE_BOUNDARY_DBLK_DISABLED) + { + return ERROR_INV_SLICE_HDR_T; + } + + COPYTHECONTEXT("SH: disable_deblocking_filter_idc", u4_temp); + ps_cur_slice->u1_disable_dblk_filter_idc = u4_temp; + if(u4_temp != 1) + { + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_cur_slice->i1_slice_alpha_c0_offset = i_temp; + COPYTHECONTEXT("SH: slice_alpha_c0_offset_div2", + ps_cur_slice->i1_slice_alpha_c0_offset >> 1); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + << 1; + if((MIN_DBLK_FIL_OFF > i_temp) || (i_temp > MAX_DBLK_FIL_OFF)) + { + return ERROR_INV_SLICE_HDR_T; + } + ps_cur_slice->i1_slice_beta_offset = i_temp; + 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; + } + + DATA_SYNC(); + ps_dec->ps_parse_cur_slice->slice_header_done = 2; + + if(ps_pps->u1_entropy_coding_mode) + { + SWITCHOFFTRACE; SWITCHONTRACECABAC; + ps_dec->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cabac; + if(ps_dec->ps_parse_cur_slice->u2_error_flag == 1) + return 0; + ps_dec->pf_parse_inter_mb = ih264d_parse_pmb_cabac; + ih264d_init_cabac_contexts(P_SLICE, ps_dec); + + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_mbaff; + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cabac_nonmbaff; + } + else + { + SWITCHONTRACE; SWITCHOFFTRACECABAC; + ps_dec->pf_parse_inter_slice = ih264d_parse_inter_slice_data_cavlc; + ps_dec->pf_parse_inter_mb = ih264d_parse_pmb_cavlc; + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_mbaff; + } + else + ps_dec->pf_get_mb_info = ih264d_get_mb_info_cavlc_nonmbaff; + } + + ps_dec->u1_B = 0; + ps_dec->pf_mvpred_ref_tfr_nby2mb = ih264d_mv_pred_ref_tfr_nby2_pmb; + ret = ps_dec->pf_parse_inter_slice(ps_dec, ps_cur_slice, u2_first_mb_in_slice); + if(ret != OK) + return ret; +// ps_dec->curr_slice_in_error = 0 ; + return OK; +} diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c new file mode 100755 index 0000000..323df43 --- /dev/null +++ b/decoder/ih264d_parse_slice.c @@ -0,0 +1,1887 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_parse_slice.c + * + * \brief + * Contains routines that decodes a slice NAL unit + * + * \date + * 19/12/2002 + * + * \author AI + ************************************************************************** + */ +#include <string.h> +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ithread.h" +#include "ih264d_structs.h" +#include "ih264d_debug.h" +#include "ih264d_bitstrm.h" +#include "ih264d_parse_mb_header.h" +#include "ih264d_process_bslice.h" +#include "ih264d_process_pslice.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_utils.h" +#include "ih264d_deblocking.h" +#include "ih264d_defs.h" +#include "ih264d_error_handler.h" +#include "ih264d_tables.h" +#include "ih264d_defs.h" +#include "ih264d_mem_request.h" +#include "ih264d_parse_islice.h" +#include "ih264d_parse_slice.h" +#include "ih264d_mvpred.h" +#include "ih264d_mb_utils.h" + +#include "ih264d_defs.h" +#include "ih264d_quant_scaling.h" + +#include "ih264d_inter_pred.h" + +#include "ih264d_sei.h" +#include "ih264d.h" +#include "ih264_error.h" +#include "ih264_disp_mgr.h" +#include "ih264_buf_mgr.h" + +#include "ih264d_thread_parse_decode.h" +#include "ih264d_thread_compute_bs.h" +#include "ih264d_dpb_manager.h" +#include <assert.h> +#include "ih264d_parse_islice.h" +#define RET_LAST_SKIP 0x80000000 + +/*! + ************************************************************************** + * \if Function name : ih264d_form_pred_weight_matrix \endif + * + * \brief + * Forms pred weight matrix. + * + * \return + * None + * + ************************************************************************** + */ + +void ih264d_form_pred_weight_matrix(dec_struct_t *ps_dec) +{ + dec_slice_params_t *ps_cur_slice; + UWORD8 uc_num_ref_idx_l0_active, uc_num_ref_idx_l1_active; + UWORD8 i, j; + UWORD32 *pu4_mat_iwt_ofst; + UWORD16 i2_idx; + UWORD32 *pui32_weight_offset_l0, *pui32_weight_offset_l1; + UWORD32 u4_temp; + + ps_cur_slice = ps_dec->ps_cur_slice; + uc_num_ref_idx_l0_active = ps_cur_slice->u1_num_ref_idx_lx_active[0]; + uc_num_ref_idx_l1_active = ps_cur_slice->u1_num_ref_idx_lx_active[1]; + + pu4_mat_iwt_ofst = ps_dec->pu4_wts_ofsts_mat; + + if(ps_cur_slice->u1_slice_type == B_SLICE) + { + for(i = 0; i < uc_num_ref_idx_l0_active; i++) + { + pui32_weight_offset_l0 = ps_cur_slice->u4_wt_ofst_lx[0][i]; + for(j = 0; j < uc_num_ref_idx_l1_active; j++) + { + pui32_weight_offset_l1 = ps_cur_slice->u4_wt_ofst_lx[1][j]; + i2_idx = i * uc_num_ref_idx_l0_active + j; + i2_idx = X3(i2_idx); + /* u4_temp = (pui32_weight_offset_l0[0] | (pui32_weight_offset_l1[0] << 16)); + pu4_mat_iwt_ofst[0] = u4_temp; + u4_temp = (pui32_weight_offset_l0[1] | (pui32_weight_offset_l1[1] << 16)); + pu4_mat_iwt_ofst[1] = u4_temp; + u4_temp = (pui32_weight_offset_l0[2] | (pui32_weight_offset_l1[2] << 16)); + pu4_mat_iwt_ofst[2] = u4_temp; + pu4_mat_iwt_ofst += 3;*/ + pu4_mat_iwt_ofst[0] = pui32_weight_offset_l0[0]; + pu4_mat_iwt_ofst[1] = pui32_weight_offset_l1[0]; + pu4_mat_iwt_ofst[2] = pui32_weight_offset_l0[1]; + pu4_mat_iwt_ofst[3] = pui32_weight_offset_l1[1]; + pu4_mat_iwt_ofst[4] = pui32_weight_offset_l0[2]; + pu4_mat_iwt_ofst[5] = pui32_weight_offset_l1[2]; + pu4_mat_iwt_ofst += 6; + } + } + } + else + { + for(i = 0; i < uc_num_ref_idx_l0_active; i++) + { + pui32_weight_offset_l0 = ps_cur_slice->u4_wt_ofst_lx[0][i]; + i2_idx = X3(i); + u4_temp = (UWORD32)pui32_weight_offset_l0[0]; + pu4_mat_iwt_ofst[0] = u4_temp; + u4_temp = (UWORD32)pui32_weight_offset_l0[1]; + pu4_mat_iwt_ofst[2] = u4_temp; + u4_temp = (UWORD32)pui32_weight_offset_l0[2]; + pu4_mat_iwt_ofst[4] = u4_temp; + pu4_mat_iwt_ofst += 6; + } + } +} + + +/*! + ************************************************************************** + * \if Function name : init_firstSliceParam \endif + * + * \brief + * Initialize the Parameter required for all the slices for a picture + * + * \return : Nothing + * + ************************************************************************** + */ + +WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, + WORD32 i4_poc, + pocstruct_t *ps_temp_poc, + UWORD16 u2_frame_num, + dec_pic_params_t *ps_pps) +{ + pocstruct_t *ps_prev_poc = &ps_dec->s_cur_pic_poc; + pocstruct_t *ps_cur_poc = ps_temp_poc; + + pic_buffer_t *pic_buf; + + ivd_video_decode_op_t * ps_dec_output = + (ivd_video_decode_op_t *)ps_dec->pv_dec_out; + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + dec_seq_params_t *ps_seq = ps_pps->ps_sps; + UWORD8 u1_bottom_field_flag = ps_cur_slice->u1_bottom_field_flag; + UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + /* high profile related declarations */ + high_profile_tools_t s_high_profile; + WORD32 ret; + + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + + 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_dec->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_dec->i1_prev_mb_qp_delta = 0; + ps_dec->i1_next_ctxt_idx = 0; + + ps_dec->u4_mb_level_deblk = 0; + + /* Disable MB_LEVEL_DEBLK if deblock thread is enabled */ + if(ps_dec->u4_num_cores >= 3) + { + ps_dec->u4_mb_level_deblk = 0; + } + + + if(ps_seq->u1_mb_aff_flag == 1) + { + ps_dec->u4_mb_level_deblk = 0; + if(ps_dec->u4_num_cores > 2) + ps_dec->u4_num_cores = 2; + } + if(ps_dec->u4_mb_level_deblk == 1) + ps_dec->u4_use_intrapred_line_copy = 1; + else + ps_dec->u4_use_intrapred_line_copy = 0; + + if((ps_dec->u4_num_cores >= 3) && (ps_seq->u1_mb_aff_flag == 0)) + { + ps_dec->u4_use_intrapred_line_copy = 1; + } + + ps_dec->u4_app_disable_deblk_frm = 0; + /* If degrade is enabled, set the degrade flags appropriately */ + if(ps_dec->i4_degrade_type && ps_dec->i4_degrade_pics) + { + WORD32 degrade_pic; + ps_dec->i4_degrade_pic_cnt++; + degrade_pic = 0; + + /* If degrade is to be done in all frames, then do not check further */ + switch(ps_dec->i4_degrade_pics) + { + case 4: + { + degrade_pic = 1; + break; + } + case 3: + { + if(ps_cur_slice->u1_slice_type != I_SLICE) + degrade_pic = 1; + + break; + } + case 2: + { + + /* If pic count hits non-degrade interval or it is an islice, then do not degrade */ + if((ps_cur_slice->u1_slice_type != I_SLICE) + && (ps_dec->i4_degrade_pic_cnt + != ps_dec->i4_nondegrade_interval)) + degrade_pic = 1; + + break; + } + case 1: + { + /* Check if the current picture is non-ref */ + if(0 == ps_cur_slice->u1_nal_ref_idc) + { + degrade_pic = 1; + } + break; + } + + } + if(degrade_pic) + { + if(ps_dec->i4_degrade_type & 0x2) + ps_dec->u4_app_disable_deblk_frm = 1; + + /* MC degrading is done only for non-ref pictures */ + if(0 == ps_cur_slice->u1_nal_ref_idc) + { + if(ps_dec->i4_degrade_type & 0x4) + ps_dec->i4_mv_frac_mask = 0; + + if(ps_dec->i4_degrade_type & 0x8) + ps_dec->i4_mv_frac_mask = 0; + } + } + else + ps_dec->i4_degrade_pic_cnt = 0; + } + + { + dec_err_status_t * ps_err = ps_dec->ps_dec_err_status; + if(ps_dec->u1_sl_typ_5_9 + && ((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(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) + { + if(ps_err->u1_err_flag) + ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); + ps_err->u1_err_flag = ACCEPT_ALL_PICS; + } + } + + ps_dec->u1_first_nal_in_pic = 0; + if(ps_dec->u1_init_dec_flag && ps_dec->s_prev_seq_params.u1_eoseq_pending) + { + /* Reset the decoder picture buffers */ + WORD32 j; + for(j = 0; j < MAX_DISP_BUFS_NEW; j++) + { + + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + j, + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[j], + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + j, + BUF_MGR_IO); + } + + /* reset the decoder structure parameters related to buffer handling */ + ps_dec->u1_second_field = 0; + ps_dec->i4_cur_display_seq = 0; + + /********************************************************************/ + /* indicate in the decoder output i4_status that some frames are being */ + /* dropped, so that it resets timestamp and wait for a new sequence */ + /********************************************************************/ + + ps_dec->s_prev_seq_params.u1_eoseq_pending = 0; + } + ret = ih264d_init_pic(ps_dec, u2_frame_num, i4_poc, ps_pps); + if(ret != OK) + return ret; + + ps_dec->pv_parse_tu_coeff_data = ps_dec->pv_pic_tu_coeff_data; + ps_dec->pv_proc_tu_coeff_data = ps_dec->pv_pic_tu_coeff_data; + ps_dec->ps_nmb_info = ps_dec->ps_frm_mb_info; + if(ps_dec->u1_separate_parse) + { + UWORD16 pic_wd = ps_dec->u4_width_at_init; + UWORD16 pic_ht = ps_dec->u4_height_at_init; + UWORD32 num_mbs; + + if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid))) + { + pic_wd = ps_dec->u2_pic_wd; + pic_ht = ps_dec->u2_pic_ht; + } + num_mbs = (pic_wd * pic_ht) >> 8; + + ps_dec->u4_start_frame_decode = 0; + if(ps_dec->pu1_dec_mb_map) + { + memset((void *)ps_dec->pu1_dec_mb_map, 0, num_mbs); + } + + if(ps_dec->pu1_recon_mb_map) + { + + memset((void *)ps_dec->pu1_recon_mb_map, 0, num_mbs); + } + + if(ps_dec->pu2_slice_num_map) + { + memset((void *)ps_dec->pu2_slice_num_map, 0, + (num_mbs * sizeof(UWORD16))); + } + + } + if(ps_dec->u4_first_slice_in_pic == 1) + { + ps_dec->ps_parse_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + ps_dec->ps_decode_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + ps_dec->ps_computebs_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + } + ps_dec->ps_parse_cur_slice->slice_header_done = 0; + ps_dec->ps_parse_cur_slice->last_slice_in_frame = 0; + ps_dec->ps_parse_cur_slice->u4_num_mbs_done_in_slice = 0; + + ps_dec->ps_parse_cur_slice->u2_error_flag = 0; + + /* Initialize all the HP toolsets to zero */ + ps_dec->s_high_profile.u1_scaling_present = 0; + ps_dec->s_high_profile.u1_transform8x8_present = 0; + + /* Get Next Free Picture */ + if(1 == ps_dec->u4_share_disp_buf) + { + UWORD32 i; + /* Free any buffer that is in the queue to be freed */ + for(i = 0; i < MAX_DISP_BUFS_NEW; i++) + { + if(0 == ps_dec->u4_disp_buf_to_be_freed[i]) + continue; + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, i, + BUF_MGR_IO); + ps_dec->u4_disp_buf_to_be_freed[i] = 0; + ps_dec->u4_disp_buf_mapping[i] = 0; + + } + } + if(!(u1_field_pic_flag && 0 != ps_dec->u1_top_bottom_decoded)) //ps_dec->u1_second_field)) + { + pic_buffer_t *ps_cur_pic; + WORD32 cur_pic_buf_id, cur_mv_buf_id; + col_mv_buf_t *ps_col_mv; + while(1) + { + ps_cur_pic = (pic_buffer_t *)ih264_buf_mgr_get_next_free( + (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + &cur_pic_buf_id); + if(ps_cur_pic == NULL) + { + ps_dec->i4_error_code = ERROR_UNAVAIL_PICBUF_T; + return ERROR_UNAVAIL_PICBUF_T; + } + if(0 == ps_dec->u4_disp_buf_mapping[cur_pic_buf_id]) + { + break; + } + + } + ps_col_mv = (col_mv_buf_t *)ih264_buf_mgr_get_next_free((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + &cur_mv_buf_id); + if(ps_col_mv == NULL) + { + ps_dec->i4_error_code = ERROR_UNAVAIL_MVBUF_T; + return ERROR_UNAVAIL_MVBUF_T; + } + + ps_dec->ps_cur_pic = ps_cur_pic; + ps_dec->u1_pic_buf_id = cur_pic_buf_id; + ps_cur_pic->u4_ts = ps_dec->u4_ts; + + + ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id; + ps_dec->au1_pic_buf_id_mv_buf_id_map[cur_pic_buf_id] = cur_mv_buf_id; + + ps_cur_pic->pu1_col_zero_flag = (UWORD8 *)ps_col_mv->pv_col_zero_flag; + ps_cur_pic->ps_mv = (mv_pred_t *)ps_col_mv->pv_mv; + ps_dec->au1_pic_buf_ref_flag[cur_pic_buf_id] = 0; + + if(!ps_dec->ps_cur_pic) + { + H264_DEC_DEBUG_PRINT("------- Display Buffers Reset --------\n"); + WORD32 j; + for(j = 0; j < MAX_DISP_BUFS_NEW; j++) + { + + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + j, + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[j], + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + j, + BUF_MGR_IO); + } + + ps_dec->i4_cur_display_seq = 0; + ps_dec->i4_prev_max_display_seq = 0; + ps_dec->i4_max_poc = 0; + + ps_cur_pic = (pic_buffer_t *)ih264_buf_mgr_get_next_free( + (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + &cur_pic_buf_id); + if(ps_cur_pic == NULL) + { + ps_dec->i4_error_code = ERROR_UNAVAIL_PICBUF_T; + return ERROR_UNAVAIL_PICBUF_T; + } + + ps_col_mv = (col_mv_buf_t *)ih264_buf_mgr_get_next_free((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + &cur_mv_buf_id); + if(ps_col_mv == NULL) + { + ps_dec->i4_error_code = ERROR_UNAVAIL_MVBUF_T; + return ERROR_UNAVAIL_MVBUF_T; + } + + ps_dec->ps_cur_pic = ps_cur_pic; + ps_dec->u1_pic_buf_id = cur_pic_buf_id; + ps_cur_pic->u4_ts = ps_dec->u4_ts; + ps_dec->apv_buf_id_pic_buf_map[cur_pic_buf_id] = (void *)ps_cur_pic; + + ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id; + ps_dec->au1_pic_buf_id_mv_buf_id_map[cur_pic_buf_id] = cur_mv_buf_id; + + ps_cur_pic->pu1_col_zero_flag = (UWORD8 *)ps_col_mv->pv_col_zero_flag; + ps_cur_pic->ps_mv = (mv_pred_t *)ps_col_mv->pv_mv; + ps_dec->au1_pic_buf_ref_flag[cur_pic_buf_id] = 0; + + } + + ps_dec->ps_cur_pic->u1_picturetype = u1_field_pic_flag; + ps_dec->ps_cur_pic->u4_pack_slc_typ = SKIP_NONE; + H264_DEC_DEBUG_PRINT("got a buffer\n"); + } + else + { + H264_DEC_DEBUG_PRINT("did not get a buffer\n"); + } + + ps_dec->u4_pic_buf_got = 1; + + ps_dec->ps_cur_pic->i4_poc = i4_poc; + ps_dec->ps_cur_pic->i4_frame_num = u2_frame_num; + ps_dec->ps_cur_pic->i4_pic_num = u2_frame_num; + ps_dec->ps_cur_pic->i4_top_field_order_cnt = ps_pps->i4_top_field_order_cnt; + ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = + ps_pps->i4_bottom_field_order_cnt; + ps_dec->ps_cur_pic->i4_avg_poc = ps_pps->i4_avg_poc; + ps_dec->ps_cur_pic->u4_time_stamp = ps_dec->u4_pts; + + ps_dec->s_cur_pic = *(ps_dec->ps_cur_pic); + if(u1_field_pic_flag && u1_bottom_field_flag) + { + WORD32 i4_temp_poc; + WORD32 i4_top_field_order_poc, i4_bot_field_order_poc; + /* Point to odd lines, since it's bottom field */ + ps_dec->s_cur_pic.pu1_buf1 += ps_dec->s_cur_pic.u2_frm_wd_y; + ps_dec->s_cur_pic.pu1_buf2 += ps_dec->s_cur_pic.u2_frm_wd_uv; + ps_dec->s_cur_pic.pu1_buf3 += ps_dec->s_cur_pic.u2_frm_wd_uv; + ps_dec->s_cur_pic.ps_mv += + ((ps_dec->u2_pic_ht * ps_dec->u2_pic_wd) >> 5); + ps_dec->s_cur_pic.pu1_col_zero_flag += ((ps_dec->u2_pic_ht + * ps_dec->u2_pic_wd) >> 5); + ps_dec->ps_cur_pic->u1_picturetype |= BOT_FLD; + i4_top_field_order_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + i4_bot_field_order_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + i4_temp_poc = MIN(i4_top_field_order_poc, + i4_bot_field_order_poc); + ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc; + } + + ps_cur_slice->u1_mbaff_frame_flag = ps_seq->u1_mb_aff_flag + && (!u1_field_pic_flag); + + ps_dec->ps_cur_pic->u1_picturetype |= (ps_cur_slice->u1_mbaff_frame_flag + << 2); + if(ps_cur_slice->u1_mbaff_frame_flag) + { + ps_dec->u2_mb_group_cols_y = ((ps_dec->u1_recon_mb_grp >> 1) << 4) + 8; + ps_dec->u2_mb_group_cols_cr = ((ps_dec->u1_recon_mb_grp >> 1) << 3) + 8; + } + else + { + ps_dec->u2_mb_group_cols_y = (ps_dec->u1_recon_mb_grp << 4) + 8; + ps_dec->u2_mb_group_cols_cr = (ps_dec->u1_recon_mb_grp << 3) + 8; + } + + + + + + ps_dec->ps_cur_mb_row = ps_dec->ps_nbr_mb_row; //[0]; + ps_dec->ps_cur_mb_row++; //Increment by 1 ,so that left mb will always be valid + ps_dec->ps_top_mb_row = + ps_dec->ps_nbr_mb_row + + ((ps_dec->u2_frm_wd_in_mbs + 1) + << (1 + - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag)); + ps_dec->ps_top_mb_row++; //Increment by 1 ,so that left mb will always be valid + + ps_dec->u2_mb_group_cols_y1 = ps_dec->u2_mb_group_cols_y; + ps_dec->u2_mb_group_cols_cr1 = ps_dec->u2_mb_group_cols_cr; + ps_dec->pu1_y = ps_dec->pu1_y_scratch[0]; + ps_dec->pu1_u = ps_dec->pu1_u_scratch[0]; + ps_dec->pu1_v = ps_dec->pu1_v_scratch[0]; + ps_dec->u1_yuv_scratch_idx = 0; + /* CHANGED CODE */ + ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv; + ps_dec->ps_mv_top = ps_dec->ps_mv_top_p[0]; + /* CHANGED CODE */ + ps_dec->u1_mv_top_p = 0; + ps_dec->u1_mb_idx = 0; + /* CHANGED CODE */ + ps_dec->ps_mv_left = ps_dec->s_cur_pic.ps_mv; + ps_dec->pu1_yleft = 0; + ps_dec->pu1_uleft = 0; + ps_dec->pu1_vleft = 0; + ps_dec->u1_not_wait_rec = 2; + ps_dec->u2_total_mbs_coded = 0; + ps_dec->i4_submb_ofst = -(SUB_BLK_SIZE); + ps_dec->u4_pred_info_idx = 0; + ps_dec->u4_pred_info_pkd_idx = 0; + ps_dec->u4_dma_buf_idx = 0; + ps_dec->ps_mv = ps_dec->s_cur_pic.ps_mv; + ps_dec->ps_mv_bank_cur = ps_dec->s_cur_pic.ps_mv; + ps_dec->pu1_col_zero_flag = ps_dec->s_cur_pic.pu1_col_zero_flag; + ps_dec->ps_part = ps_dec->ps_parse_part_params; + ps_dec->i2_prev_slice_mbx = -1; + ps_dec->i2_prev_slice_mby = 0; + ps_dec->u2_mv_2mb[0] = 0; + ps_dec->u2_mv_2mb[1] = 0; + ps_dec->u1_last_pic_not_decoded = 0; + + ps_dec->u2_cur_slice_num = 0; + ps_dec->u2_cur_slice_num_dec_thread = 0; + ps_dec->u2_cur_slice_num_bs = 0; + ps_dec->u4_intra_pred_line_ofst = 0; + ps_dec->pu1_cur_y_intra_pred_line = ps_dec->pu1_y_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line = ps_dec->pu1_u_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line = ps_dec->pu1_v_intra_pred_line; + + ps_dec->pu1_cur_y_intra_pred_line_base = ps_dec->pu1_y_intra_pred_line; + ps_dec->pu1_cur_u_intra_pred_line_base = ps_dec->pu1_u_intra_pred_line; + ps_dec->pu1_cur_v_intra_pred_line_base = ps_dec->pu1_v_intra_pred_line; + + + + + + ps_dec->pu1_prev_y_intra_pred_line = ps_dec->pu1_y_intra_pred_line + + (ps_dec->u2_frm_wd_in_mbs * MB_SIZE); + + ps_dec->pu1_prev_u_intra_pred_line = ps_dec->pu1_u_intra_pred_line + + ps_dec->u2_frm_wd_in_mbs * BLK8x8SIZE * YUV420SP_FACTOR; + ps_dec->pu1_prev_v_intra_pred_line = ps_dec->pu1_v_intra_pred_line + + ps_dec->u2_frm_wd_in_mbs * BLK8x8SIZE; + + ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic; + ps_dec->ps_deblk_mbn_curr = ps_dec->ps_deblk_mbn; + ps_dec->ps_deblk_mbn_prev = ps_dec->ps_deblk_mbn + ps_dec->u1_recon_mb_grp; + /* Initialize The Function Pointer Depending Upon the Entropy and MbAff Flag */ + { + if(ps_cur_slice->u1_mbaff_frame_flag) + { + ps_dec->pf_compute_bs = ih264d_compute_bs_mbaff; + ps_dec->pf_mvpred = ih264d_mvpred_mbaff; + } + else + { + ps_dec->pf_compute_bs = ih264d_compute_bs_non_mbaff; + ps_dec->u1_cur_mb_fld_dec_flag = ps_cur_slice->u1_field_pic_flag; + } + } + /* Set up the Parameter for DMA transfer */ + { + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + + UWORD8 u1_mbaff = ps_cur_slice->u1_mbaff_frame_flag; + + UWORD8 uc_lastmbs = (((ps_dec->u2_pic_wd) >> 4) + % (ps_dec->u1_recon_mb_grp >> u1_mbaff)); + UWORD16 ui16_lastmbs_widthY = + (uc_lastmbs ? (uc_lastmbs << 4) : ((ps_dec->u1_recon_mb_grp + >> u1_mbaff) << 4)); + UWORD16 ui16_lastmbs_widthUV = + uc_lastmbs ? (uc_lastmbs << 3) : ((ps_dec->u1_recon_mb_grp + >> u1_mbaff) << 3); + + ps_dec->s_tran_addrecon.pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1; + ps_dec->s_tran_addrecon.pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2; + ps_dec->s_tran_addrecon.pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3; + + ps_dec->s_tran_addrecon.u2_frm_wd_y = ps_dec->u2_frm_wd_y + << u1_field_pic_flag; + ps_dec->s_tran_addrecon.u2_frm_wd_uv = ps_dec->u2_frm_wd_uv + << u1_field_pic_flag; + + if(u1_field_pic_flag) + { + ui16_lastmbs_widthY += ps_dec->u2_frm_wd_y; + ui16_lastmbs_widthUV += ps_dec->u2_frm_wd_uv; + } + + /* Normal Increment of Pointer */ + ps_dec->s_tran_addrecon.u4_inc_y[0] = ((ps_dec->u1_recon_mb_grp << 4) + >> u1_mbaff); + ps_dec->s_tran_addrecon.u4_inc_uv[0] = ((ps_dec->u1_recon_mb_grp << 4) + >> u1_mbaff); + + /* End of Row Increment */ + ps_dec->s_tran_addrecon.u4_inc_y[1] = (ui16_lastmbs_widthY + + (PAD_LEN_Y_H << 1) + + ps_dec->s_tran_addrecon.u2_frm_wd_y + * ((15 << u1_mbaff) + u1_mbaff)); + ps_dec->s_tran_addrecon.u4_inc_uv[1] = (ui16_lastmbs_widthUV + + (PAD_LEN_UV_H << 2) + + ps_dec->s_tran_addrecon.u2_frm_wd_uv + * ((15 << u1_mbaff) + u1_mbaff)); + + /* Assign picture numbers to each frame/field */ + /* only once per picture. */ + ih264d_assign_pic_num(ps_dec); + ps_dec->s_tran_addrecon.u2_mv_top_left_inc = (ps_dec->u1_recon_mb_grp + << 2) - 1 - (u1_mbaff << 2); + ps_dec->s_tran_addrecon.u2_mv_left_inc = ((ps_dec->u1_recon_mb_grp + >> u1_mbaff) - 1) << (4 + u1_mbaff); + } + /**********************************************************************/ + /* High profile related initialization at pictrue level */ + /**********************************************************************/ + if(ps_seq->u1_profile_idc == HIGH_PROFILE_IDC) + { + if((ps_seq->i4_seq_scaling_matrix_present_flag) + || (ps_pps->i4_pic_scaling_matrix_present_flag)) + { + ih264d_form_scaling_matrix_picture(ps_seq, ps_pps, ps_dec); + ps_dec->s_high_profile.u1_scaling_present = 1; + } + else + { + ih264d_form_default_scaling_matrix(ps_dec); + } + + if(ps_pps->i4_transform_8x8_mode_flag) + { + ps_dec->s_high_profile.u1_transform8x8_present = 1; + } + } + else + { + ih264d_form_default_scaling_matrix(ps_dec); + } + + /* required while reading the transform_size_8x8 u4_flag */ + ps_dec->s_high_profile.u1_direct_8x8_inference_flag = + ps_seq->u1_direct_8x8_inference_flag; + ps_dec->s_high_profile.s_cavlc_ctxt = ps_dec->s_cavlc_ctxt; + + if(ps_dec->u1_separate_parse) + { + memcpy(&ps_dec->s_tran_addrecon_parse, &ps_dec->s_tran_addrecon, + sizeof(tfr_ctxt_t)); + } + + H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_deblock_display \endif + * + * \brief : The function callls the deblocking routine and manages + : the Recon buffers and displays . + * \return : Nothing + * + ************************************************************************** + */ +WORD32 ih264d_end_of_pic_dispbuf_mgr(dec_struct_t * ps_dec) +{ + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + UWORD8 u1_num_of_users = 0; + WORD32 ret; + + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + if(1) + { + + { + ih264d_delete_nonref_nondisplay_pics(ps_dec->ps_dpb_mgr); + if(ps_cur_slice->u1_mmco_equalto5 + || (ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)) + { + ps_dec->ps_cur_pic->i4_poc = 0; + if(ps_dec->u2_total_mbs_coded + == (ps_dec->ps_cur_sps->u2_max_mb_addr + 1)) + ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); + ih264d_release_display_bufs(ps_dec); + } + if(ps_dec->u4_num_reorder_frames_at_init != 0) + { + ret = ih264d_assign_display_seq(ps_dec); + if(ret != OK) + return ret; + } + } + + if(ps_cur_slice->u1_nal_ref_idc) + { + /* Mark pic buf as needed for reference */ + ih264_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_dec->u1_pic_buf_id, + BUF_MGR_REF); + /* Mark mv buf as needed for reference */ + ih264_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + BUF_MGR_REF); + ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] = 1; + } + + /* 420 consumer */ + /* Increment the number of users by 1 for display based upon */ + /*the SEEK KEY FRAME control sent to decoder */ + if(((0 == ps_dec->u1_last_pic_not_decoded) + && (0 + == (ps_dec->ps_cur_pic->u4_pack_slc_typ + & ps_dec->u4_skip_frm_mask))) + || (ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)) + { + /* Mark pic buf as needed for display */ + ih264_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_dec->u1_pic_buf_id, + BUF_MGR_IO); + + } + + if(!ps_cur_slice->u1_field_pic_flag + || ((TOP_FIELD_ONLY | BOT_FIELD_ONLY) + != ps_dec->u1_top_bottom_decoded)) + { + pic_buffer_t *ps_cur_pic = ps_dec->ps_cur_pic; + ps_cur_pic->u2_disp_width = ps_dec->u2_disp_width; + ps_cur_pic->u2_disp_height = ps_dec->u2_disp_height >> 1; + + ps_cur_pic->u2_crop_offset_y = ps_dec->u2_crop_offset_y; + ps_cur_pic->u2_crop_offset_uv = ps_dec->u2_crop_offset_uv; + ps_cur_pic->u1_pic_type = 0; + + ret = ih264d_insert_pic_in_display_list( + ps_dec->ps_dpb_mgr, + ps_dec->u1_pic_buf_id, + ps_dec->i4_prev_max_display_seq + + ps_dec->ps_cur_pic->i4_poc, + ps_dec->ps_cur_pic->i4_frame_num); + if(ret != OK) + return ret; + + { + ivd_video_decode_op_t * ps_dec_output = + (ivd_video_decode_op_t *)ps_dec->pv_dec_out; + + ps_dec_output->u4_frame_decoded_flag = 1; + } + if(ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] == 0) + { + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + BUF_MGR_REF); + ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] = 0; + + } + } + else + { + H264_DEC_DEBUG_PRINT("pic not inserted display %d %d\n", + ps_cur_slice->u1_field_pic_flag, + ps_dec->u1_second_field); + } + { + + if(!ps_cur_slice->u1_end_of_frame_signal) + { + ps_cur_slice->u1_end_of_frame_signal = 1; + } + } + + if(!ps_cur_slice->u1_field_pic_flag + || ((TOP_FIELD_ONLY | BOT_FIELD_ONLY) + == ps_dec->u1_top_bottom_decoded)) + { + if(ps_dec->u4_num_reorder_frames_at_init == 0) + { + ret = ih264d_assign_display_seq(ps_dec); + if(ret != OK) + return ret; + } + } + } + + H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + + return OK; +} + +void ih264d_err_pic_dispbuf_mgr(dec_struct_t *ps_dec) +{ + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + ivd_video_decode_op_t * ps_dec_output = + (ivd_video_decode_op_t *)ps_dec->pv_dec_out; + + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_dec->u1_pic_buf_id, + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, + ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + BUF_MGR_REF); + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_dec->u1_pic_buf_id, + BUF_MGR_IO); +} + +void ih264d_deblock_picture(void *ptr) +{ + dec_struct_t *ps_dec = (dec_struct_t *)ptr; + + { + /*Deblock picture only if all the mb's in the frame have been decoded*/ + if(ps_dec->u1_pic_decode_done == 1) + { + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag + || ps_dec->ps_cur_slice->u1_field_pic_flag) + { + ps_dec->p_DeblockPicture[ps_dec->ps_cur_slice->u1_mbaff_frame_flag]( + ps_dec); + } + else + + { + + ih264d_deblock_picture_progressive(ps_dec); + } + + } + } + +} + +/*! + ************************************************************************** + * \if Function name : ih264d_deblock_display \endif + * + * \brief : The function callls the deblocking routine and manages + : the Recon buffers and displays . + * \return : Nothing + * + ************************************************************************** + */ +WORD32 ih264d_deblock_display(dec_struct_t *ps_dec) +{ + WORD32 ret; + /* Call deblocking */ + ih264d_deblock_picture(ps_dec); + + ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec); + if(ret != OK) + return ret; + + return OK; +} + +/* + *! + ************************************************************************** + * \if Function name : EndofPoc \endif + * + * \brief + * EndofPoc Processing + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_end_of_pic(dec_struct_t *ps_dec, + UWORD8 u1_is_idr_slice, + UWORD16 u2_frame_num) +{ + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + WORD32 ret; + + ps_dec->u1_first_nal_in_pic = 1; + ps_dec->u1_first_pb_nal_in_pic = 1; + ps_dec->u2_mbx = 0xffff; + ps_dec->u2_mby = 0; + { + dec_err_status_t * ps_err = ps_dec->ps_dec_err_status; + if(ps_err->u1_err_flag & REJECT_CUR_PIC) + { + ps_err->u1_err_flag ^= REJECT_CUR_PIC; + ih264d_err_pic_dispbuf_mgr(ps_dec); + return OK; + } + } + + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + ret = ih264d_end_of_pic_processing(ps_dec); + if(ret != OK) + return ret; + ps_dec->u2_total_mbs_coded = 0; + /*--------------------------------------------------------------------*/ + /* ih264d_decode_pic_order_cnt - calculate the Pic Order Cnt */ + /* Needed to detect end of picture */ + /*--------------------------------------------------------------------*/ + { + pocstruct_t *ps_prev_poc = &ps_dec->s_prev_pic_poc; + pocstruct_t *ps_cur_poc = &ps_dec->s_cur_pic_poc; + if((0 == u1_is_idr_slice) && ps_cur_slice->u1_nal_ref_idc) + ps_dec->u2_prev_ref_frame_num = ps_cur_slice->u2_frame_num; + + if(u1_is_idr_slice || ps_cur_slice->u1_mmco_equalto5) + ps_dec->u2_prev_ref_frame_num = 0; + + if(ps_dec->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag) + { + ret = ih264d_decode_gaps_in_frame_num(ps_dec, u2_frame_num); + if(ret != OK) + return ret; + } + + 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_slice->u1_mmco_equalto5; + if(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; + } + } + if(!ps_cur_slice->u1_end_of_frame_signal) + { + return ERROR_END_OF_FRAME_EXPECTED_T; + } H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : DecodeSlice \endif + * + * \brief + * Parses a slice + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ + +WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, + UWORD8 u1_nal_ref_idc, + dec_struct_t *ps_dec /* Decoder parameters */ + ) +{ + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + dec_pic_params_t *ps_pps; + dec_seq_params_t *ps_seq; + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + pocstruct_t s_tmp_poc; + WORD32 i_delta_poc[2]; + WORD32 i4_poc = 0; + UWORD16 u2_first_mb_in_slice, u2_frame_num; + UWORD8 u1_field_pic_flag, u1_redundant_pic_cnt = 0, u1_slice_type; + UWORD32 u4_idr_pic_id = 0; + UWORD8 u1_bottom_field_flag, u1_pic_order_cnt_type; + + UWORD8 u1_nal_unit_type; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + WORD8 i1_is_end_of_poc; + + WORD32 ret; + UWORD32 u4_temp; + WORD32 i_temp; + UWORD32 u4_call_end_of_pic = 0; + + /*--------------------------------------------------------------------*/ + /* Decode Portion of the Slice header */ + /* This is done to detect end of picture */ + /*--------------------------------------------------------------------*/ + + if(ps_dec->u4_first_slice_in_pic == 0) + { + volatile dec_slice_struct_t *ps_next_slice; + + ps_next_slice = ps_dec->ps_parse_cur_slice + 1; + + /*Reset the ready u4_flag and then increment*/ + ps_next_slice->slice_header_done = 0; + DATA_SYNC(); + ps_dec->ps_parse_cur_slice++; + } + + /* read FirstMbInSlice and slice type*/ + ps_dec->ps_dpb_cmds->u1_dpb_commands_read_slc = 0; + u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if(u2_first_mb_in_slice + > (ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)) + { + + return ERROR_CORRUPTED_SLICE; + } + + /*we currently don not support ASO*/ + if(((u2_first_mb_in_slice << ps_cur_slice->u1_mbaff_frame_flag) + <= ps_dec->u2_cur_mb_addr) && (ps_dec->u2_cur_mb_addr != 0) + && (ps_dec->u4_first_slice_in_pic != 0)) + { + return ERROR_CORRUPTED_SLICE; + } + + COPYTHECONTEXT("SH: first_mb_in_slice",u2_first_mb_in_slice); + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + + if(u4_temp > 9) + return ERROR_INV_SLC_TYPE_T; + + u1_slice_type = u4_temp; + COPYTHECONTEXT("SH: slice_type",(u1_slice_type)); + ps_dec->u1_sl_typ_5_9 = 0; + /* Find Out the Slice Type is 5 to 9 or not then Set the Flag */ + /* u1_sl_typ_5_9 = 1 .Which tells that all the slices in the Pic*/ + /* will be of same type of current */ + if(u1_slice_type > 4) + { + u1_slice_type -= 5; + ps_dec->u1_sl_typ_5_9 = 1; + } + + { + UWORD32 skip; + + if((ps_dec->i4_app_skip_mode == IVD_SKIP_PB) + || (ps_dec->i4_dec_skip_mode == IVD_SKIP_PB)) + { + UWORD32 u4_bit_stream_offset = 0; + + if(ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) + { + skip = 0; + + ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE; + } + else if((I_SLICE == u1_slice_type) + && (1 >= ps_dec->ps_sps->u1_num_ref_frames)) + { + skip = 0; + + ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE; + } + else + { + skip = 1; + } + + /* If one frame worth of data is already skipped, do not skip the next one */ + if((0 == u2_first_mb_in_slice) && (1 == ps_dec->u4_prev_nal_skipped)) + { + skip = 0; + } + + if(skip) + { + ps_dec->u4_prev_nal_skipped = 1; + ps_dec->i4_dec_skip_mode = IVD_SKIP_PB; + return 0; + } + else + { + /* If the previous NAL was skipped, then + do not process that buffer in this call. + Return to app and process it in the next call. + This is necessary to handle cases where I/IDR is not complete in + the current buffer and application intends to fill the remaining part of the bitstream + later. This ensures we process only frame worth of data in every call */ + if(1 == ps_dec->u4_prev_nal_skipped) + { + ps_dec->u4_return_to_app = 1; + return 0; + } + } + } + + } + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_ERR_PIC_SET_ID) + return ERROR_INV_SPS_PPS_T; + /* discard slice if pic param is invalid */ + COPYTHECONTEXT("SH: pic_parameter_set_id", u4_temp); + ps_pps = &ps_dec->ps_pps[u4_temp]; + if(FALSE == ps_pps->u1_is_valid) + { + return ERROR_INV_SPS_PPS_T; + } + ps_seq = ps_pps->ps_sps; + if(!ps_seq) + return ERROR_INV_SPS_PPS_T; + if(FALSE == ps_seq->u1_is_valid) + return ERROR_INV_SPS_PPS_T; + + /* Get the frame num */ + u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, + ps_seq->u1_bits_in_frm_num); +// H264_DEC_DEBUG_PRINT("FRAME %d First MB in slice: %d\n", u2_frame_num, u2_first_mb_in_slice); + + COPYTHECONTEXT("SH: frame_num", u2_frame_num); +// H264_DEC_DEBUG_PRINT("Second field: %d frame num: %d prv_frame_num: %d \n", ps_dec->u1_second_field, u2_frame_num, ps_dec->u2_prv_frame_num); + + /* Get the field related flags */ + if(!ps_seq->u1_frame_mbs_only_flag) + { + + u1_field_pic_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: field_pic_flag", u1_field_pic_flag); + u1_bottom_field_flag = 0; + + if(u1_field_pic_flag) + { + ps_dec->pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_fld; + u1_bottom_field_flag = ih264d_get_bit_h264(ps_bitstrm); + COPYTHECONTEXT("SH: bottom_field_flag", u1_bottom_field_flag); + + } + else + { + ps_dec->pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + } + } + else + { + u1_field_pic_flag = 0; + u1_bottom_field_flag = 0; + + ps_dec->pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + } + + u1_nal_unit_type = SLICE_NAL; + if(u1_is_idr_slice) + { + if(0 == u1_field_pic_flag) + { + ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY; + } + u1_nal_unit_type = IDR_SLICE_NAL; + u4_idr_pic_id = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if(u4_idr_pic_id > 65535) + return ERROR_INV_SPS_PPS_T; + COPYTHECONTEXT("SH: ", u4_idr_pic_id); + } + + /* read delta pic order count information*/ + i_delta_poc[0] = i_delta_poc[1] = 0; + s_tmp_poc.i4_pic_order_cnt_lsb = 0; + s_tmp_poc.i4_delta_pic_order_cnt_bottom = 0; + u1_pic_order_cnt_type = ps_seq->u1_pic_order_cnt_type; + if(u1_pic_order_cnt_type == 0) + { + i_temp = ih264d_get_bits_h264( + ps_bitstrm, + ps_seq->u1_log2_max_pic_order_cnt_lsb_minus); + if(i_temp < 0 || i_temp >= ps_seq->i4_max_pic_order_cntLsb) + return ERROR_INV_SPS_PPS_T; + s_tmp_poc.i4_pic_order_cnt_lsb = i_temp; + COPYTHECONTEXT("SH: pic_order_cnt_lsb", s_tmp_poc.i4_pic_order_cnt_lsb); + + if((ps_pps->u1_pic_order_present_flag == 1) && (!u1_field_pic_flag)) + { + s_tmp_poc.i4_delta_pic_order_cnt_bottom = ih264d_sev( + pu4_bitstrm_ofst, pu4_bitstrm_buf); + //if(s_tmp_poc.i4_delta_pic_order_cnt_bottom > ps_seq->i4_max_pic_order_cntLsb) + COPYTHECONTEXT("SH: delta_pic_order_cnt_bottom", + s_tmp_poc.i4_delta_pic_order_cnt_bottom); + } + } + + s_tmp_poc.i4_delta_pic_order_cnt[0] = 0; + s_tmp_poc.i4_delta_pic_order_cnt[1] = 0; + if(u1_pic_order_cnt_type == 1 + && (!ps_seq->u1_delta_pic_order_always_zero_flag)) + { + s_tmp_poc.i4_delta_pic_order_cnt[0] = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + COPYTHECONTEXT("SH: delta_pic_order_cnt[0]", + s_tmp_poc.i4_delta_pic_order_cnt[0]); + + if(ps_pps->u1_pic_order_present_flag && !u1_field_pic_flag) + { + s_tmp_poc.i4_delta_pic_order_cnt[1] = ih264d_sev( + pu4_bitstrm_ofst, pu4_bitstrm_buf); + COPYTHECONTEXT("SH: delta_pic_order_cnt[1]", + s_tmp_poc.i4_delta_pic_order_cnt[1]); + } + } + + if(ps_pps->u1_redundant_pic_cnt_present_flag) + { + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp > MAX_REDUNDANT_PIC_CNT) + return ERROR_INV_SPS_PPS_T; + u1_redundant_pic_cnt = u4_temp; + COPYTHECONTEXT("SH: redundant_pic_cnt", u1_redundant_pic_cnt); + } + /*--------------------------------------------------------------------*/ + /* Check if the slice is part of new picture if so do End of Pic */ + /* processing. */ + /*--------------------------------------------------------------------*/ + i1_is_end_of_poc = 0; + if(!ps_dec->u1_first_nal_in_pic) + { + UWORD8 uc_mbs_exceed = 0; + i1_is_end_of_poc = ih264d_is_end_of_pic(u2_frame_num, u1_nal_ref_idc, + &s_tmp_poc, &ps_dec->s_cur_pic_poc, + ps_cur_slice, u1_pic_order_cnt_type, + u1_nal_unit_type, u4_idr_pic_id, + u1_field_pic_flag, + u1_bottom_field_flag); + + /*since we support only Full frame decode, every new process should + * process a new pic + */ + if(ps_dec->u4_first_slice_in_pic == 1) + { + i1_is_end_of_poc = 1; + } + + if(ps_dec->u2_total_mbs_coded + == (ps_dec->ps_cur_sps->u2_max_mb_addr + 1)) + { + /*u2_total_mbs_coded is forced to u2_max_mb_addr+ 1 at the end of decode ,so + ,if it is first slice in pic dont consider u2_total_mbs_coded to detect new picture */ + if(ps_dec->u4_first_slice_in_pic == 0) + uc_mbs_exceed = 1; + } + + if(i1_is_end_of_poc || uc_mbs_exceed) + { + + if(1 == ps_dec->u1_last_pic_not_decoded) + { + ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec); + + if(ret != OK) + return ret; + + ret = ih264d_end_of_pic(ps_dec, u1_is_idr_slice, u2_frame_num); + if(ret != OK) + return ret; +#if WIN32 + H264_DEC_DEBUG_PRINT(" ------ PIC SKIPPED ------\n"); +#endif + return RET_LAST_SKIP; + } + else + { + if((ps_dec->u2_total_mbs_coded + < (ps_dec->ps_cur_sps->u2_max_mb_addr + 1))) + { + H264_DEC_DEBUG_PRINT("Hello\n"); + ps_dec->u2_total_mbs_coded = + ps_dec->ps_cur_sps->u2_max_mb_addr + 1; + ps_dec->u1_first_nal_in_pic = 1; + ps_dec->u1_first_pb_nal_in_pic = 1; + return ERROR_END_OF_FRAME_EXPECTED_T; + /*if (ps_cur_slice->u1_field_pic_flag && + ((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)) + { + ps_cur_slice->u1_end_of_frame_signal = 0; + }*/ + } + ret = ih264d_end_of_pic(ps_dec, u1_is_idr_slice, u2_frame_num); + if(ret != OK) + return ret; + } + + } + else + { + + if(ps_dec->u4_first_slice_in_pic == 1) + { + /*If the first slice in decode api is not from a new picture, + * we will return error code ,as we don't support partial + frame decode*/ + return ERROR_PIC_NUM_IS_REPEATED; + } + } + } + ps_cur_slice->u1_end_of_frame_signal = 0; + if(u1_field_pic_flag) + { + /* + * Check if the frame number has changed. + */ + H264_DEC_DEBUG_PRINT( + "u2_frame_num: %d ps_dec->u2_prv_frame_num: %d ps_dec->u1_top_bottom_decoded: %d\n", + u2_frame_num, ps_dec->u2_prv_frame_num, + ps_dec->u1_top_bottom_decoded); + if((u2_frame_num != ps_dec->u2_prv_frame_num) + && (0 != ps_dec->u1_top_bottom_decoded)) + { + if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) + != ps_dec->u1_top_bottom_decoded) + { + H264_DEC_DEBUG_PRINT("Dangling Field, toggling second field\n"); + ps_dec->u1_second_field = 1 - ps_dec->u1_second_field; + ps_dec->u1_dangling_field = 1; + /* + * Updating the u1_bottom_field_flag since its used in the concealment function. + */ + ps_cur_slice->u1_bottom_field_flag = u1_bottom_field_flag; + ps_dec->u2_prv_frame_num = u2_frame_num; + + ret = ih264d_deblock_display(ps_dec); + if(ret != OK) + return ret; + + /* + * The bytes consumed will be handled by the + * video_decode function after the error is handled. + */ + return ERROR_DANGLING_FIELD_IN_PIC; + + } + + } + + ps_dec->u2_prv_frame_num = u2_frame_num; + } + + if(ps_cur_slice->u1_mmco_equalto5) + { + WORD32 i4_temp_poc; + WORD32 i4_top_field_order_poc, i4_bot_field_order_poc; + + if(!ps_cur_slice->u1_field_pic_flag) // or a complementary field pair + { + i4_top_field_order_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + i4_bot_field_order_poc = + ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + i4_temp_poc = MIN(i4_top_field_order_poc, + i4_bot_field_order_poc); + } + else if(!ps_cur_slice->u1_bottom_field_flag) + i4_temp_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + else + i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + + ps_dec->ps_cur_pic->i4_top_field_order_cnt = i4_temp_poc + - ps_dec->ps_cur_pic->i4_top_field_order_cnt; + ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i4_temp_poc + - ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + ps_dec->ps_cur_pic->i4_poc = i4_temp_poc; + ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc; + } + if(ps_dec->u1_first_nal_in_pic) + { + ret = ih264d_decode_pic_order_cnt(u1_is_idr_slice, u2_frame_num, + &ps_dec->s_prev_pic_poc, + &s_tmp_poc, ps_cur_slice, ps_pps, + u1_nal_ref_idc, + u1_bottom_field_flag, + u1_field_pic_flag, &i4_poc); + if(ret != OK) + return ret; + /* Display seq no calculations */ + if(i4_poc >= ps_dec->i4_max_poc) + ps_dec->i4_max_poc = i4_poc; + /* IDR Picture or POC wrap around */ + if(i4_poc == 0) + { + ps_dec->i4_prev_max_display_seq = ps_dec->i4_prev_max_display_seq + + ps_dec->i4_max_poc + + ps_dec->u1_max_dec_frame_buffering + 1; + ps_dec->i4_max_poc = 0; + } + } + + /*--------------------------------------------------------------------*/ + /* 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] = i_delta_poc[0]; + ps_cur_slice->i4_delta_pic_order_cnt[1] = i_delta_poc[1]; + ps_cur_slice->u4_idr_pic_id = u4_idr_pic_id; + ps_cur_slice->u2_first_mb_in_slice = u2_first_mb_in_slice; + 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->u1_slice_type = u1_slice_type; + ps_cur_slice->i4_pic_order_cnt_lsb = s_tmp_poc.i4_pic_order_cnt_lsb; + + ps_cur_slice->u1_nal_unit_type = u1_nal_unit_type; + ps_cur_slice->u1_redundant_pic_cnt = u1_redundant_pic_cnt; + ps_cur_slice->u1_nal_ref_idc = u1_nal_ref_idc; + ps_cur_slice->u1_pic_order_cnt_type = u1_pic_order_cnt_type; + + if(ps_seq->u1_frame_mbs_only_flag) + ps_cur_slice->u1_direct_8x8_inference_flag = + ps_seq->u1_direct_8x8_inference_flag; + else + ps_cur_slice->u1_direct_8x8_inference_flag = 1; + + if(u1_slice_type == B_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); + + 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; + if(!((ps_pps->ps_sps->u1_mb_aff_flag) && (!u1_field_pic_flag))) + ps_dec->pf_mvpred = ih264d_mvpred_nonmbaffB; + } + else + { + if(!((ps_pps->ps_sps->u1_mb_aff_flag) && (!u1_field_pic_flag))) + ps_dec->pf_mvpred = ih264d_mvpred_nonmbaff; + } + + if(ps_dec->u1_first_nal_in_pic) + { + ret = ih264d_start_of_pic(ps_dec, i4_poc, &s_tmp_poc, u2_frame_num, ps_pps); + if(ret != OK) + return ret; + + ps_dec->u4_output_present = 0; + + if(1 == ps_dec->u4_fmt_conv_in_process) + { + ih264d_get_next_display_field(ps_dec, + ps_dec->ps_out_buffer, + &(ps_dec->s_disp_op)); + /* If error code is non-zero then there is no buffer available for display, + hence avoid format conversion */ + + if(0 != ps_dec->s_disp_op.u4_error_code) + { + ps_dec->u4_fmt_conv_cur_row = ps_dec->s_disp_frame_info.u4_y_ht; + ps_dec->as_fmt_conv_part[0].u4_flag = 0; + ps_dec->as_fmt_conv_part[1].u4_flag = 0; + } + else + ps_dec->u4_output_present = 1; + } + if(ps_dec->u1_separate_parse == 1) + { + if(ps_dec->u4_dec_thread_created == 0) + { + ithread_create(ps_dec->pv_dec_thread_handle, NULL, + (void *)ih264d_decode_picture_thread, + (void *)ps_dec); + + ps_dec->u4_dec_thread_created = 1; + } + + if((ps_dec->u4_num_cores == 3) && (ps_dec->u4_app_disable_deblk_frm == 0) + && (ps_dec->u4_bs_deblk_thread_created == 0)) + { + ps_dec->u4_start_bs_deblk = 0; + ithread_create(ps_dec->pv_bs_deblk_thread_handle, NULL, + (void *)ih264d_computebs_deblk_thread, + (void *)ps_dec); + ps_dec->u4_bs_deblk_thread_created = 1; + } + } + + } + + /* INITIALIZATION of fn ptrs for MC and formMbPartInfo functions */ + { + UWORD8 uc_nofield_nombaff = 1; // = ((ps_dec->ps_sps->u1_profile_idc == 0x42) || (u1_slice_type == I_SLICE)); + + + + uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) + && (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) + && (u1_slice_type != B_SLICE) + && (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0)); + + /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */ + + if(uc_nofield_nombaff) + { + ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_bp; + ps_dec->p_motion_compensate = ih264d_motion_compensate_bp; + } + else + { + ps_dec->p_form_mb_part_info = ih264d_form_mb_part_info_mp; + ps_dec->p_motion_compensate = ih264d_motion_compensate_mp; + } + + + } + + /* + * Decide whether to decode the current picture or not + */ + { + dec_err_status_t * ps_err = ps_dec->ps_dec_err_status; + if(ps_err->u4_frm_sei_sync == 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 = u2_frame_num; + } + + /* Decision for decoding if the picture is to be skipped */ + { + WORD32 i4_skip_b_pic, i4_skip_p_pic; + + i4_skip_b_pic = (ps_dec->u4_skip_frm_mask & B_SLC_BIT) + && (B_SLICE == u1_slice_type) && (0 == u1_nal_ref_idc); + + i4_skip_p_pic = (ps_dec->u4_skip_frm_mask & P_SLC_BIT) + && (P_SLICE == u1_slice_type) && (0 == u1_nal_ref_idc); + + /**************************************************************/ + /* Skip the B picture if skip mask is set for B picture and */ + /* Current B picture is a non reference B picture or there is */ + /* no user for reference B picture */ + /**************************************************************/ + if(i4_skip_b_pic) + { + ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT; + /* Don't decode the picture in SKIP-B mode if that picture is B */ + /* and also it is not to be used as a reference picture */ + ps_dec->u1_last_pic_not_decoded = 1; + + return OK; + } + /**************************************************************/ + /* Skip the P picture if skip mask is set for P picture and */ + /* Current P picture is a non reference P picture or there is */ + /* no user for reference P picture */ + /**************************************************************/ + if(i4_skip_p_pic) + { + ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT; + /* Don't decode the picture in SKIP-P mode if that picture is P */ + /* and also it is not to be used as a reference picture */ + ps_dec->u1_last_pic_not_decoded = 1; + + return OK; + } + } + + { + UWORD16 u2_mb_x, u2_mb_y; + + ps_dec->i4_submb_ofst = ((u2_first_mb_in_slice + << ps_cur_slice->u1_mbaff_frame_flag) * SUB_BLK_SIZE) + - SUB_BLK_SIZE; + if(u2_first_mb_in_slice) + { + UWORD8 u1_mb_aff; + UWORD8 u1_field_pic; + UWORD16 u2_frm_wd_in_mbs; + u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs; + u1_mb_aff = ps_cur_slice->u1_mbaff_frame_flag; + u1_field_pic = ps_cur_slice->u1_field_pic_flag; + + { + UWORD32 x_offset; + UWORD32 y_offset; + UWORD32 u4_frame_stride; + tfr_ctxt_t *ps_trns_addr; // = &ps_dec->s_tran_addrecon_parse; + + if(ps_dec->u1_separate_parse) + { + ps_trns_addr = &ps_dec->s_tran_addrecon_parse; + } + else + { + ps_trns_addr = &ps_dec->s_tran_addrecon; + } + u2_mb_x = MOD(u2_first_mb_in_slice, u2_frm_wd_in_mbs); + u2_mb_y = DIV(u2_first_mb_in_slice, u2_frm_wd_in_mbs); + + u2_mb_y <<= u1_mb_aff; + + if((u2_mb_x > u2_frm_wd_in_mbs - 1) + || (u2_mb_y > ps_dec->u2_frm_ht_in_mbs - 1)) + { + return ERROR_CORRUPTED_SLICE; + } + + u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic; + x_offset = u2_mb_x << 4; + y_offset = (u2_mb_y * u4_frame_stride) << 4; + + ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + + y_offset; + + u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic; + x_offset >>= 1; + y_offset = (u2_mb_y * u4_frame_stride) << 3; + + x_offset *= YUV420SP_FACTOR; + + ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + + y_offset; + ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + + y_offset; + + ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y; + ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u; + ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v; + + if(ps_dec->u4_mb_level_deblk == 1) + { + /*If it is not the first mb in row,the previous MB which needs to be deblocked + * as there is delay of 1 MB*/ + if(u2_mb_x != 0) + { + ps_trns_addr->pu1_mb_y -= MB_SIZE; + ps_trns_addr->pu1_mb_u -= BLK8x8SIZE * YUV420SP_FACTOR; + ps_trns_addr->pu1_mb_v -= BLK8x8SIZE; + } + } + + // assign the deblock structure pointers to start of slice + if(ps_dec->u1_separate_parse == 1) + { + ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic + + (u2_first_mb_in_slice << u1_mb_aff); + } + else + { + if(ps_dec->u4_mb_level_deblk == 0) + ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic + + (u2_first_mb_in_slice << u1_mb_aff); + } + + ps_dec->u2_cur_mb_addr = (u2_first_mb_in_slice << u1_mb_aff); + + ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv + + ((u2_first_mb_in_slice << u1_mb_aff) << 4); + } + } + else + { + tfr_ctxt_t *ps_trns_addr; + + if(ps_dec->u1_separate_parse) + { + ps_trns_addr = &ps_dec->s_tran_addrecon_parse; + } + else + { + ps_trns_addr = &ps_dec->s_tran_addrecon; + } + + u2_mb_x = 0xffff; + u2_mb_y = 0; + // assign the deblock structure pointers to start of slice + ps_dec->u2_cur_mb_addr = 0; + ps_dec->ps_deblk_mbn = ps_dec->ps_deblk_pic; + if(ps_dec->u4_mb_level_deblk == 1) + { + ps_dec->ps_deblk_mbn_curr = ps_dec->ps_deblk_mbn; + ps_dec->ps_deblk_mbn_prev = ps_dec->ps_deblk_mbn + + ps_dec->u1_recon_mb_grp; + } + ps_dec->ps_mv_cur = ps_dec->s_cur_pic.ps_mv; + ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1; + ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2; + ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3; + + ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y; + ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u; + ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v; + + } + + ps_dec->ps_part = ps_dec->ps_parse_part_params; + + ps_dec->u2_mbx = + (MOD(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs)); + ps_dec->u2_mby = + (DIV(u2_first_mb_in_slice - 1, ps_seq->u2_frm_wd_in_mbs)); + ps_dec->u2_mby <<= ps_cur_slice->u1_mbaff_frame_flag; + ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx; + ps_dec->i2_prev_slice_mby = ps_dec->u2_mby; + } + + /* RBSP stop bit is used for CABAC decoding*/ + ps_bitstrm->u4_max_ofst += ps_dec->ps_cur_pps->u1_entropy_coding_mode; + + ps_dec->u1_B = (u1_slice_type == B_SLICE); + ps_dec->u4_next_mb_skip = 0; + + ps_dec->ps_parse_cur_slice->u4_num_mbs_done_in_slice = 0; + ps_dec->ps_parse_cur_slice->u4_first_mb_in_slice = + ps_dec->ps_cur_slice->u2_first_mb_in_slice; + ps_dec->ps_parse_cur_slice->slice_type = + ps_dec->ps_cur_slice->u1_slice_type; + ps_dec->ps_parse_cur_slice->end_of_slice = 0; + ps_dec->ps_parse_cur_slice->last_slice_in_frame = 0; + + + /*set to zero to indicate a valid slice has been decoded*/ + ps_dec->u4_first_slice_in_pic = 0; + + ps_dec->u4_start_frame_decode = 1; + + + ps_dec->u4_start_bs_deblk = 1; + + ps_dec->ps_parse_cur_slice->u2_error_flag = 0; + { + WORD32 num_entries; + WORD32 size; + UWORD8 *pu1_buf; + + num_entries = MIN(MAX_FRAMES, ps_dec->u4_num_ref_frames_at_init); + num_entries = 2 * ((2 * num_entries) + 1); + + size = num_entries * sizeof(void *); + size += PAD_MAP_IDX_POC * sizeof(void *); + + pu1_buf = (UWORD8 *)ps_dec->pv_map_ref_idx_to_poc_buf; + pu1_buf += size * ps_dec->u2_cur_slice_num; + ps_dec->ps_parse_cur_slice->ppv_map_ref_idx_to_poc = (volatile void **)pu1_buf; + } + + if(u1_slice_type == I_SLICE) + { + ps_dec->ps_cur_pic->u4_pack_slc_typ |= I_SLC_BIT; + + ret = ih264d_parse_islice(ps_dec, u2_first_mb_in_slice); + if(ret != OK) + return ret; + + if(ps_dec->i4_pic_type != B_SLICE && ps_dec->i4_pic_type != P_SLICE) + ps_dec->i4_pic_type = I_SLICE; + + } + else if(u1_slice_type == P_SLICE) + { + ps_dec->ps_cur_pic->u4_pack_slc_typ |= P_SLC_BIT; + ret = ih264d_parse_pslice(ps_dec, u2_first_mb_in_slice); + if(ret != OK) + return ret; + ps_dec->u1_pr_sl_type = u1_slice_type; + if(ps_dec->i4_pic_type != B_SLICE) + ps_dec->i4_pic_type = P_SLICE; + } + else if(u1_slice_type == B_SLICE) + { + ps_dec->ps_cur_pic->u4_pack_slc_typ |= B_SLC_BIT; + ret = ih264d_parse_bslice(ps_dec, u2_first_mb_in_slice); + if(ret != OK) + return ret; + ps_dec->u1_pr_sl_type = u1_slice_type; + ps_dec->i4_pic_type = B_SLICE; + } + else + return ERROR_INV_SLC_TYPE_T; + + ps_dec->ps_parse_cur_slice->end_of_slice = 1; + + ps_dec->u2_cur_slice_num++; + /* storing last Mb X and MbY of the slice */ + ps_dec->i2_prev_slice_mbx = ps_dec->u2_mbx; + ps_dec->i2_prev_slice_mby = ps_dec->u2_mby; + /* End of Picture detection */ + + if(ps_dec->u2_total_mbs_coded >= (ps_seq->u2_max_mb_addr + 1)) + { + ps_dec->u1_pic_decode_done = 1; + + } + + { + dec_err_status_t * ps_err = ps_dec->ps_dec_err_status; + 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; + } + } + + PRINT_BIN_BIT_RATIO(ps_dec) + + return OK; +} + diff --git a/decoder/ih264d_parse_slice.h b/decoder/ih264d_parse_slice.h new file mode 100755 index 0000000..cf5f9ce --- /dev/null +++ b/decoder/ih264d_parse_slice.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_PARSE_SLICE_H_ +#define _IH264D_PARSE_SLICE_H_ +/*! + ************************************************************************** + * \file ih264d_parse_slice.h + * + * \brief + * Contains routines that decodes a slice NAL unit + * + * \date + * 19/12/2002 + * + * \author AI + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_error_handler.h" +WORD32 ih264d_parse_decode_slice(UWORD8 u1_is_idr_slice, + UWORD8 u1_nal_ref_idc, + dec_struct_t * ps_dec ); + +WORD32 ih264d_ref_idx_reordering(dec_struct_t * ps_dec, UWORD8 u1_isB); +WORD32 ih264d_read_mmco_commands(dec_struct_t * ps_dec); +void ih264d_form_pred_weight_matrix(dec_struct_t *ps_dec); +#endif /* _IH264D_PARSE_SLICE_H_ */ diff --git a/decoder/ih264d_process_bslice.c b/decoder/ih264d_process_bslice.c new file mode 100755 index 0000000..69199cf --- /dev/null +++ b/decoder/ih264d_process_bslice.c @@ -0,0 +1,2345 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_process_bslice.c + * + * \brief + * Contains routines that decode B slice type + * + * Detailed_description + * + * \date + * 21/12/2002 + * + * \author NS + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" + +#include <string.h> +#include "ih264d_structs.h" +#include "ih264d_bitstrm.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_mvpred.h" +#include "ih264d_inter_pred.h" +#include "ih264d_process_pslice.h" +#include "ih264d_error_handler.h" +#include "ih264d_tables.h" +#include "ih264d_parse_slice.h" +#include "ih264d_process_pslice.h" +#include "ih264d_process_bslice.h" +#include "ih264d_tables.h" +#include "ih264d_parse_islice.h" +#include "ih264d_mvpred.h" + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec); +//UWORD32 g_hits = 0; +//UWORD32 g_miss = 0; +/*! + ************************************************************************** + * \if Function name : ih264d_decode_spatial_direct \endif + * + * \brief + * Decodes spatial direct mode. + * + * \return + * None. + * Arunoday T + ************************************************************************** + */ +WORD32 ih264d_decode_spatial_direct(dec_struct_t * ps_dec, + UWORD8 u1_wd_x, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num) +{ + mv_pred_t s_mv_pred, *ps_mv; + UWORD8 u1_col_zero_flag, u1_sub_mb_num, u1_direct_zero_pred_flag = 0; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + mv_pred_t *ps_mv_ntop_start; + mv_pred_t *ps_mv_nmb_start = ps_dec->ps_mv_cur + (u1_mb_num << 4); + UWORD8 partition_size, sub_partition, u1_mb_partw, u1_mb_parth; + UWORD8 i; + WORD8 i1_pred, i1_ref_frame0, i1_ref_frame1; + struct pic_buffer_t *ps_ref_frame = NULL, *ps_col_pic, *ps_pic_buff0 = NULL, + *ps_pic_buff1 = NULL; + + UWORD8 u1_zero_pred_cond_f, u1_zero_pred_cond_b; + WORD16 i2_def_mv[2], i2_spat_pred_mv[4], *pi2_final_mv0, *pi2_final_mv1; + UWORD16 ui2_mask_fwd = 0, ui2_mask_bwd = 0, u2_mask = 0; + UWORD32 *pui32_weight_ofsts = NULL; + directmv_t s_mvdirect; + UWORD8 u1_colz; + UWORD8 u1_final_ref_idx = 0; + const UWORD8 *pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + const UWORD8 *pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + const UWORD16 sub_mask_table[] = + { 0x33, 0x3, 0x11, 0x1 }; + const UWORD16 mask_table[] = + { 0xffff, /*16x16 NA */ + 0xff, /* 16x8*/ + 0x3333, /* 8x16*/ + 0x33 };/* 8x8*/ + mv_pred_t s_temp_mv_pred; + WORD32 ret = 0; + + /* CHANGED CODE */ + ps_mv_ntop_start = ps_dec->ps_mv_cur + (u1_mb_num << 4) + - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12; + + /* assign default values for MotionVector as zero */ + i2_def_mv[0] = 0; + i2_def_mv[1] = 0; + + u1_direct_zero_pred_flag = ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb_start, + ps_mv_ntop_start, &s_mv_pred, 0, 4, + 0, 1, B_DIRECT_SPATIAL); + + i2_spat_pred_mv[0] = s_mv_pred.i2_mv[0]; + i2_spat_pred_mv[1] = s_mv_pred.i2_mv[1]; + i2_spat_pred_mv[2] = s_mv_pred.i2_mv[2]; + i2_spat_pred_mv[3] = s_mv_pred.i2_mv[3]; + + i1_ref_frame0 = s_mv_pred.i1_ref_frame[0]; + i1_ref_frame1 = s_mv_pred.i1_ref_frame[1]; + + i1_ref_frame0 = (i1_ref_frame0 < 0) ? -1 : i1_ref_frame0; + i1_ref_frame1 = (i1_ref_frame1 < 0) ? -1 : i1_ref_frame1; + + i1_pred = 0; + + { + WORD8 u1_ref_idx, u1_ref_idx1; + UWORD32 uc_Idx, uc_Idx1; + UWORD8 u1_scale_ref = (ps_dec->ps_cur_slice->u1_mbaff_frame_flag + && ps_cur_mb_info->u1_mb_field_decodingflag); + u1_final_ref_idx = i1_ref_frame0; + if(i1_ref_frame0 >= 0) + { + /* convert RefIdx if it is MbAff */ + u1_ref_idx = i1_ref_frame0; + u1_ref_idx1 = i1_ref_frame0; + if(u1_scale_ref) + { + u1_ref_idx1 = u1_ref_idx >> 1; + if((u1_ref_idx & 0x01) != (1 - ps_cur_mb_info->u1_topmb)) + u1_ref_idx1 += MAX_REF_BUFS; + } + /* If i1_ref_frame0 < 0 then refIdxCol is obtained from ps_pic_buff1 */ + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][u1_ref_idx1]; + ps_ref_frame = ps_pic_buff0; + i1_pred = PRED_L0; + } + + if(i1_ref_frame1 >= 0) + { + /* convert RefIdx if it is MbAff */ + u1_ref_idx = i1_ref_frame1; + u1_ref_idx1 = i1_ref_frame1; + if(u1_scale_ref) + { + u1_ref_idx1 = u1_ref_idx >> 1; + if((u1_ref_idx & 0x01) != (1 - ps_cur_mb_info->u1_topmb)) + u1_ref_idx1 += MAX_REF_BUFS; + } + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][u1_ref_idx1]; + i1_pred = i1_pred | PRED_L1; + } + if(i1_ref_frame0 < 0) + { + ps_ref_frame = ps_pic_buff1; + u1_final_ref_idx = i1_ref_frame1; + } + + u1_zero_pred_cond_f = (u1_direct_zero_pred_flag) || (i1_ref_frame0 < 0); + u1_zero_pred_cond_b = (u1_direct_zero_pred_flag) || (i1_ref_frame1 < 0); + + if(ps_dec->ps_cur_pps->u1_wted_bipred_idc) + { + uc_Idx = ((i1_ref_frame0 < 1) ? 0 : i1_ref_frame0) + * ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + if(u1_scale_ref) + uc_Idx >>= 1; + uc_Idx1 = (i1_ref_frame1 < 0) ? 0 : i1_ref_frame1; + uc_Idx += (u1_scale_ref) ? (uc_Idx1 >> 1) : uc_Idx1; + pui32_weight_ofsts = + (UWORD32*)&ps_dec->pu4_wt_ofsts[2 * X3(uc_Idx)]; + + if(i1_ref_frame0 < 0) + pui32_weight_ofsts += 1; + + if(u1_scale_ref && (ps_dec->ps_cur_pps->u1_wted_bipred_idc == 2)) + { + WORD16 i2_ref_idx; + i2_ref_idx = MAX(i1_ref_frame0, 0); + i2_ref_idx *= (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + i2_ref_idx += MAX(i1_ref_frame1, 0); + if(!ps_cur_mb_info->u1_topmb) + i2_ref_idx += + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] + << 1) + * (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + pui32_weight_ofsts = (UWORD32*)&ps_dec->pu4_mbaff_wt_mat[2 + * X3(i2_ref_idx)]; + } + } + } + + s_temp_mv_pred.i1_ref_frame[0] = i1_ref_frame0; + s_temp_mv_pred.i1_ref_frame[1] = i1_ref_frame1; + s_temp_mv_pred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id; + s_temp_mv_pred.u1_pic_type = ps_ref_frame->u1_pic_type; + + /**********************************************************************/ + /* Call the function which gets the number of partitions and */ + /* partition info of colocated Mb */ + /**********************************************************************/ + + ps_dec->pf_parse_mvdirect(ps_dec, ps_dec->ps_col_pic, &s_mvdirect, u1_wd_x, + ps_dec->i4_submb_ofst, ps_cur_mb_info); + ps_col_pic = ps_dec->ps_col_pic; + if((s_mvdirect.u1_col_zeroflag_change == 0) || u1_direct_zero_pred_flag) + { + WORD16 i2_mv_x, i2_mv_y, i2_mvX1, i2_mvY1; + /* Most probable case */ + u1_col_zero_flag = *(ps_col_pic->pu1_col_zero_flag + + s_mvdirect.i4_mv_indices[0]); + u1_col_zero_flag = u1_col_zero_flag & 0x01; + + if(u1_zero_pred_cond_f || ((i1_ref_frame0 == 0) && (u1_col_zero_flag == 1))) + { + i2_mv_x = 0; + i2_mv_y = 0; + } + else + { + i2_mv_x = i2_spat_pred_mv[0]; + i2_mv_y = i2_spat_pred_mv[1]; + + } + + if(u1_zero_pred_cond_b || ((i1_ref_frame1 == 0) && (u1_col_zero_flag == 1))) + { + i2_mvX1 = 0; + i2_mvY1 = 0; + } + else + { + i2_mvX1 = i2_spat_pred_mv[2]; + i2_mvY1 = i2_spat_pred_mv[3]; + } + + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + u1_mb_partw = (u1_wd_x >> 2); + + + if(i1_ref_frame0 >= 0) + { + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = i2_mv_x; + i2_mv[1] = i2_mv_y; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,u1_mb_partw,u1_mb_partw,u1_sub_mb_num,i1_pred, + ps_pred_pkd,ps_pic_buff0->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff0->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + } + + if(i1_ref_frame1 >= 0) + { + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = i2_mvX1; + i2_mv[1] = i2_mvY1; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,u1_mb_partw,u1_mb_partw,u1_sub_mb_num,i1_pred, + ps_pred_pkd,ps_pic_buff1->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff1->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + } + + + /* Replication optimisation */ + s_temp_mv_pred.i2_mv[0] = i2_mv_x; + s_temp_mv_pred.i2_mv[1] = i2_mv_y; + s_temp_mv_pred.i2_mv[2] = i2_mvX1; + s_temp_mv_pred.i2_mv[3] = i2_mvY1; + + /* Calculating colocated zero information */ + { + /*************************************/ + /* If(bit2 and bit3 set) */ + /* then */ + /* (bit0 and bit1) => submmbmode */ + /* (bit2 and bit3) => mbmode */ + /* else */ + /* (bit0 and bit1) => mbmode */ + /*************************************/ + /*UWORD8 u1_packed_mb_sub_mb_mode = sub_partition ? + (s_mvdirect.i1_partitionsize[0]) : ((s_mvdirect.i1_partitionsize[0]) << 2);*/ + UWORD8 u1_packed_mb_sub_mb_mode = (u1_mb_partw == 2) ? 0x03 : 0; + + if(i1_ref_frame0 < 0) + { + i2_mv_x = i2_mvX1; + i2_mv_y = i2_mvY1; + } + + /* Change from left shift 4 to 6 - Varun */ + u1_colz = (ps_cur_mb_info->u1_mb_field_decodingflag << 1) + | ((u1_final_ref_idx == 0) && (ABS(i2_mv_x) <= 1) + && (ABS(i2_mv_y) <= 1)); + u1_colz |= (u1_packed_mb_sub_mb_mode << 6); + } + ps_mv = ps_mv_nmb_start + u1_sub_mb_num; + ih264d_rep_mv_colz(ps_dec, &s_temp_mv_pred, ps_mv, u1_sub_mb_num, u1_colz, + u1_mb_partw, u1_mb_partw); + if(u1_wd_x == MB_SIZE) + ps_dec->u1_currB_type = 0; + + + + return OK; + } + /***************************************************************************/ + /* If present MB is 16x16 and the partition of colocated Mb is >= PRED_8x8 */ + /* i.e 8x8 or less than 8x8 partitions then set up DMA for (0,0) and */ + /* spatially predicted motion vector and do the multiplexing after */ + /* motion compensation */ + /***************************************************************************/ + + + if((u1_wd_x == MB_SIZE) && (s_mvdirect.i1_num_partitions > 2)) + { + ps_cur_mb_info->u1_Mux = 1; + if(i1_ref_frame0 >= 0) + { + + { + pred_info_pkd_t *ps_pred_pkd; + WORD8 i1_ref_idx= 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(&(i2_spat_pred_mv[0]),4,4,0,i1_pred, + ps_pred_pkd,ps_pic_buff0->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff0->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + /****** (0,0) Motion vectors DMA *****/ + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = 0; + i2_mv[1] = 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,4,4,0,i1_pred, + ps_pred_pkd,ps_pic_buff0->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff0->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + } + if(i1_ref_frame1 >= 0) + { + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(&(i2_spat_pred_mv[2]),4,4,0,i1_pred, + ps_pred_pkd,ps_pic_buff1->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff1->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + /****** (0,0) Motion vectors DMA *****/ + + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = 0; + i2_mv[1] = 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,4,4,0,i1_pred, + ps_pred_pkd,ps_pic_buff1->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff1->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + } + } + + /*u1_col = *(ps_col_pic->pu1_col_zero_flag + s_mvdirect.i4_mv_indices[0]); + u1_col &= 1; + u1_init = 0;*/ + + for(i = 0; i < s_mvdirect.i1_num_partitions; i++) + { + partition_size = s_mvdirect.i1_partitionsize[i]; + u1_sub_mb_num = s_mvdirect.i1_submb_num[i]; + + sub_partition = partition_size >> 2; + partition_size &= 0x3; + u1_mb_partw = pu1_mb_partw[partition_size]; + u1_mb_parth = pu1_mb_parth[partition_size]; + u2_mask = mask_table[partition_size]; + if(sub_partition != 0) + { + u1_mb_partw >>= 1; + u1_mb_parth >>= 1; + u2_mask = sub_mask_table[partition_size]; + } + + u1_col_zero_flag = *(ps_col_pic->pu1_col_zero_flag + + s_mvdirect.i4_mv_indices[i]); + u1_col_zero_flag = u1_col_zero_flag & 0x01; + + /*if(u1_col != u1_col_zero_flag) + u1_init = 1;*/ + + if(u1_zero_pred_cond_f || ((i1_ref_frame0 == 0) && (u1_col_zero_flag == 1))) + { + pi2_final_mv0 = &i2_def_mv[0]; + ui2_mask_fwd |= (u2_mask << u1_sub_mb_num); + } + else + pi2_final_mv0 = &i2_spat_pred_mv[0]; + + if(u1_zero_pred_cond_b || ((i1_ref_frame1 == 0) && (u1_col_zero_flag == 1))) + { + pi2_final_mv1 = &i2_def_mv[0]; + ui2_mask_bwd |= (u2_mask << u1_sub_mb_num); + } + else + pi2_final_mv1 = &i2_spat_pred_mv[2]; + + if(ps_cur_mb_info->u1_Mux != 1) + { + /*u1_sub_mb_x = u1_sub_mb_num & 0x03; + uc_sub_mb_y = (u1_sub_mb_num >> 2);*/ + if(i1_ref_frame0 >= 0) + { + + { + pred_info_pkd_t *ps_pred_pkd; + WORD8 i1_ref_idx= 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(pi2_final_mv0,u1_mb_partw,u1_mb_parth,u1_sub_mb_num,i1_pred, + ps_pred_pkd,ps_pic_buff0->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff0->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + } + + if(i1_ref_frame1 >= 0) + { + { + pred_info_pkd_t *ps_pred_pkd; + WORD8 i1_ref_idx= 0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(pi2_final_mv1,u1_mb_partw,u1_mb_parth,u1_sub_mb_num,i1_pred, + ps_pred_pkd,ps_pic_buff1->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff1->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + } + } + + /* Replication optimisation */ + s_temp_mv_pred.i2_mv[0] = pi2_final_mv0[0]; + s_temp_mv_pred.i2_mv[1] = pi2_final_mv0[1]; + s_temp_mv_pred.i2_mv[2] = pi2_final_mv1[0]; + s_temp_mv_pred.i2_mv[3] = pi2_final_mv1[1]; + + /* Calculating colocated zero information */ + { + WORD16 i2_mv_x = 0, i2_mv_y = 0; + /*************************************/ + /* If(bit2 and bit3 set) */ + /* then */ + /* (bit0 and bit1) => submmbmode */ + /* (bit2 and bit3) => mbmode */ + /* else */ + /* (bit0 and bit1) => mbmode */ + /*************************************/ + UWORD8 u1_packed_mb_sub_mb_mode = + sub_partition ? (s_mvdirect.i1_partitionsize[i]) : ((s_mvdirect.i1_partitionsize[i]) + << 2); + + if(i1_ref_frame0 >= 0) + { + i2_mv_x = pi2_final_mv0[0]; + i2_mv_y = pi2_final_mv0[1]; + } + else + { + i2_mv_x = pi2_final_mv1[0]; + i2_mv_y = pi2_final_mv1[1]; + } + + u1_colz = (ps_cur_mb_info->u1_mb_field_decodingflag << 1) + | ((u1_final_ref_idx == 0) && (ABS(i2_mv_x) <= 1) + && (ABS(i2_mv_y) <= 1)); + u1_colz |= (u1_packed_mb_sub_mb_mode << 4); + } + ps_mv = ps_mv_nmb_start + u1_sub_mb_num; + ih264d_rep_mv_colz(ps_dec, &s_temp_mv_pred, ps_mv, u1_sub_mb_num, u1_colz, + u1_mb_parth, u1_mb_partw); + } + i = 0; + if(i1_ref_frame0 >= 0) + ps_cur_mb_info->u2_mask[i++] = ui2_mask_fwd; + if(i1_ref_frame1 >= 0) + ps_cur_mb_info->u2_mask[i] = ui2_mask_bwd; + + /*if(u1_init) + H264_DEC_DEBUG_PRINT("hit\n"); + else + H264_DEC_DEBUG_PRINT("miss\n");*/ + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_temporal_direct \endif + * + * \brief + * Decodes temporal direct mode. + * + * \return + * None. + * + ************************************************************************** + */ +WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, + UWORD8 u1_wd_x, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num) +{ + struct pic_buffer_t *ps_pic_buff0, *ps_pic_buff1, *ps_col_pic; + mv_pred_t *ps_mv, s_temp_mv_pred; + UWORD8 u1_sub_mb_num; + UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + WORD16 i2_mv_x0, i2_mv_y0, i2_mv_x1, i2_mv_y1; + UWORD8 u1_mb_partw, u1_mb_parth; + UWORD8 i, partition_size, sub_partition; + UWORD32 *pui32_weight_ofsts = NULL; + directmv_t s_mvdirect; + const UWORD8 *pu1_mb_parth = (const UWORD8 *)gau1_ih264d_mb_parth; + const UWORD8 *pu1_mb_partw = (const UWORD8 *)gau1_ih264d_mb_partw; + WORD8 c_refFrm0, c_refFrm1; + UWORD8 u1_ref_idx0, u1_is_cur_mb_fld; + UWORD32 pic0_poc, pic1_poc, cur_poc; + WORD32 ret = 0; + + u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][0]; + + /**********************************************************************/ + /* Call the function which gets the number of partitions and */ + /* partition info of colocated Mb */ + /**********************************************************************/ + ps_dec->pf_parse_mvdirect(ps_dec, ps_dec->ps_col_pic, &s_mvdirect, u1_wd_x, + ps_dec->i4_submb_ofst, ps_cur_mb_info); + ps_col_pic = ps_dec->ps_col_pic; + + for(i = 0; i < s_mvdirect.i1_num_partitions; i++) + { + UWORD8 u1_colz; + partition_size = s_mvdirect.i1_partitionsize[i]; + u1_sub_mb_num = s_mvdirect.i1_submb_num[i]; + ps_mv = ps_col_pic->ps_mv + s_mvdirect.i4_mv_indices[i]; + + /* This should be removed to catch unitialized memory read */ + u1_ref_idx0 = 0; + + sub_partition = partition_size >> 2; + partition_size &= 0x3; + u1_mb_partw = pu1_mb_partw[partition_size]; + u1_mb_parth = pu1_mb_parth[partition_size]; + if(sub_partition != 0) + { + u1_mb_partw >>= 1; + u1_mb_parth >>= 1; + } + c_refFrm0 = ps_mv->i1_ref_frame[0]; + c_refFrm1 = ps_mv->i1_ref_frame[1]; + + if((c_refFrm0 == -1) && (c_refFrm1 == -1)) + { + u1_ref_idx0 = 0; + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][0]; + if(u1_mbaff && u1_is_cur_mb_fld) + { + if(ps_cur_mb_info->u1_topmb) + { + pic0_poc = ps_pic_buff0->i4_top_field_order_cnt; + pic1_poc = ps_pic_buff1->i4_top_field_order_cnt; + cur_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + } + else + { + pic1_poc = ps_pic_buff1->i4_bottom_field_order_cnt; + cur_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; + pic0_poc = ps_pic_buff0->i4_bottom_field_order_cnt; + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][MAX_REF_BUFS]; + } + } + else + { + pic0_poc = ps_pic_buff0->i4_avg_poc; + pic1_poc = ps_pic_buff1->i4_avg_poc; + cur_poc = ps_dec->ps_cur_pic->i4_poc; + } + } + else + { + UWORD8 uc_i, u1_num_frw_ref_pics; + UWORD8 buf_id, u1_pic_type; + buf_id = ps_mv->u1_col_ref_pic_idx; + u1_pic_type = ps_mv->u1_pic_type; + if(ps_dec->ps_cur_slice->u1_field_pic_flag) + { + if(s_mvdirect.u1_vert_mv_scale == FRM_TO_FLD) + { + u1_pic_type = TOP_FLD; + if(ps_dec->ps_cur_slice->u1_bottom_field_flag) + u1_pic_type = BOT_FLD; + } + } + u1_num_frw_ref_pics = + ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + + for(uc_i = 0; uc_i < u1_num_frw_ref_pics; uc_i++) + { + if(ps_dec->ps_cur_slice->u1_field_pic_flag) + { + if(ps_dec->ps_ref_pic_buf_lx[0][uc_i]->u1_mv_buf_id == buf_id) + { + if(ps_dec->ps_ref_pic_buf_lx[0][uc_i]->u1_pic_type + == u1_pic_type) + { + u1_ref_idx0 = uc_i; + break; + } + } + } + else + { + if(ps_dec->ps_ref_pic_buf_lx[0][uc_i]->u1_mv_buf_id == buf_id) + { + u1_ref_idx0 = uc_i; + break; + } + } + } + + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][u1_ref_idx0]; + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][0]; + + if(u1_mbaff && u1_is_cur_mb_fld) + { + pic0_poc = ps_pic_buff0->i4_top_field_order_cnt; + u1_ref_idx0 <<= 1; + if(s_mvdirect.u1_vert_mv_scale == ONE_TO_ONE) + { + if(u1_pic_type == BOT_FLD) + { + pic0_poc = ps_pic_buff0->i4_bottom_field_order_cnt; + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][(u1_ref_idx0 + >> 1) + MAX_REF_BUFS]; + if(ps_cur_mb_info->u1_topmb) + u1_ref_idx0++; + } + else + { + if(1 - ps_cur_mb_info->u1_topmb) + u1_ref_idx0++; + } + } + if(s_mvdirect.u1_vert_mv_scale == FRM_TO_FLD) + { + if(1 - ps_cur_mb_info->u1_topmb) + { + pic0_poc = ps_pic_buff0->i4_bottom_field_order_cnt; + ps_pic_buff0 = ps_dec->ps_ref_pic_buf_lx[0][(u1_ref_idx0 + >> 1) + MAX_REF_BUFS]; + } + } + if(ps_cur_mb_info->u1_topmb) + { + pic1_poc = ps_pic_buff1->i4_top_field_order_cnt; + cur_poc = ps_dec->ps_cur_pic->i4_top_field_order_cnt; + } + else + { + pic1_poc = ps_pic_buff1->i4_bottom_field_order_cnt; + cur_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt; + ps_pic_buff1 = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; + } + } + else + { + pic0_poc = ps_pic_buff0->i4_avg_poc; + pic1_poc = ps_pic_buff1->i4_avg_poc; + cur_poc = ps_dec->ps_cur_pic->i4_poc; + } + } + { + WORD16 i16_td; + + if(c_refFrm0 >= 0) + { + i2_mv_x0 = ps_mv->i2_mv[0]; + i2_mv_y0 = ps_mv->i2_mv[1]; + } + else if(c_refFrm1 >= 0) + { + i2_mv_x0 = ps_mv->i2_mv[2]; + i2_mv_y0 = ps_mv->i2_mv[3]; + } + else + { + i2_mv_x0 = 0; + i2_mv_y0 = 0; + } + /* If FRM_TO_FLD or FLD_TO_FRM scale the "y" component of the colocated Mv*/ + if(s_mvdirect.u1_vert_mv_scale == FRM_TO_FLD) + { + i2_mv_y0 /= 2; + } + else if(s_mvdirect.u1_vert_mv_scale == FLD_TO_FRM) + { + i2_mv_y0 *= 2; + } + + i16_td = pic1_poc - pic0_poc; + if((ps_pic_buff0->u1_is_short == 0) || (i16_td == 0)) + { + i2_mv_x1 = 0; + i2_mv_y1 = 0; + } + else + { + WORD16 i16_tb, i16_tx, i2_dist_scale_factor, i16_temp; + + i16_td = CLIP3(-128, 127, i16_td); + i16_tb = cur_poc - pic0_poc; + i16_tb = CLIP3(-128, 127, i16_tb); + + i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td; + i2_dist_scale_factor = CLIP3(-1024, 1023, + (((i16_tb * i16_tx) + 32) >> 6)); + i16_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_x1 = i16_temp - i2_mv_x0; + i2_mv_x0 = i16_temp; + + i16_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8; + i2_mv_y1 = i16_temp - i2_mv_y0; + i2_mv_y0 = i16_temp; + } + { + mv_pred_t *ps_mv; + + /*u1_sub_mb_x = u1_sub_mb_num & 0x03; + uc_sub_mb_y = u1_sub_mb_num >> 2;*/ + if(ps_dec->ps_cur_pps->u1_wted_bipred_idc) + { + UWORD8 u1_idx = + u1_ref_idx0 + * ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + UWORD8 u1_scale_ref = u1_mbaff && u1_is_cur_mb_fld; + if(u1_scale_ref) + u1_idx >>= 1; + pui32_weight_ofsts = (UWORD32*)&ps_dec->pu4_wt_ofsts[2 + * X3(u1_idx)]; + if(u1_scale_ref + && (ps_dec->ps_cur_pps->u1_wted_bipred_idc + == 2)) + { + WORD16 i2_ref_idx; + i2_ref_idx = u1_ref_idx0; + i2_ref_idx *= + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + if(!ps_cur_mb_info->u1_topmb) + i2_ref_idx += + (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0] + << 1) + * (ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1] + << 1); + pui32_weight_ofsts = + (UWORD32*)&ps_dec->pu4_mbaff_wt_mat[2 + * X3(i2_ref_idx)]; + } + } + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = i2_mv_x0; + i2_mv[1] = i2_mv_y0; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,u1_mb_partw,u1_mb_parth,u1_sub_mb_num,PRED_L0 | PRED_L1, + ps_pred_pkd,ps_pic_buff0->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff0->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + { + pred_info_pkd_t *ps_pred_pkd; + WORD16 i2_mv[2]; + WORD8 i1_ref_idx= 0; + + i2_mv[0] = i2_mv_x1; + i2_mv[1] = i2_mv_y1; + + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info(i2_mv,u1_mb_partw,u1_mb_parth,u1_sub_mb_num,PRED_L0 | PRED_L1, + ps_pred_pkd,ps_pic_buff1->u1_pic_buf_id,i1_ref_idx,pui32_weight_ofsts, + ps_pic_buff1->u1_pic_type); + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + + + } + + /* Replication optimisation */ + s_temp_mv_pred.i2_mv[0] = i2_mv_x0; + s_temp_mv_pred.i2_mv[1] = i2_mv_y0; + s_temp_mv_pred.i2_mv[2] = i2_mv_x1; + s_temp_mv_pred.i2_mv[3] = i2_mv_y1; + s_temp_mv_pred.i1_ref_frame[0] = u1_ref_idx0; + s_temp_mv_pred.i1_ref_frame[1] = 0; + s_temp_mv_pred.u1_col_ref_pic_idx = ps_pic_buff0->u1_mv_buf_id; + s_temp_mv_pred.u1_pic_type = ps_pic_buff0->u1_pic_type; + ps_mv = ps_dec->ps_mv_cur + (u1_mb_num << 4) + u1_sub_mb_num; + + { + WORD16 i2_mv_x = 0, i2_mv_y = 0; + UWORD8 u1_packed_mb_sub_mb_mode = + sub_partition ? (s_mvdirect.i1_partitionsize[i]) : ((s_mvdirect.i1_partitionsize[i]) + << 2); + + if(c_refFrm0 >= 0) + { + i2_mv_x = i2_mv_x0; + i2_mv_y = i2_mv_y0; + } + else + { + i2_mv_x = i2_mv_x1; + i2_mv_y = i2_mv_y1; + } + + u1_colz = + (ps_cur_mb_info->u1_mb_field_decodingflag << 1) + | ((u1_ref_idx0 == 0) + && (ABS(i2_mv_x) + <= 1) + && (ABS(i2_mv_y) + <= 1)); + u1_colz |= (u1_packed_mb_sub_mb_mode << 4); + } + ih264d_rep_mv_colz(ps_dec, &s_temp_mv_pred, ps_mv, u1_sub_mb_num, + u1_colz, u1_mb_parth, u1_mb_partw); + } + } + } + /* return value set to UWORD8 to make it homogeneous */ + /* with decodespatialdirect */ + return OK; +} + +void ih264d_convert_frm_to_fld_list(struct pic_buffer_t *ps_ref_pic_buf_lx, + UWORD8 *pu1_L0, + dec_struct_t *ps_dec, + UWORD8 u1_num_short_term_bufs) +{ + UWORD8 uc_count = *pu1_L0, i, uc_l1, uc_lx, j; + struct pic_buffer_t *ps_ref_lx[2], *ps_ref_pic_lx; + UWORD8 u1_bottom_field_flag; + dec_slice_params_t *ps_cur_slice; + UWORD8 u1_ref[2], u1_fld[2], u1_same_fld, u1_op_fld; + UWORD32 ui_half_num_of_sub_mbs; + + uc_l1 = 0; + uc_lx = 0; + ps_cur_slice = ps_dec->ps_cur_slice; + ps_ref_pic_lx = ps_ref_pic_buf_lx - MAX_REF_BUFS; + ps_ref_lx[0] = ps_ref_pic_buf_lx; + ps_ref_lx[1] = ps_ref_pic_buf_lx; + u1_bottom_field_flag = ps_cur_slice->u1_bottom_field_flag; + ui_half_num_of_sub_mbs = ((ps_dec->u2_pic_ht * ps_dec->u2_pic_wd) >> 5); + if(u1_bottom_field_flag) + { + u1_ref[0] = BOT_REF; + u1_ref[1] = TOP_REF; + u1_fld[0] = BOT_FLD; + u1_fld[1] = TOP_FLD; + u1_same_fld = BOT_FLD; + u1_op_fld = TOP_FLD; + } + else + { + u1_ref[0] = TOP_REF; + u1_ref[1] = BOT_REF; + u1_fld[0] = TOP_FLD; + u1_fld[1] = BOT_FLD; + u1_same_fld = TOP_FLD; + u1_op_fld = BOT_FLD; + } + + /* Create the field list starting with all the short term */ + /* frames followed by all the long term frames. No long term */ + /* reference field should have a list idx less than a short */ + /* term reference field during initiailization. */ + + for(j = 0; j < 2; j++) + { + i = ((j == 0) ? 0 : u1_num_short_term_bufs); + uc_count = ((j == 0) ? u1_num_short_term_bufs : *pu1_L0); + for(; i < uc_count; i++, ps_ref_lx[0]++) + { + /* Search field of same parity in Frame list */ + if((ps_ref_lx[0]->u1_pic_type & u1_ref[0])) // || ((ps_ref_lx[0]->u1_picturetype & 0x3) == 0)) + { + /* Insert PIC of same parity in RefPicList */ + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_lx, ps_ref_lx[0]); + ps_ref_pic_lx->i4_pic_num = (ps_ref_pic_lx->i4_pic_num * 2 + 1); + ps_ref_pic_lx->u1_long_term_pic_num = + (ps_ref_pic_lx->u1_long_term_frm_idx * 2 + 1); + ps_ref_pic_lx->u1_pic_type = u1_same_fld; + if(u1_fld[0] & BOT_FLD) + { + ps_ref_pic_lx->u1_pic_type = BOT_FLD; + ps_ref_pic_lx->pu1_buf1 += ps_ref_pic_lx->u2_frm_wd_y; + ps_ref_pic_lx->pu1_buf2 += ps_ref_pic_lx->u2_frm_wd_uv; + ps_ref_pic_lx->pu1_buf3 += ps_ref_pic_lx->u2_frm_wd_uv; + if(ps_ref_pic_lx->u1_picturetype & 0x3) + { + ps_ref_pic_lx->pu1_col_zero_flag += ui_half_num_of_sub_mbs; + ps_ref_pic_lx->ps_mv += ui_half_num_of_sub_mbs; + } + ps_ref_pic_lx->i4_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + } + else + { + ps_ref_pic_lx->u1_pic_type = TOP_FLD; + ps_ref_pic_lx->i4_poc = ps_ref_pic_lx->i4_top_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_top_field_order_cnt; + } + + ps_ref_pic_lx++; + uc_lx++; + /* Find field of opposite parity */ + if(uc_l1 < uc_count && ps_ref_lx[1]) + { + while(!(ps_ref_lx[1]->u1_pic_type & u1_ref[1])) + { + ps_ref_lx[1]++; + uc_l1++; + if(uc_l1 >= uc_count) + ps_ref_lx[1] = 0; + if(!ps_ref_lx[1]) + break; + } + + if(ps_ref_lx[1]) + { + uc_l1++; + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_lx, + ps_ref_lx[1]); + ps_ref_pic_lx->u1_pic_type = u1_op_fld; + ps_ref_pic_lx->i4_pic_num = (ps_ref_pic_lx->i4_pic_num * 2); + ps_ref_pic_lx->u1_long_term_pic_num = + (ps_ref_pic_lx->u1_long_term_frm_idx * 2); + if(u1_fld[1] & BOT_FLD) + { + ps_ref_pic_lx->u1_pic_type = BOT_FLD; + ps_ref_pic_lx->pu1_buf1 += ps_ref_pic_lx->u2_frm_wd_y; + ps_ref_pic_lx->pu1_buf2 += ps_ref_pic_lx->u2_frm_wd_uv; + ps_ref_pic_lx->pu1_buf3 += ps_ref_pic_lx->u2_frm_wd_uv; + if(ps_ref_pic_lx->u1_picturetype & 0x3) + { + ps_ref_pic_lx->pu1_col_zero_flag += + ui_half_num_of_sub_mbs; + ps_ref_pic_lx->ps_mv += ui_half_num_of_sub_mbs; + } + ps_ref_pic_lx->i4_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + } + else + { + ps_ref_pic_lx->u1_pic_type = TOP_FLD; + ps_ref_pic_lx->i4_poc = + ps_ref_pic_lx->i4_top_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_top_field_order_cnt; + } + ps_ref_pic_lx++; + uc_lx++; + ps_ref_lx[1]++; + } + } + } + } + + /* Same parity fields are over, now insert left over opposite parity fields */ + /** Added if(ps_ref_lx[1]) for error checks */ + if(ps_ref_lx[1]) + { + for(; uc_l1 < uc_count; uc_l1++) + { + if(ps_ref_lx[1]->u1_pic_type & u1_ref[1]) + { + /* Insert PIC of opposite parity in RefPicList */ + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_lx, + ps_ref_lx[1]); + ps_ref_pic_lx->u1_pic_type = u1_op_fld; + ps_ref_pic_lx->i4_pic_num = (ps_ref_pic_lx->i4_pic_num * 2); + ps_ref_pic_lx->u1_long_term_pic_num = + (ps_ref_pic_lx->u1_long_term_frm_idx * 2); + if(u1_op_fld == BOT_FLD) + { + ps_ref_pic_lx->u1_pic_type = BOT_FLD; + ps_ref_pic_lx->pu1_buf1 += ps_ref_pic_lx->u2_frm_wd_y; + ps_ref_pic_lx->pu1_buf2 += ps_ref_pic_lx->u2_frm_wd_uv; + ps_ref_pic_lx->pu1_buf3 += ps_ref_pic_lx->u2_frm_wd_uv; + if(ps_ref_pic_lx->u1_picturetype & 0x3) + { + ps_ref_pic_lx->pu1_col_zero_flag += + ui_half_num_of_sub_mbs; + ps_ref_pic_lx->ps_mv += ui_half_num_of_sub_mbs; + } + ps_ref_pic_lx->i4_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_bottom_field_order_cnt; + } + else + { + ps_ref_pic_lx->i4_poc = + ps_ref_pic_lx->i4_top_field_order_cnt; + ps_ref_pic_lx->i4_avg_poc = + ps_ref_pic_lx->i4_top_field_order_cnt; + } + ps_ref_pic_lx++; + uc_lx++; + ps_ref_lx[1]++; + } + } + } + } + *pu1_L0 = uc_lx; +} + +void ih264d_convert_frm_mbaff_list(dec_struct_t *ps_dec) +{ + struct pic_buffer_t **ps_ref_pic_lx; + UWORD8 u1_max_ref_idx, idx; + UWORD16 u2_frm_wd_y, u2_frm_wd_uv; + struct pic_buffer_t **ps_ref_pic_buf_lx; + UWORD32 u4_half_num_of_sub_mbs = ((ps_dec->u2_pic_ht * ps_dec->u2_pic_wd) >> 5); + + ps_ref_pic_buf_lx = ps_dec->ps_ref_pic_buf_lx[0]; + ps_ref_pic_lx = ps_dec->ps_ref_pic_buf_lx[0]; + u1_max_ref_idx = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[0]; + for(idx = 0; idx < u1_max_ref_idx; idx++) + { + ps_ref_pic_lx[idx]->u1_pic_type = TOP_FLD; + ps_ref_pic_lx[idx]->i4_poc = ps_ref_pic_lx[idx]->i4_top_field_order_cnt; + + } + u2_frm_wd_y = ps_dec->u2_frm_wd_y; + u2_frm_wd_uv = ps_dec->u2_frm_wd_uv; + + for(idx = 0; idx < u1_max_ref_idx; idx++) + { + *ps_ref_pic_lx[idx + MAX_REF_BUFS] = *ps_ref_pic_buf_lx[idx]; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf1 = + ps_ref_pic_buf_lx[idx]->pu1_buf1 + u2_frm_wd_y; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf2 = + ps_ref_pic_buf_lx[idx]->pu1_buf2 + u2_frm_wd_uv; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf3 = + ps_ref_pic_buf_lx[idx]->pu1_buf3 + u2_frm_wd_uv; + + ps_ref_pic_lx[idx + MAX_REF_BUFS]->u1_pic_type = BOT_FLD; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->i4_poc = + ps_ref_pic_buf_lx[idx]->i4_bottom_field_order_cnt; + if(ps_ref_pic_buf_lx[idx]->u1_picturetype & 0x3) + { + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_col_zero_flag = + ps_ref_pic_buf_lx[idx]->pu1_col_zero_flag + + u4_half_num_of_sub_mbs; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->ps_mv = + ps_ref_pic_buf_lx[idx]->ps_mv + u4_half_num_of_sub_mbs; + } + } + + if(ps_dec->u1_B) + { + ps_ref_pic_buf_lx = ps_dec->ps_ref_pic_buf_lx[1]; + ps_ref_pic_lx = ps_dec->ps_ref_pic_buf_lx[1]; + u1_max_ref_idx = ps_dec->ps_cur_slice->u1_num_ref_idx_lx_active[1]; + for(idx = 0; idx < u1_max_ref_idx; idx++) + { + ps_ref_pic_lx[idx]->u1_pic_type = TOP_FLD; + ps_ref_pic_lx[idx]->i4_poc = ps_ref_pic_lx[idx]->i4_top_field_order_cnt; + + } + + for(idx = 0; idx < u1_max_ref_idx; idx++) + { + *ps_ref_pic_lx[idx + MAX_REF_BUFS] = *ps_ref_pic_buf_lx[idx]; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf1 = + ps_ref_pic_buf_lx[idx]->pu1_buf1 + u2_frm_wd_y; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf2 = + ps_ref_pic_buf_lx[idx]->pu1_buf2 + u2_frm_wd_uv; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_buf3 = + ps_ref_pic_buf_lx[idx]->pu1_buf3 + u2_frm_wd_uv; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->u1_pic_type = BOT_FLD; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->i4_poc = + ps_ref_pic_buf_lx[idx]->i4_bottom_field_order_cnt; + + if(ps_ref_pic_buf_lx[idx]->u1_picturetype & 0x3) + { + ps_ref_pic_lx[idx + MAX_REF_BUFS]->pu1_col_zero_flag = + ps_ref_pic_buf_lx[idx]->pu1_col_zero_flag + + u4_half_num_of_sub_mbs; + ps_ref_pic_lx[idx + MAX_REF_BUFS]->ps_mv = + ps_ref_pic_buf_lx[idx]->ps_mv + + u4_half_num_of_sub_mbs; + } + } + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_init_ref_idx_lx_b \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec) +{ + struct pic_buffer_t *ps_ref_pic_buf_lx; + dpb_manager_t *ps_dpb_mgr; + struct dpb_info_t *ps_next_dpb; + WORD32 i_cur_poc, i_max_st_poc, i_min_st_poc, i_ref_poc, i_temp_poc; + WORD8 i; + UWORD8 u1_max_lt_index, u1_min_lt_index, u1_lt_index; + UWORD8 u1_field_pic_flag; + dec_slice_params_t *ps_cur_slice; + UWORD8 u1_L0, u1_L1; + UWORD8 u1_num_short_term_bufs; + UWORD8 u1_max_ref_idx_l0, u1_max_ref_idx_l1; + + ps_cur_slice = ps_dec->ps_cur_slice; + u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + u1_max_ref_idx_l0 = ps_cur_slice->u1_num_ref_idx_lx_active[0] + << u1_field_pic_flag; + u1_max_ref_idx_l1 = ps_cur_slice->u1_num_ref_idx_lx_active[1] + << u1_field_pic_flag; + + ps_dpb_mgr = ps_dec->ps_dpb_mgr; + /* Get the current POC */ + i_cur_poc = ps_dec->ps_cur_pic->i4_poc; + + /* Get MaxStPOC,MinStPOC,MaxLt,MinLt */ + i_max_st_poc = i_cur_poc; + i_min_st_poc = i_cur_poc; + u1_max_lt_index = MAX_REF_BUFS + 1; + u1_min_lt_index = MAX_REF_BUFS + 1; + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + i_ref_poc = ps_next_dpb->ps_pic_buf->i4_poc; + if(i_ref_poc < i_cur_poc) + { + /* RefPic Buf POC is before Current POC in display order */ + i_min_st_poc = MIN(i_min_st_poc, i_ref_poc); + } + else + { + /* RefPic Buf POC is after Current POC in display order */ + i_max_st_poc = MAX(i_max_st_poc, i_ref_poc); + } + + /* Chase the next link */ + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + /* Start from LT head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + if(ps_next_dpb) + { + u1_max_lt_index = ps_next_dpb->u1_lt_idx; + u1_min_lt_index = ps_next_dpb->u1_lt_idx; + } + for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + u1_lt_index = ps_next_dpb->u1_lt_idx; + u1_max_lt_index = (UWORD8)(MAX(u1_max_lt_index, u1_lt_index)); + u1_min_lt_index = (UWORD8)(MIN(u1_min_lt_index, u1_lt_index)); + + /* Chase the next link */ + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + + /* 1. Initialize refIdxL0 */ + u1_L0 = 0; + if(u1_field_pic_flag) + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; + ps_ref_pic_buf_lx += MAX_REF_BUFS; + i_temp_poc = i_cur_poc; + } + else + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; + i_temp_poc = i_cur_poc - 1; + } + /* Arrange all short term buffers in output order as given by POC */ + /* 1.1 Arrange POC's less than CurrPOC in the descending POC order starting + from (CurrPOC - 1)*/ + for(; i_temp_poc >= i_min_st_poc; i_temp_poc--) + { + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) + { + /* Copy info in pic buffer */ + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx++; + u1_L0++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + } + + { + /* 1.2. Arrange POC's more than CurrPOC in the ascending POC order starting + from (CurrPOC + 1)*/ + for(i_temp_poc = i_cur_poc + 1; i_temp_poc <= i_max_st_poc; i_temp_poc++) + { + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx++; + u1_L0++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + } + } + + /* 1.3 Arrange all Long term buffers in ascending order, in LongtermIndex */ + /* Start from ST head */ + + u1_num_short_term_bufs = u1_L0; + for(u1_lt_index = u1_min_lt_index; u1_lt_index <= u1_max_lt_index; u1_lt_index++) + { + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + if(ps_next_dpb->u1_lt_idx == u1_lt_index) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx->u1_long_term_pic_num = + ps_ref_pic_buf_lx->u1_long_term_frm_idx; + + ps_ref_pic_buf_lx++; + u1_L0++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + } + + if(u1_field_pic_flag) + { + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[0][0] + MAX_REF_BUFS; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L0; u1_i < u1_max_ref_idx_l0; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + ih264d_convert_frm_to_fld_list( + ps_dpb_mgr->ps_init_dpb[0][0] + MAX_REF_BUFS, &u1_L0, + ps_dec, u1_num_short_term_bufs); + + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0] + u1_L0; + } + + ps_dec->ps_cur_slice->u1_initial_list_size[0] = u1_L0; + + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[0][0]; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L0; u1_i < u1_max_ref_idx_l0; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + { + /* 2. Initialize refIdxL1 */ + u1_L1 = 0; + if(u1_field_pic_flag) + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[1][0] + MAX_REF_BUFS; + } + else + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[1][0]; + } + + /* 2.1. Arrange POC's more than CurrPOC in the ascending POC order starting + from (CurrPOC + 1)*/ + for(i_temp_poc = i_cur_poc + 1; i_temp_poc <= i_max_st_poc; i_temp_poc++) + { + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx++; + u1_L1++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + } + + if(u1_field_pic_flag) + { + i_temp_poc = i_cur_poc; + } + else + { + i_temp_poc = i_cur_poc - 1; + } + + /* Arrange all short term buffers in output order as given by POC */ + /* 2.2 Arrange POC's less than CurrPOC in the descending POC order starting + from (CurrPOC - 1)*/ + for(; i_temp_poc >= i_min_st_poc; i_temp_poc--) + { + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx++; + u1_L1++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + } + + /* 2.3 Arrange all Long term buffers in ascending order, in LongtermIndex */ + /* Start from ST head */ + u1_num_short_term_bufs = u1_L1; + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + for(u1_lt_index = u1_min_lt_index; u1_lt_index <= u1_max_lt_index; + u1_lt_index++) + { + for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + if(ps_next_dpb->u1_lt_idx == u1_lt_index) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx->u1_long_term_pic_num = + ps_ref_pic_buf_lx->u1_long_term_frm_idx; + ps_ref_pic_buf_lx++; + u1_L1++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + } + + if(u1_field_pic_flag) + { + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[1][0] + MAX_REF_BUFS; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L1; u1_i < u1_max_ref_idx_l1; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + + ih264d_convert_frm_to_fld_list( + ps_dpb_mgr->ps_init_dpb[1][0] + MAX_REF_BUFS, + &u1_L1, ps_dec, u1_num_short_term_bufs); + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[1][0] + u1_L1; + } + + ps_dec->ps_cur_slice->u1_initial_list_size[1] = u1_L1; + + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[1][0]; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L1; u1_i < u1_max_ref_idx_l1; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + + /* If list0 and list 1 ebtries are same then swap the 0th and 1st entry */ + /* of list 1 */ + { + struct pic_buffer_t *ps_ref_pic1_buf_l0, *ps_ref_pic1_buf_l1; + struct pic_buffer_t s_ref_pic1_buf_temp; + + ps_ref_pic1_buf_l0 = ps_dpb_mgr->ps_init_dpb[0][0]; + ps_ref_pic1_buf_l1 = ps_dpb_mgr->ps_init_dpb[1][0]; + + if((u1_L0 == u1_L1) && (u1_L0 > 1)) + { + WORD32 i_index, i_swap; + + i_swap = 1; + + for(i_index = 0; i_index < u1_L0; i_index++) + { + if((ps_ref_pic1_buf_l0[i_index]).pu1_buf1 + != (ps_ref_pic1_buf_l1[i_index]).pu1_buf1) + { + i_swap = 0; + break; + } + } + if(1 == i_swap) + { + memcpy(&s_ref_pic1_buf_temp, &ps_ref_pic1_buf_l1[1], + sizeof(struct pic_buffer_t)); + memcpy(&ps_ref_pic1_buf_l1[1], &ps_ref_pic1_buf_l1[0], + sizeof(struct pic_buffer_t)); + memcpy(&ps_ref_pic1_buf_l1[0], &s_ref_pic1_buf_temp, + sizeof(struct pic_buffer_t)); + } + } + } + } +} + + + +void ih264d_get_implicit_weights(dec_struct_t *ps_dec); + +/*! + ************************************************************************** + * \if Function name : ih264d_one_to_one \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_one_to_one(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8 *pu1_col_zero_flag_start, u1_col_mb_pred_mode, u1_num_blks, u1_sub_mb_num; + UWORD8 u1_init_colzero_flag; + UNUSED(ps_cur_mb_info); + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst; + u1_col_mb_pred_mode = pu1_col_zero_flag_start[ps_dec->u1_sub_mb_num]; + u1_init_colzero_flag = u1_col_mb_pred_mode & 1; + u1_col_mb_pred_mode >>= 6; + ps_direct->u1_vert_mv_scale = ONE_TO_ONE; + ps_direct->u1_col_zeroflag_change = 0; + + if(u1_wd_x == MB_SIZE) + { + ps_dec->u1_currB_type = (!!u1_col_mb_pred_mode); + if(u1_col_mb_pred_mode == PRED_16x16) + { + ps_direct->i1_num_partitions = 1; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = PRED_16x16; + + return; + } + else if(u1_col_mb_pred_mode < PRED_8x8) + { + ps_direct->i1_num_partitions = 2; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = u1_col_mb_pred_mode; + u1_sub_mb_num = (u1_col_mb_pred_mode == PRED_16x8) ? 8 : 2; + ps_direct->i1_submb_num[1] = u1_sub_mb_num; + ps_direct->i4_mv_indices[1] = u2_sub_mb_ofst + + ps_direct->i1_submb_num[1]; + ps_direct->i1_partitionsize[1] = u1_col_mb_pred_mode; + if((pu1_col_zero_flag_start[u1_sub_mb_num] & 1) != u1_init_colzero_flag) + ps_direct->u1_col_zeroflag_change = 1; + return; + } + else + { + u1_num_blks = 4; + } + } + else + { + u1_num_blks = 1; + } + + { + const UWORD8 *pu1_top_lt_mb_part_idx; + UWORD8 u1_col_sub_mb_pred_mode, uc_blk, u1_sub_blk, u1_submb_col = 0; + UWORD8 u1_num_sub_blks, uc_direct8x8inf, *pu1_col_zero_flag, u1_sub_mb_num; + const UWORD8 *pu1_num_sub_mb_part = + (const UWORD8 *)gau1_ih264d_num_submb_part; + UWORD8 i1_num_partitions = 0, partition_size; + WORD32 mv_index; + const UWORD8 *pu1_top_lt_sub_mb_idx = gau1_ih264d_submb_indx_mod_sp_drct; + + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + uc_direct8x8inf = ps_dec->ps_cur_slice->u1_direct_8x8_inference_flag; + pu1_top_lt_mb_part_idx = gau1_ih264d_top_left_mb_part_indx_mod + + (PRED_8x8 << 1) + 1; + + for(uc_blk = 0; uc_blk < u1_num_blks; uc_blk++) + { + partition_size = PRED_8x8; + pu1_top_lt_sub_mb_idx = gau1_ih264d_submb_indx_mod_sp_drct; + if(uc_direct8x8inf == 1) + { + u1_submb_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + mv_index = u2_sub_mb_ofst + u1_submb_col; + u1_num_sub_blks = 1; + } + else + { + /* colMbPart is either 8x8, 8x4, 4x8, 4x4 */ + pu1_col_zero_flag = pu1_col_zero_flag_start + u1_sub_mb_num; + u1_col_sub_mb_pred_mode = *pu1_col_zero_flag; + u1_col_sub_mb_pred_mode = (u1_col_sub_mb_pred_mode & 0x30) >> 4; + partition_size = (UWORD8)((u1_col_sub_mb_pred_mode) + | (PRED_8x8 << 2)); + mv_index = u2_sub_mb_ofst + u1_sub_mb_num; + pu1_top_lt_sub_mb_idx += (u1_col_sub_mb_pred_mode << 1); + u1_num_sub_blks = pu1_num_sub_mb_part[u1_col_sub_mb_pred_mode]; + + } + + for(u1_sub_blk = 0; u1_sub_blk < u1_num_sub_blks; + u1_sub_blk++, pu1_top_lt_sub_mb_idx++) + { + u1_sub_mb_num += *pu1_top_lt_sub_mb_idx; + mv_index += *pu1_top_lt_sub_mb_idx; + ps_direct->i4_mv_indices[i1_num_partitions] = mv_index; + ps_direct->i1_submb_num[i1_num_partitions] = u1_sub_mb_num; + ps_direct->i1_partitionsize[i1_num_partitions] = partition_size; + i1_num_partitions++; + if(!uc_direct8x8inf) + u1_submb_col = u1_sub_mb_num; + if((pu1_col_zero_flag_start[u1_submb_col] & 1) + != u1_init_colzero_flag) + ps_direct->u1_col_zeroflag_change = 1; + } + u1_sub_mb_num = *pu1_top_lt_mb_part_idx++; + } + ps_direct->i1_num_partitions = i1_num_partitions; + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_mbaff_cross_pmbair \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_mbaff_cross_pmbair(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8 *pu1_col_zero_flag_start, *pu1_col_zero_flag, u1_sub_mb_num, + uc_sub_mb_num_col; + UWORD8 *pu1_col_zero_flag_right_half; + WORD32 i4_force_8X8; + UWORD8 u1_num_blks, u1_col_mb_pred_mode, uc_blk, u1_col_sub_mb_pred_mode, + u1_col_sub_mb_pred_mode_rt; + UWORD8 i1_num_partitions = 0, partition_size; + + WORD32 mv_index; + + UWORD8 u1_num_sub_blks; + UWORD8 u1_is_cur_mb_fld, i; + UWORD8 u1_init_colzero_flag; + + u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + ps_direct->u1_col_zeroflag_change = 0; + /*pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst; + u1_col_mb_pred_mode = pu1_col_zero_flag_start[u1_sub_mb_num]; + u1_init_colzero_flag = u1_col_mb_pred_mode & 1; + u1_col_mb_pred_mode >>= 6; */ + if(0 == u1_is_cur_mb_fld) + { + ps_direct->u1_vert_mv_scale = FLD_TO_FRM; + if(u1_wd_x == MB_SIZE) + { + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst; + u1_col_mb_pred_mode = pu1_col_zero_flag_start[0]; + u1_init_colzero_flag = u1_col_mb_pred_mode & 1; + u1_col_mb_pred_mode >>= 6; + + + if(u1_col_mb_pred_mode & 0x2) + { + ps_dec->u1_currB_type = 1; + if(u1_col_mb_pred_mode == PRED_8x16) + { + ps_direct->i1_num_partitions = 2; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = PRED_8x16; + ps_direct->i4_mv_indices[1] = u2_sub_mb_ofst + 2; + ps_direct->i1_submb_num[1] = 2; + ps_direct->i1_partitionsize[1] = PRED_8x16; + if((pu1_col_zero_flag_start[2] & 1) != u1_init_colzero_flag) + ps_direct->u1_col_zeroflag_change = 1; + } + else + { + pu1_col_zero_flag = pu1_col_zero_flag_start + u1_sub_mb_num; + u1_col_sub_mb_pred_mode = (*pu1_col_zero_flag & 0x10);/* 8x4 or 4x4 mode */ + + pu1_col_zero_flag_right_half = pu1_col_zero_flag_start + + u1_sub_mb_num + 2; + u1_col_sub_mb_pred_mode_rt = + (*pu1_col_zero_flag_right_half & 0x10);/* 8x4 or 4x4 mode */ + + i4_force_8X8 = (u1_col_sub_mb_pred_mode) + || (u1_col_sub_mb_pred_mode_rt); + if(i4_force_8X8) + { + u1_num_sub_blks = 2; + partition_size = PRED_8x8; + } + else + { + partition_size = PRED_8x16; + u1_num_sub_blks = 1; + } + + for(i = 0; i < 2; i++) + { + for(uc_blk = 0; uc_blk < u1_num_sub_blks; uc_blk++) + { + uc_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + uc_sub_mb_num_col &= 0x7; + mv_index = u2_sub_mb_ofst + uc_sub_mb_num_col; + + ps_direct->i4_mv_indices[i1_num_partitions] = + mv_index; + ps_direct->i1_submb_num[i1_num_partitions] = + u1_sub_mb_num; + ps_direct->i1_partitionsize[i1_num_partitions] = + partition_size; + i1_num_partitions++; + if((pu1_col_zero_flag_start[uc_sub_mb_num_col] & 1) + != u1_init_colzero_flag) + ps_direct->u1_col_zeroflag_change = 1; + u1_sub_mb_num += 8; + } + u1_sub_mb_num = 2; /* move to second half of Cur MB */ + } + ps_direct->i1_num_partitions = i1_num_partitions; + return; + } + } + else + { + ps_direct->i1_num_partitions = 1; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = PRED_16x16; + ps_dec->u1_currB_type = 0; + return; + } + } + else + { + uc_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + uc_sub_mb_num_col &= 0x7; + + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst + uc_sub_mb_num_col; + ps_direct->i1_submb_num[0] = u1_sub_mb_num; + ps_direct->i1_partitionsize[0] = PRED_8x8; + ps_direct->i1_num_partitions = 1; + } + } + else + { + ps_direct->u1_vert_mv_scale = FRM_TO_FLD; + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst; + u1_init_colzero_flag = pu1_col_zero_flag_start[0] & 1; + + if(u1_wd_x == MB_SIZE) + { + UWORD8 u1_submb_col; + UWORD8 *puc_colZeroFlagStart_bot_mb, uc_colMbPredMode_bot_mb; + + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst; + u1_col_mb_pred_mode = pu1_col_zero_flag_start[u1_sub_mb_num] >> 6; + + puc_colZeroFlagStart_bot_mb = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst + 16; + uc_colMbPredMode_bot_mb = puc_colZeroFlagStart_bot_mb[8] >> 6; + + i4_force_8X8 = (u1_col_mb_pred_mode & 0x2) + || (uc_colMbPredMode_bot_mb & 0x2); + if(i4_force_8X8) + { + u1_num_blks = 2; + partition_size = PRED_8x8; + } + else + { + u1_num_blks = 1; + partition_size = PRED_16x8; + } + + ps_dec->u1_currB_type = 1; + /*As this mb is derived from 2 Mbs min no of partitions = 2*/ + for(i = 0; i < 2; i++) + { + + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst; + u1_col_mb_pred_mode = pu1_col_zero_flag_start[u1_sub_mb_num] >> 6; + + for(uc_blk = 0; uc_blk < u1_num_blks; uc_blk++) + { + u1_submb_col = (u1_sub_mb_num & 0x7) ? 1 : 0; + u1_submb_col += u1_sub_mb_num; + mv_index = u2_sub_mb_ofst + u1_submb_col; + + + ps_direct->i4_mv_indices[i1_num_partitions] = mv_index; + ps_direct->i1_submb_num[i1_num_partitions] = u1_sub_mb_num; + ps_direct->i1_partitionsize[i1_num_partitions] = + partition_size; + i1_num_partitions++; + if((pu1_col_zero_flag_start[u1_submb_col] & 1) + != u1_init_colzero_flag) + ps_direct->u1_col_zeroflag_change = 1; + u1_sub_mb_num += 2; + } + u1_sub_mb_num = 8; /* move to second half of Cur MB */ + u2_sub_mb_ofst += 16;/* move to next Colocated MB */ + } + ps_direct->i1_num_partitions = i1_num_partitions; + return; + } + else + { + uc_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + uc_sub_mb_num_col &= 0xb; + u2_sub_mb_ofst += (u1_sub_mb_num >> 3) ? 16 : 0; + + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst + uc_sub_mb_num_col; + ps_direct->i1_submb_num[0] = u1_sub_mb_num; + ps_direct->i1_partitionsize[0] = PRED_8x8; + ps_direct->i1_num_partitions = 1; + return; + } + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_cal_col_pic \endif + * + * \brief + * Finds the colocated picture. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_cal_col_pic(dec_struct_t *ps_dec) +{ + struct pic_buffer_t* ps_col_pic = ps_dec->ps_col_pic; + UWORD8 uc_curpictype, uc_colpictype; + ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][0]; + uc_curpictype = (ps_dec->ps_cur_pic->u1_picturetype & 0x7); + uc_colpictype = (ps_col_pic->u1_picturetype & 0x7); + if(uc_curpictype == FRM_PIC) + { + if(uc_colpictype == FRM_PIC) + ps_dec->pf_parse_mvdirect = ih264d_one_to_one; + else if(uc_colpictype == COMP_FLD_PAIR) + { + ps_dec->pf_parse_mvdirect = ih264d_fld_to_frm; + if(ps_col_pic->i4_top_field_order_cnt + >= ps_col_pic->i4_bottom_field_order_cnt) + { + struct pic_buffer_t* ps_tempPic = ps_col_pic; + UWORD32 ui_half_num_of_sub_mbs = ((ps_dec->u2_pic_ht + * ps_dec->u2_pic_wd) >> 5); + ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; + /* memcpy ps_tempPic to ps_col_pic */ + *ps_col_pic = *ps_tempPic; + ps_col_pic->pu1_buf1 = ps_tempPic->pu1_buf1 + + ps_tempPic->u2_frm_wd_y; + ps_col_pic->pu1_buf2 = ps_tempPic->pu1_buf2 + + ps_tempPic->u2_frm_wd_uv; + ps_col_pic->pu1_buf3 = ps_tempPic->pu1_buf3 + + ps_tempPic->u2_frm_wd_uv; + ps_col_pic->pu1_col_zero_flag = ps_tempPic->pu1_col_zero_flag + + ui_half_num_of_sub_mbs; + ps_col_pic->ps_mv = ps_tempPic->ps_mv + ui_half_num_of_sub_mbs; + + + ps_col_pic->u1_pic_type = 0;/*complementary reference field pair-refering as frame */ + + + + } + } + else + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; +// i4_error_code |= 1<<IVD_CORRUPTEDDATA; + return i4_error_code; + } + } + else if(uc_curpictype == AFRM_PIC) + { + ps_dec->pf_parse_mvdirect = ih264d_fld_to_mbaff; + } + else /* must be a field*/ + { + if(uc_colpictype == FRM_PIC) + ps_dec->pf_parse_mvdirect = ih264d_frm_to_fld; + else if(uc_colpictype == AFRM_PIC) + ps_dec->pf_parse_mvdirect = ih264d_mbaff_to_fld; + else + ps_dec->pf_parse_mvdirect = ih264d_one_to_one; + } + ps_dec->ps_col_pic = ps_col_pic; + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_frm_to_fld \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_frm_to_fld(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8 *pu1_col_zero_flag_start, u1_sub_mb_num; + UWORD8 u1_num_blks, u1_col_mb_pred_mode, uc_blk; + UWORD8 i1_num_partitions = 0, partition_size, i; + WORD32 mv_index; + UWORD32 increment; + WORD32 i4_force_8X8; + UNUSED(ps_cur_mb_info); + ps_direct->u1_col_zeroflag_change = 1; + ps_direct->u1_vert_mv_scale = FRM_TO_FLD; + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + + /* new calculation specific to this function */ + if((ps_col_pic->u1_picturetype & 0x7) == FRM_PIC) + { + UWORD16 u2_frm_wd_in_mbs = ps_dec->u2_frm_wd_in_mbs; + increment = (u2_frm_wd_in_mbs << 4); + /*mbAddrCol = mbAddrCol1 */ + u2_sub_mb_ofst = (ps_dec->u2_mbx + + (2 * ps_dec->u2_mby * u2_frm_wd_in_mbs)) << 4; + } + else + increment = 16; + + if(u1_wd_x == MB_SIZE) + { + ps_dec->u1_currB_type = 1; + + { + UWORD8 *puc_colZeroFlagStart_bot_mb, uc_colMbPredMode_bot_mb; + + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst; + u1_col_mb_pred_mode = (*pu1_col_zero_flag_start >> 6); + + puc_colZeroFlagStart_bot_mb = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst + increment; + uc_colMbPredMode_bot_mb = (*puc_colZeroFlagStart_bot_mb >> 6); + + i4_force_8X8 = (u1_col_mb_pred_mode & 0x2) + || (uc_colMbPredMode_bot_mb & 0x2); + + if(i4_force_8X8) + { + u1_num_blks = 2; + partition_size = PRED_8x8; + } + else + { + partition_size = PRED_16x8; + u1_num_blks = 1; + } + } + + /*As this mb is derived from 2 Mbs, min no of partitions = 2*/ + for(i = 0; i < 2; i++) + { + for(uc_blk = 0; uc_blk < u1_num_blks; uc_blk++) + { + mv_index = u2_sub_mb_ofst + u1_sub_mb_num; + mv_index += (u1_sub_mb_num & 0x7) ? 1 : 0; + + ps_direct->i4_mv_indices[i1_num_partitions] = mv_index; + ps_direct->i1_submb_num[i1_num_partitions] = u1_sub_mb_num; + ps_direct->i1_partitionsize[i1_num_partitions] = partition_size; + i1_num_partitions++; + + u1_sub_mb_num += 2; + } + u1_sub_mb_num = 8; /* move to second half of Cur MB */ + u2_sub_mb_ofst += increment;/* move to next Colocated MB */ + } + ps_direct->i1_num_partitions = i1_num_partitions; + return; + } + else + { + UWORD8 u1_sub_mb_num_col; + u1_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + u1_sub_mb_num_col &= 0xb; + u2_sub_mb_ofst += (u1_sub_mb_num >> 3) ? increment : 0; + + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst + u1_sub_mb_num_col; + ps_direct->i1_submb_num[0] = u1_sub_mb_num; + ps_direct->i1_partitionsize[0] = PRED_8x8; + ps_direct->i1_num_partitions = 1; + return; + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_fld_to_frm \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_fld_to_frm(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8 *pu1_col_zero_flag_start, *pu1_col_zero_flag, + *pu1_col_zero_flag_right_half, u1_sub_mb_num, uc_sub_mb_num_col; + UWORD8 u1_col_mb_pred_mode, uc_blk; + WORD32 i4_force_8X8; + + UNUSED(ps_cur_mb_info); + ps_direct->u1_vert_mv_scale = FLD_TO_FRM; + ps_direct->u1_col_zeroflag_change = 1; + /* new calculation specific to this function for u2_sub_mb_ofst*/ + u2_sub_mb_ofst = (ps_dec->u2_mbx + + ((ps_dec->u2_mby >> 1) * ps_dec->u2_frm_wd_in_mbs)) << 4; + u2_sub_mb_ofst += ((ps_dec->u2_mby & 1) << 3); + + if(u1_wd_x == MB_SIZE) + { + pu1_col_zero_flag_start = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst; + u1_col_mb_pred_mode = (*pu1_col_zero_flag_start >> 6); + ps_dec->u1_currB_type = (!!u1_col_mb_pred_mode); + + if(u1_col_mb_pred_mode & 0x2) + { + if(u1_col_mb_pred_mode == PRED_8x16) + { + ps_direct->i1_num_partitions = 2; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = PRED_8x16; + ps_direct->i4_mv_indices[1] = u2_sub_mb_ofst + 2; + ps_direct->i1_submb_num[1] = 2; + ps_direct->i1_partitionsize[1] = PRED_8x16; + } + else + { + UWORD8 i1_num_partitions = 0, partition_size; + UWORD32 mv_index; + UWORD8 u1_num_sub_blks, i, u1_col_sub_mb_pred_mode, + u1_col_sub_mb_pred_mode_rt; + + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + + pu1_col_zero_flag = pu1_col_zero_flag_start + u1_sub_mb_num; + u1_col_sub_mb_pred_mode = (*pu1_col_zero_flag & 0x10);/* 8x4 or 4x4 mode */ + + pu1_col_zero_flag_right_half = pu1_col_zero_flag_start + u1_sub_mb_num + + 2; + u1_col_sub_mb_pred_mode_rt = (*pu1_col_zero_flag_right_half + & 0x10);/* 8x4 or 4x4 mode */ + + i4_force_8X8 = (u1_col_sub_mb_pred_mode) + || (u1_col_sub_mb_pred_mode_rt); + if(i4_force_8X8) + { + u1_num_sub_blks = 2; + partition_size = PRED_8x8; + } + else + { + partition_size = PRED_8x16; + u1_num_sub_blks = 1; + } + + for(i = 0; i < 2; i++) + { + for(uc_blk = 0; uc_blk < u1_num_sub_blks; uc_blk++) + { + uc_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + uc_sub_mb_num_col &= 0x7; + mv_index = u2_sub_mb_ofst + uc_sub_mb_num_col; + + ps_direct->i4_mv_indices[i1_num_partitions] = mv_index; + ps_direct->i1_submb_num[i1_num_partitions] = + u1_sub_mb_num; + ps_direct->i1_partitionsize[i1_num_partitions] = + partition_size; + i1_num_partitions++; + u1_sub_mb_num += 8; + } + + u1_sub_mb_num = 2; /* move to second half of Cur MB */ + + } + ps_direct->i1_num_partitions = i1_num_partitions; + return; + } + } + else + { + ps_direct->i1_num_partitions = 1; + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst; + ps_direct->i1_submb_num[0] = 0; + ps_direct->i1_partitionsize[0] = PRED_16x16; + return; + } + } + else + { + u1_sub_mb_num = ps_dec->u1_sub_mb_num; + uc_sub_mb_num_col = u1_sub_mb_num | (u1_sub_mb_num >> 1); + uc_sub_mb_num_col &= 0x7; + + ps_direct->i4_mv_indices[0] = u2_sub_mb_ofst + uc_sub_mb_num_col; + ps_direct->i1_submb_num[0] = u1_sub_mb_num; + ps_direct->i1_partitionsize[0] = PRED_8x8; + ps_direct->i1_num_partitions = 1; + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_one_to_one \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_mbaff_to_fld(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8* pu1_col_zero_flag, u1_iscol_mb_fld; + u2_sub_mb_ofst <<= 1; + pu1_col_zero_flag = ps_col_pic->pu1_col_zero_flag + u2_sub_mb_ofst; + u1_iscol_mb_fld = (*pu1_col_zero_flag & 0x2) >> 1; + if(u1_iscol_mb_fld) + { + u2_sub_mb_ofst += (ps_dec->ps_cur_slice->u1_bottom_field_flag << 4); + ih264d_one_to_one(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); + } + else + ih264d_frm_to_fld(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); +} +/*! + ************************************************************************** + * \if Function name : ih264d_one_to_one \endif + * + * \brief + * Initializes forward and backward refernce lists for B slice decoding. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info) +{ + if((ps_col_pic->u1_picturetype & 0x7) == COMP_FLD_PAIR) + { + /* first calculate the colocated picture which varies with Mb */ + UWORD8 u1_is_cur_mb_fld; + u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + u2_sub_mb_ofst = (u2_sub_mb_ofst & 0xffe0); /* mbaddrCol5 = curmbaddr/2;*/ + u2_sub_mb_ofst >>= 1; + + ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][0]; + if(u1_is_cur_mb_fld) + { + if(1 - ps_cur_mb_info->u1_topmb) + ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; + + ih264d_one_to_one(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); + } + else + { + + if(ABS(ps_col_pic->i4_top_field_order_cnt + - ps_dec->ps_cur_pic->i4_poc) >= + ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + { + ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS]; + } + + if(ps_cur_mb_info->u1_topmb == 0) + u2_sub_mb_ofst += 8; + ih264d_mbaff_cross_pmbair(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); + } + ps_dec->ps_col_pic = ps_col_pic; + } + else + { + UWORD8* pu1_col_zero_flag = ps_col_pic->pu1_col_zero_flag + + u2_sub_mb_ofst; + UWORD8 temp, u1_is_cur_mb_fld, u1_iscol_mb_fld; + + u1_iscol_mb_fld = (*pu1_col_zero_flag & 0x2) >> 1; + u1_is_cur_mb_fld = ps_cur_mb_info->u1_mb_field_decodingflag; + temp = (u1_iscol_mb_fld ^ u1_is_cur_mb_fld); + + if(temp == 0) + ih264d_one_to_one(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); + else + { + u2_sub_mb_ofst &= 0xffef; + if(u1_is_cur_mb_fld == 0) + { + if(ABS(ps_col_pic->i4_top_field_order_cnt + - ps_dec->ps_cur_pic->i4_poc) >= + ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt)) + { + u2_sub_mb_ofst += 0x10; + } + if(ps_cur_mb_info->u1_topmb == 0) + u2_sub_mb_ofst += 8; + } + ih264d_mbaff_cross_pmbair(ps_dec, ps_col_pic, ps_direct, u1_wd_x, + u2_sub_mb_ofst, ps_cur_mb_info); + } + } +} + diff --git a/decoder/ih264d_process_bslice.h b/decoder/ih264d_process_bslice.h new file mode 100755 index 0000000..5aa76e3 --- /dev/null +++ b/decoder/ih264d_process_bslice.h @@ -0,0 +1,108 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_PARSE_BSLICE_H_ +#define _IH264D_PARSE_BSLICE_H_ +/*! +************************************************************************** +* \file ih264d_process_bslice.h +* +* \brief +* Contains declarations of routines that decode a B slice type +* +* Detailed_description +* +* \date +* 21/12/2002 +* +* \author NS +************************************************************************** +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +WORD32 ih264d_parse_bslice(dec_struct_t * ps_dec, + UWORD16 u2_first_mb_in_slice); +WORD32 ih264d_decode_spatial_direct(dec_struct_t * ps_dec, + UWORD8 u1_wd_x, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num); +WORD32 ih264d_decode_temporal_direct(dec_struct_t * ps_dec, + UWORD8 u1_wd_x, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num); +WORD32 parseBSliceData(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); +WORD32 parseBSliceData(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); + +void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec); + +void ih264d_convert_frm_to_fld_list(struct pic_buffer_t *ps_ref_pic_buf_lx, + UWORD8 *pu1_L0, + dec_struct_t *ps_dec, + UWORD8 u1_num_short_term_bufs); + +void ih264d_convert_frm_mbaff_list(dec_struct_t *ps_dec); +void ih264d_one_to_one(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_mbaff_cross_pmbair(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_frm_to_fld(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_fld_to_frm(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_mbaff_to_fld(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +void ih264d_fld_to_mbaff(dec_struct_t *ps_dec, + struct pic_buffer_t *ps_col_pic, + directmv_t *ps_direct, + UWORD8 u1_wd_x, + WORD32 u2_sub_mb_ofst, + dec_mb_info_t * ps_cur_mb_info); +WORD32 ih264d_cal_col_pic(dec_struct_t *ps_dec); + +WORD32 ih264d_mv_pred_ref_tfr_nby2_bmb(dec_struct_t * ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbsNby2); + +#endif /* _IH264D_PARSE_BSLICE_H_ */ diff --git a/decoder/ih264d_process_intra_mb.c b/decoder/ih264d_process_intra_mb.c new file mode 100755 index 0000000..96006ce --- /dev/null +++ b/decoder/ih264d_process_intra_mb.c @@ -0,0 +1,2006 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_process_intra_mb.c + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ + +#include <string.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_parse_slice.h" +#include "ih264d_process_intra_mb.h" +#include "ih264d_error_handler.h" +#include "ih264d_quant_scaling.h" +#include "ih264d_tables.h" + +/*! + ************************************************************************** + * \if Function name : ih264d_itrans_recon_luma_dc \endif + * + * \brief + * This function does InvTransform, scaling and reconstruction of Luma DC. + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +void ih264d_itrans_recon_luma_dc(dec_struct_t *ps_dec, + WORD16* pi2_src, + WORD16* pi2_coeff_block, + const UWORD16 *pu2_weigh_mat) +{ + WORD32 i; + WORD16 pi2_out[16]; + WORD32 pi4_tmp[16]; + WORD16 *pi2_out_ptr = &pi2_out[0]; + PROFILE_DISABLE_IQ_IT_RECON_RETURN() + ps_dec->pf_ihadamard_scaling_4x4(pi2_src, pi2_out, + ps_dec->pu2_quant_scale_y, pu2_weigh_mat, + ps_dec->u1_qp_y_div6, pi4_tmp); + for(i = 0; i < 4; i++) + { + pi2_coeff_block[0] = pi2_out_ptr[0]; + pi2_coeff_block[4 * 16] = pi2_out_ptr[4]; + pi2_coeff_block[8 * 16] = pi2_out_ptr[8]; + pi2_coeff_block[12 * 16] = pi2_out_ptr[12]; + + pi2_out_ptr++; /* Point to next column */ + pi2_coeff_block += 16; + } +} +/*! + ************************************************************************** + * \if Function name : ih264d_read_intra_pred_modes \endif + * + * \brief + * Reads the intra pred mode related values of I4x4 MB from bitstream. + * + * This function will read the prev intra pred mode flags and + * stores it in pu1_prev_intra4x4_pred_mode_flag. If the u4_flag + * indicates that most probable mode is not intra pred mode, then + * the rem_intra4x4_pred_mode is read and stored in + * pu1_rem_intra4x4_pred_mode array. + * + * + * \return + * 0 on success and Error code otherwise + * + ************************************************************************** + */ +WORD32 ih264d_read_intra_pred_modes(dec_struct_t * ps_dec, + UWORD8 * pu1_prev_intra4x4_pred_mode_flag, + UWORD8 * pu1_rem_intra4x4_pred_mode, + UWORD32 u4_trans_form8x8) +{ + WORD32 i4x4_luma_blk_idx = 0, i8x8_luma_blk_idx = 0; + + dec_bit_stream_t * ps_bitstrm = ps_dec->ps_bitstrm; + + if(!u4_trans_form8x8) + { + for(i4x4_luma_blk_idx = 0; i4x4_luma_blk_idx < 16; ++i4x4_luma_blk_idx) + { + UWORD32 u4_temp; + SWITCHOFFTRACE; + + GETBIT(u4_temp, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); + *pu1_prev_intra4x4_pred_mode_flag = (UWORD8)u4_temp; + if(!(*pu1_prev_intra4x4_pred_mode_flag)) + { + GETBITS(u4_temp, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer, 3); + + *(pu1_rem_intra4x4_pred_mode) = (UWORD8)u4_temp; + } + + pu1_prev_intra4x4_pred_mode_flag++; + pu1_rem_intra4x4_pred_mode++; + } + } + else + { + /**********************************************************************/ + /* prev_intra4x4_pred_modes to be interpreted as */ + /* prev_intra8x8_pred_modes in case of transform 8x8 */ + /**********************************************************************/ + for(i8x8_luma_blk_idx = 0; i8x8_luma_blk_idx < 4; i8x8_luma_blk_idx++) + { + UWORD32 u4_temp; + GETBIT(u4_temp, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer); + *pu1_prev_intra4x4_pred_mode_flag = (UWORD8)u4_temp; + if(!(*pu1_prev_intra4x4_pred_mode_flag)) + { + GETBITS(u4_temp, ps_bitstrm->u4_ofst, ps_bitstrm->pu4_buffer, 3); + + (*pu1_rem_intra4x4_pred_mode) = (UWORD8)u4_temp; + } + pu1_prev_intra4x4_pred_mode_flag++; + pu1_rem_intra4x4_pred_mode++; + } + } + return (0); +} +WORD32 ih264d_unpack_coeff4x4_4x4blk(dec_struct_t * ps_dec, + WORD16 *pi2_out_coeff_data, + UWORD8 *pu1_inv_scan) +{ + tu_sblk4x4_coeff_data_t *ps_tu_4x4 = (tu_sblk4x4_coeff_data_t *)ps_dec->pv_proc_tu_coeff_data; + UWORD16 u2_sig_coeff_map = ps_tu_4x4->u2_sig_coeff_map; + WORD32 idx = 0; + WORD16 *pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + WORD32 dc_only_flag = 0; + WORD32 num_coeff = 0; + + PROFILE_DISABLE_UNPACK_LUMA() + while(u2_sig_coeff_map) + { + idx = CLZ(u2_sig_coeff_map); + + idx = 31 - idx; + RESET_BIT(u2_sig_coeff_map,idx); + + idx = pu1_inv_scan[idx]; + pi2_out_coeff_data[idx] = *pi2_coeff_data++; + num_coeff++; + } + + if((num_coeff == 1) && (idx == 0)) + { + dc_only_flag = 1; + } + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_4x4; + offset = ALIGN4(offset); + ps_dec->pv_proc_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_proc_tu_coeff_data + offset); + } + + return dc_only_flag; +} + +UWORD32 ih264d_unpack_coeff4x4_8x8blk(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD16 ui2_luma_csbp, + WORD16 *pi2_out_coeff_data) +{ + UWORD8 *pu1_inv_scan; + UWORD8 u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 u1_field_coding_flag = ps_cur_mb_info->ps_curmb->u1_mb_fld; + UWORD32 u4_luma_dc_only_csbp = 0; + WORD32 dc_only_flag = 0; + + PROFILE_DISABLE_UNPACK_LUMA() + if(u1_field_coding_flag || u1_mb_field_decoding_flag) + { + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_fld; + } + else + { + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + } + + // sub 0 + if(ui2_luma_csbp & 0x1) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + dc_only_flag = ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + + INSERT_BIT(u4_luma_dc_only_csbp, 0, dc_only_flag); + } + + pi2_out_coeff_data += 16; + // sub 1 + if(ui2_luma_csbp & 0x2) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + dc_only_flag = ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + INSERT_BIT(u4_luma_dc_only_csbp, 1, dc_only_flag); + } + + pi2_out_coeff_data += 16 + 32; + // sub 2 + if(ui2_luma_csbp & 0x10) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + dc_only_flag = ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + INSERT_BIT(u4_luma_dc_only_csbp, 4, dc_only_flag); + } + + pi2_out_coeff_data += 16; + // sub 3 + if(ui2_luma_csbp & 0x20) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + dc_only_flag = ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + INSERT_BIT(u4_luma_dc_only_csbp, 5, dc_only_flag); + } + return u4_luma_dc_only_csbp; +} +WORD32 ih264d_unpack_coeff8x8_8x8blk_cavlc(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD16 ui2_luma_csbp, + WORD16 *pi2_out_coeff_data) +{ + UWORD8 *pu1_inv_scan; + UWORD8 u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 u1_field_coding_flag = ps_cur_mb_info->ps_curmb->u1_mb_fld; + WORD32 dc_only_flag = 0; + + PROFILE_DISABLE_UNPACK_LUMA() + if(ui2_luma_csbp & 0x33) + { + memset(pi2_out_coeff_data,0,64*sizeof(WORD16)); + } + + if(!u1_mb_field_decoding_flag) + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[0]; + } + else + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[0]; + } + // sub 0 + if(ui2_luma_csbp & 0x1) + { + dc_only_flag = ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + + if(!u1_mb_field_decoding_flag) + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[1]; + } + else + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[1]; + } + // sub 1 + if(ui2_luma_csbp & 0x2) + { + dc_only_flag = 0; + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + + if(!u1_mb_field_decoding_flag) + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[2]; + } + else + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[2]; + } + // sub 2 + if(ui2_luma_csbp & 0x10) + { + dc_only_flag = 0; + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + + if(!u1_mb_field_decoding_flag) + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_prog8x8_cavlc[3]; + } + else + { + pu1_inv_scan = + (UWORD8*)gau1_ih264d_inv_scan_int8x8_cavlc[3]; + } + // sub 3 + if(ui2_luma_csbp & 0x20) + { + dc_only_flag = 0; + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + return dc_only_flag; +} +void ih264d_unpack_coeff4x4_8x8blk_chroma(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD16 ui2_chroma_csbp, + WORD16 *pi2_out_coeff_data) +{ + UWORD8 *pu1_inv_scan; + UWORD8 u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 u1_field_coding_flag = ps_cur_mb_info->ps_curmb->u1_mb_fld; + + PROFILE_DISABLE_UNPACK_CHROMA() + if(u1_field_coding_flag || u1_mb_field_decoding_flag) + { + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_fld; + } + else + { + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + } + + if(ui2_chroma_csbp & 0x1) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + pi2_out_coeff_data += 16; + if(ui2_chroma_csbp & 0x2) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + + pi2_out_coeff_data += 16; + if(ui2_chroma_csbp & 0x4) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } + + pi2_out_coeff_data += 16; + if(ui2_chroma_csbp & 0x8) + { + memset(pi2_out_coeff_data,0,16*sizeof(WORD16)); + ih264d_unpack_coeff4x4_4x4blk(ps_dec, + pi2_out_coeff_data, + pu1_inv_scan); + } +} +UWORD32 ih264d_unpack_luma_coeff4x4_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 intra_flag) +{ + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD16 ui2_luma_csbp = ps_cur_mb_info->u2_luma_csbp; + UWORD8 *pu1_inv_scan = ps_dec->pu1_inv_scan; + WORD16 *pi2_coeff_data = ps_dec->pi2_coeff_data; + + PROFILE_DISABLE_UNPACK_LUMA() + if(!ps_cur_mb_info->u1_tran_form8x8) + { + UWORD32 u4_luma_dc_only_csbp = 0; + UWORD32 u4_temp = 0; + WORD16* pi2_dc_val = NULL; + /* + * Reserve the pointer to dc vals. The dc vals will be copied + * after unpacking of ac vals since memset to 0 inside. + */ + if(intra_flag && (u1_mb_type != I_4x4_MB)) + { + if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag,0)) + { + pi2_dc_val = (WORD16 *)ps_dec->pv_proc_tu_coeff_data; + + ps_dec->pv_proc_tu_coeff_data = (void *)(pi2_dc_val + 16); + } + } + + if(ui2_luma_csbp) + { + pi2_coeff_data = ps_dec->pi2_coeff_data; + u4_temp = ih264d_unpack_coeff4x4_8x8blk(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + u4_luma_dc_only_csbp = u4_temp; + + pi2_coeff_data += 32; + + ui2_luma_csbp = ui2_luma_csbp >> 2; + u4_temp = ih264d_unpack_coeff4x4_8x8blk(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + + u4_luma_dc_only_csbp |= (u4_temp << 2); + + pi2_coeff_data += 32 + 64; + + ui2_luma_csbp = ui2_luma_csbp >> 6; + u4_temp = ih264d_unpack_coeff4x4_8x8blk(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + + u4_luma_dc_only_csbp |= (u4_temp << 8); + + pi2_coeff_data += 32; + + ui2_luma_csbp = ui2_luma_csbp >> 2; + u4_temp = ih264d_unpack_coeff4x4_8x8blk(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + u4_luma_dc_only_csbp |= (u4_temp << 10); + } + + if(pi2_dc_val != NULL) + { + WORD32 i; + pi2_coeff_data = ps_dec->pi2_coeff_data; + for(i = 0; i < 4; i++) + { + pi2_coeff_data[0] = pi2_dc_val[0]; + pi2_coeff_data[4 * 16] = pi2_dc_val[4]; + pi2_coeff_data[8 * 16] = pi2_dc_val[8]; + pi2_coeff_data[12 * 16] = pi2_dc_val[12]; + + pi2_dc_val++; /* Point to next column */ + pi2_coeff_data += 16; + } + u4_luma_dc_only_csbp = ps_cur_mb_info->u2_luma_csbp ^ 0xFFFF; + } + return u4_luma_dc_only_csbp; + } + else + { + UWORD32 u4_luma_dc_only_cbp = 0; + WORD32 dc_only_flag; + if(ui2_luma_csbp) + { + pi2_coeff_data = ps_dec->pi2_coeff_data; + dc_only_flag = ih264d_unpack_coeff8x8_8x8blk_cavlc(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + INSERT_BIT(u4_luma_dc_only_cbp, 0, dc_only_flag); + + pi2_coeff_data += 64; + + ui2_luma_csbp = ui2_luma_csbp >> 2; + dc_only_flag = ih264d_unpack_coeff8x8_8x8blk_cavlc(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + + INSERT_BIT(u4_luma_dc_only_cbp, 1, dc_only_flag); + + pi2_coeff_data += 64; + + ui2_luma_csbp = ui2_luma_csbp >> 6; + dc_only_flag = ih264d_unpack_coeff8x8_8x8blk_cavlc(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + + INSERT_BIT(u4_luma_dc_only_cbp, 2, dc_only_flag); + + pi2_coeff_data += 64; + ui2_luma_csbp = ui2_luma_csbp >> 2; + dc_only_flag = ih264d_unpack_coeff8x8_8x8blk_cavlc(ps_dec, + ps_cur_mb_info, + ui2_luma_csbp, + pi2_coeff_data); + INSERT_BIT(u4_luma_dc_only_cbp, 3, dc_only_flag); + } + return u4_luma_dc_only_cbp; + } + +} + +void ih264d_unpack_chroma_coeff4x4_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info) +{ + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD16 ui2_chroma_csbp = ps_cur_mb_info->u2_chroma_csbp; + UWORD8 *pu1_inv_scan = ps_dec->pu1_inv_scan; + WORD16 *pi2_coeff_data = ps_dec->pi2_coeff_data; + WORD32 i; + WORD16 *pi2_dc_val_u = NULL; + WORD16 *pi2_dc_val_v = NULL; + + PROFILE_DISABLE_UNPACK_CHROMA() + if((ps_cur_mb_info->u1_cbp >> 4) == CBPC_ALLZERO) + return; + + /* + * Reserve the pointers to dc vals. The dc vals will be copied + * after unpacking of ac vals since memset to 0 inside. + */ + if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag,1)) + { + pi2_dc_val_u = (WORD16 *)ps_dec->pv_proc_tu_coeff_data; + + ps_dec->pv_proc_tu_coeff_data = (void *)(pi2_dc_val_u + 4); + } + if(CHECKBIT(ps_cur_mb_info->u1_yuv_dc_block_flag,2)) + { + pi2_dc_val_v = (WORD16 *)ps_dec->pv_proc_tu_coeff_data; + + ps_dec->pv_proc_tu_coeff_data = (void *)(pi2_dc_val_v + 4); + } + + if((ps_cur_mb_info->u1_cbp >> 4) == CBPC_NONZERO) + { + pi2_coeff_data = ps_dec->pi2_coeff_data; + ih264d_unpack_coeff4x4_8x8blk_chroma(ps_dec, + ps_cur_mb_info, + ui2_chroma_csbp, + pi2_coeff_data); + + pi2_coeff_data += 64; + ui2_chroma_csbp = ui2_chroma_csbp >> 4; + ih264d_unpack_coeff4x4_8x8blk_chroma(ps_dec, + ps_cur_mb_info, + ui2_chroma_csbp, + pi2_coeff_data); + + } + + pi2_coeff_data = ps_dec->pi2_coeff_data; + if(pi2_dc_val_u != NULL) + { + pi2_coeff_data[0] = *pi2_dc_val_u++; + pi2_coeff_data[1 * 16] = *pi2_dc_val_u++; + pi2_coeff_data[2 * 16] = *pi2_dc_val_u++; + pi2_coeff_data[3 * 16] = *pi2_dc_val_u++; + } + else + { + pi2_coeff_data[0] = 0; + pi2_coeff_data[1 * 16] = 0; + pi2_coeff_data[2 * 16] = 0; + pi2_coeff_data[3 * 16] = 0; + } + pi2_coeff_data += 64; + if(pi2_dc_val_v != NULL) + { + pi2_coeff_data[0] = *pi2_dc_val_v++; + pi2_coeff_data[1 * 16] = *pi2_dc_val_v++; + pi2_coeff_data[2 * 16] = *pi2_dc_val_v++; + pi2_coeff_data[3 * 16] = *pi2_dc_val_v++; + } + else + { + pi2_coeff_data[0] = 0; + pi2_coeff_data[1 * 16] = 0; + pi2_coeff_data[2 * 16] = 0; + pi2_coeff_data[3 * 16] = 0; + } +} +UWORD32 ih264d_unpack_luma_coeff8x8_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info) +{ + WORD32 blk_8x8_cnt; + WORD16 *pi2_out_coeff_data = ps_dec->pi2_coeff_data; + UWORD8 u1_field_coding_flag = ps_cur_mb_info->ps_curmb->u1_mb_fld; + UWORD8 *pu1_inv_scan; + UWORD32 u4_luma_dc_only_cbp = 0; + + PROFILE_DISABLE_UNPACK_LUMA() + if(!u1_field_coding_flag) + { + /*******************************************************************/ + /* initializing inverse scan matrices */ + /*******************************************************************/ + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_prog8x8_cabac; + } + else + { + /*******************************************************************/ + /* initializing inverse scan matrices */ + /*******************************************************************/ + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan_int8x8_cabac; + } + + for(blk_8x8_cnt = 0; blk_8x8_cnt < 4; blk_8x8_cnt++) + { + if(CHECKBIT(ps_cur_mb_info->u1_cbp, blk_8x8_cnt)) + { + tu_blk8x8_coeff_data_t *ps_tu_8x8 = (tu_blk8x8_coeff_data_t *)ps_dec->pv_proc_tu_coeff_data; + UWORD32 u4_sig_coeff_map; + WORD32 idx = 0; + WORD16 *pi2_coeff_data = &ps_tu_8x8->ai2_level[0]; + WORD32 num_coeff = 0; + + /* memset 64 coefficient to zero */ + memset(pi2_out_coeff_data,0,64*sizeof(WORD16)); + + u4_sig_coeff_map = ps_tu_8x8->au4_sig_coeff_map[1]; + + while(u4_sig_coeff_map) + { + idx = CLZ(u4_sig_coeff_map); + + idx = 31 - idx; + RESET_BIT(u4_sig_coeff_map,idx); + + idx = pu1_inv_scan[idx + 32]; + pi2_out_coeff_data[idx] = *pi2_coeff_data++; + num_coeff++; + } + + u4_sig_coeff_map = ps_tu_8x8->au4_sig_coeff_map[0]; + while(u4_sig_coeff_map) + { + idx = CLZ(u4_sig_coeff_map); + + idx = 31 - idx; + RESET_BIT(u4_sig_coeff_map,idx); + + idx = pu1_inv_scan[idx]; + pi2_out_coeff_data[idx] = *pi2_coeff_data++; + num_coeff++; + } + + if((num_coeff == 1) && (idx == 0)) + { + SET_BIT(u4_luma_dc_only_cbp,blk_8x8_cnt); + } + + + { + WORD32 offset; + offset = (UWORD8 *)pi2_coeff_data - (UWORD8 *)ps_tu_8x8; + offset = ALIGN4(offset); + ps_dec->pv_proc_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_proc_tu_coeff_data + offset); + } + } + pi2_out_coeff_data += 64; + } + + return u4_luma_dc_only_cbp; +} +/*! + ************************************************************************** + * \if Function name : ih264d_process_intra_mb \endif + * + * \brief + * This function decodes an I MB. Intraprediction is carried out followed + * by InvTramsform. Both IntraPrediction and Reconstrucion are carried out + * row buffer itself. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num) +{ + UWORD8 u1_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD8 uc_temp = ps_cur_mb_info->u1_mb_ngbr_availablity; + UWORD8 u1_top_available = BOOLEAN(uc_temp & TOP_MB_AVAILABLE_MASK); + UWORD8 u1_left_available = BOOLEAN(uc_temp & LEFT_MB_AVAILABLE_MASK); + UWORD8 u1_use_top_right_mb = BOOLEAN(uc_temp & TOP_RIGHT_MB_AVAILABLE_MASK); + UWORD8 u1_use_top_left_mb = BOOLEAN(uc_temp & TOP_LEFT_MB_AVAILABLE_MASK); + UWORD8 uc_useTopMB = u1_top_available; + UWORD16 u2_use_left_mb = u1_left_available; + UWORD16 u2_use_left_mb_pack; + UWORD8 *pu1_luma_pred_buffer; + /* CHANGED CODE */ + UWORD8 *pu1_luma_rei1_buffer; + UWORD8 *puc_top; + + mb_neigbour_params_t *ps_left_mb; + mb_neigbour_params_t *ps_top_mb; + mb_neigbour_params_t *ps_top_right_mb; + mb_neigbour_params_t *ps_curmb; + + UWORD16 u2_mbx = ps_cur_mb_info->u2_mbx; + UWORD32 ui_pred_width, ui_rec_width; + WORD16 *pi2_y_coeff; + UWORD8 u1_mbaff, u1_topmb, u1_mb_field_decoding_flag; + UWORD32 u4_num_pmbair; + UWORD16 ui2_luma_csbp = ps_cur_mb_info->u2_luma_csbp; + UWORD8 *pu1_yleft, *pu1_ytop_left; + /* Chroma variables*/ + UWORD8 *pu1_top_u; + UWORD8 *pu1_uleft; + UWORD8 *pu1_u_top_left; + /* CHANGED CODE */ + UWORD8 *pu1_mb_cb_rei1_buffer, *pu1_mb_cr_rei1_buffer; + UWORD32 u4_recwidth_cr; + /* CHANGED CODE */ + tfr_ctxt_t *ps_frame_buf = &ps_dec->s_tran_addrecon; + UWORD32 u4_luma_dc_only_csbp = 0; + UWORD32 u4_luma_dc_only_cbp = 0; + + UWORD8 *pu1_prev_intra4x4_pred_mode_data = (UWORD8 *)ps_dec->pv_proc_tu_coeff_data; //Pointer to keep track of intra4x4_pred_mode data in pv_proc_tu_coeff_data buffer + u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + u1_topmb = ps_cur_mb_info->u1_topmb; + u4_num_pmbair = (u1_mb_num >> u1_mbaff); + + + /*--------------------------------------------------------------------*/ + /* Find the current MB's mb params */ + /*--------------------------------------------------------------------*/ + u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + + ps_curmb = ps_cur_mb_info->ps_curmb; + ps_top_mb = ps_cur_mb_info->ps_top_mb; + ps_left_mb = ps_cur_mb_info->ps_left_mb; + ps_top_right_mb = ps_cur_mb_info->ps_top_right_mb; + + /*--------------------------------------------------------------------*/ + /* Check whether neighbouring MB is Inter MB and */ + /* constrained intra pred is 1. */ + /*--------------------------------------------------------------------*/ + u2_use_left_mb_pack = (u2_use_left_mb << 8) + u2_use_left_mb; + + if(ps_dec->ps_cur_pps->u1_constrained_intra_pred_flag) + { + UWORD8 u1_left = (UWORD8)u2_use_left_mb; + + uc_useTopMB = uc_useTopMB + && ((ps_top_mb->u1_mb_type != P_MB) + && (ps_top_mb->u1_mb_type != B_MB)); + u2_use_left_mb = u2_use_left_mb + && ((ps_left_mb->u1_mb_type != P_MB) + && (ps_left_mb->u1_mb_type != B_MB)); + + u2_use_left_mb_pack = (u2_use_left_mb << 8) + u2_use_left_mb; + if(u1_mbaff) + { + if(u1_mb_field_decoding_flag ^ ps_left_mb->u1_mb_fld) + { + u1_left = u1_left + && (((ps_left_mb + 1)->u1_mb_type != P_MB) + && ((ps_left_mb + 1)->u1_mb_type + != B_MB)); + u2_use_left_mb = u2_use_left_mb && u1_left; + if(u1_mb_field_decoding_flag) + u2_use_left_mb_pack = (u1_left << 8) + + (u2_use_left_mb_pack & 0xff); + else + u2_use_left_mb_pack = (u2_use_left_mb << 8) + + (u2_use_left_mb); + } + } + u1_use_top_right_mb = + u1_use_top_right_mb + && ((ps_top_right_mb->u1_mb_type != P_MB) + && (ps_top_right_mb->u1_mb_type + != B_MB)); + + u1_use_top_left_mb = + u1_use_top_left_mb + && ((ps_cur_mb_info->u1_topleft_mbtype != P_MB) + && (ps_cur_mb_info->u1_topleft_mbtype + != B_MB)); + } + + /*********************Common pointer calculations *************************/ + /* CHANGED CODE */ + pu1_luma_pred_buffer = ps_dec->pu1_y; + pu1_luma_rei1_buffer = ps_frame_buf->pu1_dest_y + (u4_num_pmbair << 4); + pu1_mb_cb_rei1_buffer = ps_frame_buf->pu1_dest_u + + (u4_num_pmbair << 3) * YUV420SP_FACTOR; + pu1_mb_cr_rei1_buffer = ps_frame_buf->pu1_dest_v + (u4_num_pmbair << 3); + ui_pred_width = MB_SIZE; + ui_rec_width = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + u4_recwidth_cr = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + /************* Current and top luma pointer *****************/ + + if(u1_mbaff) + { + if(u1_topmb == 0) + { + pu1_luma_rei1_buffer += ( + u1_mb_field_decoding_flag ? + (ui_rec_width >> 1) : + (ui_rec_width << 4)); + pu1_mb_cb_rei1_buffer += ( + u1_mb_field_decoding_flag ? + (u4_recwidth_cr >> 1) : + (u4_recwidth_cr << 3)); + pu1_mb_cr_rei1_buffer += ( + u1_mb_field_decoding_flag ? + (u4_recwidth_cr >> 1) : + (u4_recwidth_cr << 3)); + } + } + + /* CHANGED CODE */ + if(ps_dec->u4_use_intrapred_line_copy == 1) + { + puc_top = ps_dec->pu1_prev_y_intra_pred_line + (ps_cur_mb_info->u2_mbx << 4); + pu1_top_u = ps_dec->pu1_prev_u_intra_pred_line + + (ps_cur_mb_info->u2_mbx << 3) * YUV420SP_FACTOR; + } + else + { + puc_top = pu1_luma_rei1_buffer - ui_rec_width; + pu1_top_u = pu1_mb_cb_rei1_buffer - u4_recwidth_cr; + } + /* CHANGED CODE */ + + /************* Left pointer *****************/ + pu1_yleft = pu1_luma_rei1_buffer - 1; + pu1_uleft = pu1_mb_cb_rei1_buffer - 1 * YUV420SP_FACTOR; + + /**************Top Left pointer calculation**********/ + pu1_ytop_left = puc_top - 1; + pu1_u_top_left = pu1_top_u - 1 * YUV420SP_FACTOR; + + /* CHANGED CODE */ + PROFILE_DISABLE_INTRA_PRED() + { + pu1_prev_intra4x4_pred_mode_data = (UWORD8 *)ps_dec->pv_proc_tu_coeff_data; + if(u1_mb_type == I_4x4_MB && ps_cur_mb_info->u1_tran_form8x8 == 0) + { + ps_dec->pv_proc_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_proc_tu_coeff_data + 32); + + } + else if (u1_mb_type == I_4x4_MB && ps_cur_mb_info->u1_tran_form8x8 == 1) + { + ps_dec->pv_proc_tu_coeff_data = (void *)((UWORD8 *)ps_dec->pv_proc_tu_coeff_data + 8); + } + } + if(!ps_cur_mb_info->u1_tran_form8x8) + { + u4_luma_dc_only_csbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, + ps_cur_mb_info, + 1); + } + else + { + if(!ps_dec->ps_cur_pps->u1_entropy_coding_mode) + { + u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, + ps_cur_mb_info, + 1); + } + else + { + u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff8x8_mb(ps_dec, + ps_cur_mb_info); + } + } + + pi2_y_coeff = ps_dec->pi2_coeff_data; + + if(u1_mb_type != I_4x4_MB) + { + UWORD8 u1_intrapred_mode = MB_TYPE_TO_INTRA_16x16_MODE(u1_mb_type); + /*--------------------------------------------------------------------*/ + /* 16x16 IntraPrediction */ + /*--------------------------------------------------------------------*/ + { + UWORD8 u1_packed_modes = (u1_top_available << 1) + + u1_left_available; + UWORD8 u1_err_code = + (u1_intrapred_mode & 1) ? + u1_intrapred_mode : + (u1_intrapred_mode ^ 2); + + if((u1_err_code & u1_packed_modes) ^ u1_err_code) + { + return ERROR_INTRAPRED; + } + } + { + UWORD8 au1_ngbr_pels[33]; + /* Get neighbour pixels */ + /* left pels */ + if(u2_use_left_mb) + { + WORD32 i; + for(i = 0; i < 16; i++) + au1_ngbr_pels[16 - 1 - i] = pu1_yleft[i * ui_rec_width]; + } + else + { + memset(au1_ngbr_pels, 0, 16); + } + + /* top left pels */ + au1_ngbr_pels[16] = *pu1_ytop_left; + + /* top pels */ + if(uc_useTopMB) + { + memcpy(au1_ngbr_pels + 16 + 1, puc_top, 16); + } + else + { + memset(au1_ngbr_pels + 16 + 1, 0, 16); + } + PROFILE_DISABLE_INTRA_PRED() + ps_dec->apf_intra_pred_luma_16x16[u1_intrapred_mode]( + au1_ngbr_pels, pu1_luma_rei1_buffer, 1, ui_rec_width, + ((uc_useTopMB << 2) | u2_use_left_mb)); + } + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 16; i++) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_luma_rei1_buffer + + ((i & 0x3) * BLK_SIZE) + + (i >> 2) * (ui_rec_width << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(ps_cur_mb_info->u2_luma_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_luma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[0], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 1, + pi2_level); + } + else if((CHECKBIT(u4_luma_dc_only_csbp, i)) && pi2_level[0] != 0) + { + ps_dec->pf_iquant_itrans_recon_luma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[0], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 1, + pi2_level); + } + } + } + } + } + else if(!ps_cur_mb_info->u1_tran_form8x8) + { + UWORD8 u1_is_left_sub_block, u1_is_top_sub_block = uc_useTopMB; + UWORD8 u1_sub_blk_x, u1_sub_blk_y, u1_sub_mb_num; + WORD8 i1_top_pred_mode; + WORD8 i1_left_pred_mode; + UWORD8 *pu1_top, *pu1_left, *pu1_top_left, *pu1_top_right; + WORD8 *pi1_cur_pred_mode, *pi1_left_pred_mode, *pc_topPredMode; + UWORD16 ui2_left_pred_buf_width = 0xffff; + WORD8 i1_intra_pred; + UWORD8 *pu1_prev_intra4x4_pred_mode_flag = pu1_prev_intra4x4_pred_mode_data; + UWORD8 *pu1_rem_intra4x4_pred_mode = pu1_prev_intra4x4_pred_mode_data + 16; + WORD16 *pi2_y_coeff1; + UWORD8 u1_cur_sub_block; + UWORD16 ui2_top_rt_mask; + + /*--------------------------------------------------------------------*/ + /* 4x4 IntraPrediction */ + /*--------------------------------------------------------------------*/ + /* Calculation of Top Right subblock mask */ + /* */ + /* (a) Set it to default mask */ + /* [It has 0 for sublocks which will never have top-right sub block] */ + /* */ + /* (b) If top MB is not available */ + /* Clear the bits of the first row sub blocks */ + /* */ + /* (c) Set/Clear bit for top-right sublock of MB */ + /* [5 sub-block in decoding order] based on TOP RIGHT MB availablity */ + /*--------------------------------------------------------------------*/ + + pu1_top = puc_top; + + ui2_top_rt_mask = (u1_use_top_right_mb << 3) | (0x5750); + if(uc_useTopMB) + ui2_top_rt_mask |= 0x7; + + /*Top Related initialisations*/ + + + pi1_cur_pred_mode = ps_cur_mb_info->ps_curmb->pi1_intrapredmodes; + pc_topPredMode = ps_cur_mb_info->ps_top_mb->pi1_intrapredmodes; + /*-------------------------------------- + if(u1_mbaff) + { + + pi1_cur_pred_mode += (u2_mbx << 2); + pc_topPredMode = pi1_cur_pred_mode + ps_cur_mb_info->i1_offset; + pi1_cur_pred_mode += (u1_topmb) ? 0: 4; + }*/ + + if(u1_top_available) + { + if(ps_top_mb->u1_mb_type == I_4x4_MB) + *(WORD32*)pi1_cur_pred_mode = *(WORD32*)pc_topPredMode; + else + *(WORD32*)pi1_cur_pred_mode = + (uc_useTopMB) ? DC_DC_DC_DC : NOT_VALID; + } + else + *(WORD32*)pi1_cur_pred_mode = NOT_VALID; + /* CHANGED CODE */ + + /* CHANGED CODE */ + + /*Left Related initialisations*/ + pi1_left_pred_mode = ps_dec->pi1_left_pred_mode; + if(!u1_mbaff) + { + + if(u1_left_available) + { + + if(ps_left_mb->u1_mb_type != I_4x4_MB) + *(WORD32*)pi1_left_pred_mode = + (u2_use_left_mb_pack) ? + DC_DC_DC_DC : + NOT_VALID; + + } + else + { + + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + + } + else + { + UWORD8 u1_curMbfld = ps_cur_mb_info->u1_mb_field_decodingflag; + UWORD8 u1_leftMbfld = ps_left_mb->u1_mb_fld; + + if(u1_curMbfld ^ u1_leftMbfld) + { + + if(u1_topmb + | ((u1_topmb == 0) + && ((ps_curmb - 1)->u1_mb_type + != I_4x4_MB))) + { + if(u1_left_available) + { + if(ps_left_mb->u1_mb_type != I_4x4_MB) + { + if(CHECKBIT(u2_use_left_mb_pack,0) == 0) + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + else + *(WORD32*)pi1_left_pred_mode = DC_DC_DC_DC; + } + } + else + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + + if(u1_curMbfld) + { + if(u1_left_available) + { + if((ps_left_mb + 1)->u1_mb_type != I_4x4_MB) + { + if(u2_use_left_mb_pack >> 8) + *(WORD32*)(pi1_left_pred_mode + 4) = + DC_DC_DC_DC; + else + *(WORD32*)(pi1_left_pred_mode + 4) = + NOT_VALID; + } + } + else + *(WORD32*)(pi1_left_pred_mode + 4) = NOT_VALID; + pi1_left_pred_mode[1] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[2] = pi1_left_pred_mode[4]; + pi1_left_pred_mode[3] = pi1_left_pred_mode[6]; + *(WORD32*)(pi1_left_pred_mode + 4) = + *(WORD32*)pi1_left_pred_mode; + } + else + { + + pi1_left_pred_mode[7] = pi1_left_pred_mode[3]; + pi1_left_pred_mode[6] = pi1_left_pred_mode[3]; + pi1_left_pred_mode[5] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[4] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[3] = pi1_left_pred_mode[1]; + pi1_left_pred_mode[2] = pi1_left_pred_mode[1]; + pi1_left_pred_mode[1] = pi1_left_pred_mode[0]; + } + } + pi1_left_pred_mode += (u1_topmb) ? 0 : 4; + } + else + { + + pi1_left_pred_mode += (u1_topmb) ? 0 : 4; + if(u1_left_available) + { + + if(ps_left_mb->u1_mb_type != I_4x4_MB) + *(WORD32*)pi1_left_pred_mode = + (u2_use_left_mb_pack) ? + DC_DC_DC_DC : + NOT_VALID; + } + else + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + } + /* One time pointer initialisations*/ + pi2_y_coeff1 = pi2_y_coeff; + pu1_top_left = pu1_ytop_left; + + /* Scan the sub-blocks in Raster Scan Order */ + for(u1_sub_mb_num = 0; u1_sub_mb_num < 16; u1_sub_mb_num++) + { + UWORD8 au1_ngbr_pels[13]; + + u1_sub_blk_x = u1_sub_mb_num & 0x3; + u1_sub_blk_y = u1_sub_mb_num >> 2; + i1_top_pred_mode = pi1_cur_pred_mode[u1_sub_blk_x]; + i1_left_pred_mode = pi1_left_pred_mode[u1_sub_blk_y]; + u1_use_top_right_mb = (!!CHECKBIT(ui2_top_rt_mask, u1_sub_mb_num)); + + /*********** left subblock availability**********/ + if(u1_sub_blk_x) + u1_is_left_sub_block = 1; + else + u1_is_left_sub_block = + (u1_sub_blk_y < 2) ? + (CHECKBIT(u2_use_left_mb_pack, + 0)) : + (u2_use_left_mb_pack >> 8); + + /* CHANGED CODE */ + if(u1_sub_blk_y) + u1_is_top_sub_block = 1; + + /* CHANGED CODE */ + /***************** Top *********************/ + if(ps_dec->u4_use_intrapred_line_copy == 1) + { + + if(u1_sub_blk_y) + pu1_top = pu1_luma_rei1_buffer - ui_rec_width; + else + pu1_top = puc_top + (u1_sub_blk_x << 2); + } + else + { + pu1_top = pu1_luma_rei1_buffer - ui_rec_width; + } + /***************** Top Right *********************/ + pu1_top_right = pu1_top + 4; + /***************** Top Left *********************/ + pu1_top_left = pu1_top - 1; + /***************** Left *********************/ + pu1_left = pu1_luma_rei1_buffer - 1; + /* CHANGED CODE */ + + /*---------------------------------------------------------------*/ + /* Calculation of Intra prediction mode */ + /*---------------------------------------------------------------*/ + i1_intra_pred = ((i1_left_pred_mode < 0) | (i1_top_pred_mode < 0)) ? + DC : MIN(i1_left_pred_mode, i1_top_pred_mode); + { + UWORD8 u1_packed_modes = (u1_is_top_sub_block << 1) + + u1_is_left_sub_block; + UWORD8 *pu1_intra_err_codes = + (UWORD8 *)gau1_ih264d_intra_pred_err_code; + UWORD8 uc_b2b0 = ((u1_sub_mb_num & 4) >> 1) | (u1_sub_mb_num & 1); + UWORD8 uc_b3b1 = ((u1_sub_mb_num & 8) >> 2) + | ((u1_sub_mb_num & 2) >> 1); + + u1_cur_sub_block = (uc_b3b1 << 2) + uc_b2b0; + PROFILE_DISABLE_INTRA_PRED() + if(!pu1_prev_intra4x4_pred_mode_flag[u1_cur_sub_block]) + { + i1_intra_pred = + pu1_rem_intra4x4_pred_mode[u1_cur_sub_block] + + (pu1_rem_intra4x4_pred_mode[u1_cur_sub_block] + >= i1_intra_pred); + } + { + UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred]; + + /*if((u1_err_code & u1_packed_modes) ^ u1_err_code) + { + }*/ + + } + } + { + /* Get neighbour pixels */ + /* left pels */ + if(u1_is_left_sub_block) + { + WORD32 i; + for(i = 0; i < 4; i++) + au1_ngbr_pels[4 - 1 - i] = pu1_left[i * ui_rec_width]; + } + else + { + memset(au1_ngbr_pels, 0, 4); + } + + /* top left pels */ + au1_ngbr_pels[4] = *pu1_top_left; + + /* top pels */ + if(u1_is_top_sub_block) + { + memcpy(au1_ngbr_pels + 4 + 1, pu1_top, 4); + } + else + { + memset(au1_ngbr_pels + 4 + 1, 0, 4); + } + + /* top right pels */ + if(u1_use_top_right_mb) + { + memcpy(au1_ngbr_pels + 4 * 2 + 1, pu1_top_right, 4); + } + else if(u1_is_top_sub_block) + { + memset(au1_ngbr_pels + 4 * 2 + 1, au1_ngbr_pels[4 * 2], 4); + } + } + PROFILE_DISABLE_INTRA_PRED() + ps_dec->apf_intra_pred_luma_4x4[i1_intra_pred]( + au1_ngbr_pels, pu1_luma_rei1_buffer, 1, + ui_rec_width, + ((u1_is_top_sub_block << 2) | u1_is_left_sub_block)); + + /* CHANGED CODE */ + if(CHECKBIT(ui2_luma_csbp, u1_sub_mb_num)) + { + WORD16 ai2_tmp[16]; + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u4_luma_dc_only_csbp, u1_sub_mb_num)) + { + ps_dec->pf_iquant_itrans_recon_luma_4x4_dc( + pi2_y_coeff1, + pu1_luma_rei1_buffer, + pu1_luma_rei1_buffer, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[0], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + else + { + ps_dec->pf_iquant_itrans_recon_luma_4x4( + pi2_y_coeff1, + pu1_luma_rei1_buffer, + pu1_luma_rei1_buffer, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[0], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + } + + } + + /*---------------------------------------------------------------*/ + /* Update sub block number */ + /*---------------------------------------------------------------*/ + pi2_y_coeff1 += 16; + pu1_luma_rei1_buffer += + (u1_sub_blk_x == 3) ? (ui_rec_width << 2) - 12 : 4; + pu1_luma_pred_buffer += + (u1_sub_blk_x == 3) ? (ui_pred_width << 2) - 12 : 4; + /* CHANGED CODE */ + pi1_cur_pred_mode[u1_sub_blk_x] = i1_intra_pred; + pi1_left_pred_mode[u1_sub_blk_y] = i1_intra_pred; + } + } + else if((u1_mb_type == I_4x4_MB) && (ps_cur_mb_info->u1_tran_form8x8 == 1)) + { + UWORD8 u1_is_left_sub_block, u1_is_top_sub_block = uc_useTopMB; + UWORD8 u1_sub_blk_x, u1_sub_blk_y, u1_sub_mb_num; + WORD8 i1_top_pred_mode; + WORD8 i1_left_pred_mode; + UWORD8 *pu1_top, *pu1_left, *pu1_top_left; + WORD8 *pi1_cur_pred_mode, *pi1_left_pred_mode, *pc_topPredMode; + UWORD16 ui2_left_pred_buf_width = 0xffff; + WORD8 i1_intra_pred; + UWORD8 *pu1_prev_intra4x4_pred_mode_flag = pu1_prev_intra4x4_pred_mode_data; + UWORD8 *pu1_rem_intra4x4_pred_mode = pu1_prev_intra4x4_pred_mode_data + 4; + WORD16 *pi2_y_coeff1; + UWORD16 ui2_top_rt_mask; + UWORD32 u4_4x4_left_offset = 0; + + /*--------------------------------------------------------------------*/ + /* 8x8 IntraPrediction */ + /*--------------------------------------------------------------------*/ + /* Calculation of Top Right subblock mask */ + /* */ + /* (a) Set it to default mask */ + /* [It has 0 for sublocks which will never have top-right sub block] */ + /* */ + /* (b) If top MB is not available */ + /* Clear the bits of the first row sub blocks */ + /* */ + /* (c) Set/Clear bit for top-right sublock of MB */ + /* [5 sub-block in decoding order] based on TOP RIGHT MB availablity */ + /* */ + /* ui2_top_rt_mask: marks availibility of top right(neighbour) */ + /* in the 8x8 Block ordering */ + /* */ + /* tr0 tr1 */ + /* 0 1 tr3 */ + /* 2 3 */ + /* */ + /* Top rights for 0 is in top MB */ + /* top right of 1 will be in top right MB */ + /* top right of 3 in right MB and hence not available */ + /* This corresponds to ui2_top_rt_mask having default value 0x4 */ + /*--------------------------------------------------------------------*/ + + ui2_top_rt_mask = (u1_use_top_right_mb << 1) | (0x4); + + if(uc_useTopMB) + { + ui2_top_rt_mask |= 0x1; + } + + /* Top Related initialisations */ + pi1_cur_pred_mode = ps_cur_mb_info->ps_curmb->pi1_intrapredmodes; + pc_topPredMode = ps_cur_mb_info->ps_top_mb->pi1_intrapredmodes; + /* + if(u1_mbaff) + { + pi1_cur_pred_mode += (u2_mbx << 2); + pc_topPredMode = pi1_cur_pred_mode + ps_cur_mb_info->i1_offset; + pi1_cur_pred_mode += (u1_topmb) ? 0: 4; + } + */ + if(u1_top_available) + { + if(ps_top_mb->u1_mb_type == I_4x4_MB) + { + *(WORD32*)pi1_cur_pred_mode = *(WORD32*)pc_topPredMode; + } + else + { + *(WORD32*)pi1_cur_pred_mode = + (uc_useTopMB) ? DC_DC_DC_DC : NOT_VALID; + } + } + else + { + *(WORD32*)pi1_cur_pred_mode = NOT_VALID; + } + + pu1_top = puc_top - 8; + + /*Left Related initialisations*/ + pi1_left_pred_mode = ps_dec->pi1_left_pred_mode; + + if(!u1_mbaff) + { + if(u1_left_available) + { + if(ps_left_mb->u1_mb_type != I_4x4_MB) + { + *(WORD32*)pi1_left_pred_mode = + (u2_use_left_mb_pack) ? + DC_DC_DC_DC : + NOT_VALID; + } + } + else + { + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + } + else + { + UWORD8 u1_curMbfld = ps_cur_mb_info->u1_mb_field_decodingflag; + + UWORD8 u1_leftMbfld = ps_left_mb->u1_mb_fld; + + if((!u1_curMbfld) && (u1_leftMbfld)) + { + u4_4x4_left_offset = 1; + } + + if(u1_curMbfld ^ u1_leftMbfld) + { + + if(u1_topmb + | ((u1_topmb == 0) + && ((ps_curmb - 1)->u1_mb_type + != I_4x4_MB))) + + { + if(u1_left_available) + { + if(ps_left_mb->u1_mb_type != I_4x4_MB) + { + if(CHECKBIT(u2_use_left_mb_pack,0) == 0) + { + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + else + { + *(WORD32*)pi1_left_pred_mode = DC_DC_DC_DC; + } + } + } + else + { + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + + if(u1_curMbfld) + { + if(u1_left_available) + { + if((ps_left_mb + 1)->u1_mb_type != I_4x4_MB) + { + if(u2_use_left_mb_pack >> 8) + { + *(WORD32*)(pi1_left_pred_mode + 4) = + DC_DC_DC_DC; + } + else + { + *(WORD32*)(pi1_left_pred_mode + 4) = + NOT_VALID; + } + } + } + else + { + *(WORD32*)(pi1_left_pred_mode + 4) = NOT_VALID; + } + + pi1_left_pred_mode[1] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[2] = pi1_left_pred_mode[4]; + pi1_left_pred_mode[3] = pi1_left_pred_mode[6]; + *(WORD32*)(pi1_left_pred_mode + 4) = + *(WORD32*)pi1_left_pred_mode; + } + else + { + pi1_left_pred_mode[7] = pi1_left_pred_mode[3]; + pi1_left_pred_mode[6] = pi1_left_pred_mode[3]; + pi1_left_pred_mode[5] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[4] = pi1_left_pred_mode[2]; + pi1_left_pred_mode[3] = pi1_left_pred_mode[1]; + pi1_left_pred_mode[2] = pi1_left_pred_mode[1]; + pi1_left_pred_mode[1] = pi1_left_pred_mode[0]; + } + } + pi1_left_pred_mode += (u1_topmb) ? 0 : 4; + } + else + { + pi1_left_pred_mode += (u1_topmb) ? 0 : 4; + + if(u1_left_available) + { + if(ps_left_mb->u1_mb_type != I_4x4_MB) + { + *(WORD32*)pi1_left_pred_mode = + (u2_use_left_mb_pack) ? + DC_DC_DC_DC : + NOT_VALID; + } + } + else + { + *(WORD32*)pi1_left_pred_mode = NOT_VALID; + } + } + } + + /* One time pointer initialisations*/ + pi2_y_coeff1 = pi2_y_coeff; + + if(u1_use_top_left_mb) + { + pu1_top_left = pu1_ytop_left; + } + else + { + pu1_top_left = NULL; + } + + /* Scan the sub-blocks in Raster Scan Order */ + for(u1_sub_mb_num = 0; u1_sub_mb_num < 4; u1_sub_mb_num++) + { + u1_sub_blk_x = (u1_sub_mb_num & 0x1); + u1_sub_blk_y = (u1_sub_mb_num >> 1); + i1_top_pred_mode = pi1_cur_pred_mode[u1_sub_blk_x << 1]; + i1_left_pred_mode = pi1_left_pred_mode[u1_sub_blk_y << 1]; + + if(2 == u1_sub_mb_num) + { + i1_left_pred_mode = pi1_left_pred_mode[(u1_sub_blk_y << 1) + + u4_4x4_left_offset]; + } + + u1_use_top_right_mb = (!!CHECKBIT(ui2_top_rt_mask, u1_sub_mb_num)); + + /*********** left subblock availability**********/ + if(u1_sub_blk_x) + { + u1_is_left_sub_block = 1; + } + else + { + u1_is_left_sub_block = + (u1_sub_blk_y < 1) ? + (CHECKBIT(u2_use_left_mb_pack, + 0)) : + (u2_use_left_mb_pack >> 8); + } + + /***************** Top *********************/ + if(u1_sub_blk_y) + { + u1_is_top_sub_block = 1; + // sushant + pu1_top = /*pu1_luma_pred_buffer*/pu1_luma_rei1_buffer - ui_rec_width; + } + else + { + pu1_top += 8; + } + + /***************** Left *********************/ + if((u1_sub_blk_x) | (u4_num_pmbair != 0)) + { + // sushant + pu1_left = /*pu1_luma_pred_buffer*/pu1_luma_rei1_buffer - 1; + ui2_left_pred_buf_width = ui_rec_width; + } + else + { + pu1_left = pu1_yleft; + pu1_yleft += (ui_rec_width << 3); + ui2_left_pred_buf_width = ui_rec_width; + } + + /***************** Top Left *********************/ + if(u1_sub_mb_num) + { + pu1_top_left = (u1_sub_blk_x) ? + pu1_top - 1 : pu1_left - ui_rec_width; + + if((u1_sub_blk_x && (!u1_is_top_sub_block)) + || ((!u1_sub_blk_x) && (!u1_is_left_sub_block))) + { + pu1_top_left = NULL; + } + } + + /*---------------------------------------------------------------*/ + /* Calculation of Intra prediction mode */ + /*---------------------------------------------------------------*/ + i1_intra_pred = ((i1_left_pred_mode < 0) | (i1_top_pred_mode < 0)) ? + DC : MIN(i1_left_pred_mode, i1_top_pred_mode); + { + UWORD8 u1_packed_modes = (u1_is_top_sub_block << 1) + + u1_is_left_sub_block; + UWORD8 *pu1_intra_err_codes = + (UWORD8 *)gau1_ih264d_intra_pred_err_code; + + /********************************************************************/ + /* Same intra4x4_pred_mode array is filled with intra4x4_pred_mode */ + /* for a MB with 8x8 intrapredicition */ + /********************************************************************/ + PROFILE_DISABLE_INTRA_PRED() + if(!pu1_prev_intra4x4_pred_mode_flag[u1_sub_mb_num]) + { + i1_intra_pred = pu1_rem_intra4x4_pred_mode[u1_sub_mb_num] + + (pu1_rem_intra4x4_pred_mode[u1_sub_mb_num] + >= i1_intra_pred); + } + { + UWORD8 u1_err_code = pu1_intra_err_codes[i1_intra_pred]; + + if((u1_err_code & u1_packed_modes) ^ u1_err_code) + { + return ERROR_INTRAPRED; + } + } + } + + { + UWORD8 au1_ngbr_pels[25]; + WORD32 ngbr_avail; + ngbr_avail = u1_is_left_sub_block << 0; + ngbr_avail |= u1_is_top_sub_block << 2; + + if(pu1_top_left) + ngbr_avail |= 1 << 1; + + ngbr_avail |= u1_use_top_right_mb << 3; + PROFILE_DISABLE_INTRA_PRED() + { + ps_dec->pf_intra_pred_ref_filtering(pu1_left, pu1_top_left, + pu1_top, au1_ngbr_pels, + ui2_left_pred_buf_width, + ngbr_avail); + + ps_dec->apf_intra_pred_luma_8x8[i1_intra_pred]( + au1_ngbr_pels, pu1_luma_rei1_buffer, 1, + ui_rec_width, + ((u1_is_top_sub_block << 2) | u1_is_left_sub_block)); + } + } + + /* Inverse Transform and Reconstruction */ + if(CHECKBIT(ps_cur_mb_info->u1_cbp, u1_sub_mb_num)) + { + WORD16 *pi2_scale_matrix_ptr; + WORD16 ai2_tmp[64]; + + pi2_scale_matrix_ptr = + ps_dec->s_high_profile.i2_scalinglist8x8[0]; + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u4_luma_dc_only_cbp, u1_sub_mb_num)) + { + ps_dec->pf_iquant_itrans_recon_luma_8x8_dc( + pi2_y_coeff1, + pu1_luma_rei1_buffer, + pu1_luma_rei1_buffer, + ui_rec_width, + ui_rec_width, + gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)pi2_scale_matrix_ptr, + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + else + { + ps_dec->pf_iquant_itrans_recon_luma_8x8( + pi2_y_coeff1, + pu1_luma_rei1_buffer, + pu1_luma_rei1_buffer, + ui_rec_width, + ui_rec_width, + gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)pi2_scale_matrix_ptr, + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + } + + } + + /*---------------------------------------------------------------*/ + /* Update sub block number */ + /*---------------------------------------------------------------*/ + pi2_y_coeff1 += 64; + + pu1_luma_rei1_buffer += + (u1_sub_blk_x == 1) ? + (ui_rec_width << 3) - (8 * 1) : 8; + + /*---------------------------------------------------------------*/ + /* Pred mode filled in terms of 4x4 block so replicated in 2 */ + /* locations. */ + /*---------------------------------------------------------------*/ + pi1_cur_pred_mode[u1_sub_blk_x << 1] = i1_intra_pred; + pi1_cur_pred_mode[(u1_sub_blk_x << 1) + 1] = i1_intra_pred; + pi1_left_pred_mode[u1_sub_blk_y << 1] = i1_intra_pred; + pi1_left_pred_mode[(u1_sub_blk_y << 1) + 1] = i1_intra_pred; + } + } + /* Decode Chroma Block */ + ih264d_unpack_chroma_coeff4x4_mb(ps_dec, + ps_cur_mb_info); + /*--------------------------------------------------------------------*/ + /* Chroma Blocks decoding */ + /*--------------------------------------------------------------------*/ + { + UWORD8 u1_intra_chrom_pred_mode; + UWORD8 u1_chroma_cbp = (UWORD8)(ps_cur_mb_info->u1_cbp >> 4); + + /*--------------------------------------------------------------------*/ + /* Perform Chroma intra prediction */ + /*--------------------------------------------------------------------*/ + + u1_intra_chrom_pred_mode = CHROMA_TO_LUMA_INTRA_MODE( + ps_cur_mb_info->u1_chroma_pred_mode); + + { + UWORD8 u1_packed_modes = (u1_top_available << 1) + + u1_left_available; + UWORD8 u1_err_code = + (u1_intra_chrom_pred_mode & 1) ? + u1_intra_chrom_pred_mode : + (u1_intra_chrom_pred_mode ^ 2); + if((u1_err_code & u1_packed_modes) ^ u1_err_code) + return ERROR_INTRAPRED; + } + + /* CHANGED CODE */ + if(u1_chroma_cbp != CBPC_ALLZERO) + { + UWORD16 u2_chroma_csbp = + (u1_chroma_cbp == CBPC_ACZERO) ? + 0 : ps_cur_mb_info->u2_chroma_csbp; + UWORD32 u4_scale_u; + UWORD32 u4_scale_v; + + { + UWORD16 au2_ngbr_pels[33]; + UWORD8 *pu1_ngbr_pels = (UWORD8 *)au2_ngbr_pels; + UWORD16 *pu2_left_uv; + UWORD16 *pu2_topleft_uv; + WORD32 use_left1 = (u2_use_left_mb_pack & 0x0ff); + WORD32 use_left2 = (u2_use_left_mb_pack & 0xff00) >> 8; + + pu2_left_uv = (UWORD16 *)pu1_uleft; + pu2_topleft_uv = (UWORD16 *)pu1_u_top_left; + /* Get neighbour pixels */ + /* left pels */ + if(u2_use_left_mb_pack) + { + WORD32 i; + if(use_left1) + { + for(i = 0; i < 4; i++) + au2_ngbr_pels[8 - 1 - i] = pu2_left_uv[i + * u4_recwidth_cr / YUV420SP_FACTOR]; + } + else + { + memset(au2_ngbr_pels + 4, 0, 4 * sizeof(UWORD16)); + } + + if(use_left2) + { + for(i = 4; i < 8; i++) + au2_ngbr_pels[8 - 1 - i] = pu2_left_uv[i + * u4_recwidth_cr / YUV420SP_FACTOR]; + } + else + { + memset(au2_ngbr_pels, 0, 4 * sizeof(UWORD16)); + } + } + else + { + memset(au2_ngbr_pels, 0, 8 * sizeof(UWORD16)); + } + + /* top left pels */ + au2_ngbr_pels[8] = *pu2_topleft_uv; + + /* top pels */ + if(uc_useTopMB) + { + memcpy(au2_ngbr_pels + 8 + 1, pu1_top_u, + 8 * sizeof(UWORD16)); + } + else + { + memset(au2_ngbr_pels + 8 + 1, 0, 8 * sizeof(UWORD16)); + } + + PROFILE_DISABLE_INTRA_PRED() + ps_dec->apf_intra_pred_chroma[u1_intra_chrom_pred_mode]( + pu1_ngbr_pels, + pu1_mb_cb_rei1_buffer, + 1, + u4_recwidth_cr, + ((uc_useTopMB << 2) | (use_left2 << 4) + | use_left1)); + } + u4_scale_u = ps_cur_mb_info->u1_qpc_div6; + u4_scale_v = ps_cur_mb_info->u1_qpcr_div6; + pi2_y_coeff = ps_dec->pi2_coeff_data; + + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 4; i++) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_mb_cb_rei1_buffer + + ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) + + (i >> 1) * (u4_recwidth_cr << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u2_chroma_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[1], + u4_scale_u, ai2_tmp, pi2_level); + } + else if(pi2_level[0] != 0) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[1], + u4_scale_u, ai2_tmp, pi2_level); + } + } + + } + } + + pi2_y_coeff += MB_CHROM_SIZE; + u2_chroma_csbp = u2_chroma_csbp >> 4; + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 4; i++) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_mb_cb_rei1_buffer + 1 + + ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) + + (i >> 1) * (u4_recwidth_cr << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u2_chroma_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[2], + u4_scale_v, ai2_tmp, pi2_level); + } + else if(pi2_level[0] != 0) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[2], + u4_scale_v, ai2_tmp, pi2_level); + } + } + } + } + + } + else + { + /* If no inverse transform is needed, pass recon buffer pointer */ + /* to Intraprediction module instead of pred buffer pointer */ + { + UWORD16 au2_ngbr_pels[33]; + UWORD8 *pu1_ngbr_pels = (UWORD8 *)au2_ngbr_pels; + UWORD16 *pu2_left_uv; + UWORD16 *pu2_topleft_uv; + pu2_topleft_uv = (UWORD16 *)pu1_u_top_left; + pu2_left_uv = (UWORD16 *)pu1_uleft; + WORD32 use_left1 = (u2_use_left_mb_pack & 0x0ff); + WORD32 use_left2 = (u2_use_left_mb_pack & 0xff00) >> 8; + + /* Get neighbour pixels */ + /* left pels */ + if(u2_use_left_mb_pack) + { + WORD32 i; + if(use_left1) + { + for(i = 0; i < 4; i++) + au2_ngbr_pels[8 - 1 - i] = pu2_left_uv[i + * u4_recwidth_cr / YUV420SP_FACTOR]; + } + else + { + memset(au2_ngbr_pels + 4, 0, 4 * sizeof(UWORD16)); + } + + if(use_left2) + { + for(i = 4; i < 8; i++) + au2_ngbr_pels[8 - 1 - i] = pu2_left_uv[i + * u4_recwidth_cr / YUV420SP_FACTOR]; + } + else + { + memset(au2_ngbr_pels, 0, 4 * sizeof(UWORD16)); + } + + } + else + { + memset(au2_ngbr_pels, 0, 8 * sizeof(UWORD16)); + } + + /* top left pels */ + au2_ngbr_pels[8] = *pu2_topleft_uv; + + /* top pels */ + if(uc_useTopMB) + { + memcpy(au2_ngbr_pels + 8 + 1, pu1_top_u, + 8 * sizeof(UWORD16)); + } + else + { + memset(au2_ngbr_pels + 8 + 1, 0, 8 * sizeof(UWORD16)); + } + + PROFILE_DISABLE_INTRA_PRED() + ps_dec->apf_intra_pred_chroma[u1_intra_chrom_pred_mode]( + pu1_ngbr_pels, + pu1_mb_cb_rei1_buffer, + 1, + u4_recwidth_cr, + ((uc_useTopMB << 2) | (use_left2 << 4) + | use_left1)); + } + + } + + } + return OK; +} diff --git a/decoder/ih264d_process_intra_mb.h b/decoder/ih264d_process_intra_mb.h new file mode 100755 index 0000000..30d7819 --- /dev/null +++ b/decoder/ih264d_process_intra_mb.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_process_intra_mb.h + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 07/07/2003 + * + * \author NS + ************************************************************************** + */ +#ifndef _IH264D_PROCESS_INTRA_MB_H_ +#define _IH264D_PROCESS_INTRA_MB_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" + +#define CHROMA_TO_LUMA_INTRA_MODE(x) (x ^ ( (!(x & 0x01)) << 1)) +#define MB_TYPE_TO_INTRA_16x16_MODE(x) ((x - 1) & 0x03) + +UWORD32 ih264d_unpack_luma_coeff4x4_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 intra_flag); +void ih264d_unpack_chroma_coeff4x4_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info); +UWORD32 ih264d_unpack_luma_coeff8x8_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info); + +WORD32 ih264d_read_intra_pred_modes(dec_struct_t *ps_dec, + UWORD8 *pu1_prev_intra4x4_pred_mode_flag, + UWORD8 *pu1_rem_intra4x4_pred_mode, + UWORD32 u4_trans_form8x8); + +WORD32 ih264d_process_intra_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num); + +#endif /* _IH264D_PROCESS_INTRA_MB_H_ */ + diff --git a/decoder/ih264d_process_pslice.c b/decoder/ih264d_process_pslice.c new file mode 100755 index 0000000..b1230f6 --- /dev/null +++ b/decoder/ih264d_process_pslice.c @@ -0,0 +1,1139 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_process_pslice.c + * + * \brief + * Contains routines that decode a I slice type + * + * Detailed_description + * + * \date + * 21/12/2002 + * + * \author NS + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" + +#include <string.h> +#include "ih264d_bitstrm.h" +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_mb_utils.h" +#include "ih264d_deblocking.h" +#include "ih264d_dpb_manager.h" +#include "ih264d_mvpred.h" +#include "ih264d_inter_pred.h" +#include "ih264d_process_pslice.h" +#include "ih264d_error_handler.h" +#include "ih264d_cabac.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_parse_slice.h" +#include "ih264d_utils.h" +#include "ih264d_parse_islice.h" +#include "ih264d_process_bslice.h" +#include "ih264d_process_intra_mb.h" + +void ih264d_init_cabac_contexts(UWORD8 u1_slice_type, dec_struct_t * ps_dec); + +void ih264d_insert_pic_in_ref_pic_listx(struct pic_buffer_t *ps_ref_pic_buf_lx, + struct pic_buffer_t *ps_pic) +{ + *ps_ref_pic_buf_lx = *ps_pic; +} + +WORD32 ih264d_mv_pred_ref_tfr_nby2_pmb(dec_struct_t * ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs) +{ + parse_pmbarams_t * ps_mb_part_info; + parse_part_params_t * ps_part; + mv_pred_t *ps_mv_nmb, *ps_mv_nmb_start, *ps_mv_ntop, *ps_mv_ntop_start; + UWORD32 i, j; + const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + dec_mb_info_t * ps_cur_mb_info; + WORD32 i2_mv_x, i2_mv_y; + WORD32 ret; + + ps_dec->i4_submb_ofst -= (u1_num_mbs - u1_mb_idx) << 4; + ps_mb_part_info = ps_dec->ps_parse_mb_data; // + u1_mb_idx; + ps_part = ps_dec->ps_parse_part_params; // + u1_mb_idx; + + /* N/2 Mb MvPred and Transfer Setup Loop */ + for(i = u1_mb_idx; i < u1_num_mbs; i++, ps_mb_part_info++) + { + UWORD32 u1_colz; + UWORD32 u1_field; + mv_pred_t s_mvPred; + mv_pred_t *ps_mv_pred = &s_mvPred; + + + + *ps_mv_pred = ps_dec->s_default_mv_pred; + + ps_dec->i4_submb_ofst += SUB_BLK_SIZE; + ps_dec->u2_wait_id = i; + + /* Restore the slice scratch MbX and MbY context */ + ps_cur_mb_info = ps_dec->ps_nmb_info + i; + u1_field = ps_cur_mb_info->u1_mb_field_decodingflag; + + + + ps_mv_nmb_start = ps_dec->ps_mv_cur + (i << 4); + ps_dec->u2_mbx = ps_cur_mb_info->u2_mbx; + ps_dec->u2_mby = ps_cur_mb_info->u2_mby; + ps_dec->u2_mv_2mb[i & 0x1] = 0; + + /* Look for MV Prediction and Reference Transfer in Non-I Mbs */ + if(!ps_mb_part_info->u1_isI_mb) + { + UWORD32 u1_blk_no; + WORD32 i1_ref_idx, i1_ref_idx1; + UWORD32 u1_sub_mb_x, u1_sub_mb_y, u1_sub_mb_num; + UWORD32 u1_num_part, u1_num_ref, u1_wd, u1_ht; + UWORD32 *pu4_wt_offst, **ppu4_wt_ofst; + UWORD32 u1_scale_ref, u4_bot_mb; + WORD8 *pi1_ref_idx = ps_mb_part_info->i1_ref_idx[0]; + pic_buffer_t *ps_ref_frame, **pps_ref_frame; + deblk_mb_t * ps_cur_deblk_mb = ps_dec->ps_deblk_mbn + i; + + /* MB Level initialisations */ + ps_dec->u4_num_pmbair = i >> u1_mbaff; + ps_dec->u1_mb_idx_mv = i; + ppu4_wt_ofst = ps_mb_part_info->pu4_wt_offst; + pps_ref_frame = ps_dec->ps_ref_pic_buf_lx[0]; + /* CHANGED CODE */ + ps_mv_ntop_start = ps_mv_nmb_start + - (ps_dec->u2_frm_wd_in_mbs << (4 + u1_mbaff)) + 12; + + u1_num_part = ps_mb_part_info->u1_num_part; + ps_cur_deblk_mb->u1_mb_type |= (u1_num_part > 1) << 1; + ps_cur_mb_info->u4_pred_info_pkd_idx = ps_dec->u4_pred_info_pkd_idx; + ps_cur_mb_info->u1_num_pred_parts = 0; + + + /****************************************************/ + /* weighted u4_ofst pointer calculations, this loop */ + /* runs maximum 4 times, even in direct cases */ + /****************************************************/ + u1_scale_ref = u1_mbaff & u1_field; + + u4_bot_mb = 1 - ps_cur_mb_info->u1_topmb; + if(ps_dec->ps_cur_pps->u1_wted_pred_flag) + { + u1_num_ref = MIN(u1_num_part, 4); + for(u1_blk_no = 0; u1_blk_no < u1_num_ref; u1_blk_no++) + { + i1_ref_idx = pi1_ref_idx[u1_blk_no]; + if(u1_scale_ref) + i1_ref_idx >>= 1; + pu4_wt_offst = (UWORD32*)&ps_dec->pu4_wt_ofsts[2 + * X3(i1_ref_idx)]; + ppu4_wt_ofst[u1_blk_no] = pu4_wt_offst; + } + } + else + { + ppu4_wt_ofst[0] = NULL; + ppu4_wt_ofst[1] = NULL; + ppu4_wt_ofst[2] = NULL; + ppu4_wt_ofst[3] = NULL; + } + + /**************************************************/ + /* Loop on Partitions */ + /**************************************************/ + ps_dec->u4_dma_buf_idx = 0; + + for(j = 0; j < u1_num_part; j++, ps_part++) + { + + u1_sub_mb_num = ps_part->u1_sub_mb_num; + ps_dec->u1_sub_mb_num = u1_sub_mb_num; + + if(PART_NOT_DIRECT != ps_part->u1_is_direct) + { + /* Mb Skip Mode */ + /* Setting the default and other members of MvPred Structure */ + s_mvPred.i2_mv[2] = -1; + s_mvPred.i2_mv[3] = -1; + s_mvPred.i1_ref_frame[0] = 0; + i1_ref_idx = (u1_scale_ref && u4_bot_mb) ? MAX_REF_BUFS : 0; + ps_ref_frame = pps_ref_frame[i1_ref_idx]; + s_mvPred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id; + s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type; + pu4_wt_offst = (UWORD32*)&ps_dec->pu4_wt_ofsts[0]; + + ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb_start, + ps_mv_ntop_start, &s_mvPred, 0, 4, 0, 1, + MB_SKIP); + + + + + + + { + pred_info_pkd_t *ps_pred_pkd; + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info (s_mvPred.i2_mv,4,4,0,PRED_L0,ps_pred_pkd,ps_ref_frame->u1_pic_buf_id, + (i1_ref_idx >> u1_scale_ref),pu4_wt_offst, + ps_ref_frame->u1_pic_type); + + + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + } + + + + /* Storing colocated zero information */ + u1_colz = ((ABS(s_mvPred.i2_mv[0]) <= 1) + && (ABS(s_mvPred.i2_mv[1]) <= 1)) + + (u1_field << 1); + + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, + u1_colz, 4, 4); + } + else + { + u1_sub_mb_x = u1_sub_mb_num & 0x03; + u1_sub_mb_y = u1_sub_mb_num >> 2; + u1_blk_no = + (u1_num_part < 4) ? + j : + (((u1_sub_mb_y >> 1) << 1) + + (u1_sub_mb_x + >> 1)); + + ps_mv_ntop = ps_mv_ntop_start + u1_sub_mb_x; + ps_mv_nmb = ps_mv_nmb_start + u1_sub_mb_num; + + u1_wd = ps_part->u1_partwidth; + u1_ht = ps_part->u1_partheight; + + /* Populate the colpic info and reference frames */ + i1_ref_idx = pi1_ref_idx[u1_blk_no]; + s_mvPred.i1_ref_frame[0] = i1_ref_idx; + + /********************************************************/ + /* Predict Mv */ + /* Add Mv Residuals and store back */ + /********************************************************/ + ps_dec->pf_mvpred(ps_dec, ps_cur_mb_info, ps_mv_nmb, ps_mv_ntop, + &s_mvPred, u1_sub_mb_num, u1_wd, 0, 1, + ps_cur_mb_info->u1_mb_mc_mode); + i2_mv_x = ps_mv_nmb->i2_mv[0]; + i2_mv_y = ps_mv_nmb->i2_mv[1]; + i2_mv_x += s_mvPred.i2_mv[0]; + i2_mv_y += s_mvPred.i2_mv[1]; + s_mvPred.i2_mv[0] = i2_mv_x; + s_mvPred.i2_mv[1] = i2_mv_y; + + /********************************************************/ + /* Transfer setup call */ + /* convert RefIdx if it is MbAff */ + /* Pass Weight Offset and refFrame */ + /********************************************************/ + i1_ref_idx1 = i1_ref_idx >> u1_scale_ref; + if(u1_scale_ref && ((i1_ref_idx & 0x01) != u4_bot_mb)) + i1_ref_idx1 += MAX_REF_BUFS; + ps_ref_frame = pps_ref_frame[i1_ref_idx1]; + pu4_wt_offst = ppu4_wt_ofst[u1_blk_no]; + + + + + + + { + pred_info_pkd_t *ps_pred_pkd; + ps_pred_pkd = ps_dec->ps_pred_pkd + ps_dec->u4_pred_info_pkd_idx; + ih264d_fill_pred_info (s_mvPred.i2_mv,u1_wd,u1_ht,u1_sub_mb_num,PRED_L0,ps_pred_pkd, + ps_ref_frame->u1_pic_buf_id,(i1_ref_idx >> u1_scale_ref),pu4_wt_offst, + ps_ref_frame->u1_pic_type); + + ps_dec->u4_pred_info_pkd_idx++; + ps_cur_mb_info->u1_num_pred_parts++; + } + + + + /* Fill colocated info in MvPred structure */ + s_mvPred.u1_col_ref_pic_idx = ps_ref_frame->u1_mv_buf_id; + s_mvPred.u1_pic_type = ps_ref_frame->u1_pic_type; + + /* Calculating colocated zero information */ + u1_colz = + (u1_field << 1) + | ((i1_ref_idx == 0) + && (ABS(i2_mv_x) + <= 1) + && (ABS(i2_mv_y) + <= 1)); + u1_colz |= ps_mb_part_info->u1_col_info[u1_blk_no]; + + /* Replicate the motion vectors and colzero u4_flag */ + /* for all sub-partitions */ + + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb, + u1_sub_mb_num, u1_colz, u1_ht, + u1_wd); + } + } + + } + else + { + /* Storing colocated zero information */ + ih264d_rep_mv_colz(ps_dec, &s_mvPred, ps_mv_nmb_start, 0, + (UWORD8)(u1_field << 1), 4, 4); + + } + /*if num _cores is set to 3,compute bs will be done in another thread*/ + if(ps_dec->u4_num_cores < 3) + { + + if(ps_dec->u4_app_disable_deblk_frm == 0) + ps_dec->pf_compute_bs(ps_dec, ps_cur_mb_info, + (UWORD16)(i >> u1_mbaff)); + } + } + + + + return OK; +} + +#if THREAD_PARSE + +#else +WORD32 ih264d_decode_recon_tfr_nmb(dec_struct_t * ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_tfr_n_mb, + UWORD8 u1_end_of_row) +{ + WORD32 i,j; + UWORD32 u1_end_of_row_next; + dec_mb_info_t * ps_cur_mb_info; + UWORD32 u4_update_mbaff = 0; + WORD32 ret; + const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + const UWORD32 u1_slice_type = ps_dec->ps_cur_slice->u1_slice_type; + const WORD32 u1_skip_th = ( + (u1_slice_type != I_SLICE) ? + (ps_dec->u1_B ? B_8x8 : PRED_8x8R0) : -1); + const UWORD32 u1_ipcm_th = ( + (u1_slice_type != I_SLICE) ? (ps_dec->u1_B ? 23 : 5) : 0); + + + + + + /* N Mb MC Loop */ + for(i = u1_mb_idx; i < u1_num_mbs; i++) + { + ps_cur_mb_info = ps_dec->ps_nmb_info + i; + ps_dec->u4_dma_buf_idx = 0; + ps_dec->u4_pred_info_idx = 0; + + if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) + { + { + WORD32 pred_cnt = 0; + pred_info_pkd_t *ps_pred_pkd; + UWORD32 u4_pred_info_pkd_idx; + WORD8 i1_pred; + + u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; + + while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) + { + + ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; + + ps_dec->p_form_mb_part_info(ps_pred_pkd,ps_dec, + ps_cur_mb_info->u2_mbx,ps_cur_mb_info->u2_mby,(i >> u1_mbaff), + ps_cur_mb_info); + u4_pred_info_pkd_idx++; + pred_cnt++; + } + } + + ps_dec->p_motion_compensate(ps_dec, ps_cur_mb_info); + + } + else if(ps_cur_mb_info->u1_mb_type == MB_SKIP) + { + { + WORD32 pred_cnt = 0; + pred_info_pkd_t *ps_pred_pkd; + UWORD32 u4_pred_info_pkd_idx; + WORD8 i1_pred; + + u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; + + while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) + { + + ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; + + ps_dec->p_form_mb_part_info(ps_pred_pkd,ps_dec, + ps_cur_mb_info->u2_mbx,ps_cur_mb_info->u2_mby,(i >> u1_mbaff), + ps_cur_mb_info); + + u4_pred_info_pkd_idx++; + pred_cnt++; + } + } + /* Decode MB skip */ + ps_dec->p_motion_compensate(ps_dec, ps_cur_mb_info); + + } + + } + + + /* N Mb IQ IT RECON Loop */ + for(j = u1_mb_idx; j < i; j++) + { + ps_cur_mb_info = ps_dec->ps_nmb_info + j; + + if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) + { + ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j); + + } + else if(ps_cur_mb_info->u1_mb_type != MB_SKIP) + { + if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type) + { + ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1); + ret = ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j); + if(ret != OK) + return ret; + } + } + + if(ps_dec->u4_mb_level_deblk == 1) + { + ih264d_deblock_mb_level(ps_dec, ps_cur_mb_info, j); + + } + + if(u1_mbaff) + { + if(u4_update_mbaff) + { + UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx + + ps_dec->u2_frm_wd_in_mbs + * (ps_cur_mb_info->u2_mby >> 1); + UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); + u4_update_mbaff = 0; + } + else + { + u4_update_mbaff = 1; + } + } + else + { + UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx + + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby; + UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); + } + } + + + if(u1_tfr_n_mb) + { + /****************************************************************/ + /* Check for End Of Row in Next iteration */ + /****************************************************************/ + u1_end_of_row_next = + u1_num_mbs_next + && (u1_num_mbs_next + <= (ps_dec->u1_recon_mb_grp + >> u1_mbaff)); + + /****************************************************************/ + /* Transfer the Following things */ + /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */ + /* N-Mb Recon Data ( To Ext Frame Buffer ) */ + /* N-Mb Intrapredline Data ( Updated Internally) */ + /* N-Mb MV Data ( To Ext MV Buffer ) */ + /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */ + /****************************************************************/ + ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row, + u1_end_of_row_next); + ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs; + + if(u1_end_of_row) + { + /* Reset the N-Mb Recon Buf Index to default Values */ + ps_dec->u2_mb_group_cols_y1 = ps_dec->u2_mb_group_cols_y; + ps_dec->u2_mb_group_cols_cr1 = ps_dec->u2_mb_group_cols_cr; + } + /* If next N-Mb Group is the EndOfRow, set the N-Mb Recon Buf Index */ + else if(u1_end_of_row_next) + { + ps_dec->u2_mb_group_cols_y1 = (u1_num_mbs_next << 4) + 8; + ps_dec->u2_mb_group_cols_cr1 = (u1_num_mbs_next << 3) + 8; + } + ps_dec->u4_pred_info_idx = 0; + ps_dec->u4_dma_buf_idx = 0; + + + } + return OK; +} +#endif +/*! + ************************************************************************** + * \if Function name : ih264d_process_inter_mb \endif + * + * \brief + * This function decodes an Inter MB. + * + * + * \return + * 0 on Success and Error code otherwise + ************************************************************************** + */ +WORD32 ih264d_process_inter_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num) +{ + /* CHANGED CODE */ + UWORD8 *pu1_rec_y, *pu1_rec_u, *pu1_rec_v; + + /*CHANGED CODE */ + UWORD32 ui_rec_width, u4_recwidth_cr; + WORD16 *pi2_y_coeff; + UWORD32 u1_mb_field_decoding_flag; + const UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD32 uc_botMb; + UWORD32 u4_num_pmbair; + /* CHANGED CODE */ + tfr_ctxt_t *ps_frame_buf = &ps_dec->s_tran_addrecon; + UWORD32 u4_luma_dc_only_csbp = 0; + UWORD32 u4_luma_dc_only_cbp = 0; + /* CHANGED CODE */ + + uc_botMb = 1 - ps_cur_mb_info->u1_topmb; + u4_num_pmbair = (u1_mb_num >> u1_mbaff); + u1_mb_field_decoding_flag = ps_cur_mb_info->u1_mb_field_decodingflag; + + + /* CHANGED CODE */ + pu1_rec_y = ps_frame_buf->pu1_dest_y + (u4_num_pmbair << 4); + pu1_rec_u = + ps_frame_buf->pu1_dest_u + + (u4_num_pmbair << 3) * YUV420SP_FACTOR; + pu1_rec_v = ps_frame_buf->pu1_dest_v + (u4_num_pmbair << 3); + ui_rec_width = ps_dec->u2_frm_wd_y << u1_mb_field_decoding_flag; + u4_recwidth_cr = ps_dec->u2_frm_wd_uv << u1_mb_field_decoding_flag; + + /* CHANGED CODE */ + + if(u1_mbaff) + { + if(uc_botMb) + { + pu1_rec_y += (u1_mb_field_decoding_flag ? + (ui_rec_width >> 1) : (ui_rec_width << 4)); + pu1_rec_u += (u1_mb_field_decoding_flag ? + (u4_recwidth_cr >> 1) : (u4_recwidth_cr << 3)); + pu1_rec_v += (u1_mb_field_decoding_flag ? + (u4_recwidth_cr >> 1) : (u4_recwidth_cr << 3)); + } + } + + if(!ps_cur_mb_info->u1_tran_form8x8) + { + u4_luma_dc_only_csbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, + ps_cur_mb_info, + 0); + } + else + { + if(!ps_dec->ps_cur_pps->u1_entropy_coding_mode) + { + u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff4x4_mb(ps_dec, + ps_cur_mb_info, + 0); + } + else + { + u4_luma_dc_only_cbp = ih264d_unpack_luma_coeff8x8_mb(ps_dec, + ps_cur_mb_info); + } + } + + pi2_y_coeff = ps_dec->pi2_coeff_data; + /* Inverse Transform and Reconstruction */ + if(ps_cur_mb_info->u1_cbp & 0x0f) + { + /* CHANGED CODE */ + if(!ps_cur_mb_info->u1_tran_form8x8) + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 16; i++) + { + if(CHECKBIT(ps_cur_mb_info->u2_luma_csbp, i)) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_rec_y + ((i & 0x3) * BLK_SIZE) + + (i >> 2) * (ui_rec_width << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u4_luma_dc_only_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_luma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[3], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + else + { + ps_dec->pf_iquant_itrans_recon_luma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[3], + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + } + } + } + } + else + { + WORD16 *pi2_scale_matrix_ptr; + WORD32 i; + + pi2_scale_matrix_ptr = + ps_dec->s_high_profile.i2_scalinglist8x8[1]; + + for(i = 0; i < 4; i++) + { + WORD16 ai2_tmp[64]; + WORD16 *pi16_levelBlock = pi2_y_coeff + (i << 6); /* move to the next 8x8 adding 64 */ + + UWORD8 *pu1_pred_sblk = pu1_rec_y + ((i & 0x1) * BLK8x8SIZE) + + (i >> 1) * (ui_rec_width << 3); + if(CHECKBIT(ps_cur_mb_info->u1_cbp, i)) + { + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u4_luma_dc_only_cbp, i)) + { + ps_dec->pf_iquant_itrans_recon_luma_8x8_dc( + pi16_levelBlock, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)pi2_scale_matrix_ptr, + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + else + { + ps_dec->pf_iquant_itrans_recon_luma_8x8( + pi16_levelBlock, + pu1_pred_sblk, + pu1_pred_sblk, + ui_rec_width, + ui_rec_width, + gau1_ih264d_dequant8x8_cavlc[ps_cur_mb_info->u1_qp_rem6], + (UWORD16 *)pi2_scale_matrix_ptr, + ps_cur_mb_info->u1_qp_div6, ai2_tmp, 0, + NULL); + } + } + } + } + + } + } + + /* Decode Chroma Block */ + ih264d_unpack_chroma_coeff4x4_mb(ps_dec, + ps_cur_mb_info); + /*--------------------------------------------------------------------*/ + /* Chroma Blocks decoding */ + /*--------------------------------------------------------------------*/ + { + UWORD8 u1_chroma_cbp = (UWORD8)(ps_cur_mb_info->u1_cbp >> 4); + + if(u1_chroma_cbp != CBPC_ALLZERO) + { + UWORD32 u4_scale_u = ps_cur_mb_info->u1_qpc_div6; + UWORD32 u4_scale_v = ps_cur_mb_info->u1_qpcr_div6; + UWORD16 u2_chroma_csbp = ps_cur_mb_info->u2_chroma_csbp; + + pi2_y_coeff = ps_dec->pi2_coeff_data; + + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 4; i++) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_rec_u + + ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) + + (i >> 1) * (u4_recwidth_cr << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u2_chroma_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[4], + u4_scale_u, ai2_tmp, pi2_level); + } + else if(pi2_level[0] != 0) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpc_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[4], + u4_scale_u, ai2_tmp, pi2_level); + } + } + } + } + + pi2_y_coeff += MB_CHROM_SIZE; + u2_chroma_csbp >>= 4; + + { + UWORD32 i; + WORD16 ai2_tmp[16]; + for(i = 0; i < 4; i++) + { + WORD16 *pi2_level = pi2_y_coeff + (i << 4); + UWORD8 *pu1_pred_sblk = pu1_rec_u + 1 + + ((i & 0x1) * BLK_SIZE * YUV420SP_FACTOR) + + (i >> 1) * (u4_recwidth_cr << 2); + PROFILE_DISABLE_IQ_IT_RECON() + { + if(CHECKBIT(u2_chroma_csbp, i)) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[5], + u4_scale_v, ai2_tmp, pi2_level); + } + else if(pi2_level[0] != 0) + { + ps_dec->pf_iquant_itrans_recon_chroma_4x4_dc( + pi2_level, + pu1_pred_sblk, + pu1_pred_sblk, + u4_recwidth_cr, + u4_recwidth_cr, + gau2_ih264_iquant_scale_4x4[ps_cur_mb_info->u1_qpcr_rem6], + (UWORD16 *)ps_dec->s_high_profile.i2_scalinglist4x4[5], + u4_scale_v, ai2_tmp, pi2_level); + } + } + } + } + } + } + return (0); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_parse_pred_weight_table \endif + * + * \brief + * Implements pred_weight_table() of 7.3.3.2. + * + * \return + * None + * + ************************************************************************** + */ +WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, + dec_bit_stream_t * ps_bitstrm) +{ + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + WORD8 i, cont, lx; + UWORD8 uc_weight_flag; + UWORD32 *pui32_weight_offset_lx; + WORD16 c_weight, c_offset; + UWORD32 ui32_y_def_weight_ofst, ui32_cr_def_weight_ofst; + UWORD32 ui32_temp; + UWORD8 uc_luma_log2_weight_denom; + UWORD8 uc_chroma_log2_weight_denom; + + /* Variables for error resilience checks */ + UWORD32 u4_temp; + WORD32 i_temp; + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + { + return ERROR_PRED_WEIGHT_TABLE_T; + } + uc_luma_log2_weight_denom = u4_temp; + COPYTHECONTEXT("SH: luma_log2_weight_denom",uc_luma_log2_weight_denom); + ui32_y_def_weight_ofst = (1 << uc_luma_log2_weight_denom); + + u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(u4_temp & MASK_LOG2_WEIGHT_DENOM) + { + return ERROR_PRED_WEIGHT_TABLE_T; + } + uc_chroma_log2_weight_denom = u4_temp; + COPYTHECONTEXT("SH: chroma_log2_weight_denom",uc_chroma_log2_weight_denom); + ui32_cr_def_weight_ofst = (1 << uc_chroma_log2_weight_denom); + + ps_cur_slice->u2_log2Y_crwd = uc_luma_log2_weight_denom + | (uc_chroma_log2_weight_denom << 8); + + cont = (ps_cur_slice->u1_slice_type == B_SLICE); + lx = 0; + do + { + for(i = 0; i < ps_cur_slice->u1_num_ref_idx_lx_active[lx]; i++) + { + pui32_weight_offset_lx = ps_cur_slice->u4_wt_ofst_lx[lx][i]; + + uc_weight_flag = ih264d_get_bit_h264(ps_bitstrm); + pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + COPYTHECONTEXT("SH: luma_weight_l0_flag",uc_weight_flag); + if(uc_weight_flag) + { + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_weight = i_temp; + COPYTHECONTEXT("SH: luma_weight_l0",c_weight); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_offset = i_temp; + COPYTHECONTEXT("SH: luma_offset_l0",c_offset); + + ui32_temp = (c_offset << 16) | (c_weight & 0xFFFF); + pui32_weight_offset_lx[0] = ui32_temp; + } + else + { + + pui32_weight_offset_lx[0] = ui32_y_def_weight_ofst; + } + + { + WORD8 c_weightCb, c_weightCr, c_offsetCb, c_offsetCr; + uc_weight_flag = ih264d_get_bit_h264(ps_bitstrm); + pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + COPYTHECONTEXT("SH: chroma_weight_l0_flag",uc_weight_flag); + if(uc_weight_flag) + { + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_weightCb = i_temp; + COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCb); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_offsetCb = i_temp; + COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCb); + + ui32_temp = (c_offsetCb << 16) | (c_weightCb & 0xFFFF); + pui32_weight_offset_lx[1] = ui32_temp; + + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_weightCr = i_temp; + COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCr); + + i_temp = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET) + return ERROR_PRED_WEIGHT_TABLE_T; + c_offsetCr = i_temp; + COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCr); + + ui32_temp = (c_offsetCr << 16) | (c_weightCr & 0xFFFF); + pui32_weight_offset_lx[2] = ui32_temp; + } + else + { + pui32_weight_offset_lx[1] = ui32_cr_def_weight_ofst; + pui32_weight_offset_lx[2] = ui32_cr_def_weight_ofst; + } + } + } + lx++; + } + while(cont--); + + return OK; +} + + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_init_ref_idx_lx_p */ +/* */ +/* Description : This function initializes the reference picture L0 list */ +/* for P slices as per section 8.2.4.2.1 and 8.2.4.2.2. */ +/* */ +/* Inputs : pointer to ps_dec struture */ +/* Globals : NO */ +/* Processing : arranges all the short term pictures according to */ +/* pic_num in descending order starting from curr pic_num. */ +/* and inserts it in L0 list followed by all Long term */ +/* pictures in ascending order. */ +/* */ +/* Returns : void */ +/* */ +/* Issues : <List any issues or problems with this function> */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ +void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec) +{ + struct pic_buffer_t *ps_ref_pic_buf_lx; + dpb_manager_t *ps_dpb_mgr; + struct dpb_info_t *ps_next_dpb; + WORD8 i; + UWORD8 u1_max_lt_index, u1_min_lt_index, u1_lt_index; + UWORD8 u1_field_pic_flag; + dec_slice_params_t *ps_cur_slice; + UWORD8 u1_L0; + WORD32 i4_cur_pic_num, i4_min_st_pic_num; + WORD32 i4_temp_pic_num, i4_ref_pic_num; + UWORD8 u1_num_short_term_bufs; + UWORD8 u1_max_ref_idx_l0; + + ps_cur_slice = ps_dec->ps_cur_slice; + u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; + u1_max_ref_idx_l0 = ps_cur_slice->u1_num_ref_idx_lx_active[0] + << u1_field_pic_flag; + + ps_dpb_mgr = ps_dec->ps_dpb_mgr; + /* Get the current frame number */ + i4_cur_pic_num = ps_dec->ps_cur_pic->i4_pic_num; + + /* Get Min pic_num,MinLt */ + i4_min_st_pic_num = i4_cur_pic_num; + u1_max_lt_index = MAX_REF_BUFS + 1; + u1_min_lt_index = MAX_REF_BUFS + 1; + + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + i4_ref_pic_num = ps_next_dpb->ps_pic_buf->i4_pic_num; + if(i4_ref_pic_num < i4_cur_pic_num) + { + /* RefPic Buf pic_num is before Current pic_num in decode order */ + i4_min_st_pic_num = MIN(i4_min_st_pic_num, i4_ref_pic_num); + } + + /* Chase the next link */ + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + /* Start from LT head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + if(ps_next_dpb) + { + u1_max_lt_index = ps_next_dpb->u1_lt_idx; + u1_min_lt_index = ps_next_dpb->u1_lt_idx; + + for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + u1_lt_index = ps_next_dpb->u1_lt_idx; + u1_max_lt_index = (UWORD8)(MAX(u1_max_lt_index, u1_lt_index)); + u1_min_lt_index = (UWORD8)(MIN(u1_min_lt_index, u1_lt_index)); + + /* Chase the next link */ + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + } + /* 1. Initialize refIdxL0 */ + u1_L0 = 0; + if(u1_field_pic_flag) + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; + ps_ref_pic_buf_lx += MAX_REF_BUFS; + i4_temp_pic_num = i4_cur_pic_num; + } + else + { + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; + i4_temp_pic_num = i4_cur_pic_num; + } + + /* Arrange all short term buffers in output order as given by pic_num */ + /* Arrange pic_num's less than Curr pic_num in the descending pic_num */ + /* order starting from (Curr pic_num - 1) */ + for(; i4_temp_pic_num >= i4_min_st_pic_num; i4_temp_pic_num--) + { + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + if((WORD32)ps_next_dpb->ps_pic_buf->i4_pic_num == i4_temp_pic_num) + { + /* Copy info in pic buffer */ + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + ps_ref_pic_buf_lx++; + u1_L0++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + } + + /* Arrange all Long term buffers in ascending order, in LongtermIndex */ + /* Start from LT head */ + u1_num_short_term_bufs = u1_L0; + for(u1_lt_index = u1_min_lt_index; u1_lt_index <= u1_max_lt_index; + u1_lt_index++) + { + ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; + for(i = 0; i < ps_dpb_mgr->u1_num_lt_ref_bufs; i++) + { + if(ps_next_dpb->u1_lt_idx == u1_lt_index) + { + ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, + ps_next_dpb->ps_pic_buf); + + ps_ref_pic_buf_lx->u1_long_term_pic_num = + ps_ref_pic_buf_lx->u1_long_term_frm_idx; + ps_ref_pic_buf_lx++; + u1_L0++; + break; + } + ps_next_dpb = ps_next_dpb->ps_prev_long; + } + } + + if(u1_field_pic_flag) + { + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[0][0] + MAX_REF_BUFS; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L0; u1_i < u1_max_ref_idx_l0; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + + ih264d_convert_frm_to_fld_list( + ps_dpb_mgr->ps_init_dpb[0][0] + MAX_REF_BUFS, &u1_L0, + ps_dec, u1_num_short_term_bufs); + + ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0] + u1_L0; + } + + /* Initialize the rest of the entries in the */ + /* reference list to handle of errors */ + { + UWORD8 u1_i; + pic_buffer_t *ps_ref_pic; + + ps_ref_pic = ps_dpb_mgr->ps_init_dpb[0][0]; + + if(NULL == ps_ref_pic->pu1_buf1) + { + ps_ref_pic = ps_dec->ps_cur_pic; + } + for(u1_i = u1_L0; u1_i < u1_max_ref_idx_l0; u1_i++) + { + *ps_ref_pic_buf_lx = *ps_ref_pic; + ps_ref_pic_buf_lx++; + } + } + ps_dec->ps_cur_slice->u1_initial_list_size[0] = u1_L0; +} + diff --git a/decoder/ih264d_process_pslice.h b/decoder/ih264d_process_pslice.h new file mode 100755 index 0000000..8740eb4 --- /dev/null +++ b/decoder/ih264d_process_pslice.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_PROCESS_PSLICE_H_ +#define _IH264D_PROCESS_PSLICE_H_ +/*! +************************************************************************** +* \file ih264d_process_pslice.h +* +* \brief +* Contains declarations of routines that decode a P slice type +* +* Detailed_description +* +* \date +* 21/12/2002 +* +* \author NS +************************************************************************** +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +WORD32 ih264d_parse_pslice(dec_struct_t *ps_dec, + UWORD16 u2_first_mb_in_slice); +WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice, + dec_bit_stream_t * ps_bitstrm); + +WORD32 parsePSliceData(dec_struct_t * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); + +WORD32 ih264d_process_inter_mb(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num); + +void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec); + +WORD32 ih264d_mv_pred_ref_tfr_nby2_pmb(dec_struct_t * ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbsNby2); + +WORD32 ih264d_decode_recon_tfr_nmb(dec_struct_t * ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_tfr_n_mb, + UWORD8 u1_end_of_row); + +void ih264d_insert_pic_in_ref_pic_listx(struct pic_buffer_t *ps_ref_pic_buf_lx, + struct pic_buffer_t *ps_pic); +#endif /* _IH264D_PROCESS_PSLICE_H_ */ diff --git a/decoder/ih264d_quant_scaling.c b/decoder/ih264d_quant_scaling.c new file mode 100755 index 0000000..fa9aeb5 --- /dev/null +++ b/decoder/ih264d_quant_scaling.c @@ -0,0 +1,274 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" + +#include "ih264d_parse_slice.h" +#include "ih264d_tables.h" +#include "ih264d_utils.h" +#include "ih264d_nal.h" +#include "ih264d_deblocking.h" + +#include "ih264d_mem_request.h" +#include "ih264d_debug.h" + +#include "ih264d_error_handler.h" +#include "ih264d_mb_utils.h" +#include "ih264d_sei.h" +#include "ih264d_vui.h" +#include "ih264d_tables.h" + +#define IDCT_BLOCK_WIDTH8X8 8 + +void ih264d_scaling_list(WORD16 *pi2_scaling_list, + WORD32 i4_size_of_scalinglist, + UWORD8 *pu1_use_default_scaling_matrix_flag, + dec_bit_stream_t *ps_bitstrm) +{ + WORD32 i4_j, i4_delta_scale, i4_lastScale = 8, i4_nextScale = 8; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + + *pu1_use_default_scaling_matrix_flag = 0; + + for(i4_j = 0; i4_j < i4_size_of_scalinglist; i4_j++) + { + if(i4_nextScale != 0) + { + i4_delta_scale = ih264d_sev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + + i4_nextScale = ((i4_lastScale + i4_delta_scale + 256) & 0xff); + + *pu1_use_default_scaling_matrix_flag = ((i4_j == 0) + && (i4_nextScale == 0)); + + } + pi2_scaling_list[i4_j] = + (i4_nextScale == 0) ? (i4_lastScale) : (i4_nextScale); + i4_lastScale = pi2_scaling_list[i4_j]; + } +} + +void ih264d_form_default_scaling_matrix(dec_struct_t *ps_dec) +{ + + /*************************************************************************/ + /* perform the inverse scanning for the frame and field scaling matrices */ + /*************************************************************************/ + { + UWORD8 *pu1_inv_scan; + WORD32 i4_i, i4_j; + + pu1_inv_scan = (UWORD8 *)gau1_ih264d_inv_scan; + + /* for all 4x4 matrices */ + for(i4_i = 0; i4_i < 6; i4_i++) + { + for(i4_j = 0; i4_j < 16; i4_j++) + { + ps_dec->s_high_profile.i2_scalinglist4x4[i4_i][pu1_inv_scan[i4_j]] = + 16; + + } + } + + /* for all 8x8 matrices */ + for(i4_i = 0; i4_i < 2; i4_i++) + { + for(i4_j = 0; i4_j < 64; i4_j++) + { + ps_dec->s_high_profile.i2_scalinglist8x8[i4_i][gau1_ih264d_inv_scan_prog8x8_cabac[i4_j]] = + 16; + + } + } + } +} + +void ih264d_form_scaling_matrix_picture(dec_seq_params_t *ps_seq, + dec_pic_params_t *ps_pic, + dec_struct_t *ps_dec) +{ + /* default scaling matrices */ + WORD32 i4_i; + + /* check the SPS first */ + if(ps_seq->i4_seq_scaling_matrix_present_flag) + { + for(i4_i = 0; i4_i < 8; i4_i++) + { + if(i4_i < 6) + { + /* fall-back rule A */ + if(!ps_seq->u1_seq_scaling_list_present_flag[i4_i]) + { + if((i4_i == 0) || (i4_i == 3)) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i == 0) ? (WORD16 *)(gai2_ih264d_default_intra4x4) : (WORD16 *)(gai2_ih264d_default_inter4x4); + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_dec->s_high_profile.pi2_scale_mat[i4_i + - 1]; + } + } + else + { + if(ps_seq->u1_use_default_scaling_matrix_flag[i4_i]) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i < 3) ? (WORD16 *)(gai2_ih264d_default_intra4x4) : (WORD16 *)(gai2_ih264d_default_inter4x4); + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_seq->i2_scalinglist4x4[i4_i]; + } + } + + } + else + { + /* fall-back rule A */ + if((!ps_seq->u1_seq_scaling_list_present_flag[i4_i]) + || (ps_seq->u1_use_default_scaling_matrix_flag[i4_i])) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i == 6) ? ((WORD16*)gai2_ih264d_default_intra8x8) : ((WORD16*)gai2_ih264d_default_inter8x8); + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_seq->i2_scalinglist8x8[i4_i - 6]; + } + } + } + } + + /* checking for the PPS */ + + if(ps_pic->i4_pic_scaling_matrix_present_flag) + { + for(i4_i = 0; i4_i < 8; i4_i++) + { + if(i4_i < 6) + { + /* fall back rule B */ + if(!ps_pic->u1_pic_scaling_list_present_flag[i4_i]) + { + if((i4_i == 0) || (i4_i == 3)) + { + if(!ps_seq->i4_seq_scaling_matrix_present_flag) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i == 0) ? (WORD16 *)(gai2_ih264d_default_intra4x4) : (WORD16 *)(gai2_ih264d_default_inter4x4); + } + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_dec->s_high_profile.pi2_scale_mat[i4_i + - 1]; + } + } + else + { + if(ps_pic->u1_pic_use_default_scaling_matrix_flag[i4_i]) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i < 3) ? (WORD16 *)(gai2_ih264d_default_intra4x4) : (WORD16 *)(gai2_ih264d_default_inter4x4); + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_pic->i2_pic_scalinglist4x4[i4_i]; + } + } + } + else + { + if(!ps_pic->u1_pic_scaling_list_present_flag[i4_i]) + { + if(!ps_seq->u1_seq_scaling_list_present_flag[i4_i]) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i == 6) ? ((WORD16*)gai2_ih264d_default_intra8x8) : ((WORD16*)gai2_ih264d_default_inter8x8); + } + } + else + { + if(ps_pic->u1_pic_use_default_scaling_matrix_flag[i4_i]) + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + (i4_i == 6) ? (WORD16 *)(gai2_ih264d_default_intra8x8) : (WORD16 *)(gai2_ih264d_default_inter8x8); + } + else + { + ps_dec->s_high_profile.pi2_scale_mat[i4_i] = + ps_pic->i2_pic_scalinglist8x8[i4_i - 6]; + } + } + } + } + } + + /*************************************************************************/ + /* perform the inverse scanning for the frame and field scaling matrices */ + /*************************************************************************/ + { + UWORD8 *pu1_inv_scan_4x4; + WORD32 i4_i, i4_j; + + pu1_inv_scan_4x4 = (UWORD8 *)gau1_ih264d_inv_scan; + + /* for all 4x4 matrices */ + for(i4_i = 0; i4_i < 6; i4_i++) + { + for(i4_j = 0; i4_j < 16; i4_j++) + { + ps_dec->s_high_profile.i2_scalinglist4x4[i4_i][pu1_inv_scan_4x4[i4_j]] = + ps_dec->s_high_profile.pi2_scale_mat[i4_i][i4_j]; + + } + } + + /* for all 8x8 matrices */ + for(i4_i = 0; i4_i < 2; i4_i++) + { + for(i4_j = 0; i4_j < 64; i4_j++) + { + ps_dec->s_high_profile.i2_scalinglist8x8[i4_i][gau1_ih264d_inv_scan_prog8x8_cabac[i4_j]] = + ps_dec->s_high_profile.pi2_scale_mat[i4_i + 6][i4_j]; + + } + } + } +} + diff --git a/decoder/ih264d_quant_scaling.h b/decoder/ih264d_quant_scaling.h new file mode 100755 index 0000000..d9bd377 --- /dev/null +++ b/decoder/ih264d_quant_scaling.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_QUANT_SCALING_H_ +#define _IH264D_QUANT_SCALING_H_ +void ih264d_scaling_list(WORD16 *pi2_scaling_list, + WORD32 i4_size_of_scalinglist, + UWORD8 *pu1_use_default_scaling_matrix_flag, + dec_bit_stream_t *ps_bitstrm); + + +void ih264d_form_scaling_matrix_picture(dec_seq_params_t *ps_seq, + dec_pic_params_t *ps_pic, + dec_struct_t *ps_dec); + +void ih264d_form_default_scaling_matrix(dec_struct_t *ps_dec); + + + + +#endif diff --git a/decoder/ih264d_sei.c b/decoder/ih264d_sei.c new file mode 100755 index 0000000..14ffcd6 --- /dev/null +++ b/decoder/ih264d_sei.c @@ -0,0 +1,386 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_sei.c */ +/* */ +/* Description : This file contains routines to parse SEI NAL's */ +/* */ +/* List of Functions : <List the functions defined in this file> */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 05 2005 NS Draft */ +/* */ +/*****************************************************************************/ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_sei.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" +#include "ih264d_error_handler.h" +#include "ih264d_vui.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_defs.h" + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_buffering_period */ +/* */ +/* Description : This function parses SEI message buffering_period */ +/* Inputs : ps_buf_prd pointer to struct buf_period_t */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : Parses SEI payload buffering period. */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented fully */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_buffering_period(buf_period_t *ps_buf_prd, + dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec) +{ + UWORD8 u1_seq_parameter_set_id; + dec_seq_params_t *ps_seq; + UWORD8 u1_nal_hrd_present, u1_vcl_hrd_present; + UWORD32 i; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UNUSED(ps_buf_prd); + u1_seq_parameter_set_id = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + if(u1_seq_parameter_set_id > MAX_NUM_SEQ_PARAMS) + return ERROR_INVALID_SEQ_PARAM; + ps_seq = &ps_dec->ps_sps[u1_seq_parameter_set_id]; + if(TRUE != ps_seq->u1_is_valid) + return (-1); + + ps_dec->ps_sei->u1_seq_param_set_id = u1_seq_parameter_set_id; + ps_dec->ps_cur_sps = ps_seq; + if(FALSE == ps_seq->u1_is_valid) + return ERROR_INVALID_SEQ_PARAM; + if(1 == ps_seq->u1_vui_parameters_present_flag) + { + u1_nal_hrd_present = ps_seq->s_vui.u1_nal_hrd_params_present; + if(u1_nal_hrd_present) + { + for(i = 0; i < ps_seq->s_vui.s_nal_hrd.u4_cpb_cnt; i++) + { + ih264d_get_bits_h264( + ps_bitstrm, + ps_seq->s_vui.s_nal_hrd.u1_initial_cpb_removal_delay); + ih264d_get_bits_h264( + ps_bitstrm, + ps_seq->s_vui.s_nal_hrd.u1_initial_cpb_removal_delay); + } + } + + u1_vcl_hrd_present = ps_seq->s_vui.u1_vcl_hrd_params_present; + if(u1_vcl_hrd_present) + { + for(i = 0; i < ps_seq->s_vui.s_vcl_hrd.u4_cpb_cnt; i++) + { + ih264d_get_bits_h264( + ps_bitstrm, + ps_seq->s_vui.s_vcl_hrd.u1_initial_cpb_removal_delay); + ih264d_get_bits_h264( + ps_bitstrm, + ps_seq->s_vui.s_vcl_hrd.u1_initial_cpb_removal_delay); + } + } + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_pic_timing */ +/* */ +/* Description : This function parses SEI message pic_timing */ +/* Inputs : ps_bitstrm Bitstream */ +/* ps_dec Poniter decoder context */ +/* ui4_payload_size pay load i4_size */ +/* Globals : None */ +/* Processing : Parses SEI payload picture timing */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented fully */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_pic_timing(dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec, + UWORD32 ui4_payload_size) +{ + sei *ps_sei; + vui_t *ps_vu4; + UWORD8 u1_cpb_dpb_present; + UWORD8 u1_pic_struct_present_flag; + UWORD32 u4_start_offset, u4_bits_consumed; + UWORD8 u1_cpb_removal_delay_length, u1_dpb_output_delay_length; + + ps_sei = (sei *)ps_dec->ps_sei; + ps_vu4 = &ps_dec->ps_cur_sps->s_vui; + + u1_cpb_dpb_present = ps_vu4->u1_vcl_hrd_params_present + + ps_vu4->u1_nal_hrd_params_present; + + if(ps_vu4->u1_vcl_hrd_params_present) + { + u1_cpb_removal_delay_length = + ps_vu4->s_vcl_hrd.u1_cpb_removal_delay_length; + u1_dpb_output_delay_length = + ps_vu4->s_vcl_hrd.u1_dpb_output_delay_length; + } + else if(ps_vu4->u1_nal_hrd_params_present) + { + u1_cpb_removal_delay_length = + ps_vu4->s_nal_hrd.u1_cpb_removal_delay_length; + u1_dpb_output_delay_length = + ps_vu4->s_nal_hrd.u1_dpb_output_delay_length; + } + else + { + u1_cpb_removal_delay_length = 24; + u1_dpb_output_delay_length = 24; + + } + + u4_start_offset = ps_bitstrm->u4_ofst; + if(u1_cpb_dpb_present) + { + ih264d_get_bits_h264(ps_bitstrm, u1_cpb_removal_delay_length); + ih264d_get_bits_h264(ps_bitstrm, u1_dpb_output_delay_length); + } + + u1_pic_struct_present_flag = ps_vu4->u1_pic_struct_present_flag; + if(u1_pic_struct_present_flag) + { + ps_sei->u1_pic_struct = ih264d_get_bits_h264(ps_bitstrm, 4); + ps_dec->u1_pic_struct_copy = ps_sei->u1_pic_struct; + ps_sei->u1_is_valid = 1; + } + u4_bits_consumed = ps_bitstrm->u4_ofst - u4_start_offset; + ih264d_flush_bits_h264(ps_bitstrm, + (ui4_payload_size << 3) - u4_bits_consumed); + + return (0); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_recovery_point */ +/* */ +/* Description : This function parses SEI message recovery point */ +/* Inputs : ps_bitstrm Bitstream */ +/* ps_dec Poniter decoder context */ +/* ui4_payload_size pay load i4_size */ +/* Globals : None */ +/* Processing : Parses SEI payload picture timing */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented fully */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_parse_recovery_point(dec_bit_stream_t *ps_bitstrm, + dec_struct_t *ps_dec, + UWORD32 ui4_payload_size) +{ + sei *ps_sei = ps_dec->ps_sei; + dec_err_status_t *ps_err = ps_dec->ps_dec_err_status; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UNUSED(ui4_payload_size); + ps_sei->u2_recovery_frame_cnt = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_err->u4_frm_sei_sync = ps_err->u4_cur_frm + + ps_sei->u2_recovery_frame_cnt; + ps_sei->u1_exact_match_flag = ih264d_get_bit_h264(ps_bitstrm); + ps_sei->u1_broken_link_flag = ih264d_get_bit_h264(ps_bitstrm); + ps_sei->u1_changing_slice_grp_idc = ih264d_get_bits_h264(ps_bitstrm, 2); + + return (0); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_sei_payload */ +/* */ +/* Description : This function parses SEI pay loads. Currently it's */ +/* implemented partially. */ +/* Inputs : ps_bitstrm Bitstream */ +/* ui4_payload_type SEI payload type */ +/* ui4_payload_size SEI payload i4_size */ +/* Globals : None */ +/* Processing : Parses SEI payloads units and stores the info */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented fully */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_sei_payload(dec_bit_stream_t *ps_bitstrm, + UWORD32 ui4_payload_type, + UWORD32 ui4_payload_size, + dec_struct_t *ps_dec) +{ + sei *ps_sei; + WORD32 i4_status = 0; + ps_sei = (sei *)ps_dec->ps_sei; + switch(ui4_payload_type) + { + case SEI_BUF_PERIOD: + + i4_status = ih264d_parse_buffering_period(&ps_sei->s_buf_period, + ps_bitstrm, ps_dec); + /*if(i4_status != OK) + return i4_status;*/ + break; + case SEI_PIC_TIMING: + if(NULL == ps_dec->ps_cur_sps) + ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3)); + else + ih264d_parse_pic_timing(ps_bitstrm, ps_dec, + ui4_payload_size); + break; + case SEI_RECOVERY_PT: + ih264d_parse_recovery_point(ps_bitstrm, ps_dec, + ui4_payload_size); + break; + default: + ih264d_flush_bits_h264(ps_bitstrm, (ui4_payload_size << 3)); + break; + } + return (i4_status); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_sei_message */ +/* */ +/* Description : This function is parses and decode SEI. Currently it's */ +/* not implemented fully. */ +/* Inputs : ps_dec Decoder parameters */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : Parses SEI NAL units and stores the info */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented fully */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_sei_message(dec_struct_t *ps_dec, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD32 ui4_payload_type, ui4_payload_size; + UWORD32 u4_bits; + WORD32 i4_status = 0; + + do + { + ui4_payload_type = 0; + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); + while(0xff == u4_bits) + { + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); + ui4_payload_type += 255; + } + ui4_payload_type += u4_bits; + + ui4_payload_size = 0; + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); + while(0xff == u4_bits) + { + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); + ui4_payload_size += 255; + } + ui4_payload_size += u4_bits; + + i4_status = ih264d_parse_sei_payload(ps_bitstrm, ui4_payload_type, + ui4_payload_size, ps_dec); + if(i4_status == -1) + { + i4_status = 0; + break; + } + + if(i4_status != OK) + return i4_status; + + if(ih264d_check_byte_aligned(ps_bitstrm) == 0) + { + u4_bits = ih264d_get_bit_h264(ps_bitstrm); + if(0 == u4_bits) + { + H264_DEC_DEBUG_PRINT("\nError in parsing SEI message"); + } + while(0 == ih264d_check_byte_aligned(ps_bitstrm)) + { + u4_bits = ih264d_get_bit_h264(ps_bitstrm); + if(u4_bits) + { + H264_DEC_DEBUG_PRINT("\nError in parsing SEI message"); + } + } + } + } + while(ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst); + return (i4_status); +} + diff --git a/decoder/ih264d_sei.h b/decoder/ih264d_sei.h new file mode 100755 index 0000000..5033740 --- /dev/null +++ b/decoder/ih264d_sei.h @@ -0,0 +1,91 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_sei.h */ +/* */ +/* Description : This file contains routines to parse SEI NAL's */ +/* */ +/* List of Functions : <List the functions defined in this file> */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 05 2005 NS Draft */ +/* */ +/*****************************************************************************/ + +#ifndef _IH264D_SEI_H_ +#define _IH264D_SEI_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" +#include "ih264d_structs.h" + +#define SEI_BUF_PERIOD 0 +#define SEI_PIC_TIMING 1 +#define SEI_PAN_SCAN_RECT 2 +#define SEI_FILLER 3 +#define SEI_UD_REG_T35 4 +#define SEI_UD_UN_REG 5 +#define SEI_RECOVERY_PT 6 +#define SEI_DEC_REF_MARK 7 +#define SEI_SPARE_PIC 8 +#define SEI_SCENE_INFO 9 +#define SEI_SUB_SEQN_INFO 10 +#define SEI_SUB_SEQN_LAY_CHAR 11 +#define SEI_SUB_SEQN_CHAR 12 +#define SEI_FULL_FRAME_FREEZE 13 +#define SEI_FULL_FRAME_FREEZE_REL 14 +#define SEI_FULL_FRAME_SNAP_SHOT 15 +#define SEI_PROG_REF_SEGMENT_START 16 +#define SEI_PROG_REF_SEGMENT_END 17 +#define SEI_MOT_CON_SLICE_GRP_SET 18 +/* Declaration of dec_struct_t to avoid CCS compilation Error */ +struct _DecStruct; +WORD32 ih264d_parse_sei_message(struct _DecStruct *ps_dec, + dec_bit_stream_t *ps_bitstrm); +typedef struct +{ + UWORD8 u1_seq_parameter_set_id; + UWORD32 u4_initial_cpb_removal_delay; + UWORD32 u4_nitial_cpb_removal_delay_offset; + +} buf_period_t; + +struct _sei +{ + UWORD8 u1_seq_param_set_id; + buf_period_t s_buf_period; + UWORD8 u1_pic_struct; + UWORD16 u2_recovery_frame_cnt; + UWORD8 u1_exact_match_flag; + UWORD8 u1_broken_link_flag; + UWORD8 u1_changing_slice_grp_idc; + UWORD8 u1_is_valid; +}; +typedef struct _sei sei; +#endif /* _IH264D_SEI_H_ */ + diff --git a/decoder/ih264d_structs.h b/decoder/ih264d_structs.h new file mode 100755 index 0000000..110f71d --- /dev/null +++ b/decoder/ih264d_structs.h @@ -0,0 +1,1582 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_STRUCTS_H_ +#define _IH264D_STRUCTS_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "iv.h" +#include "ivd.h" + +#include "ih264d_transfer_address.h" +#include "ih264d_defs.h" +#include "ih264d_defs.h" +#include "ih264d_bitstrm.h" +#include "ih264d_debug.h" +#include "ih264d_dpb_manager.h" +/* includes for CABAC */ +#include "ih264d_cabac.h" +#include "ih264d_dpb_manager.h" + +#include "ih264d_vui.h" +#include "ih264d_sei.h" +#include "iv.h" +#include "ivd.h" + +#include "ih264_weighted_pred.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" +#include "ih264_mem_fns.h" +#include "ih264_padding.h" +#include "ih264_intra_pred_filters.h" +#include "ih264_deblk_edge_filters.h" + + +/** Number of Mb's whoose syntax will be read */ +/************************************************************/ +/* MB_GROUP should be a multiple of 2 */ +/************************************************************/ +#define PARSE_MB_GROUP_4 4 + +/* MV_SCRATCH_BUFS assumed to be pow(2) */ +#define MV_SCRATCH_BUFS 4 + +#define LEFT_MB_PIXELS 4 +#define LEFT_MB_PIXELS_Y_FRM_BOT 64 /* 4 * 16 */ +#define LEFT_MB_PIXELS_CR_FRM_BOT 32 /* 4 * 8 */ + +#define TOP_FIELD_ONLY 0x02 +#define BOT_FIELD_ONLY 0x01 + +#define MAX_REF_BUF_SIZE (3776*2*2) + +struct _DecStruct; +struct _DecMbInfo; + + +#define NUM_INT_G_TABLE ((UWORD32) (sigcoeff_ctxtinc_field8x8 + 1)) +#define NUM_EXT_G_TABLE ((UWORD32) (ITTIAM_LOGO_V_BUF_T + 1)) + +typedef enum +{ + MB_TYPE_SI_SLICE = 0, + MB_TYPE_I_SLICE = 3, + MB_SKIP_FLAG_P_SLICE = 11, + MB_TYPE_P_SLICE = 14, + SUB_MB_TYPE_P_SLICE = 21, + MB_SKIP_FLAG_B_SLICE = 24, + MB_TYPE_B_SLICE = 27, + SUB_MB_TYPE_B_SLICE = 36, + MVD_X = 40, + MVD_Y = 47, + REF_IDX = 54, + MB_QP_DELTA = 60, + INTRA_CHROMA_PRED_MODE = 64, + PREV_INTRA4X4_PRED_MODE_FLAG = 68, + REM_INTRA4X4_PRED_MODE = 69, + MB_FIELD_DECODING_FLAG = 70, + CBP_LUMA = 73, + CBP_CHROMA = 77, + CBF = 85, + SIGNIFICANT_COEFF_FLAG_FRAME = 105, + SIGNIFICANT_COEFF_FLAG_FLD = 277, + LAST_SIGNIFICANT_COEFF_FLAG_FRAME = 166, + LAST_SIGNIFICANT_COEFF_FLAG_FLD = 338, + COEFF_ABS_LEVEL_MINUS1 = 227, + + /* High profile related Syntax element CABAC offsets */ + TRANSFORM_SIZE_8X8_FLAG = 399, + SIGNIFICANT_COEFF_FLAG_8X8_FRAME = 402, + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FRAME = 417, + COEFF_ABS_LEVEL_MINUS1_8X8 = 426, + SIGNIFICANT_COEFF_FLAG_8X8_FIELD = 436, + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FIELD = 451 + +} cabac_table_num_t; + +typedef enum +{ + SIG_COEFF_CTXT_CAT_0_OFFSET = 0, + SIG_COEFF_CTXT_CAT_1_OFFSET = 15, + SIG_COEFF_CTXT_CAT_2_OFFSET = 29, + SIG_COEFF_CTXT_CAT_3_OFFSET = 44, + SIG_COEFF_CTXT_CAT_4_OFFSET = 47, + SIG_COEFF_CTXT_CAT_5_OFFSET = 0, + COEFF_ABS_LEVEL_CAT_0_OFFSET = 0, + COEFF_ABS_LEVEL_CAT_1_OFFSET = 10, + COEFF_ABS_LEVEL_CAT_2_OFFSET = 20, + COEFF_ABS_LEVEL_CAT_3_OFFSET = 30, + COEFF_ABS_LEVEL_CAT_4_OFFSET = 39, + COEFF_ABS_LEVEL_CAT_5_OFFSET = 0 +} cabac_blk_cat_offset_t; + +typedef enum +{ + CABAC_IPBMB_LD_ADRS_T, + CABAC_IPBMB_LD_SZ_T, + CAVLC_IPBMB_LD_ADRS_T, + CAVLC_IPBMB_LD_SZ_T, + PARSE_IPBMB_RUN_ADRS_T, + + MVP_MBAFF_LD_ADRS_T, + MVP_MBAFF_LD_SZ_T, + MVP_NON_MBAFF_LD_ADRS_T, + MVP_NON_MBAFF_LD_SZ_T, + MVPRED_RUN_ADRS_T, + + B_REF_DMA_LD_ADRS_T, + B_REF_DMA_LD_SZ_T, + P_REF_DMA_LD_ADRS_T, + P_REF_DMA_LD_SZ_T, + REF_DMA_RUN_ADRS_T, + + SP_DRCT_LD_ADRS_T, + SP_DRCT_LD_SZ_T, + TMP_DRCT_LD_ADRS_T, + TMP_DRCT_LD_SZ_T, + B_SKIP_RUN_ADRS_T, + + DEC_DEBLK_RUN_ADRS_T, + H264_DBLK_LD_ADRS_T, + H264_DBLK_LD_SZ_T, + H264_DEC_LD_ADRS_T, + + /* + * (H264_DEC_LD_SZ_T + 1) will be considered as the end of this table + * new members to be added before this + */ + H264_DEC_LD_SZ_T +} code_overlay_tab_t; + +/** Structure for the MV bank */ +typedef struct _mv_pred_t +{ + WORD16 i2_mv[4]; /** 0- mvFwdX, 1- mvFwdY, 2- mvBwdX, 3- mvBwdY */ + WORD8 i1_ref_frame[2]; + + UWORD8 u1_col_ref_pic_idx; /** Idx into the pic buff array */ + UWORD8 u1_pic_type; /** Idx into the pic buff array */ + +} mv_pred_t; + +typedef struct +{ + WORD32 i4_mv_indices[16]; + WORD8 i1_submb_num[16]; + WORD8 i1_partitionsize[16]; + WORD8 i1_num_partitions; + WORD8 u1_vert_mv_scale; + UWORD8 u1_col_zeroflag_change; +} directmv_t; + +typedef struct pic_buffer_t +{ + /**Different components of the picture */ + UWORD8 *pu1_buf1; + UWORD8 *pu1_buf2; + UWORD8 *pu1_buf3; + UWORD16 u2_disp_width; /** Width of the display luma frame in pixels */ + UWORD16 u2_disp_height; /** Height of the display luma frame in pixels */ + UWORD32 u4_time_stamp; /** Time at which frame has to be displayed */ + UWORD16 u2_frm_wd_y; /** Width of the luma frame in pixels */ + UWORD16 u2_frm_wd_uv; /** Width of the chroma frame */ + UWORD16 u2_frm_ht_y; /** Height of the luma frame in pixels */ + UWORD16 u2_frm_ht_uv; /** Height of the chroma frame */ + /* Upto this is resembling the structure IH264DEC_DispUnit */ + + /* If any member is to be added, add below this */ + + /* u4_ofst from start of picture buffer to display position for Y buffer */ + UWORD16 u2_crop_offset_y; + + /* u4_ofst from start of picture buffer to display position for UV buffer */ + UWORD16 u2_crop_offset_uv; + + UWORD8 u1_is_short; /** (1: short 0: long) term ref pic */ + UWORD8 u1_pic_type; /** frame / field / complementary field pair */ + UWORD8 u1_pic_buf_id; /** Idx into the picBufAPI array */ + UWORD8 u1_mv_buf_id; + WORD32 i4_seq; + UWORD8 *pu1_col_zero_flag; + mv_pred_t *ps_mv; /** Pointer to the MV bank array */ + WORD32 i4_poc; /** POC */ + WORD32 i4_pic_num; + WORD32 i4_frame_num; + WORD32 i4_top_field_order_cnt; /** TopPOC */ + WORD32 i4_bottom_field_order_cnt; /** BottomPOC */ + WORD32 i4_avg_poc; /** minPOC */ + UWORD8 u1_picturetype; /*Same as u1_pic_type..u1_pic_type gets overwritten whereas + this doesnot get overwritten ...stores the pictype of + frame/complementary field pair/ mbaff */ + UWORD8 u1_long_term_frm_idx; + UWORD8 u1_long_term_pic_num; + UWORD32 u4_pack_slc_typ; /* It will contain information about types of slices */ + + /* ! */ + UWORD32 u4_ts; + UWORD8 u1_pic_struct;/* Refer to SEI table D-1 */ + +} pic_buffer_t; + +typedef struct +{ + void *u4_add[4]; +} neighbouradd_t; + +typedef struct +{ + const UWORD8 *pu1_inv_scan; + void *pv_table[6]; +} cavlc_cntxt_t; + +/** + ************************************************************************ + * \file ih264d_structs.h + * + * \brief + * Structures used in the H.264 decoder + * + * \date + * 18/11/2002 + * + * \author Sriram Sethuraman + * + ************************************************************************ + */ + +/** + * Structure to represent a MV Bank buffer and col flag + */ +typedef struct +{ + /** + * Pointer to buffer that holds col flag. + */ + void *pv_col_zero_flag; + + /** + * Pointer to buffer that holds mv_pred + */ + void *pv_mv; + + }col_mv_buf_t; + + +/* Note the i4_size of this structure is hardcoded in arm_default_weighted_Pred.s as 0x3C. + * ADD r0,r0,#0x3C and so on.. + * If there is a change in i4_size update above file accordingly. + */ +typedef struct +{ + UWORD8 u1_mc_addr_ofst; /** Offset in bytes relative to pu1_dma_dest_addr */ + UWORD8 u1_dydx; /** 4*dy + dx for Y comp / 8*dy + dx for UV comp */ + UWORD8 u1_is_bi_direct; /** 1: is bi-direct 0: forward / backward only */ + UWORD8 u1_wght_pred_type; /** 0-default 1-singleWeighted 2-BiWeighted */ + WORD8 i1_mb_partwidth; /** Width of MB partition */ + WORD8 i1_mb_partheight; /** Height of MB partition */ + WORD8 i1_mc_wd; /** Number of bytes in a DMA stride */ + WORD8 i1_dma_ht; /** Number of strides */ + + WORD8 i1_pod_ht; /** Flag specifying height of pad on demand */ + /** 0 (No pod) -ve(Top pod) +ve(Bottom pod) */ + UWORD16 u2_dst_stride; /** Stride value of the destination */ + UWORD16 u2_u1_ref_buf_wd; /** Width of the ref buffer */ + UWORD16 u2_frm_wd; + UWORD16 u2_dummy; + + UWORD8 *u1_pi1_wt_ofst_rec_v; /** Pointer to packed weight and u4_ofst */ + UWORD8 *pu1_rec_y_u; /** MB partition address in row buffer */ + UWORD8 *pu1_dma_dest_addr; /** Destination address for DMA transfer */ + UWORD8 *pu1_y_ref; + UWORD8 *pu1_u_ref; + UWORD8 *pu1_v_ref; + + UWORD8 *pu1_pred; + UWORD8 *pu1_pred_u; + UWORD8 *pu1_pred_v; + UWORD8 u1_dma_wd_y; + UWORD8 u1_dma_ht_y; + UWORD8 u1_dma_wd_uv; + UWORD8 u1_dma_ht_uv; +} pred_info_t; + +typedef struct +{ + UWORD32 *pu4_wt_offst; + WORD16 i2_mv[2]; + + /***************************************************/ + /*packing information i1_size_pos_info */ + /* bit 1:0 -> X position in terms of (4x4) units */ + /* bit 3:2 -> Y position in terms of (4x4) units */ + /* bit 5:4 -> PU width 0:4,1:8,2:16 */ + /* bit 7:6 -> PU height 0:4,1:8,2:16 */ + /***************************************************/ + WORD8 i1_size_pos_info; + + /***************************************************/ + /*packing information ref idx info */ + /* bit 5:0 ->ref_idx */ + /* bit 6:7 -> 0:l0,1:l1,2:bipred */ + /***************************************************/ + WORD8 i1_ref_idx_info; + + WORD8 i1_buf_id; + + + UWORD8 u1_pic_type; /** frame /top field/bottom field/mbaff / complementary field pair */ + +}pred_info_pkd_t; +/*! Sequence level parameters */ + +typedef struct +{ + UWORD8 u1_seq_parameter_set_id; /** id for the seq par set 0-31 */ + UWORD8 u1_is_valid; /** is Seq Param set valid */ + + UWORD16 u2_frm_wd_in_mbs; /** Frame width expressed in MB units */ + UWORD16 u2_frm_ht_in_mbs; /** Frame height expressed in MB units */ + + /* Following are derived from the above two */ + UWORD16 u2_fld_ht_in_mbs; /** Field height expressed in MB units */ + UWORD16 u2_max_mb_addr; /** Total number of macroblocks in a coded picture */ + UWORD16 u2_total_num_of_mbs; /** Total number of macroblocks in a coded picture */ + UWORD32 u4_fld_ht; /** field height */ + UWORD32 u4_cwidth; /** chroma width */ + UWORD32 u4_chr_frm_ht; /** chroma height */ + UWORD32 u4_chr_fld_ht; /** chroma field height */ + UWORD8 u1_mb_aff_flag; /** 0 - no mb_aff; 1 - uses mb_aff */ + + UWORD8 u1_profile_idc; /** profile value */ + UWORD8 u1_level_idc; /** level value */ + + /* high profile related syntax elements */ + WORD32 i4_chroma_format_idc; + WORD32 i4_bit_depth_luma_minus8; + WORD32 i4_bit_depth_chroma_minus8; + WORD32 i4_qpprime_y_zero_transform_bypass_flag; + WORD32 i4_seq_scaling_matrix_present_flag; + UWORD8 u1_seq_scaling_list_present_flag[8]; + UWORD8 u1_use_default_scaling_matrix_flag[8]; + WORD16 i2_scalinglist4x4[6][16]; + WORD16 i2_scalinglist8x8[2][64]; + UWORD8 u1_more_than_one_slice_group_allowed_flag; + UWORD8 u1_arbitrary_slice_order_allowed_flag; + UWORD8 u1_redundant_slices_allowed_flag; + UWORD8 u1_bits_in_frm_num; /** Number of bits in frame num */ + UWORD16 u2_u4_max_pic_num_minus1; /** Maximum frame num minus 1 */ + UWORD8 u1_pic_order_cnt_type; /** 0 - 2 indicates the method to code picture order count */ + UWORD8 u1_log2_max_pic_order_cnt_lsb_minus; + WORD32 i4_max_pic_order_cntLsb; + UWORD8 u1_num_ref_frames_in_pic_order_cnt_cycle; + UWORD8 u1_delta_pic_order_always_zero_flag; + WORD32 i4_ofst_for_non_ref_pic; + WORD32 i4_ofst_for_top_to_bottom_field; + WORD32 i4_ofst_for_ref_frame[MAX_NUM_REF_FRAMES_OFFSET]; + UWORD8 u1_num_ref_frames; + UWORD8 u1_gaps_in_frame_num_value_allowed_flag; + UWORD8 u1_frame_mbs_only_flag; /** 1 - frame only; 0 - field/frame pic */ + UWORD8 u1_direct_8x8_inference_flag; + UWORD8 u1_vui_parameters_present_flag; + vui_t s_vui; +} dec_seq_params_t; + +typedef struct +{ + UWORD16 u2_frm_wd_in_mbs; /** Frame width expressed in MB units */ + UWORD16 u2_frm_ht_in_mbs; /** Frame height expressed in MB units */ + UWORD8 u1_frame_mbs_only_flag; /** 1 - frame only; 0 - field/frame pic */ + UWORD8 u1_profile_idc; /** profile value */ + UWORD8 u1_level_idc; /** level value */ + UWORD8 u1_direct_8x8_inference_flag; + UWORD8 u1_eoseq_pending; +} prev_seq_params_t; + +/** Picture level parameters */ +typedef struct +{ + dec_seq_params_t *ps_sps; /** applicable seq. parameter set */ + + /* High profile related syntax elements */ + WORD32 i4_transform_8x8_mode_flag; + WORD32 i4_pic_scaling_matrix_present_flag; + UWORD8 u1_pic_scaling_list_present_flag[8]; + UWORD8 u1_pic_use_default_scaling_matrix_flag[8]; + WORD16 i2_pic_scalinglist4x4[6][16]; + WORD16 i2_pic_scalinglist8x8[2][64]; + WORD8 i1_second_chroma_qp_index_offset; + + UWORD32 u4_slice_group_change_rate; + UWORD8 *pu1_slice_groupmb_map; /** MB map with slice membership labels */ + UWORD8 u1_pic_parameter_set_id; /** id for the picture par set 0-255*/ + UWORD8 u1_entropy_coding_mode; /** Entropy coding : 0-VLC; 1 - CABAC */ + UWORD8 u1_num_slice_groups; /** Number of slice groups */ + UWORD8 u1_pic_init_qp; /** Initial QPY for the picture {-26,25}*/ + WORD8 i1_chroma_qp_index_offset; /** Chroma QP u4_ofst w.r.t QPY {-12,12} */ + UWORD8 u1_dblk_filter_parms_flag; /** Slice layer has deblocking filter parameters */ + UWORD8 u1_constrained_intra_pred_flag; /** Constrained intra prediction u4_flag */ + UWORD8 u1_redundant_pic_cnt_present_flag; /** Redundant_pic_cnt is in slices using this PPS */ + UWORD8 u1_pic_order_present_flag; /** Pic order present u4_flag */ + UWORD8 u1_num_ref_idx_lx_active[2]; /** Maximum reference picture index in the reference list 0 : range [1 - 15] */ + UWORD8 u1_wted_pred_flag; + UWORD8 u1_wted_bipred_idc; + UWORD8 u1_pic_init_qs; + UWORD8 u1_deblocking_filter_parameters_present_flag; + UWORD8 u1_vui_pic_parameters_flag; + UWORD8 u1_mb_slice_group_map_type; + UWORD8 u1_slice_group_change_direction_flag; + UWORD8 u1_frame_cropping_flag; + UWORD8 u1_frame_cropping_rect_left_ofst; + UWORD8 u1_frame_cropping_rect_right_ofst; + UWORD8 u1_frame_cropping_rect_top_ofst; + UWORD8 u1_frame_cropping_rect_bottom_ofst; + void * pv_codec_handle; /* For Error Handling */ + WORD32 i4_top_field_order_cnt; + WORD32 i4_bottom_field_order_cnt; + WORD32 i4_avg_poc; + UWORD8 u1_is_valid; /** is Pic Param set valid */ +} dec_pic_params_t; + +/** Picture Order Count Paramsters */ +typedef struct +{ + WORD32 i4_pic_order_cnt_lsb; + WORD32 i4_pic_order_cnt_msb; + WORD32 i4_delta_pic_order_cnt_bottom; + WORD32 i4_delta_pic_order_cnt[2]; + WORD32 i4_prev_frame_num_ofst; + UWORD8 u1_mmco_equalto5; + UWORD8 u1_bot_field; + UWORD16 u2_frame_num; + WORD32 i4_top_field_order_count; + WORD32 i4_bottom_field_order_count; +} pocstruct_t; + +/*****************************************************************************/ +/* parse_mb_pers_info contains necessary mb info data required persistently */ +/* in the form of top and left neighbours. */ +/*****************************************************************************/ +typedef struct +{ + void *u4_pic_addrress[4]; /* picture address for BS calc */ + WORD8 pi1_intrapredmodes[4]; /* calc Intra pred modes */ + UWORD8 pu1_nnz_y[4]; + UWORD8 pu1_nnz_uv[4]; + UWORD8 u1_mb_fld; + UWORD8 u1_mb_type; + UWORD16 u2_luma_csbp; /* Luma csbp used for BS calc */ + UWORD8 u1_tran_form8x8; +} mb_neigbour_params_t; + +/* This info is required for decoding purposes except Deblockng */ +typedef struct _DecMbInfo +{ + UWORD8 u1_mb_type; /** macroblock type: I/P/B/SI/SP */ + UWORD8 u1_chroma_pred_mode; + UWORD8 u1_cbp; + UWORD8 u1_mb_mc_mode; /** 16x16, 2 16x8, 2 8x16, 4 8x8 */ + UWORD8 u1_topmb; /** top Mb u4_flag */ + UWORD8 u1_mb_ngbr_availablity; + UWORD8 u1_end_of_slice; + UWORD8 u1_mb_field_decodingflag; + UWORD8 u1_topleft_mb_fld; + UWORD8 u1_topleft_mbtype; + WORD8 i1_offset; + UWORD8 u1_Mux; + UWORD8 u1_qp_div6; + UWORD8 u1_qp_rem6; + UWORD8 u1_qpc_div6; + UWORD8 u1_qpcr_div6; + UWORD8 u1_qpc_rem6; + UWORD8 u1_qpcr_rem6; + UWORD8 u1_tran_form8x8; + UWORD8 u1_num_pred_parts; + UWORD8 u1_yuv_dc_block_flag; + UWORD16 u2_top_right_avail_mask; + UWORD16 u2_top_left_avail_mask; + UWORD16 u2_luma_csbp; /** Coded 4x4 Sub Block Pattern */ + UWORD16 u2_chroma_csbp; /** Coded 4x4 Sub Block Pattern */ + UWORD16 u2_mbx; + UWORD16 u2_mby; + UWORD16 u2_mask[2]; + + UWORD32 u4_pred_info_pkd_idx; + + mb_neigbour_params_t *ps_left_mb; + mb_neigbour_params_t *ps_top_mb; + mb_neigbour_params_t *ps_top_right_mb; + mb_neigbour_params_t *ps_curmb; +} dec_mb_info_t; + + +/** Slice level parameters */ +typedef struct +{ + dec_pic_params_t *ps_pps; /** PPS used */ + WORD32 i4_delta_pic_order_cnt[2]; + WORD32 i4_poc; /** Pic order cnt of picture to which slice belongs*/ + UWORD32 u4_idr_pic_id; /** IDR pic ID */ + UWORD16 u2_first_mb_in_slice; /** Address of first MB in slice*/ + UWORD16 u2_frame_num; /** Frame number from prev IDR pic */ + + UWORD8 u1_mbaff_frame_flag; /** Mb adaptive frame field u4_flag */ + UWORD8 u1_field_pic_flag; /** Field picture or not */ + UWORD8 u1_bottom_field_flag; /** If slice belongs to bot field pic */ + UWORD8 u1_slice_type; /** I/P/B/SI/SP */ + WORD32 i4_pic_order_cnt_lsb; /** Picture Order Count */ + UWORD8 u1_slice_qp; /** Add slice_qp_delta to pic_init_QP */ + UWORD8 u1_disable_dblk_filter_idc; /** 0-dblk all edges; 1 - suppress; 2 - suppress only edges */ + WORD8 i1_slice_alpha_c0_offset; /** dblk: alpha and C0 table u4_ofst {-12,12}*/ + WORD8 i1_slice_beta_offset; /** dblk: beta table u4_ofst {-12, 12}*/ + UWORD8 u1_sp_for_switch_flag; + UWORD8 u1_no_output_of_prior_pics_flag; + UWORD8 u1_long_term_reference_flag; + UWORD8 u1_num_ref_idx_lx_active[2]; + UWORD8 u1_cabac_init_idc; /** cabac_init_idc */ + UWORD8 u1_num_ref_idx_active_override_flag; + UWORD8 u1_direct_spatial_mv_pred_flag; + WORD32 (*pf_decodeDirect)(struct _DecStruct *ps_dec, + UWORD8 u1_wd_x, + dec_mb_info_t *ps_cur_mb_info, + UWORD8 u1_mb_num); + UWORD8 u1_redundant_pic_cnt; + WORD8 i1_slice_qs_delta; + UWORD8 u1_nal_ref_idc; /** NAL ref idc of the Slice NAL unit */ + UWORD8 u1_nal_unit_type; /** NAL unit type of the Slice NAL */ + UWORD8 u1_direct_8x8_inference_flag; + UWORD8 u1_mmco_equalto5; /** any of the MMCO command equal to 5 */ + UWORD8 u1_pic_order_cnt_type; + pocstruct_t s_POC; + /* DataStructures required for weighted prediction */ + UWORD16 u2_log2Y_crwd; /** Packed luma and chroma log2_weight_denom */ + /* [list0/list1]:[ref pics index]:[0-Y 1-Cb 2-Cr] [weight/u4_ofst], + weights and offsets are signed numbers, since they are packed, it is defined + unsigned. LSB byte : weight and MSB byte: u4_ofst */ + UWORD32 u4_wt_ofst_lx[2][MAX_REF_BUFS][3]; + void * pv_codec_handle; /* For Error Handling */ + UWORD8 u1_end_of_frame_signal; + + /* This is used when reordering is done in Forward or */ + /* backward lists. This is because reordering can point */ + /* to any valid entry in initial list irrespective of */ + /* num_ref_idx_active which could be overwritten using */ + /* ref_idx_reorder_flag */ + UWORD8 u1_initial_list_size[2]; + UWORD32 u4_mbs_in_slice; +} dec_slice_params_t; + + +typedef struct +{ + UWORD8 u1_mb_type; /* Bit representations, X- reserved */ + /** |Field/Frame|X|X|X|X|Bslice u4_flag|PRED_NON_16x16 u4_flag |Intra Mbflag| */ + UWORD8 u1_mb_qp; + UWORD8 u1_deblocking_mode; /** dblk: Mode [ NO / NO TOP / NO LEFT] filter */ + WORD8 i1_slice_alpha_c0_offset; /** dblk: alpha and C0 table u4_ofst {-12,12}*/ + WORD8 i1_slice_beta_offset; /** dblk: beta table u4_ofst {-12, 12}*/ + UWORD8 u1_single_call; + UWORD8 u1_topmb_qp; + UWORD8 u1_left_mb_qp; + UWORD32 u4_bs_table[10]; /* Boundary strength */ + +} deblk_mb_t; + +typedef struct +{ + UWORD8 u1_mb_type; + UWORD8 u1_mb_qp; +} deblkmb_neighbour_t; + +#define MAX_MV_RESIDUAL_INFO_PER_MB 32 +#define MAX_REFIDX_INFO_PER_MB 4 +#define PART_NOT_DIRECT 0 +#define PART_DIRECT_8x8 1 +#define PART_DIRECT_16x16 2 +typedef struct +{ + UWORD8 u1_is_direct; + UWORD8 u1_pred_mode; + UWORD8 u1_sub_mb_num; + UWORD8 u1_partheight; + UWORD8 u1_partwidth; +} parse_part_params_t; + +typedef struct +{ + UWORD8 u1_isI_mb; + UWORD8 u1_num_part; + UWORD32 *pu4_wt_offst[MAX_REFIDX_INFO_PER_MB]; + WORD8 i1_ref_idx[2][MAX_REFIDX_INFO_PER_MB]; + UWORD8 u1_col_info[MAX_REFIDX_INFO_PER_MB]; +} parse_pmbarams_t; + +typedef struct +{ + UWORD8 *pu1_mb_y; /* pointer to N-Mb pad buffer Y (Horz) */ + UWORD8 *pu1_mb_u; /* pointer to N-Mb pad buffer U (Horz) */ + UWORD8 *pu1_mb_v; /* pointer to N-Mb pad buffer V (Horz) */ + UWORD8 *pu1_row_y; /* pointer to row pad buffer Y (Vert) */ + UWORD8 *pu1_row_u; /* pointer to row pad buffer U (Vert) */ + UWORD8 *pu1_row_v; /* pointer to row pad buffer V (Vert) */ + UWORD8 u1_vert_pad_top; /* flip-flop u4_flag remembering pad area (Vert) */ + UWORD8 u1_vert_pad_bot; /* flip-flop u4_flag remembering pad area (Vert) */ + UWORD8 u1_horz_pad; /* flip-flop u4_flag remembering pad area (Vert) */ + UWORD8 u1_pad_len_y_v; /* vertical pad amount for luma */ + UWORD8 u1_pad_len_cr_v; /* vertical pad amount for chroma */ +} pad_mgr_t; + +typedef struct code_overlay_ctxt +{ + UWORD8 u1_pb_slice_type; + UWORD8 u1_entropy_coding_type; + UWORD8 u1_mbaff_frame_flag; + UWORD8 u1_b_direct_flag; +} code_overlay_ctxt_t; + +#define ACCEPT_ALL_PICS (0x00) +#define REJECT_CUR_PIC (0x01) +#define REJECT_PB_PICS (0x02) + +#define PIC_TYPE_UNKNOWN (0xFF) +#define PIC_TYPE_I (0x00) +#define SYNC_FRM_DEFAULT (0xFFFFFFFF) +#define INIT_FRAME (0xFFFFFF) + +typedef struct dec_err_status_t +{ + UWORD8 u1_cur_pic_type; + UWORD8 u1_pic_aud_i; + UWORD8 u1_err_flag; + UWORD32 u4_frm_sei_sync; + UWORD32 u4_cur_frm; +} dec_err_status_t; + +/**************************************************************************/ +/* Structure holds information about all high profile toolsets */ +/**************************************************************************/ +typedef struct +{ + /*****************************************/ + /* variables required for scaling */ + /*****************************************/ + UWORD8 u1_scaling_present; + WORD16 *pi2_scale_mat[8]; + + /*************************************************/ + /* scaling matrices for frame macroblocks after */ + /* inverse scanning */ + /*************************************************/ + WORD16 i2_scalinglist4x4[6][16]; + WORD16 i2_scalinglist8x8[2][64]; + + + /*****************************************/ + /* variables required for transform8x8 */ + /*****************************************/ + UWORD8 u1_transform8x8_present; + UWORD8 u1_direct_8x8_inference_flag; + /* temporary variable to get noSubMbPartSizeLessThan8x8Flag from ih264d_parse_bmb_non_direct_cavlc */ + UWORD8 u1_no_submb_part_size_lt8x8_flag; + + /* needed for inverse scanning */ + cavlc_cntxt_t s_cavlc_ctxt; + + /* contexts for the CABAC related parsing */ + bin_ctxt_model_t *ps_transform8x8_flag; + bin_ctxt_model_t *ps_sigcoeff_8x8_frame; + bin_ctxt_model_t *ps_last_sigcoeff_8x8_frame; + bin_ctxt_model_t *ps_coeff_abs_levelminus1; + bin_ctxt_model_t *ps_sigcoeff_8x8_field; + bin_ctxt_model_t *ps_last_sigcoeff_8x8_field; + +/* variables required for intra8x8 */ + +/* variables required for handling different Qp for Cb and Cr */ + +} high_profile_tools_t; + +typedef struct +{ + UWORD32 u4_num_bufs; /* Number of buffers in each display frame. 2 for 420SP and 3 for 420P and so on */ + void *buf[3]; /* Pointers to each of the components */ + UWORD32 u4_bufsize[3]; + UWORD32 u4_ofst[3]; +} disp_buf_t; +typedef struct _dec_slice_struct +{ + volatile UWORD32 u4_first_mb_in_slice; + volatile UWORD32 u4_num_mbs_done_in_slice; + volatile UWORD32 slice_type; + volatile UWORD32 end_of_slice; + volatile UWORD32 slice_header_done; + volatile UWORD32 last_slice_in_frame; + volatile UWORD16 u2_log2Y_crwd; + volatile UWORD16 u2_error_flag; + volatile void **ppv_map_ref_idx_to_poc; +} dec_slice_struct_t; + +typedef struct +{ + UWORD32 u4_flag; + UWORD32 u4_start_y; + UWORD32 u4_num_rows_y; +} fmt_conv_part_t; + +/** + * Structure to hold coefficient info for a 4x4 transform + */ +typedef struct +{ + /** + * significant coefficient map + */ + UWORD16 u2_sig_coeff_map; + + /** + * holds coefficients + */ + WORD16 ai2_level[16]; +}tu_sblk4x4_coeff_data_t; + +/** + * Structure to hold coefficient info for a 8x8 transform + */ +typedef struct +{ + + /** + * significant coefficient map + */ + UWORD32 au4_sig_coeff_map[2]; + + /** + * holds coefficients + */ + WORD16 ai2_level[64]; +}tu_blk8x8_coeff_data_t; + +/** Aggregating structure that is globally available */ +typedef struct _DecStruct +{ + + /* Add below all other static memory allocations and pointers to items + that are dynamically allocated once per session */ + dec_bit_stream_t *ps_bitstrm; + dec_seq_params_t *ps_cur_sps; + dec_pic_params_t *ps_cur_pps; + dec_slice_params_t *ps_cur_slice; + + dec_pic_params_t *ps_pps; + dec_seq_params_t *ps_sps; + const UWORD16 *pu2_quant_scale_y; + const UWORD16 *pu2_quant_scale_u; + const UWORD16 *pu2_quant_scale_v; + UWORD16 u2_mbx; + UWORD16 u2_mby; + + UWORD16 u2_frm_wd_y; /** Width for luma buff */ + UWORD16 u2_frm_ht_y; /** Height for luma buff */ + UWORD16 u2_frm_wd_uv; /** Width for chroma buff */ + UWORD16 u2_frm_ht_uv; /** Height for chroma buff */ + UWORD16 u2_frm_wd_in_mbs; /** Frame width expressed in MB units */ + UWORD16 u2_frm_ht_in_mbs; /** Frame height expressed in MB units */ + WORD32 i4_submb_ofst; /** Offset in subMbs from the top left edge */ + /* Pointer to colocated Zero frame Image, will be used in B_DIRECT mode */ + /* colZeroFlag | // 0th bit + field_flag | // 1st bit + XX | // 2:3 bit don't cares + subMbMode | // 4:5 bit + MbMode | // 6:7 bit */ + + UWORD8 *pu1_col_zero_flag; + + UWORD16 u2_pic_wd; /** Width of the picture being decoded */ + UWORD16 u2_pic_ht; /** Height of the picture being decoded */ + + UWORD8 u1_first_nal_in_pic; + UWORD8 u1_mb_ngbr_availablity; + UWORD8 u1_ref_idxl0_active_minus1; + UWORD8 u1_qp; + UWORD8 u1_qp_y_div6; + UWORD8 u1_qp_u_div6; + UWORD8 u1_qp_y_rem6; + UWORD8 u1_qp_u_rem6; + + /*********************************/ + /* configurable mb-group numbers */ + /* very critical to the decoder */ + /*********************************/ + /************************************************************/ + /* MB_GROUP should be a multiple of 2 */ + /************************************************************/ + UWORD8 u1_recon_mb_grp; + UWORD8 u1_recon_mb_grp_pair; + /* Variables to handle Cabac */ + decoding_envirnoment_t s_cab_dec_env; /* < Structure for decoding_envirnoment_t */ + /* These things need to be updated at each MbLevel */ + WORD8 i1_next_ctxt_idx; /* < next Ctxt Index */ + UWORD8 u1_currB_type; + WORD8 i1_prev_mb_qp_delta; /* Prev MbQpDelta */ + UWORD8 u1_nal_unit_type; + + ctxt_inc_mb_info_t *p_ctxt_inc_mb_map; /* Pointer to ctxt_inc_mb_info_t map */ + ctxt_inc_mb_info_t *p_left_ctxt_mb_info; /* Pointer to left ctxt_inc_mb_info_t */ + ctxt_inc_mb_info_t *p_top_ctxt_mb_info; /* Pointer to top ctxt_inc_mb_info_t */ + ctxt_inc_mb_info_t *ps_curr_ctxt_mb_info; /* Pointer to current ctxt_inc_mb_info_t */ + ctxt_inc_mb_info_t *ps_def_ctxt_mb_info; /* Pointer to default ctxt_inc_mb_info_t */ + + /* mv contexts for mv decoding using cabac */ + //UWORD8 u1_top_mv_ctxt_inc[4][4]; + /* Dimensions for u1_left_mv_ctxt_inc_arr is [2][4][4] for Mbaff case */ + UWORD8 u1_left_mv_ctxt_inc_arr[2][4][4]; + UWORD8 (*pu1_left_mv_ctxt_inc)[4]; + + UWORD8 u1_sub_mb_num; + UWORD8 u1_B; /** if B slice u1_B = 1 else 0 */ + WORD16 i2_only_backwarddma_info_idx; + mv_pred_t *ps_mv; /** Pointer to the MV bank array */ + mv_pred_t *ps_mv_bank_cur; /** Pointer to the MV bank array */ + mv_pred_t s_default_mv_pred; /** Structure containing the default values + for MV predictor */ + + pred_info_t *ps_pred; /** Stores info to cfg MC */ + pred_info_t *ps_pred_start; + + UWORD32 u4_pred_info_idx; + pred_info_pkd_t *ps_pred_pkd; + pred_info_pkd_t *ps_pred_pkd_start; + UWORD32 u4_pred_info_pkd_idx; + UWORD8 *pu1_ref_buff; /** Destination buffer for DMAs */ + UWORD32 u4_dma_buf_idx; + + UWORD8 *pu1_y; + UWORD8 *pu1_u; + UWORD8 *pu1_v; + + WORD16 *pi2_y_coeff; + UWORD8 *pu1_inv_scan; + + /** + * Pointer frame level TU subblock coeff data + */ + void *pv_pic_tu_coeff_data; + + /** + * Pointer to TU subblock coeff data and number of subblocks and scan idx + * Incremented each time a coded subblock is processed + * + */ + void *pv_parse_tu_coeff_data; + + void *pv_proc_tu_coeff_data; + + WORD16 *pi2_coeff_data; + + cavlc_cntxt_t s_cavlc_ctxt; + + UWORD32 u4_n_leftY[2]; + UWORD32 u4_n_left_cr[2]; + UWORD32 u4_n_left_temp_y; + + UWORD8 pu1_left_nnz_y[4]; + UWORD8 pu1_left_nnz_uv[4]; + UWORD32 u4_n_left_temp_uv; + /***************************************************************************/ + /* Base pointer to all the cabac contexts */ + /***************************************************************************/ + bin_ctxt_model_t *p_cabac_ctxt_table_t; + + /***************************************************************************/ + /* cabac context pointers for every SE mapped into in p_cabac_ctxt_table_t */ + /***************************************************************************/ + bin_ctxt_model_t *p_mb_type_t; + bin_ctxt_model_t *p_mb_skip_flag_t; + bin_ctxt_model_t *p_sub_mb_type_t; + bin_ctxt_model_t *p_mvd_x_t; + bin_ctxt_model_t *p_mvd_y_t; + bin_ctxt_model_t *p_ref_idx_t; + bin_ctxt_model_t *p_mb_qp_delta_t; + bin_ctxt_model_t *p_intra_chroma_pred_mode_t; + bin_ctxt_model_t *p_prev_intra4x4_pred_mode_flag_t; + bin_ctxt_model_t *p_rem_intra4x4_pred_mode_t; + bin_ctxt_model_t *p_mb_field_dec_flag_t; + bin_ctxt_model_t *p_cbp_luma_t; + bin_ctxt_model_t *p_cbp_chroma_t; + bin_ctxt_model_t *p_cbf_t[NUM_CTX_CAT]; + bin_ctxt_model_t *p_significant_coeff_flag_t[NUM_CTX_CAT]; + bin_ctxt_model_t *p_coeff_abs_level_minus1_t[NUM_CTX_CAT]; + + UWORD32 u4_num_pmbair; /** MB pair number */ + mv_pred_t *ps_mv_left; /** Pointer to left motion vector bank */ + mv_pred_t *ps_mv_top_left; /** Pointer to top left motion vector bank */ + mv_pred_t *ps_mv_top_right; /** Pointer to top right motion vector bank */ + + UWORD8 *pu1_left_yuv_dc_csbp; + + /* c64x_map.inc takes care of only this part + If you change/add any members above this, + modify c64x_map.inc accordingly */ + + void **pp_ext_g_table_ptr; + + deblkmb_neighbour_t deblk_left_mb[2]; + deblkmb_neighbour_t *ps_deblk_top_mb; + neighbouradd_t (*ps_left_mvpred_addr)[2]; /* Left MvPred Address Ping Pong*/ +// neighbouradd_t *ps_topMvPredAdd; + + /***************************************************************************/ + /* Ref_idx contexts are stored in the following way */ + /* Array Idx 0,1 for reference indices in Forward direction */ + /* Array Idx 2,3 for reference indices in backward direction */ + /***************************************************************************/ + + /* Dimensions for u1_left_ref_ctxt_inc_arr is [2][4] for Mbaff:Top and Bot */ + WORD8 i1_left_ref_idx_ctx_inc_arr[2][4]; + WORD8 *pi1_left_ref_idx_ctxt_inc; + + /*************************************************************************/ + /* Arrangnment of DC CSBP */ + /* bits: b7 b6 b5 b4 b3 b2 b1 b0 */ + /* CSBP: x x x x x Vdc Udc Ydc */ + /*************************************************************************/ + /*************************************************************************/ + /* Points either to u1_yuv_dc_csbp_topmb or u1_yuv_dc_csbp_bot_mb */ + /*************************************************************************/ + UWORD8 u1_yuv_dc_csbp_topmb; + UWORD8 u1_yuv_dc_csbp_bot_mb; + + /* DMA SETUP */ + tfr_ctxt_t s_tran_addrecon_parse; + tfr_ctxt_t s_tran_addrecon; + + /* slice Header Simplification */ + UWORD8 u1_pr_sl_type; + UWORD8 u1_sl_typ_5_9; + WORD32 i4_frametype; + UWORD32 u4_app_disp_width; + WORD32 i4_error_code; + UWORD8 u1_first_pb_nal_in_pic; + UWORD32 u4_bitoffset; + + /* Variables added to handle field pics */ + + UWORD8 u1_second_field; + WORD32 i4_pic_type; + WORD32 i4_content_type; + WORD32 i4_decode_header; + WORD32 i4_header_decoded; + UWORD32 u4_total_frames_decoded; + + ctxt_inc_mb_info_t *ps_left_mb_ctxt_info; /* structure containing the left MB's + context info, incase of Mbaff */ + pocstruct_t s_prev_pic_poc; + pocstruct_t s_cur_pic_poc; + WORD32 i4_cur_display_seq; + WORD32 i4_prev_max_display_seq; + WORD32 i4_max_poc; + deblk_mb_t *ps_cur_deblk_mb; + + /* Pointers to local scratch buffers */ + deblk_mb_t *ps_deblk_pic; + + /* Pointers to Picture Buffers (Given by BufAPI Lib) */ + struct pic_buffer_t *ps_cur_pic; /** Pointer to Current picture buffer */ + + /* Scratch Picture Buffers (Given by BufAPI Lib) */ + struct pic_buffer_t s_cur_pic; + + /* Current Slice related information */ + volatile UWORD16 u2_cur_slice_num; + volatile UWORD16 u2_cur_slice_num_dec_thread; + + /* Variables needed for Buffer API handling */ + UWORD8 u1_nal_buf_id; + UWORD8 u1_pic_buf_id; + UWORD8 u1_pic_bufs; + + WORD16 *pi2_pred1; //[441]; /** Temp predictor buffer for MC */ + /* Pointer to refernce Pic buffers list, 0:fwd, 1:bwd */ + pic_buffer_t **ps_ref_pic_buf_lx[2]; + /* refIdx to POC mapping */ + void **ppv_map_ref_idx_to_poc; + UWORD32 *pu4_defI_wts_ofsts; + UWORD32 *pu4_wts_ofsts_mat; + UWORD32 *pu4_wt_ofsts; + UWORD32 *pu4_mbaff_wt_mat; + /* Function pointers to read Params common to CAVLC and CABAC */ + WORD32 (*pf_parse_inter_mb)(struct _DecStruct * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD8 u1_mb_num, + UWORD8 u1_num_mbsNby2); + WORD32 (*pf_mvpred_ref_tfr_nby2mb)(struct _DecStruct * ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbsNby2); + + WORD32 (*pf_parse_inter_slice)(struct _DecStruct * ps_dec, + dec_slice_params_t * ps_slice, + UWORD16 u2_first_mb_in_slice); + + UWORD32 (*pf_get_mb_info)(struct _DecStruct * ps_dec, + const UWORD16 u2_cur_mb_address, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mbskip_run); + + /* Variables for Decode Buffer Management */ + dpb_manager_t *ps_dpb_mgr; + dpb_commands_t *ps_dpb_cmds; + + /* Variables Required for N MB design */ + dec_mb_info_t *ps_nmb_info; + + UWORD8 *pu1_y_intra_pred_line; + UWORD8 *pu1_u_intra_pred_line; + UWORD8 *pu1_v_intra_pred_line; + + UWORD8 *pu1_cur_y_intra_pred_line; + UWORD8 *pu1_cur_u_intra_pred_line; + UWORD8 *pu1_cur_v_intra_pred_line; + + UWORD8 *pu1_cur_y_intra_pred_line_base; + UWORD8 *pu1_cur_u_intra_pred_line_base; + UWORD8 *pu1_cur_v_intra_pred_line_base; + + UWORD8 *pu1_prev_y_intra_pred_line; + UWORD8 *pu1_prev_u_intra_pred_line; + UWORD8 *pu1_prev_v_intra_pred_line; + + UWORD32 u4_intra_pred_line_ofst; + + /* Scratch ping reconstruction pointers for Y U V */ + UWORD8 *pu1_y_scratch[2]; + UWORD8 *pu1_u_scratch[2]; + UWORD8 *pu1_v_scratch[2]; + UWORD8 u1_yuv_scratch_idx; + UWORD8 u1_not_wait_rec; + UWORD8 u1_res_changed; + + UWORD8 *pu1_yleft; /** Left Y pointer, used for intra-pred */ + UWORD8 *pu1_uleft; /** Left U pointer, used for intra-pred */ + UWORD8 *pu1_vleft; /** Left V pointer, used for intra-pred */ + UWORD8 u1_y_topleft[2]; /** Left Y pointer, used for intra-pred */ + UWORD8 u1_u_topleft[2]; /** Left U pointer, used for intra-pred */ + UWORD8 u1_v_topleft[2]; /** Left V pointer, used for intra-pred */ + UWORD16 u2_mb_group_cols_y; /** Number of Y pixels in the N MB group */ + UWORD16 u2_mb_group_cols_cr; /** Number of U/V pixels in the N MB group */ + UWORD16 u2_mb_group_cols_y1; /** Number of Y pixels in the N MB group */ + UWORD16 u2_mb_group_cols_cr1; /** Number of U/V pixels in the N MB group */ + + mv_pred_t *ps_mv_cur; /** pointer to current motion vector bank */ + mv_pred_t *ps_mv_top; /** pointer to top motion vector bank */ + mv_pred_t *ps_mv_top_right2;/** Pointer to top right motion vector bank */ + mv_pred_t *ps_mv_p[2]; /** Scratch ping motion vector bank */ + mv_pred_t *ps_mv_top_p[MV_SCRATCH_BUFS]; /** Scratch top pong motion vector bank */ + UWORD8 u1_mv_top_p; + + deblk_mb_t *ps_deblk_mbn; + deblk_mb_t *ps_deblk_mbn_dec_thrd;/*pointer used by parsing when spearaet_parse is 1*/ + deblk_mb_t *ps_deblk_mbn_curr; + deblk_mb_t *ps_deblk_mbn_prev; + + UWORD8 *pu1_temp_mc_buffer; + + struct _sei *ps_sei; + UWORD8 u1_pic_struct_copy; + /* Variables required for cropping */ + UWORD16 u2_disp_width; + UWORD16 u2_disp_height; + UWORD16 u2_crop_offset_y; + UWORD16 u2_crop_offset_uv; + + /* Variable required to get presentation time stamp through application */ + UWORD32 u4_pts; + + /* Variables used for gaps in frame number */ + UWORD16 u2_prev_ref_frame_num; + UWORD8 u1_vert_up_scale_flag; + iv_mem_rec_t *ps_mem_tab; + + UWORD16 u2_wait_id; + + void *pi4_ctxt_save_register; + void *pi4_ctxt_save_register_dec; + + UWORD8 u1_mb_idx; + struct pic_buffer_t *ps_col_pic; + void (*pf_parse_mvdirect)(struct _DecStruct*, + struct pic_buffer_t*, + directmv_t*, + UWORD8, + WORD32, + dec_mb_info_t *); + void *pv_dec_out; + void *pv_dec_in; + void *pv_scratch_sps_pps; /*used temeporarily store sps/ spps while parsing*/ + + /* state pointers to mb and partition information */ + parse_pmbarams_t *ps_parse_mb_data; + parse_part_params_t *ps_parse_part_params; + + /* scratch pointers to mb and partition information */ + parse_part_params_t *ps_part; + + UWORD8 u1_max_dec_frame_buffering; + pad_mgr_t s_pad_mgr; + UWORD8 (*pf_mvpred)(struct _DecStruct *ps_dec, + struct _DecMbInfo *ps_cur_mb_info, + mv_pred_t *ps_mv_pred, + mv_pred_t *ps_mv_nmb, + mv_pred_t *ps_mv_ntop, + UWORD8 u1_sub_mb_num, + UWORD8 uc_mb_part_width, + UWORD8 uc_lxstart, + UWORD8 uc_lxend, + UWORD8 u1_mb_mc_mode); + void (*pf_compute_bs)(struct _DecStruct * ps_dec, + struct _DecMbInfo * ps_cur_mb_info, + const UWORD16 u2_mbxn_mb); + UWORD8 u1_init_dec_flag; + prev_seq_params_t s_prev_seq_params; + UWORD8 u1_cur_mb_fld_dec_flag; /* current Mb fld or Frm */ + + code_overlay_ctxt_t s_code_overlay_ctxt; + UWORD8 u1_code_overlay; + +// WORD8 *pi1_cur_predmodes; + WORD8 pi1_left_pred_mode[8]; + UWORD8 u1_topleft_mb_fld; + UWORD8 u1_topleft_mbtype; + UWORD8 u1_topleft_mb_fld_bot; + UWORD8 u1_topleft_mbtype_bot; + UWORD8 u1_deblk_mb_grp; + WORD16 i2_prev_slice_mbx; + WORD16 i2_prev_slice_mby; + UWORD16 u2_top_left_mask; + UWORD16 u2_top_right_mask; + dec_err_status_t * ps_dec_err_status; + + UWORD32 *pu4_sos_signal; + UWORD8 u1_mb_idx_mv; + UWORD16 u2_mv_2mb[2]; + UWORD32 u4_ref_buf_size; + UWORD32 u4_packet_cnt; + /* to remember the i4_status & input parameters from the sample app */ + void *pv_dec_status; // itt_dec_status_t void pointer */ + void *pv_dec_params; // itt_dec_prms_t void pointer + void *pv_app_ctxt; + UWORD32 u4_skip_frm_mask; + void *pv_fmt_con_ctxt; + /* for the parallel format conversion */ + UWORD8 *pu1_frmt_conv_y[3]; + UWORD8 *pu1_frmt_conv_u[3]; + UWORD8 *pu1_frmt_conv_v[3]; + UWORD8 *pu1_deblk_scr; + UWORD32 u4_deblk_scr_sz; + + /* variable for finding the no.of mbs decoded in the current picture */ + UWORD16 u2_total_mbs_coded; + /* member added for supporting fragmented annex - B */ +// frg_annex_read_t s_frag_annex_read; + /* added for vui_t, sei support*/ + WORD32 i4_vui_frame_rate; + /* To Store the value of ref_idx_active for previous slice */ + /* useful in error handling */ + UWORD8 u1_num_ref_idx_lx_active_prev; + /* Flag added to come out of process call in annex-b if&if frame is decoded */ + /* presence of access unit delimters and pps and sps */ + UWORD8 u1_frame_decoded_flag; + + /* To keep track of whether the last picture was decoded or not */ + /* in case of skip mode set by the application */ + UWORD8 u1_last_pic_not_decoded; + UWORD32 *pu4_return_remaining_bufs; + + /* Used for disabling deblocking of non-reference pictures */ + WORD32 i4_set_low_complexity_mode; + WORD32 i4_disable_deblock; + + WORD32 e_dec_status; + UWORD32 u4_num_fld_in_frm; + + /* Function pointer for 4x4 residual cavlc parsing based on total coeff */ + WORD32 (*pf_cavlc_4x4res_block[3])(UWORD32 u4_isdc, + UWORD32 u4_total_coeff_trail_one, /**TotalCoefficients<<16+trailingones*/ + dec_bit_stream_t *ps_bitstrm); + + /* Function pointer array for interpolate functions in called from motion compensattion module */ + void (*p_mc_interpolate_x_y[16][3])(UWORD8*, + UWORD8*, + UWORD8*, + UWORD8, + UWORD16, + UWORD16, + UWORD8); + + /**************************************************************************/ + /* Function pointer for 4x4 totalcoeff, trlone and residual cavlc parsing */ + /* based on u4_n (neigbourinng nnz average) */ + /* These point to two functions depending on (u4_n > 7) and (u4_n <= 7) */ + /**************************************************************************/ + WORD32 (*pf_cavlc_parse4x4coeff[2])(WORD16 *pi2_coeff_block, + UWORD32 u4_isdc, /* is it a DC block */ + WORD32 u4_n, + struct _DecStruct *ps_dec, /** Decoder Parameters */ + UWORD32 *pu4_total_coeff); + + /**************************************************************************/ + /* Function pointer for luma 8x8block cavlc parsing based on top and left */ + /* neigbour availability. */ + /**************************************************************************/ + WORD32 (*pf_cavlc_parse_8x8block[4])(WORD16 *pi2_coeff_block, + UWORD32 u4_sub_block_strd, + UWORD32 u4_isdc, + struct _DecStruct *ps_dec, + UWORD8 *pu1_top_nnz, + UWORD8 *pu1_left_nnz, + UWORD8 u1_tran_form8x8, + UWORD8 u1_mb_field_decodingflag, + UWORD32 *pu4_csbp); + + /**************************************************************************/ + /* Ping pong top and current rows of mb neigbour_params */ + /**************************************************************************/ + mb_neigbour_params_t *ps_nbr_mb_row; + mb_neigbour_params_t *ps_cur_mb_row; + mb_neigbour_params_t *ps_top_mb_row; + + /**************************************************************************/ + /* Function pointer for 16x16 and non16x16 Bs1 calculations depending on */ + /* P and B slice. */ + /***************************************************************************/ + void (*pf_fill_bs1[2][2])(mv_pred_t *ps_cur_mv_pred, + mv_pred_t *ps_top_mv_pred, + void **ppv_map_ref_idx_to_poc, + UWORD32 *pu4_bs_table, /* pointer to the BsTable array */ + mv_pred_t *ps_leftmost_mv_pred, + neighbouradd_t *ps_left_addr, + void **u4_pic_addrress, + WORD32 i4_ver_mvlimit); + + void (*pf_fill_bs_xtra_left_edge[2])(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_left_mb_t_csbp, /* left mbpair's top csbp */ + WORD32 u4_left_mb_b_csbp, /* left mbpair's bottom csbp*/ + WORD32 u4_cur_mb_csbp, /* csbp of current mb */ + UWORD32 u4_cur_mb_bot /* is top or bottom mb */ + + ); + /* Function pointer array for BP and MP functions for MC*/ + void (*p_motion_compensate)(struct _DecStruct * ps_dec, + dec_mb_info_t *ps_cur_mb_info); + + + void (*p_mc_dec_thread)(struct _DecStruct * ps_dec, dec_mb_info_t *ps_cur_mb_info); + + /* Function pointer array for BP and MP functions for formMbPartInfo*/ + + WORD32 (*p_form_mb_part_info)(pred_info_pkd_t *ps_pred_pkd, + struct _DecStruct * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info); + + WORD32 (*p_form_mb_part_info_thread)(pred_info_pkd_t *ps_pred_pkd, + struct _DecStruct * ps_dec, + UWORD16 u2_mb_x, + UWORD16 u2_mb_y, + WORD32 mb_index, + dec_mb_info_t *ps_cur_mb_info); + + + /* Required for cabac mbaff bottom mb */ + UWORD32 u4_next_mb_skip; + + void (*p_DeblockPicture[2])(struct _DecStruct *); + + /* ! */ + UWORD32 u4_ts; + UWORD8 u1_flushfrm; + + /* Output format sent by the application */ + UWORD8 u1_chroma_format; + UWORD8 u1_pic_decode_done; + UWORD32 u4_level_at_init; + UWORD32 u4_width_at_init; + UWORD32 u4_height_at_init; + WORD32 init_done; + WORD32 process_called; + + /******************************************/ + /* For the high profile related variables */ + /******************************************/ + high_profile_tools_t s_high_profile; + /* CBCR */ + UWORD8 u1_qp_v_div6; + UWORD8 u1_qp_v_rem6; + /* + * TO help solve the dangling field case. + * Check for the previous frame number and the current frame number. + */ + UWORD16 u2_prv_frame_num; + UWORD8 u1_top_bottom_decoded; + UWORD8 u1_dangling_field; + + /* + * For Low Memory case + */ + UWORD32 u4_num_ref_frames_at_init; + UWORD32 u4_num_reorder_frames_at_init; + UWORD32 u4_num_extra_disp_bufs_at_init; + UWORD32 u4_num_disp_bufs_requested; + WORD32 i4_display_delay; + UWORD32 u4_slice_start_code_found; + + UWORD32 u4_mb_level_deblk; + UWORD32 u4_use_intrapred_line_copy; + UWORD32 u4_num_mbs_prev_nmb; + UWORD32 u4_app_deblk_disable_level; + UWORD32 u4_app_disable_deblk_frm; + WORD32 i4_app_skip_mode; + WORD32 i4_mv_frac_mask; + + disp_buf_t disp_bufs[MAX_DISP_BUFS_NEW]; + UWORD32 u4_disp_buf_mapping[MAX_DISP_BUFS_NEW]; + UWORD32 u4_disp_buf_to_be_freed[MAX_DISP_BUFS_NEW]; + UWORD32 u4_share_disp_buf; + UWORD32 u4_num_disp_bufs; + UWORD32 u4_prev_nal_skipped; + UWORD32 u4_return_to_app; + WORD32 i4_dec_skip_mode; + + UWORD32 u4_bs_deblk_thread_created; + volatile UWORD32 u4_start_bs_deblk; + void *pv_bs_deblk_thread_handle; + + UWORD32 u4_cur_bs_mb_num; + UWORD32 u4_bs_cur_slice_num_mbs; + UWORD32 u4_cur_slice_bs_done; + UWORD32 u4_cur_deblk_mb_num; + volatile UWORD16 u2_cur_slice_num_bs; + + UWORD32 u4_deblk_mb_x; + UWORD32 u4_deblk_mb_y; + deblk_mb_t *ps_cur_deblk_thrd_mb; + + + iv_yuv_buf_t s_disp_frame_info; + UWORD32 u4_fmt_conv_num_rows; + UWORD32 u4_fmt_conv_cur_row; + ivd_out_bufdesc_t *ps_out_buffer; + ivd_get_display_frame_op_t s_disp_op; + UWORD32 u4_stop_threads; + UWORD32 u4_output_present; + + volatile UWORD16 cur_dec_mb_num; + volatile UWORD16 u2_cur_mb_addr; + WORD16 i2_dec_thread_mb_y; + + UWORD8 u1_separate_parse; +// 0: slice parse not started, 1: slice decode can start, 2: slice in error + volatile UWORD32 u4_start_frame_decode; + UWORD32 u4_dec_thread_created; + void *pv_dec_thread_handle; + volatile UWORD8 *pu1_dec_mb_map; + volatile UWORD8 *pu1_recon_mb_map; + volatile UWORD16 *pu2_slice_num_map; + dec_slice_struct_t *ps_dec_slice_buf; + void *pv_map_ref_idx_to_poc_buf; + dec_mb_info_t *ps_frm_mb_info; + volatile dec_slice_struct_t * volatile ps_parse_cur_slice; + volatile dec_slice_struct_t * volatile ps_decode_cur_slice; + volatile dec_slice_struct_t * volatile ps_computebs_cur_slice; + UWORD32 u4_cur_slice_decode_done; + UWORD32 u4_extra_mem_used; + + UWORD32 u4_first_slice_in_pic; + UWORD32 u4_num_cores; + IVD_ARCH_T e_processor_arch; + IVD_SOC_T e_processor_soc; + + /** + * Pictures that are are degraded + * 0 : No degrade + * 1 : Only on non-reference frames + * 2 : Use interval specified by u4_nondegrade_interval + * 3 : All non-key frames + * 4 : All frames + */ + WORD32 i4_degrade_pics; + + /** + * Interval for pictures which are completely decoded without any degradation + */ + WORD32 i4_nondegrade_interval; + + /** + * bit position (lsb is zero): Type of degradation + * 1 : Disable deblocking + * 2 : Faster inter prediction filters + * 3 : Fastest inter prediction filters + */ + WORD32 i4_degrade_type; + + /** Degrade pic count, Used to maintain the interval between non-degraded pics + * + */ + WORD32 i4_degrade_pic_cnt; + + fmt_conv_part_t as_fmt_conv_part[2]; + UWORD32 u4_fmt_conv_in_process; + UWORD32 u4_pic_buf_got; + UWORD16 u2_mb_skip_error; + volatile UWORD16 u2_skip_deblock; + + /** + * Col flag and mv pred buffer manager + */ + void *pv_mv_buf_mgr; + + /** + * Picture buffer manager + */ + void *pv_pic_buf_mgr; + + /** + * Display buffer manager + */ + void *pv_disp_buf_mgr; + + void *apv_buf_id_pic_buf_map[MAX_DISP_BUFS_NEW]; + + UWORD8 au1_pic_buf_id_mv_buf_id_map[MAX_DISP_BUFS_NEW]; + + UWORD8 au1_pic_buf_ref_flag[MAX_DISP_BUFS_NEW]; + + ih264_default_weighted_pred_ft *pf_default_weighted_pred_luma; + + ih264_default_weighted_pred_ft *pf_default_weighted_pred_chroma; + + ih264_weighted_pred_ft *pf_weighted_pred_luma; + + ih264_weighted_pred_ft *pf_weighted_pred_chroma; + + ih264_weighted_bi_pred_ft *pf_weighted_bi_pred_luma; + + ih264_weighted_bi_pred_ft *pf_weighted_bi_pred_chroma; + + ih264_pad *pf_pad_top; + ih264_pad *pf_pad_bottom; + ih264_pad *pf_pad_left_luma; + ih264_pad *pf_pad_left_chroma; + ih264_pad *pf_pad_right_luma; + ih264_pad *pf_pad_right_chroma; + + ih264_inter_pred_chroma_ft *pf_inter_pred_chroma; + + ih264_inter_pred_luma_ft *apf_inter_pred_luma[16]; + + ih264_intra_pred_luma_ft *apf_intra_pred_luma_16x16[4]; + + ih264_intra_pred_luma_ft *apf_intra_pred_luma_8x8[9]; + + ih264_intra_pred_luma_ft *apf_intra_pred_luma_4x4[9]; + + ih264_intra_pred_ref_filtering_ft *pf_intra_pred_ref_filtering; + + ih264_intra_pred_chroma_ft *apf_intra_pred_chroma[4]; + + ih264_iquant_itrans_recon_ft *pf_iquant_itrans_recon_luma_4x4; + + ih264_iquant_itrans_recon_ft *pf_iquant_itrans_recon_luma_4x4_dc; + + ih264_iquant_itrans_recon_ft *pf_iquant_itrans_recon_luma_8x8; + + ih264_iquant_itrans_recon_ft *pf_iquant_itrans_recon_luma_8x8_dc; + + ih264_iquant_itrans_recon_chroma_ft *pf_iquant_itrans_recon_chroma_4x4; + + ih264_iquant_itrans_recon_chroma_ft *pf_iquant_itrans_recon_chroma_4x4_dc; + + ih264_ihadamard_scaling_ft *pf_ihadamard_scaling_4x4; + + /** + * deblock vertical luma edge with blocking strength 4 + */ + ih264_deblk_edge_bs4_ft *pf_deblk_luma_vert_bs4; + + /** + * deblock vertical luma edge with blocking strength less than 4 + */ + ih264_deblk_edge_bslt4_ft *pf_deblk_luma_vert_bslt4; + + /** + * deblock vertical luma edge with blocking strength 4 for mbaff + */ + ih264_deblk_edge_bs4_ft *pf_deblk_luma_vert_bs4_mbaff; + + /** + * deblock vertical luma edge with blocking strength less than 4 for mbaff + */ + ih264_deblk_edge_bslt4_ft *pf_deblk_luma_vert_bslt4_mbaff; + + /** + * deblock vertical chroma edge with blocking strength 4 + */ + ih264_deblk_chroma_edge_bs4_ft *pf_deblk_chroma_vert_bs4; + + /** + * deblock vertical chroma edge with blocking strength less than 4 + */ + ih264_deblk_chroma_edge_bslt4_ft *pf_deblk_chroma_vert_bslt4; + + /** + * deblock vertical chroma edge with blocking strength 4 for mbaff + */ + ih264_deblk_chroma_edge_bs4_ft *pf_deblk_chroma_vert_bs4_mbaff; + + /** + * deblock vertical chroma edge with blocking strength less than 4 for mbaff + */ + ih264_deblk_chroma_edge_bslt4_ft *pf_deblk_chroma_vert_bslt4_mbaff; + + /** + * deblock horizontal luma edge with blocking strength 4 + */ + ih264_deblk_edge_bs4_ft *pf_deblk_luma_horz_bs4; + + /** + * deblock horizontal luma edge with blocking strength less than 4 + */ + ih264_deblk_edge_bslt4_ft *pf_deblk_luma_horz_bslt4; + + /** + * deblock horizontal chroma edge with blocking strength 4 + */ + ih264_deblk_chroma_edge_bs4_ft *pf_deblk_chroma_horz_bs4; + + /** + * deblock horizontal chroma edge with blocking strength less than 4 + */ + ih264_deblk_chroma_edge_bslt4_ft *pf_deblk_chroma_horz_bslt4; + + +} dec_struct_t; + +#endif /* _H264_DEC_STRUCTS_H */ diff --git a/decoder/ih264d_tables.c b/decoder/ih264d_tables.c new file mode 100755 index 0000000..ddca2fb --- /dev/null +++ b/decoder/ih264d_tables.c @@ -0,0 +1,872 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_tables.c + * + * \brief + * Defination of all tables used by h264 decoder + * + * \date + * 17/09/2004 + * + * \author MA + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_defs.h" + +const UWORD8 gau1_ih264d_qp_scale_cr[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 29, 30, 31, 32, 32, 33, 34, 34, 35, 35, 36, 36, 37, 37, 37, 38, 38, 38, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39 }; +const UWORD8 gau1_ih264d_alpha_table[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 15, 17, 20, 22, 25, 28, 32, 36, + 40, 45, 50, 56, 63, 71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; +const UWORD8 gau1_ih264d_beta_table[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, + 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18 }; + +const UWORD8 gau1_ih264d_clip_table[][4] = + { + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 0 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 1, 1 }, + { 0, 0, 1, 1 }, + { 0, 1, 1, 1 }, + { 0, 1, 1, 1 }, + { 0, 1, 1, 1 }, + { 0, 1, 1, 1 }, + { 0, 1, 1, 2 }, + { 0, 1, 1, 2 }, + { 0, 1, 1, 2 }, + { 0, 1, 1, 2 }, + { 0, 1, 2, 3 }, + { 0, 1, 2, 3 }, + { 0, 2, 2, 3 }, + { 0, 2, 2, 4 }, + { 0, 2, 3, 4 }, + { 0, 2, 3, 4 }, + { 0, 3, 3, 5 }, + { 0, 3, 4, 6 }, + { 0, 3, 4, 6 }, + { 0, 4, 5, 7 }, + { 0, 4, 5, 8 }, + { 0, 4, 6, 9 }, + { 0, 5, 7, 10 }, + { 0, 6, 8, 11 }, + { 0, 6, 8, 13 }, + { 0, 7, 10, 14 }, + { 0, 8, 11, 16 }, + { 0, 9, 12, 18 }, + { 0, 10, 13, 20 }, + { 0, 11, 15, 23 }, + { 0, 13, 17, 25 }, + + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 }, + { 0, 13, 17, 25 } + + }; +const UWORD8 gau1_ih264d_clip_table_deblock[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 }; + +/****************DEBLOCKING TABLES ENDS*******************/ + +/*************************************************************/ +/* BS CALCULATION TABLES */ +/*************************************************************/ +UWORD32 const gau4_ih264d_packed_bs2[32] = + { + /*************************************************************/ + /* BS TABLES FOR NORMAL EDGES */ + /*************************************************************/ + 0x00000000, + 0x02000000, 0x00020000, 0x02020000, 0x00000200, 0x02000200, 0x00020200, + 0x02020200, 0x00000002, 0x02000002, 0x00020002, 0x02020002, 0x00000202, + 0x02000202, 0x00020202, 0x02020202, + + /*************************************************************/ + /* BS TABLES FOR XTRA LEFT MB EDGES IN MBAFF CASE */ + /*************************************************************/ + 0x01010101, + 0x02010101, 0x01020101, 0x02020101, 0x01010201, 0x02010201, 0x01020201, + 0x02020201, 0x01010102, 0x02010102, 0x01020102, 0x02020102, 0x01010202, + 0x02010202, 0x01020202, 0x02020202, }; + +UWORD16 const gau2_ih264d_4x4_v2h_reorder[16] = + { 0x0000, 0x0001, 0x0010, 0x0011, 0x0100, 0x0101, 0x0110, 0x0111, 0x1000, + 0x1001, 0x1010, 0x1011, 0x1100, 0x1101, 0x1110, 0x1111 }; + +/****************SCALING TABLES STARTS *****************/ +const WORD16 gai2_ih264d_default_intra4x4[16] = + { 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42 }; + +const WORD16 gai2_ih264d_default_inter4x4[16] = + { 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34 }; + +const WORD16 gai2_ih264d_default_intra8x8[64] = + { 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, + 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, + 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, + 36, 36, 36, 38, 38, 38, 40, 40, 42 }; + +const WORD16 gai2_ih264d_default_inter8x8[64] = + { 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, + 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, + 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, + 30, 30, 30, 32, 32, 32, 33, 33, 35 }; + +const WORD16 gai2_ih264d_flat_4x4[16] = + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + +const WORD16 gai2_ih264d_flat_8x8[64] = + { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + +/****************SCALING TABLES ENDS *****************/ + +/*Inverse scan tables for individual 4x4 blocks of 8x8 transform coeffs of CAVLC */ + +/* progressive */ + +const UWORD8 gau1_ih264d_inv_scan_prog8x8_cavlc[4][16] = + { + { 0, 9, 17, 18, 12, 40, 27, 7, 35, 57, 29, 30, 58, 38, 53, 47 }, /* for First subblock */ + { 1, 2, 24, 11, 19, 48, 20, 14, 42, 50, 22, 37, 59, 31, 60, 55 }, /* for second subblock */ + { 8, 3, 32, 4, 26, 41, 13, 21, 49, 43, 15, 44, 52, 39, 61, 62 }, /* for third subblock */ + { 16, 10, 25, 5, 33, 34, 6, 28, 56, 36, 23, 51, 45, 46, 54, 63 } /* for fourth subblock */ + }; + +const UWORD8 gau1_ih264d_inv_scan_int8x8_cavlc[4][16] = + { + { 0, 9, 2, 56, 18, 26, 34, 27, 35, 28, 36, 29, 45, 7, 54, 39 }, /* for First subblock */ + { 8, 24, 25, 33, 41, 11, 42, 12, 43, 13, 44, 14, 53, 15, 62, 47 }, /* for second subblock */ + { 16, 32, 40, 10, 49, 4, 50, 5, 51, 6, 52, 22, 61, 38, 23, 55 }, /* for third subblock */ + { 1, 17, 48, 3, 57, 19, 58, 20, 59, 21, 60, 37, 30, 46, 31, 63 } /* for fourth subblock */ + }; + +/*Inverse scan tables for individual 8x8 blocks of 8x8 transform coeffs of CABAC */ +/* progressive */ + +const UWORD8 gau1_ih264d_inv_scan_prog8x8_cabac[64] = + { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, + 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, + 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, + 60, 61, 54, 47, 55, 62, 63 }; + +/* interlace */ + +const UWORD8 gau1_ih264d_inv_scan_int8x8_cabac[64] = + { 0, 8, 16, 1, 9, 24, 32, 17, 2, 25, 40, 48, 56, 33, 10, 3, 18, 41, 49, 57, + 26, 11, 4, 19, 34, 42, 50, 58, 27, 12, 5, 20, 35, 43, 51, 59, 28, 13, 6, + 21, 36, 44, 52, 60, 29, 14, 22, 37, 45, 53, 61, 30, 7, 15, 38, 46, 54, 62, + 23, 31, 39, 47, 55, 63 }; + +/****************PARSING TABLES *******************/ +UWORD8 const gau1_ih264d_subblk_offset[16] = + { 8, 9, 12, 13, 10, 11, 14, 15, 16, 17, 20, 21, 18, 19, 22, 23 }; + +const UWORD8 gau1_ih264d_cbp_tab[6] = + { 0, 16, 32, 15, 31, 47 }; + +/** gives CBP value from codeword number, both for intra and inter */ + +const UWORD8 gau1_ih264d_cbp_table[48][2] = + { + { 47, 0 }, + { 31, 16 }, + { 15, 1 }, + { 0, 2 }, + { 23, 4 }, + { 27, 8 }, + { 29, 32 }, + { 30, 3 }, + { 7, 5 }, + { 11, 10 }, + { 13, 12 }, + { 14, 15 }, + { 39, 47 }, + { 43, 7 }, + { 45, 11 }, + { 46, 13 }, + { 16, 14 }, + { 3, 6 }, + { 5, 9 }, + { 10, 31 }, + { 12, 35 }, + { 19, 37 }, + { 21, 42 }, + { 26, 44 }, + { 28, 33 }, + { 35, 34 }, + { 37, 36 }, + { 42, 40 }, + { 44, 39 }, + { 1, 43 }, + { 2, 45 }, + { 4, 46 }, + { 8, 17 }, + { 17, 18 }, + { 18, 20 }, + { 20, 24 }, + { 24, 19 }, + { 6, 21 }, + { 9, 26 }, + { 22, 28 }, + { 25, 23 }, + { 32, 27 }, + { 33, 29 }, + { 34, 30 }, + { 36, 22 }, + { 40, 25 }, + { 38, 38 }, + { 41, 41 }, }; +/****************PARSING TABLES ENDS *******************/ + +/****************DECODE SLICE TABLES STARTS *******************/ +/*Definition of Tables needed by functions of this file */ +const UWORD8 gau1_ih264d_inv_scan[16] = + { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; + +const UWORD8 gau1_ih264d_inv_scan_fld[16] = + { 0, 4, 1, 8, 12, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 }; + +const UWORD8 gau1_ih264d_dequant_matrix[6][16] = +{ + { 10, 13, 10, 13, 13, 16, 13, 16, 10, 13, 10 ,13, 13, 16, 13, 16}, + { 11, 14, 11, 14, 14, 18, 14, 18, 11, 14, 11 ,14, 14, 18, 14, 18}, + { 13, 16, 13, 16, 16, 20, 16, 20, 13, 16, 13 ,16, 16, 20, 16, 20}, + { 14, 18, 14, 18, 18, 23, 18, 23, 14, 18, 14, 18, 18, 23, 18, 23}, + { 16, 20, 16, 20, 20, 25, 20, 25, 16, 20, 16, 20, 20, 25, 20, 25}, + { 18, 23, 18, 23, 23, 29, 23, 29, 18, 23, 18, 23, 23, 29, 23, 29} +}; + +const UWORD16 gau2_ih264_iquant_scale_4x4[6][16] = + { + { 10, 13, 10, 13, 13, 16, 13, 16, 10, 13, 10, 13, 13, 16, 13, 16 }, + { 11, 14, 11, 14, 14, 18, 14, 18, 11, 14, 11, 14, 14, 18, 14, 18 }, + { 13, 16, 13, 16, 16, 20, 16, 20, 13, 16, 13, 16, 16, 20, 16, 20 }, + { 14, 18, 14, 18, 18, 23, 18, 23, 14, 18, 14, 18, 18, 23, 18, 23 }, + { 16, 20, 16, 20, 20, 25, 20, 25, 16, 20, 16, 20, 20, 25, 20, 25 }, + { 18, 23, 18, 23, 23, 29, 23, 29, 18, 23, 18, 23, 23, 29, 23, 29 } }; + +const UWORD8 gau1_ih264d_dequant8x8_zigzag_cavlc[4][6][16] = + { + { + { 20, 18, 24, 32, 19, 19, 18, 19, 19, 18, 18, 24, + 24, 25, 24, 18 }, /* for First subblock */ + { 22, 19, 26, 35, 21, 21, 19, 21, 21, 19, 19, 26, + 26, 28, 26, 19 }, + { 26, 23, 31, 42, 24, 24, 23, 24, 24, 23, 23, 31, + 31, 33, 31, 23 }, + { 28, 25, 33, 45, 26, 26, 25, 26, 26, 25, 25, 33, + 33, 35, 33, 25 }, + { 32, 28, 38, 51, 30, 30, 28, 30, 30, 28, 28, 38, + 38, 40, 38, 28 }, + { 36, 32, 43, 58, 34, 34, 32, 34, 34, 32, 32, 43, + 43, 46, 43, 32 } }, + { + { 19, 25, 19, 18, 24, 25, 25, 24, 24, 32, 32, 19, + 18, 18, 19, 24 }, /* for second subblock */ + { 21, 28, 21, 19, 26, 28, 28, 26, 26, 35, 35, + 21, 19, 19, 21, 26 }, + { 24, 33, 24, 23, 31, 33, 33, 31, 31, 42, 42, + 24, 23, 23, 24, 31 }, + { 26, 35, 26, 25, 33, 35, 35, 33, 33, 45, 45, + 26, 25, 25, 26, 33 }, + { 30, 40, 30, 28, 38, 40, 40, 38, 38, 51, 51, + 30, 28, 28, 30, 38 }, + { 34, 46, 34, 32, 43, 46, 46, 43, 43, 58, 58, + 34, 32, 32, 34, 43 } }, + { + { 19, 19, 20, 20, 24, 18, 18, 24, 24, 18, 18, 19, + 25, 19, 18, 24 }, /* for third subblock */ + { 21, 21, 22, 22, 26, 19, 19, 26, 26, 19, 19, + 21, 28, 21, 19, 26 }, + { 24, 24, 26, 26, 31, 23, 23, 31, 31, 23, 23, + 24, 33, 24, 23, 31 }, + { 26, 26, 28, 28, 33, 25, 25, 33, 33, 25, 25, + 26, 35, 26, 25, 33 }, + { 30, 30, 32, 32, 38, 28, 28, 38, 38, 28, 28, + 30, 40, 30, 28, 38 }, + { 34, 34, 36, 36, 43, 32, 32, 43, 43, 32, 32, + 34, 46, 34, 32, 43 } }, + { + { 25, 24, 18, 19, 19, 25, 25, 19, 19, 20, 24, 24, + 18, 24, 32, 18 }, /* for fourth subblock */ + { 28, 26, 19, 21, 21, 28, 28, 21, 21, 22, 26, + 26, 19, 26, 35, 19 }, + { 33, 31, 23, 24, 24, 33, 33, 24, 24, 26, 31, + 31, 23, 31, 42, 23 }, + { 35, 33, 25, 26, 26, 35, 35, 26, 26, 28, 33, + 33, 25, 33, 45, 25 }, + { 40, 38, 28, 30, 30, 40, 40, 30, 30, 32, 38, + 38, 28, 38, 51, 28 }, + { 46, 43, 32, 34, 34, 46, 46, 34, 34, 36, 43, + 43, 32, 43, 58, 32 } } + + }; + +const UWORD16 gau1_ih264d_dequant8x8_cavlc[6][64] = + { + { 20, 19, 25, 19, 20, 19, 25, 19, 19, 18, 24, 18, 19, + 18, 24, 18, 25, 24, 32, 24, 25, 24, 32, 24, 19, 18, + 24, 18, 19, 18, 24, 18, 20, 19, 25, 19, 20, 19, 25, + 19, 19, 18, 24, 18, 19, 18, 24, 18, 25, 24, 32, 24, + 25, 24, 32, 24, 19, 18, 24, 18, 19, 18, 24, 18 }, + { 22, 21, 28, 21, 22, 21, 28, 21, 21, 19, 26, 19, 21, + 19, 26, 19, 28, 26, 35, 26, 28, 26, 35, 26, 21, 19, + 26, 19, 21, 19, 26, 19, 22, 21, 28, 21, 22, 21, 28, + 21, 21, 19, 26, 19, 21, 19, 26, 19, 28, 26, 35, 26, + 28, 26, 35, 26, 21, 19, 26, 19, 21, 19, 26, 19 }, + { 26, 24, 33, 24, 26, 24, 33, 24, 24, 23, 31, 23, 24, + 23, 31, 23, 33, 31, 42, 31, 33, 31, 42, 31, 24, 23, + 31, 23, 24, 23, 31, 23, 26, 24, 33, 24, 26, 24, 33, + 24, 24, 23, 31, 23, 24, 23, 31, 23, 33, 31, 42, 31, + 33, 31, 42, 31, 24, 23, 31, 23, 24, 23, 31, 23 }, + { 28, 26, 35, 26, 28, 26, 35, 26, 26, 25, 33, 25, 26, + 25, 33, 25, 35, 33, 45, 33, 35, 33, 45, 33, 26, 25, + 33, 25, 26, 25, 33, 25, 28, 26, 35, 26, 28, 26, 35, + 26, 26, 25, 33, 25, 26, 25, 33, 25, 35, 33, 45, 33, + 35, 33, 45, 33, 26, 25, 33, 25, 26, 25, 33, 25 }, + { 32, 30, 40, 30, 32, 30, 40, 30, 30, 28, 38, 28, 30, + 28, 38, 28, 40, 38, 51, 38, 40, 38, 51, 38, 30, 28, + 38, 28, 30, 28, 38, 28, 32, 30, 40, 30, 32, 30, 40, + 30, 30, 28, 38, 28, 30, 28, 38, 28, 40, 38, 51, 38, + 40, 38, 51, 38, 30, 28, 38, 28, 30, 28, 38, 28 }, + { 36, 34, 46, 34, 36, 34, 46, 34, 34, 32, 43, 32, 34, + 32, 43, 32, 46, 43, 58, 43, 46, 43, 58, 43, 34, 32, + 43, 32, 34, 32, 43, 32, 36, 34, 46, 34, 36, 34, 46, + 34, 34, 32, 43, 32, 34, 32, 43, 32, 46, 43, 58, 43, + 46, 43, 58, 43, 34, 32, 43, 32, 34, 32, 43, 32 }, }; + +/****************DECODE SLICE TABLES ENDS *******************/ + +/****************MOTION VECTOR DECODING TABLES STARTS *******************/ + +/** + ************************************************************************** + * \brief This array is used to evaluate the condition when only one of + * predictor subMbs has a reference frame equal to that of E subMb. + ************************************************************************** + */ + +const WORD8 gau1_ih264d_mv_pred_condition[] = + { -1, 0, 1, -1, 2, -1, -1, -1 }; + +/** Number of subMbs for the 8x8 prediction mode */ +const UWORD8 gau1_ih264d_num_submb_part[] = + { 1, 2, 2, 4 }; + +/** Width of the 8x8 prediction mode in terms of subMbs */ +const UWORD8 gau1_ih264d_submb_partw[] = + { 2, 2, 1, 1 }; + +/** Height of the 8x8 prediction mode in terms of subMbs */ +const UWORD8 gau1_ih264d_submb_parth[] = + { 2, 1, 2, 1 }; + +/** Number of MB partitions for the MB prediction mode */ +const UWORD8 gau1_ih264d_num_mb_part[] = + { 1, 2, 2, 4 }; + +/** Width of the MB partition in terms of subMbs */ +const UWORD8 gau1_ih264d_mb_partw[] = + { 4, 4, 2, 2, 2 }; + +/** Height of the MB partition in terms of subMbs */ +const UWORD8 gau1_ih264d_mb_parth[] = + { 4, 2, 4, 2, 2 }; + +/** MB partition information is packed into a UWORD32 {0,number,width,height} */ +const UWORD32 gau4_ih264d_submb_part[] = + { 0x00010202, 0x00020201, 0x00020102, 0x00040101 }; + +const UWORD8 gau1_ih264d_submb_indx_mod[] = + { 0, 0, /* 16x16 */ + 0, 8, /* 16x8 */ + 0, 2, /* 8x16 */ + 0, 0, /* 8x8 */ + 0, 4, /* 8x4 */ + 0, 1, /* 4x8 */ + 0, 1, 3, 1 /* 4x4 */ + }; + +/** This table is used to assign CBPs to Inter MBs. */ +const UWORD8 gau1_ih264d_cbp_inter[] = + { 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13, 14, 6, 9, 31, 35, + 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46, 17, 18, 20, 24, 19, 21, 26, + 28, 23, 27, 29, 30, 22, 25, 38, 41 }; + +/** Motion comp modes for P followed by B, + 0 to 4 : P Mbs + 5 to 27 : B Mbs + 28 to 30 : DIRECT */ +const UWORD8 gau1_ih264d_mb_mc_mode[] = + { + PRED_16x16, + PRED_16x8, PRED_8x16, PRED_8x8, PRED_8x8R0, + PRED_16x16, + PRED_16x16, PRED_16x16, PRED_16x16, PRED_16x8, PRED_8x16, + PRED_16x8, + PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, + PRED_16x8, + PRED_8x16, PRED_16x8, PRED_8x16, PRED_16x8, PRED_8x16, + PRED_16x8, + PRED_8x16, PRED_16x8, PRED_8x16, PRED_8x8, + /* Self defined modes for B_SKIP and DIRECT16x16 */ + PRED_8x8, + PRED_8x8, PRED_8x8 }; + +const UWORD8 gau1_ih264d_submb_mc_mode[] = + { SUBMB_8x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4, + SUBMB_8x8, + SUBMB_8x8, SUBMB_8x8, SUBMB_8x8, SUBMB_8x4, SUBMB_4x8, + SUBMB_8x4, + SUBMB_4x8, SUBMB_8x4, SUBMB_4x8, SUBMB_4x4, SUBMB_4x4, SUBMB_4x4, + /* Self defined modes B DIRECT8x8 */ + SUBMB_4x4, + SUBMB_4x4, SUBMB_4x4 }; + +/** Sub MB pred modes for B slice */ +const UWORD8 gau1_ih264d_submb_pred_modes[] = + { + PRED_L0, + PRED_L0, PRED_L0, PRED_L0, + B_DIRECT, + PRED_L0, PRED_L1, BI_PRED, PRED_L0, PRED_L0, PRED_L1, + PRED_L1, + BI_PRED, BI_PRED, PRED_L0, PRED_L1, BI_PRED, + /* Self defined modes for B DIRECT8x8 */ + BI_PRED, + PRED_L0, PRED_L1, }; + +/** MB pred modes for P and B slice */ +const WORD8 gau1_ih264d_mb_pred_modes[2][32] = + { + { PRED_L0, PRED_L0, PRED_L0, PRED_INVALID, PRED_INVALID, + B_DIRECT, + PRED_L0, PRED_L1, BI_PRED, PRED_L0, PRED_L0, PRED_L1, PRED_L1, + PRED_L0, + PRED_L0, PRED_L1, PRED_L1, PRED_L0, PRED_L0, PRED_L1, PRED_L1, + BI_PRED, + BI_PRED, BI_PRED, BI_PRED, BI_PRED, BI_PRED, PRED_INVALID, + /* Self defined modes for B_SKIP and DIRECT16x16 */ + BI_PRED, + PRED_L0, PRED_L1, }, + { PRED_INVALID, PRED_L0, PRED_L0, PRED_INVALID, PRED_INVALID, + PRED_INVALID, + PRED_INVALID, PRED_INVALID, PRED_INVALID, PRED_L0, PRED_L0, + PRED_L1, + PRED_L1, PRED_L1, PRED_L1, PRED_L0, PRED_L0, BI_PRED, BI_PRED, + BI_PRED, + BI_PRED, PRED_L0, PRED_L0, PRED_L1, PRED_L1, BI_PRED, BI_PRED, + PRED_INVALID, + /* Self defined modes for B_SKIP and DIRECT16x16 */ + PRED_INVALID, + PRED_INVALID, PRED_INVALID } }; + +/****************MOTION VECTOR DECODING TABLES ENDS *******************/ + +/****************CAVLC DECODING TABLES STARTS *******************/ + +/*****************************************************************************/ +/* 6 Bit table look for total zeros (totalcoeff = 2to10) as in Table 9.7 */ +/* of H264 standard. In each table entry, lower 4 bits represent total zeros */ +/* decoded while upper 4 bit represent the bits to be flushed from ps_bitstrm */ +/*****************************************************************************/ +const UWORD8 gau1_ih264d_table_total_zero_2to10[9][64] = + { + /* For total coeff = 2 */ + { 0x6E, 0x6D, 0x6C, 0x6B, 0x5A, 0x5A, 0x59, 0x59, 0x48, 0x48, 0x48, + 0x48, 0x47, 0x47, 0x47, 0x47, 0x46, 0x46, 0x46, 0x46, 0x45, 0x45, + 0x45, 0x45, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, }, + + /* For total coeff = 3 */ + { 0x6D, 0x6B, 0x5C, 0x5C, 0x5A, 0x5A, 0x59, 0x59, 0x48, 0x48, 0x48, + 0x48, 0x45, 0x45, 0x45, 0x45, 0x44, 0x44, 0x44, 0x44, 0x40, 0x40, + 0x40, 0x40, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, }, + + /* For total coeff = 4 */ + { 0x5C, 0x5C, 0x5B, 0x5B, 0x5A, 0x5A, 0x50, 0x50, 0x49, 0x49, 0x49, + 0x49, 0x47, 0x47, 0x47, 0x47, 0x43, 0x43, 0x43, 0x43, 0x42, 0x42, + 0x42, 0x42, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, }, + + /* For total coeff = 5 */ + { 0x5B, 0x5B, 0x59, 0x59, 0x4A, 0x4A, 0x4A, 0x4A, 0x48, 0x48, 0x48, + 0x48, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x40, 0x40, + 0x40, 0x40, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, }, + + /* For total coeff = 6 */ + { 0x6A, 0x60, 0x51, 0x51, 0x48, 0x48, 0x48, 0x48, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, }, + + /* For total coeff = 7 */ + { 0x69, 0x60, 0x51, 0x51, 0x47, 0x47, 0x47, 0x47, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x38, 0x38, 0x38, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, }, + + /* For total coeff = 8 */ + { 0x68, 0x60, 0x52, 0x52, 0x41, 0x41, 0x41, 0x41, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, }, + + /* For total coeff = 9 */ + { 0x61, 0x60, 0x57, 0x57, 0x42, 0x42, 0x42, 0x42, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, + 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, }, + + /* For total coeff = 10 */ + { 0x51, 0x51, 0x50, 0x50, 0x46, 0x46, 0x46, 0x46, 0x32, 0x32, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, + 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, + 0x24, 0x24, 0x24, 0x24, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, } + + }; + +/*****************************************************************************/ +/* 4 Bit table look for total zeros (totalcoeff = 11to15) as in Table 9.7 */ +/* of H264 standard. In each table entry, lower 4 bits represent total zeros */ +/* decoded while upper 4 bit represent the bits to be flushed from ps_bitstrm */ +/*****************************************************************************/ +const UWORD8 gau1_ih264d_table_total_zero_11to15[5][16] = + { + /* For total coeff = 11 */ + { 0x40, 0x41, 0x32, 0x32, 0x33, 0x33, 0x35, 0x35, 0x14, 0x14, 0x14, + 0x14, 0x14, 0x14, 0x14, 0x14, }, + + /* For total coeff = 12 */ + { 0x40, 0x41, 0x34, 0x34, 0x22, 0x22, 0x22, 0x22, 0x13, 0x13, 0x13, + 0x13, 0x13, 0x13, 0x13, 0x13, }, + + /* For total coeff = 13 */ + { 0x30, 0x30, 0x31, 0x31, 0x23, 0x23, 0x23, 0x23, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, }, + + /* For total coeff = 14 */ + { 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x12, 0x12, 0x12, + 0x12, 0x12, 0x12, 0x12, 0x12, }, + + /* For total coeff = 15 */ + { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, }, }; + +/** Tables used to read "Run Before", Below tables are packed to reduce lookups */ +/** (Base addess of Gx << 2) + (Max code length for that Gx) */ +const UWORD8 gau1_ih264d_table_run_before[64] = + { 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 1, 1, 1, 1, 10, 10, 6, 6, 1, 1, 1, 1, + 14, 14, 10, 10, 6, 6, 2, 2, 19, 15, 10, 10, 6, 6, 2, 2, 23, 19, 15, 11, 6, + 6, 2, 2, 7, 11, 19, 15, 27, 23, 2, 2, 27, 27, 23, 19, 15, 11, 7, 3 }; + +/*****************************************************************************/ +/* Lookup table for CAVLC 4x4 total_coeff,trailing_ones as pers Table 9-5 */ +/* in the standard. Starting form lsb first 2 bits=flushbits, next 2bits= */ +/* trailing ones, next 5 bits=total_coeff. Total bits used = 9 out of 16 */ +/*****************************************************************************/ +const UWORD16 gau2_ih264d_code_gx[304] = + { + /* Lookup for 0 <= nC < 2 */ + 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0014, 0x0014, + 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0028, 0x0028, 0x0028, + 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0026, 0x0026, 0x0012, 0x0012, + 0x003D, 0x003D, 0x003D, 0x003D, 0x005E, 0x005E, 0x003A, 0x003A, 0x004D, + 0x004D, 0x004D, 0x004D, 0x006E, 0x006E, 0x004A, 0x004A, 0x0036, 0x0036, + 0x0022, 0x0022, 0x007E, 0x007E, 0x005A, 0x005A, 0x0046, 0x0046, 0x0032, + 0x0032, 0x008E, 0x008E, 0x006A, 0x006A, 0x0056, 0x0056, 0x0042, 0x0042, + 0x009E, 0x009E, 0x007A, 0x007A, 0x0066, 0x0066, 0x0052, 0x0052, 0x0083, + 0x009B, 0x0087, 0x0073, 0x00AF, 0x008B, 0x0077, 0x0063, 0x00CF, 0x00BB, + 0x00A7, 0x00A3, 0x00BF, 0x00AB, 0x0097, 0x0093, 0x00EF, 0x00DB, 0x00C7, + 0x00C3, 0x00DF, 0x00CB, 0x00B7, 0x00B3, 0x010F, 0x00FB, 0x00F7, 0x00E3, + 0x00FF, 0x00EB, 0x00E7, 0x00D3, 0x0102, 0x0102, 0x010A, 0x010A, 0x0106, + 0x0106, 0x00F2, 0x00F2, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, 0x00D4, + 0x00D4, 0x00D4, + + /* Lookup for 2 <= nC < 4 */ + 0x0015, + 0x0015, 0x0015, 0x0015, 0x0001, 0x0001, 0x0001, 0x0001, 0x004E, 0x004E, + 0x003E, 0x003E, 0x0029, 0x0029, 0x0029, 0x0029, 0x006F, 0x003B, 0x0037, + 0x0013, 0x005E, 0x005E, 0x0026, 0x0026, 0x007E, 0x007E, 0x004A, 0x004A, + 0x0046, 0x0046, 0x0022, 0x0022, 0x008E, 0x008E, 0x005A, 0x005A, 0x0056, + 0x0056, 0x0032, 0x0032, 0x0052, 0x0052, 0x006A, 0x006A, 0x0066, 0x0066, + 0x0042, 0x0042, 0x009E, 0x009E, 0x007A, 0x007A, 0x0076, 0x0076, 0x0062, + 0x0062, 0x00BF, 0x009B, 0x0097, 0x0083, 0x00AF, 0x008B, 0x0087, 0x0073, + 0x00B3, 0x00BB, 0x00B7, 0x00A3, 0x00CF, 0x00AB, 0x00A7, 0x0093, 0x00EF, + 0x00DB, 0x00D7, 0x00D3, 0x00DF, 0x00CB, 0x00C7, 0x00C3, 0x00F7, 0x00F3, + 0x00FB, 0x00E7, 0x00EA, 0x00EA, 0x00E2, 0x00E2, 0x010E, 0x010E, 0x010A, + 0x010A, 0x0106, 0x0106, 0x0102, 0x0102, 0x00FC, 0x00FC, 0x00FC, 0x00FC, + 0x00FC, 0x00FC, 0x00FC, 0x00FC, + + /* Lookup for 4 <= nC < 8 */ + 0x007F, + 0x006F, 0x005F, 0x004F, 0x003F, 0x002B, 0x0017, 0x0003, 0x0057, 0x005B, + 0x0047, 0x004B, 0x0037, 0x008F, 0x003B, 0x0027, 0x0033, 0x007B, 0x0077, + 0x0023, 0x009F, 0x006B, 0x0067, 0x0013, 0x0073, 0x0063, 0x009B, 0x0053, + 0x00AF, 0x008B, 0x0087, 0x0043, 0x00CF, 0x00BB, 0x00A7, 0x0093, 0x00BF, + 0x00AB, 0x0097, 0x0083, 0x00C3, 0x00DB, 0x00C7, 0x00B3, 0x00DF, 0x00CB, + 0x00B7, 0x00A3, 0x00F7, 0x00E3, 0x00EF, 0x00EB, 0x00E7, 0x00D3, 0x00D6, + 0x00D6, 0x0106, 0x0106, 0x00F2, 0x00F2, 0x00FE, 0x00FE, 0x00FA, 0x00FA, + 0x010D, 0x010D, 0x010D, 0x010D, 0x0109, 0x0109, 0x0109, 0x0109, 0x0100, + 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100 }; + +/*****************************************************************************/ +/* Lookup table for CAVLC ChromaDC total_coeff,trailing_ones parsing as per */ +/* Table 9-5 in the standard. Starting from msb, First 4bits=total_coeff, */ +/* next 2bits=trailing_ones and last 2bits=flushbits-1 */ +/*****************************************************************************/ +const UWORD8 gau1_ih264d_cav_chromdc_vld[256] = + { 0x9E, 0x9E, 0x97, 0x8F, 0x76, 0x76, 0x6E, 0x6E, 0x85, 0x85, 0x85, 0x85, + 0x65, 0x65, 0x65, 0x65, 0x45, 0x45, 0x45, 0x45, 0x7D, 0x7D, 0x7D, 0x7D, + 0x4D, 0x4D, 0x4D, 0x4D, 0x25, 0x25, 0x25, 0x25, + + 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, + + 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + + 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, }; + +const UWORD16 gau2_ih264d_offset_num_vlc_tab[9] = + { 0, 0, 120, 120, 224, 224, 224, 224, 224 }; + +/*****************************************************************************/ +/* Function pointer u4_ofst table lookup for parsing 4x4 residual blocks in */ +/* CAVLC. The u4_ofst is dependent on total coeffs coded */ +/*****************************************************************************/ +const UWORD8 gau1_ih264d_total_coeff_fn_ptr_offset[16] = + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2 }; + +/****************************************************************************/ +/* gai2_ih264d_trailing_one_level lookup tables based on trailing one bits */ +/* All zeroes are u2_dummy in the table are u2_dummy to keep 3 uniform elements */ +/****************************************************************************/ +const WORD16 gai2_ih264d_trailing_one_level[14][3] = + { + /* All zeroes are u2_dummy */ + /**********************************************************************/ + /* Levels for trailing ones = 1, bits read can be 0 or 1 */ + /**********************************************************************/ + { 1, 0, 0 }, /* 0 */ + { -1, 0, 0 }, /* 1 */ + + /**********************************************************************/ + /* Levels for trailing ones = 2, bits read can be 00, 01, 10 ,11 */ + /**********************************************************************/ + { 1, 1, 0 }, /* 00 */ + { 1, -1, 0 }, /* 01 */ + { -1, 1, 0 }, /* 10 */ + { -1, -1, 0 }, /* 11 */ + + /**********************************************************************/ + /* Levels for trailing ones = 3, bits read can be 000 - 111 */ + /**********************************************************************/ + { 1, 1, 1 }, /* 000 */ + { 1, 1, -1 }, /* 001 */ + { 1, -1, 1 }, /* 010 */ + { 1, -1, -1 }, /* 011 */ + { -1, 1, 1 }, /* 100 */ + { -1, 1, -1 }, /* 101 */ + { -1, -1, 1 }, /* 110 */ + { -1, -1, -1 }, /* 111 */ + }; +/****************CAVLC DECODING TABLES ENDS *******************/ + +/****************************************************************************/ +/* These are the codes used for error detection in intra pred4x4 modes */ +/****************************************************************************/ +const UWORD8 gau1_ih264d_intra_pred_err_code[9] = + { 2, 1, 0, 2, 3, 3, 3, 2, 1 }; + +/* Number of users for top field , bottom field, which field needs to be */ +/* displayed first */ +const UWORD8 gau1_ih264d_sei_fld_usage[9][3] = + { + { 1, 1, DISP_FLD_FIRST_UNDEF }, + { 1, 0, DISP_TOP_FLD_FIRST }, + { 0, 1, DISP_BOT_FLD_FIRST }, + { 1, 1, DISP_TOP_FLD_FIRST }, + { 1, 1, DISP_BOT_FLD_FIRST }, + { 2, 1, DISP_TOP_FLD_FIRST }, + { 1, 2, DISP_BOT_FLD_FIRST }, + { 2, 2, DISP_FLD_FIRST_UNDEF }, + { 3, 3, DISP_FLD_FIRST_UNDEF } }; + +/*****************************************************************/ +/* Context increment for significant coefficient(CABAC) */ +/* Requires only 63 elements. But the last element with value -1 */ +/* is kept to make it 64 */ +/*****************************************************************/ +const UWORD8 gau1_ih264d_sigcoeff_context_inc_frame[64] = + { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5, 4, 4, 4, 4, 3, 3, 6, 7, 7, + 7, 8, 9, 10, 9, 8, 7, 7, 6, 11, 12, 13, 11, 6, 7, 8, 9, 14, 10, 9, 8, 6, + 11, 12, 13, 11, 6, 9, 14, 10, 9, 11, 12, 13, 11, 14, 10, 12, -1 }; + +const UWORD8 gau1_ih264d_sigcoeff_context_inc_field[64] = + { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5, 6, 9, 10, 10, 8, 11, 12, + 11, 9, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, 10, 8, 11, 12, 11, 9, 9, 10, + 10, 8, 13, 13, 9, 9, 10, 10, 8, 13, 13, 9, 9, 10, 10, 14, 14, 14, 14, 14, + -1 }; + +const UWORD8 gau1_ih264d_lastcoeff_context_inc[64] = + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, + 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, -1 }; + +/*! + ************************************************************************** + * \brief gau1_ih264d_top_left_mb_part_indx_mod + * + * SubBlk number of the top left subBlk in each of the MB partition + * (16x16, 16x8, 8x16, 8x8) + ************************************************************************** + */ +const UWORD8 gau1_ih264d_top_left_mb_part_indx_mod[] = + { 0, 0 /* Junk */, /* 16x16 */ + 0, 8, /* 16x8 */ + 0, 2, /* 8x16 */ + 0, 2, 8, 10 /* 8x8 */ + }; + +/*! + ************************************************************************** + * \brief gau1_ih264d_submb_indx_mod_sp_drct + * + * Contains increments to the subBlk num in a given subMb partition. + ************************************************************************** + */ +const UWORD8 gau1_ih264d_submb_indx_mod_sp_drct[] = + { 0, 0 /* Junk */, /* 8x8 */ + 0, 4, /* 8x4 */ + 0, 1, /* 4x8 */ + 0, 1, 3, 1 /* 4x4 */ + }; diff --git a/decoder/ih264d_tables.h b/decoder/ih264d_tables.h new file mode 100755 index 0000000..04dfbd0 --- /dev/null +++ b/decoder/ih264d_tables.h @@ -0,0 +1,157 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ + +#ifndef _IH264D_TABLES_H_ +#define _IH264D_TABLES_H_ + +/** + ************************************************************************** + * \file ih264d_tables.h + * + * \brief + * Declaration of all tables used by h264 decoder + * + * \date + * 17/09/2004 + * + * \author MA + ************************************************************************** + */ +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_cabac.h" + +/*Deblocking Table declaration*/ +extern const UWORD8 gau1_ih264d_qp_scale_cr[]; +extern const UWORD8 gau1_ih264d_alpha_table[]; +extern const UWORD8 gau1_ih264d_clip_table_deblock[]; +extern const UWORD8 gau1_ih264d_beta_table[]; +extern const UWORD8 gau1_ih264d_clip_table[][4]; + +/*Parsing Table declaration*/ +extern const UWORD8 gau1_ih264d_cbp_tab[6]; +extern const UWORD32 gau4_ih264d_packed_bs2[16]; +extern const UWORD16 gau2_ih264d_4x4_v2h_reorder[16]; +extern const UWORD8 gau1_ih264d_subblk_offset[16]; +extern const UWORD8 gau1_ih264d_cbp_table[48][2]; + +/*Decode Slice Table declaration*/ +extern const UWORD8 gau1_ih264d_inv_scan[16]; +extern const UWORD8 gau1_ih264d_inv_scan_fld[16]; +extern const UWORD8 gau1_ih264d_dequant_matrix[6][16]; +extern const UWORD16 gau2_ih264_iquant_scale_4x4[6][16]; +extern const UWORD8 gau1_ih264d_dequant8x8_zigzag_cavlc[4][6][16]; +extern const UWORD16 gau1_ih264d_dequant8x8_cavlc[6][64]; + +extern const UWORD8 gau1_ih264d_inv_scan_prog8x8_cavlc[4][16]; +extern const UWORD8 gau1_ih264d_inv_scan_int8x8_cavlc[4][16]; +extern const UWORD8 gau1_ih264d_inv_scan_prog8x8_cabac[64]; +extern const UWORD8 gau1_ih264d_inv_scan_int8x8_cabac[64]; + +extern const UWORD8 gau1_ih264d_lastcoeff_context_inc[64]; +extern const UWORD8 gau1_ih264d_sigcoeff_context_inc_frame[64]; +extern const UWORD8 gau1_ih264d_sigcoeff_context_inc_field[64]; + +/* scaling related table declaration */ +extern const WORD16 gai2_ih264d_default_intra4x4[16]; +extern const WORD16 gai2_ih264d_default_inter4x4[16]; +extern const WORD16 gai2_ih264d_default_intra8x8[64]; +extern const WORD16 gai2_ih264d_default_inter8x8[64]; +extern const WORD16 gai2_ih264d_flat_4x4[16]; +extern const WORD16 gai2_ih264d_flat_8x8[64]; + +/*Decode MV Table declaration*/ +extern const WORD8 gau1_ih264d_mv_pred_condition[]; + +/** Number of subMbs for the 8x8 prediction mode */ +extern const UWORD8 gau1_ih264d_num_submb_part[]; + +/** Width of the 8x8 prediction mode in terms of subMbs */ +extern const UWORD8 gau1_ih264d_submb_partw[]; + +/** Height of the 8x8 prediction mode in terms of subMbs */ +extern const UWORD8 gau1_ih264d_submb_parth[]; + +/** Number of MB partitions for the MB prediction mode */ +extern const UWORD8 gau1_ih264d_num_mb_part[]; + +/** Width of the MB partition in terms of subMbs */ +extern const UWORD8 gau1_ih264d_mb_partw[]; + +/** Height of the MB partition in terms of subMbs */ +extern const UWORD8 gau1_ih264d_mb_parth[]; + +/** MB partition information is packed into a UWORD32 {0,number,width,height} */ +extern const UWORD32 gau4_ih264d_submb_part[]; + +extern const UWORD8 gau1_ih264d_submb_indx_mod[]; + +/** This table is used to assign CBPs to Inter MBs. */ +extern const UWORD8 gau1_ih264d_cbp_inter[]; + +/** Motion comp modes for P followed by B, + 0 to 4 : P Mbs + 5 to 27 : B Mbs + 28 to 30 : DIRECT */ +extern const UWORD8 gau1_ih264d_mb_mc_mode[]; + +extern const UWORD8 gau1_ih264d_submb_mc_mode[]; + +/** Sub MB pred modes for B slice */ +extern const UWORD8 gau1_ih264d_submb_pred_modes[]; + +/** MB pred modes for P and B slice */ +extern const WORD8 gau1_ih264d_mb_pred_modes[2][32]; + +/*Decode CAVLC Table declaration*/ +extern const UWORD8 gau1_ih264d_table_total_zero_2to10[9][64]; +extern const UWORD8 gau1_ih264d_table_total_zero_11to15[5][16]; +extern const UWORD8 gau1_ih264d_table_run_before[64]; +extern const UWORD16 gau2_ih264d_code_gx[304]; +extern const UWORD8 gau1_ih264d_cav_chromdc_vld[256]; +extern const UWORD16 gau2_ih264d_offset_num_vlc_tab[9]; +extern const UWORD8 gau1_ih264d_total_coeff_fn_ptr_offset[16]; +extern const WORD16 gai2_ih264d_trailing_one_level[14][3]; + +/*Decode CABAC Table declaration*/ +extern const UWORD32 gau4_ih264d_cabac_table[]; + +/****************************************************************************/ +/* For error detection in intra pred4x4 modes */ +/****************************************************************************/ +extern const UWORD8 gau1_ih264d_intra_pred_err_code[9]; + +/*****************************************************************************/ +/* Cabac tables for context initialization depending upon type of Slice, */ +/* cabac init Idc value and Qp. */ +/*****************************************************************************/ +extern const UWORD8 gau1_ih264d_cabac_ctxt_init_table[NUM_CAB_INIT_IDC_PLUS_ONE][QP_RANGE][NUM_CABAC_CTXTS]; + +/*****************************************************************************/ +/* SEI tables for field usge and which field first */ +/*****************************************************************************/ +extern const UWORD8 gau1_ih264d_sei_fld_usage[9][3]; + + +extern const UWORD8 gau1_ih264d_top_left_mb_part_indx_mod[]; +extern const UWORD8 gau1_ih264d_submb_indx_mod_sp_drct[]; + +#endif /*TABLES_H*/ diff --git a/decoder/ih264d_thread_compute_bs.c b/decoder/ih264d_thread_compute_bs.c new file mode 100755 index 0000000..6812d57 --- /dev/null +++ b/decoder/ih264d_thread_compute_bs.c @@ -0,0 +1,802 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_thread_compute_bs.c + * + * \brief + * Contains routines that for multi-thread decoder + * + * Detailed_description + * + * \date + * 20/02/2012 + * + * \author ZR + ************************************************************************** + */ +#include "ih264d_error_handler.h" +#include "ih264d_debug.h" +#include <string.h> +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_mb_utils.h" + +#include "ih264d_thread_compute_bs.h" +#include "ithread.h" +#include "ih264d_deblocking.h" +#include "ih264d_mb_utils.h" +#include "ih264d_tables.h" +#include "ih264d_format_conv.h" +#include "ih264d_defs.h" +UWORD16 ih264d_update_csbp_8x8(UWORD16 u2_luma_csbp); +void ih264d_fill_bs2_horz_vert(UWORD32 *pu4_bs, /* Base pointer of BS table */ + WORD32 u4_left_mb_csbp, /* csbp of left mb */ + WORD32 u4_top_mb_csbp, /* csbp of top mb */ + WORD32 u4_cur_mb_csbp, /* csbp of current mb */ + const UWORD32 *pu4_packed_bs2, const UWORD16 *pu2_4x4_v2h_reorder); + +#define BS_MB_GROUP 4 +#define DEBLK_MB_GROUP 1 +#define FORMAT_CONV_MB_GROUP 4 + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_compute_bs_non_mbaff_thread */ +/* */ +/* Description : This function computes the pointers of left,top & current*/ +/* : Nnz, MvPred & deblk_mb_t and supplies to FillBs function for*/ +/* : Boundary Strength Calculation .this function is used */ +/* : BS being calculated in separate thread */ +/* Inputs : pointer to decoder context,cur_mb_info,u4_mb_num */ +/* Processing : */ +/* */ +/* Outputs : Produces the Boundary Strength for Current Mb */ +/* Returns : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* ITTIAM */ +/*****************************************************************************/ + +void ih264d_compute_bs_non_mbaff_thread(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mb_num) +{ + /* Mvpred and Nnz for top and Courrent */ + mv_pred_t *ps_cur_mv_pred, *ps_top_mv_pred = NULL, *ps_left_mv_pred; + /* deblk_mb_t Params */ + deblk_mb_t *ps_cur_mb_params; /*< Parameters of current MacroBlock */ + deblkmb_neighbour_t *ps_deblk_top_mb; + + /* Reference Index to POC mapping*/ + void ** apv_map_ref_idx_to_poc; + UWORD32 u4_leftmbtype; + + UWORD16 u2_left_csbp, u2_top_csbp, u2_cur_csbp; + + /* Set of flags */ + UWORD32 u4_cur_mb_intra, u1_top_mb_typ, u4_cur_mb_fld; + UWORD32 u1_cur_mb_type; + UWORD32 * pu4_bs_table; + + /* Neighbour availability */ + /* Initialization */ + const UWORD32 u2_mbx = ps_cur_mb_info->u2_mbx; + const UWORD32 u2_mby = ps_cur_mb_info->u2_mby; + const UWORD32 u1_pingpong = u2_mbx & 0x01; + ps_deblk_top_mb = ps_dec->ps_deblk_top_mb + u2_mbx; + + /* Pointer assignment for Current DeblkMB, Current Mv Pred */ + ps_cur_mb_params = ps_dec->ps_deblk_pic + u4_mb_num; + ps_cur_mv_pred = ps_dec->s_cur_pic.ps_mv + (u4_mb_num << 4); + + apv_map_ref_idx_to_poc = + (void **)ps_dec->ps_computebs_cur_slice->ppv_map_ref_idx_to_poc + + 1; + u1_cur_mb_type = ps_cur_mb_params->u1_mb_type; + u1_top_mb_typ = ps_deblk_top_mb->u1_mb_type; + ps_deblk_top_mb->u1_mb_type = u1_cur_mb_type; + + { + ps_cur_mb_params->u1_topmb_qp = ps_deblk_top_mb->u1_mb_qp; + ps_deblk_top_mb->u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + ps_cur_mb_params->u1_left_mb_qp = ps_dec->deblk_left_mb[1].u1_mb_qp; + ps_dec->deblk_left_mb[1].u1_mb_qp = ps_cur_mb_params->u1_mb_qp; + + } + + /* if no deblocking required for current Mb then continue */ + /* Check next Mbs in Mb group */ + if(ps_cur_mb_params->u1_deblocking_mode & MB_DISABLE_FILTERING) + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + { + /* Store Parameter for Top MvPred refernce frame Address */ + + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + + /* Store Left addresses for Next Mb */ + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add; + WORD8 * p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + + + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]]; + //} + /* Storing the leftMbtype for next Mb */ + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + } + + return; + } + + /* Flag for extra left Edge */ + ps_cur_mb_params->u1_single_call = 1; + + /* Update the Left deblk_mb_t and Left MvPred Parameters */ + if(!u2_mbx) + { + u4_leftmbtype = 0; + + /* Initialize the ps_left_mv_pred with Junk but Valid Location */ + /* to avoid invalid memory access */ + /* this is read only pointer */ + ps_left_mv_pred = ps_cur_mv_pred + 3; + } + else + { + u4_leftmbtype = ps_dec->deblk_left_mb[1].u1_mb_type; + + /* Come to Left Most Edge of the MB */ + ps_left_mv_pred = ps_cur_mv_pred - (1 << 4) + 3; + } + + if(!u2_mby) + u1_top_mb_typ = 0; + + /* MvPred Pointer Calculation */ + /* CHANGED CODE */ + ps_top_mv_pred = ps_cur_mv_pred - (ps_dec->u2_frm_wd_in_mbs << 4) + 12; + + u4_cur_mb_intra = u1_cur_mb_type & D_INTRA_MB; + u4_cur_mb_fld = !!(u1_cur_mb_type & D_FLD_MB); + /* Compute BS function */ + pu4_bs_table = ps_cur_mb_params->u4_bs_table; + + u2_cur_csbp = ps_cur_mb_info->ps_curmb->u2_luma_csbp; + u2_left_csbp = ps_cur_mb_info->ps_left_mb->u2_luma_csbp; + u2_top_csbp = ps_cur_mb_info->ps_top_mb->u2_luma_csbp; + + /* Compute BS function */ + if(ps_dec->ps_cur_sps->u1_profile_idc == HIGH_PROFILE_IDC) + { + if(ps_cur_mb_info->u1_tran_form8x8 == 1) + { + u2_cur_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_curmb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_left_mb->u1_tran_form8x8 == 1) + { + u2_left_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_left_mb->u2_luma_csbp); + } + + if(ps_cur_mb_info->ps_top_mb->u1_tran_form8x8 == 1) + { + u2_top_csbp = ih264d_update_csbp_8x8( + ps_cur_mb_info->ps_top_mb->u2_luma_csbp); + } + } + if(u4_cur_mb_intra) + { + + pu4_bs_table[4] = 0x04040404; + pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404; + pu4_bs_table[1] = 0x03030303; + pu4_bs_table[2] = 0x03030303; + pu4_bs_table[3] = 0x03030303; + pu4_bs_table[5] = 0x03030303; + pu4_bs_table[6] = 0x03030303; + pu4_bs_table[7] = 0x03030303; + } + else + { + UWORD32 u4_is_non16x16 = !!(u1_cur_mb_type & D_PRED_NON_16x16); + UWORD32 u4_is_b = + (ps_dec->ps_computebs_cur_slice->slice_type == B_SLICE); + + + + + + + ih264d_fill_bs2_horz_vert(pu4_bs_table, u2_left_csbp, u2_top_csbp, + u2_cur_csbp, gau4_ih264d_packed_bs2, + gau2_ih264d_4x4_v2h_reorder); + + if(u4_leftmbtype & D_INTRA_MB) + pu4_bs_table[4] = 0x04040404; + + if(u1_top_mb_typ & D_INTRA_MB) + pu4_bs_table[0] = u4_cur_mb_fld ? 0x03030303 : 0x04040404; + + ps_dec->pf_fill_bs1[u4_is_b][u4_is_non16x16]( + ps_cur_mv_pred, ps_top_mv_pred, apv_map_ref_idx_to_poc, + pu4_bs_table, ps_left_mv_pred, + &(ps_dec->ps_left_mvpred_addr[u1_pingpong][1]), + ps_cur_mb_info->ps_top_mb->u4_pic_addrress, + (4 >> u4_cur_mb_fld)); + } + + { + void ** pu4_map_ref_idx_to_poc_l1 = apv_map_ref_idx_to_poc + + POC_LIST_L0_TO_L1_DIFF; + { + /* Store Parameter for Top MvPred refernce frame Address */ + + void ** ppv_top_mv_pred_addr = ps_cur_mb_info->ps_curmb->u4_pic_addrress; + WORD8 * p1_refTop0 = (ps_cur_mv_pred + 12)->i1_ref_frame; + WORD8 * p1_refTop1 = (ps_cur_mv_pred + 14)->i1_ref_frame; + + /* Store Left addresses for Next Mb */ + void ** ppv_left_mv_pred_addr = + ps_dec->ps_left_mvpred_addr[!u1_pingpong][1].u4_add; + WORD8 * p1_refleft0 = (ps_cur_mv_pred + 3)->i1_ref_frame; + + ppv_top_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refTop0[0]]; + ppv_top_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refTop0[1]]; + + ppv_left_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_top_mv_pred_addr[2] = apv_map_ref_idx_to_poc[p1_refTop1[0]]; + ppv_left_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + ppv_top_mv_pred_addr[3] = pu4_map_ref_idx_to_poc_l1[p1_refTop1[1]]; + + ppv_left_mv_pred_addr[0] = apv_map_ref_idx_to_poc[p1_refleft0[0]]; + ppv_left_mv_pred_addr[1] = pu4_map_ref_idx_to_poc_l1[p1_refleft0[1]]; + + /* Storing the leftMbtype for next Mb */ + ps_dec->deblk_left_mb[1].u1_mb_type = ps_cur_mb_params->u1_mb_type; + + } + } + + /* For transform 8x8 disable deblocking of the intrernal edges of a 8x8 block */ + if(ps_cur_mb_info->u1_tran_form8x8) + { + pu4_bs_table[1] = 0; + pu4_bs_table[3] = 0; + pu4_bs_table[5] = 0; + pu4_bs_table[7] = 0; + } +} + +void ih264d_check_mb_map_deblk(dec_struct_t *ps_dec, + UWORD32 deblk_mb_grp, + tfr_ctxt_t *ps_tfr_cxt) +{ + UWORD32 i = 0; + UWORD32 u4_mb_num; + UWORD32 u4_cur_mb, u4_right_mb; + volatile UWORD8 *mb_map = ps_dec->pu1_recon_mb_map; + UWORD32 u4_mb_x, u4_mb_y, u4_image_wd_mb; + deblk_mb_t *ps_cur_mb = ps_dec->ps_cur_deblk_thrd_mb; + deblk_mb_t *ps_top_mb; + deblk_mb_t *ps_left_mb; + const WORD32 i4_cb_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + const WORD32 i4_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + + UWORD32 u4_wd_y, u4_wd_uv; + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + + u4_mb_num = ps_dec->u4_cur_deblk_mb_num; + u4_mb_x = ps_dec->u4_deblk_mb_x; + u4_mb_y = ps_dec->u4_deblk_mb_y; + u4_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; + u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; + ps_cur_mb = ps_dec->ps_cur_deblk_thrd_mb; + + for(i = 0; i < deblk_mb_grp; i++) + { + + //while(1) + //{ + CHECK_MB_MAP_BYTE(u4_mb_num, mb_map, u4_cur_mb); + + if(ps_dec->u4_cur_bs_mb_num <= u4_mb_num) + u4_cur_mb = 0; + + if(u4_mb_x < (u4_image_wd_mb - 1)) + { + CHECK_MB_MAP_BYTE((u4_mb_num + 1), mb_map, u4_right_mb); + } + else + u4_right_mb = 1; + + if((u4_cur_mb && u4_right_mb) == 0) + { + break; + } + else + { + + } + //} + + u4_mb_num++; + { + UWORD32 u4_deb_mode, u4_mbs_next; + u4_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u4_deb_mode & MB_DISABLE_FILTERING)) + { + + if(u4_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + + } + else + { + ps_left_mb = NULL; + + } + if(u4_mb_y != 0) + { + ps_top_mb = ps_cur_mb - (u4_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u4_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u4_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, + i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst, + ps_cur_mb, u4_wd_y, u4_wd_uv, + ps_top_mb, ps_left_mb); + + } + + ps_cur_mb++; + u4_mb_x++; + u4_mbs_next = u4_image_wd_mb - u4_mb_x; + + ps_tfr_cxt->pu1_mb_y += 16; + ps_tfr_cxt->pu1_mb_u += 8 * YUV420SP_FACTOR; + ps_tfr_cxt->pu1_mb_v += 8; + + if(!u4_mbs_next) + { + ps_tfr_cxt->pu1_mb_y += ps_tfr_cxt->u4_y_inc; + ps_tfr_cxt->pu1_mb_u += ps_tfr_cxt->u4_uv_inc; + ps_tfr_cxt->pu1_mb_v += ps_tfr_cxt->u4_uv_inc; + u4_mb_y++; + u4_mb_x = 0; + } + } + + } + + ps_dec->u4_cur_deblk_mb_num = u4_mb_num; + ps_dec->u4_deblk_mb_x = u4_mb_x; + ps_dec->u4_deblk_mb_y = u4_mb_y; + ps_dec->ps_cur_deblk_thrd_mb = ps_cur_mb; + +} + +void ih264d_check_mb_map_deblk_wait(dec_struct_t *ps_dec, + UWORD32 deblk_mb_grp, + tfr_ctxt_t *ps_tfr_cxt) +{ + UWORD32 i = 0; + UWORD32 u4_mb_num; + UWORD32 u4_cur_mb, u4_right_mb; + volatile UWORD8 *mb_map = ps_dec->pu1_recon_mb_map; + UWORD32 u4_mb_x, u4_mb_y, u4_image_wd_mb; + deblk_mb_t *ps_cur_mb = ps_dec->ps_cur_deblk_thrd_mb; + deblk_mb_t *ps_top_mb; + deblk_mb_t *ps_left_mb; + const WORD32 i4_cb_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_chroma_qp_index_offset; + const WORD32 i4_cr_qp_idx_ofst = + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset; + + UWORD32 u4_wd_y, u4_wd_uv; + UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + + u4_mb_num = ps_dec->u4_cur_deblk_mb_num; + u4_mb_x = ps_dec->u4_deblk_mb_x; + u4_mb_y = ps_dec->u4_deblk_mb_y; + u4_image_wd_mb = ps_dec->u2_frm_wd_in_mbs; + u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag; + u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag; + ps_cur_mb = ps_dec->ps_cur_deblk_thrd_mb; + + for(i = 0; i < deblk_mb_grp; i++) + { + + while(1) + { + CHECK_MB_MAP_BYTE(u4_mb_num, mb_map, u4_cur_mb); + + if(ps_dec->u4_cur_bs_mb_num <= u4_mb_num) + u4_cur_mb = 0; + + if(u4_mb_x < (u4_image_wd_mb - 1)) + { + CHECK_MB_MAP_BYTE((u4_mb_num + 1), mb_map, u4_right_mb); + } + else + u4_right_mb = 1; + + if(ps_dec->u2_mb_skip_error) + { + ps_dec->u2_skip_deblock = 1; + break; + } + + + if(ps_dec->u2_skip_deblock == 1) + { + break; + } + if((u4_cur_mb && u4_right_mb) == 0) + { + + if(ps_dec->u4_output_present + && ps_dec->u4_fmt_conv_cur_row + < ps_dec->s_disp_frame_info.u4_y_ht) + { + ps_dec->u4_fmt_conv_num_rows = + MIN(ps_dec->u4_fmt_conv_num_rows, + (ps_dec->s_disp_frame_info.u4_y_ht + - ps_dec->u4_fmt_conv_cur_row)); + ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), + ps_dec->u4_fmt_conv_cur_row, + ps_dec->u4_fmt_conv_num_rows); + ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; + } + else + NOP(32); + } + else + { + break; + } + } + + u4_mb_num++; + { + UWORD32 u4_deb_mode, u4_mbs_next; + u4_deb_mode = ps_cur_mb->u1_deblocking_mode; + if(!(u4_deb_mode & MB_DISABLE_FILTERING)) + { + + if(u4_mb_x) + { + ps_left_mb = ps_cur_mb - 1; + + } + else + { + ps_left_mb = NULL; + + } + if(u4_mb_y != 0) + { + ps_top_mb = ps_cur_mb - (u4_image_wd_mb); + } + else + { + ps_top_mb = NULL; + } + + if(u4_deb_mode & MB_DISABLE_LEFT_EDGE) + ps_left_mb = NULL; + if(u4_deb_mode & MB_DISABLE_TOP_EDGE) + ps_top_mb = NULL; + + ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, + i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst, + ps_cur_mb, u4_wd_y, u4_wd_uv, + ps_top_mb, ps_left_mb); + } + + ps_cur_mb++; + u4_mb_x++; + u4_mbs_next = u4_image_wd_mb - u4_mb_x; + + ps_tfr_cxt->pu1_mb_y += 16; + ps_tfr_cxt->pu1_mb_u += 8 * YUV420SP_FACTOR; + ps_tfr_cxt->pu1_mb_v += 8; + + if(!u4_mbs_next) + { + ps_tfr_cxt->pu1_mb_y += ps_tfr_cxt->u4_y_inc; + ps_tfr_cxt->pu1_mb_u += ps_tfr_cxt->u4_uv_inc; + ps_tfr_cxt->pu1_mb_v += ps_tfr_cxt->u4_uv_inc; + u4_mb_y++; + u4_mb_x = 0; + } + } + + } + + ps_dec->u4_cur_deblk_mb_num = u4_mb_num; + ps_dec->u4_deblk_mb_x = u4_mb_x; + ps_dec->u4_deblk_mb_y = u4_mb_y; + ps_dec->ps_cur_deblk_thrd_mb = ps_cur_mb; + +} +void ih264d_computebs_deblk_slice(dec_struct_t *ps_dec, tfr_ctxt_t *ps_tfr_cxt) +{ + dec_mb_info_t *p_cur_mb; + UWORD32 u4_max_addr = ps_dec->ps_cur_sps->u2_max_mb_addr; + UWORD32 i; + UWORD32 u1_mb_aff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD16 u2_slice_num; + UWORD32 u4_mb_num; + + ps_dec->u4_cur_slice_bs_done = 0; + ps_dec->u4_bs_cur_slice_num_mbs = 0; + ps_dec->u4_cur_bs_mb_num = + (ps_dec->ps_computebs_cur_slice->u4_first_mb_in_slice) + << u1_mb_aff; + + while(ps_dec->u4_cur_slice_bs_done != 1) + { + UWORD32 bs_mb_grp = BS_MB_GROUP; + while(1) + { + + UWORD32 u4_cond = 0; + + u4_mb_num = ps_dec->u4_cur_bs_mb_num; + + /*introducing 1 MB delay*/ + if((u4_mb_num + BS_MB_GROUP) <= u4_max_addr) + u4_mb_num = u4_mb_num + BS_MB_GROUP; + else + { + bs_mb_grp = u4_max_addr - u4_mb_num + 1; + u4_mb_num = u4_max_addr; + + } + + CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond); + if(u4_cond) + { + break; + } + + if(ps_dec->u2_skip_deblock == 0) + { + ih264d_check_mb_map_deblk(ps_dec, DEBLK_MB_GROUP, ps_tfr_cxt); + } + } + + GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, ps_dec->u4_cur_bs_mb_num, + u2_slice_num); + + if(u2_slice_num != ps_dec->u2_cur_slice_num_bs) + { + ps_dec->u4_cur_slice_bs_done = 1; + } + + /* Compute BS for NMB group*/ + for(i = 0; i < bs_mb_grp; i++) + { + GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, + ps_dec->u4_cur_bs_mb_num, u2_slice_num); + + if(u2_slice_num != ps_dec->u2_cur_slice_num_bs) + { + ps_dec->u4_cur_slice_bs_done = 1; + } + + if(ps_dec->u4_cur_slice_bs_done == 1) + break; + + p_cur_mb = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_bs_mb_num + & PD_MB_BUF_SIZE_MOD]; + + DEBUG_THREADS_PRINTF("ps_dec->u4_cur_bs_mb_num = %d\n",ps_dec->u4_cur_bs_mb_num); + ih264d_compute_bs_non_mbaff_thread(ps_dec, p_cur_mb, + ps_dec->u4_cur_bs_mb_num); + ps_dec->u4_cur_bs_mb_num++; + ps_dec->u4_bs_cur_slice_num_mbs++; + + } + + if(ps_dec->u4_cur_bs_mb_num > u4_max_addr) + { + ps_dec->u4_cur_slice_bs_done = 1; + } + + /*deblock MB group*/ + { + UWORD32 u4_num_mbs; + + if(ps_dec->u4_cur_bs_mb_num > ps_dec->u4_cur_deblk_mb_num) + + u4_num_mbs = ps_dec->u4_cur_bs_mb_num + - ps_dec->u4_cur_deblk_mb_num; + else + u4_num_mbs = 0; + + if(u4_num_mbs >= DEBLK_MB_GROUP) + u4_num_mbs = DEBLK_MB_GROUP; + if(ps_dec->u2_skip_deblock == 0) + { + ih264d_check_mb_map_deblk_wait(ps_dec, u4_num_mbs, ps_tfr_cxt); + } + } + + } +} + +void ih264d_computebs_deblk_thread(dec_struct_t *ps_dec) +{ + tfr_ctxt_t s_tfr_ctxt; + tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt; // = &ps_dec->s_tran_addrecon; + pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr; + + UWORD32 yield_cnt = 0; + + ithread_set_name("ih264d_computebs_deblk_thread"); + + + // run the loop till all slices are decoded + + // 0: un-identified state, 1 - bs needed, 2 - bs not needed + while(1) + { + if(ps_dec->u4_start_bs_deblk == 0) + { + NOP(128); + NOP(128); + NOP(128); + NOP(128); + } + else + { + break; + } + } + + if(ps_dec->u4_start_bs_deblk == 1) + { + ps_dec->u4_cur_deblk_mb_num = 0; + ps_dec->u4_deblk_mb_x = 0; + ps_dec->u4_deblk_mb_y = 0; + + ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt, + ps_dec->u2_frm_wd_in_mbs, 0); + + ps_tfr_cxt->pu1_mb_y = ps_tfr_cxt->pu1_src_y + 4; + ps_tfr_cxt->pu1_mb_u = ps_tfr_cxt->pu1_src_u + 4; + ps_tfr_cxt->pu1_mb_v = ps_tfr_cxt->pu1_src_v + 4; + + ps_dec->ps_cur_deblk_thrd_mb = ps_dec->ps_deblk_pic; + + while(1) + { + /*Complete all writes before processing next slice*/ + DATA_SYNC(); + /*wait untill all the slice params have been populated*/ + while(ps_dec->ps_computebs_cur_slice->slice_header_done == 0) + { + NOP(32); DEBUG_THREADS_PRINTF(" waiting for slice header at compute bs\n"); + } + + DEBUG_THREADS_PRINTF(" Entering compute bs slice\n"); + ih264d_computebs_deblk_slice(ps_dec, ps_tfr_cxt); + + DEBUG_THREADS_PRINTF(" Exit compute bs slice \n"); + + /*Complete all writes before processing next slice*/ + DATA_SYNC(); + + while(1) + { + volatile void * parse_addr, *computebs_addr; + volatile UWORD32 last_slice; + + parse_addr = (volatile void *)ps_dec->ps_parse_cur_slice; + computebs_addr = + (volatile void *)ps_dec->ps_computebs_cur_slice; + last_slice = + ps_dec->ps_computebs_cur_slice->last_slice_in_frame; + + if(last_slice == 1) + break; + + if(parse_addr != computebs_addr) + break; + + DEBUG_THREADS_PRINTF("Waiting at compute bs for next slice or end of frame\n"); + + NOP(32); + + } + + DEBUG_THREADS_PRINTF("CBS thread:Got next slice/end of frame signal \n "); + + if((void *)ps_dec->ps_parse_cur_slice + > (void *)ps_dec->ps_computebs_cur_slice) + { + ps_dec->ps_computebs_cur_slice++; + ps_dec->u2_cur_slice_num_bs++; + } + else + { + /*Last slice in frame*/ + break; + } + + } + + /*deblock remaining MBs*/ + { + UWORD32 u4_num_mbs; + + u4_num_mbs = ps_dec->ps_cur_sps->u2_max_mb_addr + - ps_dec->u4_cur_deblk_mb_num + 1; + + DEBUG_PERF_PRINTF("mbs left for deblocking= %d \n",u4_num_mbs); + + if(u4_num_mbs != 0) + if(ps_dec->u2_skip_deblock == 0) + ih264d_check_mb_map_deblk_wait(ps_dec, u4_num_mbs, + ps_tfr_cxt); + } + } + + ps_dec->u4_start_bs_deblk = 0; + ithread_exit(0); +} + + diff --git a/decoder/ih264d_thread_compute_bs.h b/decoder/ih264d_thread_compute_bs.h new file mode 100755 index 0000000..1bef07f --- /dev/null +++ b/decoder/ih264d_thread_compute_bs.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +/* + * ih264d_thread_parse_decode.h + * + * Created on: Feb 21, 2012 + * Author: 100492 + */ + +#ifndef _IH264D_THREAD_COMPUTE_BS_H_ +#define _IH264D_THREAD_COMPUTE_BS_H_ +void ih264d_compute_bs_non_mbaff_thread(dec_struct_t * ps_dec, + dec_mb_info_t * ps_cur_mb_info, + UWORD32 u4_mb_num); + +void ih264d_computebs_deblk_thread(dec_struct_t *ps_dec); +#endif /* _IH264D_THREAD_COMPUTE_BS_H_ */ diff --git a/decoder/ih264d_thread_parse_decode.c b/decoder/ih264d_thread_parse_decode.c new file mode 100755 index 0000000..be3cb01 --- /dev/null +++ b/decoder/ih264d_thread_parse_decode.c @@ -0,0 +1,732 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_thread_parse_decode.c + * + * \brief + * Contains routines that for multi-thread decoder + * + * Detailed_description + * + * \date + * 20/02/2012 + * + * \author ZR + ************************************************************************** + */ + +#include "ih264d_error_handler.h" +#include "ih264d_debug.h" +#include "ithread.h" +#include <string.h> +#include "ih264d_defs.h" +#include "ih264d_debug.h" +#include "ih264d_tables.h" +#include "ih264d_structs.h" +#include "ih264d_defs.h" +#include "ih264d_mb_utils.h" +#include "ih264d_thread_parse_decode.h" +#include "ih264d_inter_pred.h" + +#include "ih264d_process_pslice.h" +#include "ih264d_process_intra_mb.h" +#include "ih264d_deblocking.h" +#include "ih264d_format_conv.h" + +void ih264d_deblock_mb_level(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index); + +void ih264d_copy_intra_pred_line(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD32 nmb_index); + +void ih264d_parse_tfr_nmb(dec_struct_t * ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_tfr_n_mb, + UWORD8 u1_end_of_row) +{ + WORD32 i, u4_mb_num; + + const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD32 u4_n_mb_start; + + UNUSED(u1_mb_idx); + UNUSED(u1_num_mbs_next); + if(u1_tfr_n_mb) + { + + + u4_n_mb_start = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs; + + // copy into s_frmMbInfo + + u4_mb_num = u4_n_mb_start; + ps_dec->ps_parse_cur_slice->u4_num_mbs_done_in_slice += u1_num_mbs; + u4_mb_num = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs; + + for(i = 0; i < u1_num_mbs; i++) + { + DATA_SYNC(); + UPDATE_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u4_mb_num, + ps_dec->u2_cur_slice_num); + UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_dec_mb_map, u4_mb_num); + + u4_mb_num++; + } + + DATA_SYNC(); + /****************************************************************/ + /* Check for End Of Row in Next iteration */ + /****************************************************************/ + + /****************************************************************/ + /* Transfer the Following things */ + /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */ + /* N-Mb Recon Data ( To Ext Frame Buffer ) */ + /* N-Mb Intrapredline Data ( Updated Internally) */ + /* N-Mb MV Data ( To Ext MV Buffer ) */ + /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */ + /****************************************************************/ + + /* Swap top and current pointers */ + + ps_dec->s_tran_addrecon_parse.pu1_dest_y += + ps_dec->s_tran_addrecon_parse.u4_inc_y[u1_end_of_row]; + ps_dec->s_tran_addrecon_parse.pu1_dest_u += + ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row]; + ps_dec->s_tran_addrecon_parse.pu1_dest_v += + ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row]; + + if(u1_end_of_row) + { + UWORD16 u2_mb_y; + UWORD32 u4_frame_stride, y_offset; + + ps_dec->ps_top_mb_row = ps_dec->ps_cur_mb_row; + ps_dec->ps_cur_mb_row += ((ps_dec->u2_frm_wd_in_mbs) << u1_mbaff); + + u2_mb_y = ps_dec->u2_mby + (1 + u1_mbaff); + u4_frame_stride = ps_dec->u2_frm_wd_y + << ps_dec->ps_cur_slice->u1_field_pic_flag; + y_offset = (u2_mb_y * u4_frame_stride) << 4; + ps_dec->s_tran_addrecon_parse.pu1_dest_y = + ps_dec->s_cur_pic.pu1_buf1 + y_offset; + + u4_frame_stride = ps_dec->u2_frm_wd_uv + << ps_dec->ps_cur_slice->u1_field_pic_flag; + y_offset = (u2_mb_y * u4_frame_stride) << 3; + ps_dec->s_tran_addrecon_parse.pu1_dest_u = + ps_dec->s_cur_pic.pu1_buf2 + y_offset; + ps_dec->s_tran_addrecon_parse.pu1_dest_v = + ps_dec->s_cur_pic.pu1_buf3 + y_offset; + + } + + ps_dec->ps_deblk_mbn += u1_num_mbs; + + /* + * The Slice boundary is also a valid condition to transfer. So recalculate + * the Left increment, in case the number of MBs is lesser than the + * N MB value. c_numMbs will be equal to N of N MB if the entire N Mb is + * decoded. + */ + ps_dec->s_tran_addrecon.u2_mv_left_inc = ((u1_num_mbs >> u1_mbaff) - 1) + << (4 + u1_mbaff); + ps_dec->s_tran_addrecon.u2_mv_top_left_inc = (u1_num_mbs << 2) - 1 + - (u1_mbaff << 2); + + /* reassign left MV and cur MV pointers */ + ps_dec->ps_mv_left = ps_dec->ps_mv_cur + + ps_dec->s_tran_addrecon.u2_mv_left_inc; + + + + + + ps_dec->ps_mv_cur += (u1_num_mbs << 4); + ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs; + + + ps_dec->u4_dma_buf_idx = 0; + + } +} + +void ih264d_decode_tfr_nmb(dec_struct_t * ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_end_of_row) +{ + + UWORD32 u1_end_of_row_next; + + const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + + /****************************************************************/ + /* Check for End Of Row in Next iteration */ + /****************************************************************/ + u1_end_of_row_next = + u1_num_mbs_next + && ((u1_num_mbs_next) + <= (ps_dec->u1_recon_mb_grp + >> u1_mbaff)); + + /****************************************************************/ + /* Transfer the Following things */ + /* N-Mb DeblkParams Data ( To Ext DeblkParams Buffer ) */ + /* N-Mb Recon Data ( To Ext Frame Buffer ) */ + /* N-Mb Intrapredline Data ( Updated Internally) */ + /* N-Mb MV Data ( To Ext MV Buffer ) */ + /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers) */ + /****************************************************************/ + if(u1_end_of_row) + { + ps_dec->i2_dec_thread_mb_y += (1 << u1_mbaff); + } + ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row, + u1_end_of_row_next); + + if(u1_end_of_row) + { + /* Reset the N-Mb Recon Buf Index to default Values */ + ps_dec->u2_mb_group_cols_y1 = ps_dec->u2_mb_group_cols_y; + ps_dec->u2_mb_group_cols_cr1 = ps_dec->u2_mb_group_cols_cr; + } + /* If next N-Mb Group is the EndOfRow, set the N-Mb Recon Buf Index */ + else if(u1_end_of_row_next) + { + ps_dec->u2_mb_group_cols_y1 = (u1_num_mbs_next << 4) + 8; + ps_dec->u2_mb_group_cols_cr1 = (u1_num_mbs_next << 3) + 8; + } +} + +WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec, UWORD8 u1_num_mbs, // number of MBs loop should run + UWORD8 u1_num_mbs_next, + UWORD8 u1_end_of_row) +{ + WORD32 i,j; + dec_mb_info_t * ps_cur_mb_info; + UWORD32 u4_update_mbaff = 0; + const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + UWORD32 u1_slice_type, u1_B; + WORD32 u1_skip_th; + UWORD32 u1_ipcm_th; + UWORD32 u4_cond; + UWORD16 u2_slice_num,u2_cur_dec_mb_num; + WORD32 ret; + + u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type; + + u1_B = (u1_slice_type == B_SLICE); + + u1_skip_th = + ((u1_slice_type != I_SLICE) ? + (u1_B ? B_8x8 : PRED_8x8R0) : -1); + + u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0); + + u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num; + + /* N Mb MC Loop */ + for(i = 0; i < u1_num_mbs; i++) + { + DATA_SYNC(); + + // check dec_mb_map + UWORD32 yield_cnt = 0, u4_max_addr; + + u4_max_addr = ps_dec->ps_cur_sps->u2_max_mb_addr; + while(1) + { + UWORD32 u4_mb_num = u2_cur_dec_mb_num; + + /*introducing 1 MB delay*/ + if(u4_mb_num < u4_max_addr) + u4_mb_num = u4_mb_num + 1; + + CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond); + if(u4_cond) + { + break; + } + else + { + + { + NOP(128); + + } + + DEBUG_THREADS_PRINTF("waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr = %d\n",u2_cur_dec_mb_num, + ps_dec->u2_cur_mb_addr); + + } + } + + GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num, + u2_slice_num); + + if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread) + { + ps_dec->u4_cur_slice_decode_done = 1; + break; + } + + ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num + & PD_MB_BUF_SIZE_MOD]; + + ps_dec->u4_dma_buf_idx = 0; + ps_dec->u4_pred_info_idx = 0; + + if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) + { + + { + WORD32 pred_cnt = 0; + pred_info_pkd_t *ps_pred_pkd; + UWORD32 u4_pred_info_pkd_idx; + WORD8 i1_pred; + + u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; + + while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) + { + + ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; + + + ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec, + ps_cur_mb_info->u2_mbx,ps_cur_mb_info->u2_mby,(i >> u1_mbaff), + ps_cur_mb_info); + + u4_pred_info_pkd_idx++; + pred_cnt++; + + } + } + ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info); + } + else if(ps_cur_mb_info->u1_mb_type == MB_SKIP) + { + { + WORD32 pred_cnt = 0; + pred_info_pkd_t *ps_pred_pkd; + UWORD32 u4_pred_info_pkd_idx; + WORD8 i1_pred; + + u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx; + + + + while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts) + { + + ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx; + + + ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec, + ps_cur_mb_info->u2_mbx,ps_cur_mb_info->u2_mby,(i >> u1_mbaff), + ps_cur_mb_info); + + + u4_pred_info_pkd_idx++; + pred_cnt++; + } + } + /* Decode MB skip */ + ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info); + } + + u2_cur_dec_mb_num++; + } + + /* N Mb IQ IT RECON Loop */ + for(j = 0; j < i; j++) + { + DATA_SYNC(); + + + ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num + & PD_MB_BUF_SIZE_MOD]; + + + if(ps_cur_mb_info->u1_mb_type <= u1_skip_th) + { + ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j); + } + else if(ps_cur_mb_info->u1_mb_type != MB_SKIP) + { + if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type) + { + ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1); + ret = ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j); + if(ret != OK) + return ret; + } + } + + if(ps_dec->u4_mb_level_deblk == 1) + { + + ih264d_deblock_mb_level(ps_dec, ps_cur_mb_info, j); + } + + if((ps_dec->u4_num_cores >= 3) && (u1_mbaff == 0)) + ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j); + if(u1_mbaff) + { + if(u4_update_mbaff) + { + UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx + + ps_dec->u2_frm_wd_in_mbs + * (ps_cur_mb_info->u2_mby >> 1); + UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); + u4_update_mbaff = 0; + } + else + { + u4_update_mbaff = 1; + } + } + else + { + UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx + + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby; + UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num); + } + ps_dec->cur_dec_mb_num++; + } + + + /*handle the last mb in picture case*/ + if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr) + ps_dec->u4_cur_slice_decode_done = 1; + + if(i != u1_num_mbs) + { + u1_end_of_row = 0; + /*Number of MB's left in row*/ + u1_num_mbs_next = u1_num_mbs_next + ((u1_num_mbs - i) >> u1_mbaff); + } + + ih264d_decode_tfr_nmb(ps_dec, (i), u1_num_mbs_next, u1_end_of_row); + + return OK; +} + +WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec /* Decoder parameters */ +) +{ + UWORD8 u1_num_mbs_next, u1_num_mbsleft, u1_end_of_row = 0; //, u1_slice_end, u1_tfr_n_mb, u1_decode_nmb; + const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs; + UWORD8 u1_mbaff, u1_num_mbs; //,uc_more_data_flag,u1_mb_idx; + + UWORD16 u2_first_mb_in_slice; + + /*dec_bit_stream_t *const ps_bitstrm = ps_dec->ps_bitstrm; + UWORD32 * pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;*/ + + UWORD16 i16_mb_x, i16_mb_y; + UWORD8 u1_field_pic; + UWORD32 u4_frame_stride, x_offset, y_offset; + WORD32 ret; + + tfr_ctxt_t *ps_trns_addr; + + if(ps_dec->ps_decode_cur_slice->slice_header_done != 2) + return ERROR_INV_SLICE_HDR_T; + + + + u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; + + u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice; + + i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs); + i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs); + i16_mb_y <<= u1_mbaff; + ps_dec->i2_dec_thread_mb_y = i16_mb_y; + + /*if((i16_mb_x > (i2_pic_wdin_mbs - 1)) + || (i16_mb_y > ps_dec->u2_frm_ht_in_mbs - 1)) + { + }*/ + if(ps_dec->cur_dec_mb_num == u2_first_mb_in_slice << u1_mbaff) + { + ps_dec->u2_mb_skip_error = 0; + } + else + { + ps_dec->u2_mb_skip_error = 1; + } + ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u1_mbaff; + + // recalculate recon pointers + u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag; + u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic; + x_offset = i16_mb_x << 4; + y_offset = (i16_mb_y * u4_frame_stride) << 4; + + ps_trns_addr = &(ps_dec->s_tran_addrecon); + + ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset; + + u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic; + x_offset >>= 1; + y_offset = (i16_mb_y * u4_frame_stride) << 3; + + x_offset *= YUV420SP_FACTOR; + + ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset; + ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset; + + ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y; + ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u; + ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v; + + if(ps_dec->u4_mb_level_deblk == 1) + { + /*If it is not the first mb in row,the previous MB which needs to be deblocked + * as there is delay of 1 MB*/ + if(i16_mb_x != 0) + { + ps_trns_addr->pu1_mb_y -= MB_SIZE; + ps_trns_addr->pu1_mb_u -= BLK8x8SIZE * YUV420SP_FACTOR; + ps_trns_addr->pu1_mb_v -= BLK8x8SIZE; + } + } + + /**********Number of Mbs in Slice**********/ + + ps_dec->ps_deblk_mbn_dec_thrd = ps_dec->ps_deblk_pic + + (u2_first_mb_in_slice << u1_mbaff); + + /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */ + + { + ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp; + ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp; + } + { + UWORD8 uc_nofield_nombaff; + uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) + && (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) + && (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE) + && (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0)); + + if(uc_nofield_nombaff == 0) + { + ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp; + ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp; + } + + } + + ps_dec->u4_cur_slice_decode_done = 0; + + + while(ps_dec->u4_cur_slice_decode_done != 1) + { + + u1_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u1_mbaff); + + if(u1_num_mbsleft <= ps_dec->u1_recon_mb_grp) + { + u1_num_mbs = u1_num_mbsleft; + + /*Indicate number of mb's left in a row*/ + u1_num_mbs_next = 0; + u1_end_of_row = 1; + i16_mb_x = 0; + } + else + { + u1_num_mbs = ps_dec->u1_recon_mb_grp; + + /*Indicate number of mb's left in a row*/ + u1_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x + - (ps_dec->u1_recon_mb_grp >> u1_mbaff); + i16_mb_x += (u1_num_mbs >> u1_mbaff); + u1_end_of_row = 0; + + } + ret = ih264d_decode_recon_tfr_nmb_thread(ps_dec, u1_num_mbs, u1_num_mbs_next, + u1_end_of_row); + if(ret != OK) + return ret; + } + return OK; +} + +void ih264d_decode_picture_thread(dec_struct_t *ps_dec ) +{ + volatile WORD32 i4_err_status; + + + ithread_set_name("ih264d_decode_picture_thread"); + + + + // run the loop till all slices are decoded + + while(1) + { + if(ps_dec->u4_start_frame_decode) + { + break; + } + else + { + NOP(32); + + } + } + + DEBUG_THREADS_PRINTF("Got start of frame u4_flag\n"); + + if(ps_dec->u4_start_frame_decode == 1) + { + while(1) + { + /*Complete all writes before processing next slice*/ + DATA_SYNC(); + /*wait untill all the slice params have been populated*/ + while(ps_dec->ps_decode_cur_slice->slice_header_done == 0) + { + NOP(32); DEBUG_THREADS_PRINTF(" waiting for slice header \n"); + } + + DEBUG_THREADS_PRINTF(" Entering decode slice\n"); + + ih264d_decode_slice_thread(ps_dec); + DEBUG_THREADS_PRINTF(" Exit ih264d_decode_slice_thread \n"); + + /*Complete all writes before processing next slice*/ + DATA_SYNC(); + + while(1) + { + volatile void * parse_addr, *dec_addr; + volatile UWORD32 last_slice; + + parse_addr = (volatile void *)ps_dec->ps_parse_cur_slice; + dec_addr = (volatile void *)ps_dec->ps_decode_cur_slice; + last_slice = ps_dec->ps_decode_cur_slice->last_slice_in_frame; + + if(last_slice == 1) + break; + + if(parse_addr != dec_addr) + break; + + DEBUG_THREADS_PRINTF("Waiting for next slice or end of frame\n"); + + NOP(32); + if(i4_err_status != 0) + { + /*In the case of error set decode Mb number ,so that the + parse thread does not wait because of mb difference being + greated the 32*/ + ps_dec->cur_dec_mb_num = ps_dec->u2_cur_mb_addr - 1; + } + } + + DEBUG_THREADS_PRINTF("Got next slice/end of frame signal \n "); + + if((void *)ps_dec->ps_parse_cur_slice + > (void *)ps_dec->ps_decode_cur_slice) + { + ps_dec->ps_decode_cur_slice++; + ps_dec->u2_cur_slice_num_dec_thread++; + } + else + { + /*Last slice in frame*/ + break; + } + + } + } + + if(ps_dec->u4_output_present) + { + while(1) + { + volatile UWORD32 *u4_flag = &(ps_dec->as_fmt_conv_part[1].u4_flag); + + DEBUG_THREADS_PRINTF(" Format conversion loop in decode *u4_flag = %d\n",*u4_flag); + if(2 == *u4_flag) + { + if(ps_dec->as_fmt_conv_part[1].u4_num_rows_y) + ih264d_format_convert( + ps_dec, &(ps_dec->s_disp_op), + ps_dec->as_fmt_conv_part[1].u4_start_y, + ps_dec->as_fmt_conv_part[1].u4_num_rows_y); + + break; + } + else if(1 == *u4_flag) + { + NOP(32); + + } + else + break; + + } + } + + ithread_exit(0); + +} + +void ih264d_signal_decode_thread(dec_struct_t *ps_dec) +{ + if(ps_dec->u4_dec_thread_created == 1) + { + + if(ps_dec->u4_start_frame_decode == 1) + ps_dec->ps_parse_cur_slice->last_slice_in_frame = 1; + else + /*to indicate frame in error*/ + ps_dec->u4_start_frame_decode = 2; + + ithread_join(ps_dec->pv_dec_thread_handle, NULL); + ps_dec->u4_dec_thread_created = 0; + } +} +void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec) +{ + if(ps_dec->u4_bs_deblk_thread_created) + { + /*signal error*/ + if(ps_dec->u4_start_bs_deblk == 0) + ps_dec->u4_start_bs_deblk = 2; + + ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); + ps_dec->u4_bs_deblk_thread_created = 0; + } + +} diff --git a/decoder/ih264d_thread_parse_decode.h b/decoder/ih264d_thread_parse_decode.h new file mode 100755 index 0000000..013b14f --- /dev/null +++ b/decoder/ih264d_thread_parse_decode.h @@ -0,0 +1,48 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +/* + * ih264d_thread_parse_decode.h + * + * Created on: Feb 21, 2012 + * Author: 100492 + */ + +#ifndef _IH264D_THREAD_PARSE_DECPDE_H_ +#define _IH264D_THREAD_PARSE_DECPDE_H_ +void ih264d_parse_tfr_nmb(dec_struct_t *ps_dec, + UWORD8 u1_mb_idx, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_tfr_n_mb, + UWORD8 u1_end_of_row); +void ih264d_decode_tfr_nmb(dec_struct_t *ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_end_of_row); +WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t *ps_dec, + UWORD8 u1_num_mbs, + UWORD8 u1_num_mbs_next, + UWORD8 u1_end_of_row); +void ih264d_decode_picture_thread(dec_struct_t *ps_dec); +WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec); + + + +#endif /* _IH264D_THREAD_PARSE_DECPDE_H_ */ diff --git a/decoder/ih264d_transfer_address.h b/decoder/ih264d_transfer_address.h new file mode 100755 index 0000000..aa64b85 --- /dev/null +++ b/decoder/ih264d_transfer_address.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_TRANSFER_ADDRESS_H_ +#define _IH264D_TRANSFER_ADDRESS_H_ + +typedef struct +{ + UWORD8 *pu1_src_y; + UWORD8 *pu1_src_u; + UWORD8 *pu1_src_v; + UWORD8 *pu1_dest_y; + UWORD8 *pu1_dest_u; + UWORD8 *pu1_dest_v; + UWORD32 u4_inc_y[2]; + UWORD32 u4_inc_uv[2]; + UWORD16 u2_frm_wd_y; + UWORD16 u2_frm_wd_uv; + UWORD8 *pu1_mb_y; + UWORD8 *pu1_mb_u; + UWORD8 *pu1_mb_v; + UWORD16 u2_mv_left_inc; + UWORD16 u2_mv_top_left_inc; + UWORD32 u4_y_inc; + UWORD32 u4_uv_inc; + +} tfr_ctxt_t; + +#endif diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c new file mode 100755 index 0000000..f60d99c --- /dev/null +++ b/decoder/ih264d_utils.c @@ -0,0 +1,2625 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 ih264d_utils.c + * + * \brief + * Contains routines that handle of start and end of pic processing + * + * \date + * 19/12/2002 + * + * \author AI + ************************************************************************** + */ + +#include <string.h> +#include "ih264_typedefs.h" +#include "ithread.h" +#include "ih264d_deblocking.h" +#include "ih264d_parse_slice.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_dpb_manager.h" +#include "ih264d_defs.h" +#include "ih264d_structs.h" +#include "ih264d_mem_request.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_tables.h" +#include "ih264d_debug.h" +#include "ih264d_mb_utils.h" +#include "ih264d_error_handler.h" +#include "ih264d_dpb_manager.h" +#include "ih264d_utils.h" +#include "ih264d_defs.h" +#include "ih264d_tables.h" +#include "ih264d_inter_pred.h" +#include "ih264d_dpb_manager.h" +#include "iv.h" +#include "ivd.h" +#include "ih264d_format_conv.h" +#include "ih264_error.h" +#include "ih264_disp_mgr.h" +#include "ih264_buf_mgr.h" +#include "ih264d_utils.h" + +/*! + ************************************************************************** + * \if Function name : ih264d_is_end_of_pic \endif + * + * \brief + * Determines whether current slice is first slice of a new picture as + * defined in 7.4.1.2.4 of 14496-10. + * + * \return + * Return 1 if current slice is first slice of a new picture + * Otherwise it returns 0 + ************************************************************************** + */ +UWORD8 ih264d_is_end_of_pic(UWORD16 u2_frame_num, + UWORD8 u1_nal_ref_idc, + pocstruct_t *ps_cur_poc, + pocstruct_t *ps_prev_poc, + dec_slice_params_t * ps_prev_slice, /*!< Previous slice parameters*/ + UWORD8 u1_pic_order_cnt_type, + UWORD8 u1_nal_unit_type, + UWORD32 u4_idr_pic_id, + UWORD8 u1_field_pic_flag, + UWORD8 u1_bottom_field_flag) +{ + WORD8 i1_is_end_of_pic; + WORD8 a, b, c, d, e, f, g, h; + + a = b = c = d = e = f = g = h = 0; + a = (ps_prev_slice->u2_frame_num != u2_frame_num); + b = (ps_prev_slice->u1_field_pic_flag != u1_field_pic_flag); + if(u1_field_pic_flag && ps_prev_slice->u1_field_pic_flag) + c = (u1_bottom_field_flag != ps_prev_slice->u1_bottom_field_flag); + d = + (u1_nal_ref_idc == 0 && ps_prev_slice->u1_nal_ref_idc != 0) + || (u1_nal_ref_idc != 0 + && ps_prev_slice->u1_nal_ref_idc + == 0); + if(!a) + { + if((u1_pic_order_cnt_type == 0) + && (ps_prev_slice->u1_pic_order_cnt_type == 0)) + { + e = + ((ps_cur_poc->i4_pic_order_cnt_lsb + != ps_prev_poc->i4_pic_order_cnt_lsb) + || (ps_cur_poc->i4_delta_pic_order_cnt_bottom + != ps_prev_poc->i4_delta_pic_order_cnt_bottom)); + } + + if((u1_pic_order_cnt_type == 1) + && (ps_prev_slice->u1_pic_order_cnt_type == 1)) + { + f = + ((ps_cur_poc->i4_delta_pic_order_cnt[0] + != ps_prev_poc->i4_delta_pic_order_cnt[0]) + || (ps_cur_poc->i4_delta_pic_order_cnt[1] + != ps_prev_poc->i4_delta_pic_order_cnt[1])); + } + } + + if((u1_nal_unit_type == IDR_SLICE_NAL) + && (ps_prev_slice->u1_nal_unit_type == IDR_SLICE_NAL)) + { + g = (u4_idr_pic_id != ps_prev_slice->u4_idr_pic_id); + } + + if((u1_nal_unit_type == IDR_SLICE_NAL) + && (ps_prev_slice->u1_nal_unit_type != IDR_SLICE_NAL)) + { + h = 1; + } + i1_is_end_of_pic = a + b + c + d + e + f + g + h; + return (i1_is_end_of_pic); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_decode_pic_order_cnt \endif + * + * \brief + * Calculates picture order count of picture. + * + * \return + * Returns the pic order count of the picture to which current + * Slice belongs. + * + ************************************************************************** + */ +WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, + UWORD32 u2_frame_num, + pocstruct_t *ps_prev_poc, + pocstruct_t *ps_cur_poc, + dec_slice_params_t *ps_cur_slice, /*!< Pointer to current slice Params*/ + dec_pic_params_t * ps_pps, + UWORD8 u1_nal_ref_idc, + UWORD8 u1_bottom_field_flag, + UWORD8 u1_field_pic_flag, + WORD32 *pi4_poc) +{ + WORD16 i1_pic_msb; + WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0; + dec_seq_params_t *ps_seq = ps_pps->ps_sps; + WORD32 i4_prev_frame_num_ofst; + + switch(ps_seq->u1_pic_order_cnt_type) + { + case 0: + /* POC TYPE 0 */ + if(u1_is_idr_slice) + { + ps_prev_poc->i4_pic_order_cnt_msb = 0; + ps_prev_poc->i4_pic_order_cnt_lsb = 0; + } + if(ps_prev_poc->u1_mmco_equalto5) + { + if(ps_prev_poc->u1_bot_field != 1) + { + ps_prev_poc->i4_pic_order_cnt_msb = 0; + ps_prev_poc->i4_pic_order_cnt_lsb = + ps_prev_poc->i4_top_field_order_count; + } + else + { + ps_prev_poc->i4_pic_order_cnt_msb = 0; + ps_prev_poc->i4_pic_order_cnt_lsb = 0; + } + } + + if((ps_cur_poc->i4_pic_order_cnt_lsb + < ps_prev_poc->i4_pic_order_cnt_lsb) + && ((ps_prev_poc->i4_pic_order_cnt_lsb + - ps_cur_poc->i4_pic_order_cnt_lsb) + >= (ps_seq->i4_max_pic_order_cntLsb + >> 1))) + { + i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + + ps_seq->i4_max_pic_order_cntLsb; + } + else if((ps_cur_poc->i4_pic_order_cnt_lsb + > ps_prev_poc->i4_pic_order_cnt_lsb) + && ((ps_cur_poc->i4_pic_order_cnt_lsb + - ps_prev_poc->i4_pic_order_cnt_lsb) + >= (ps_seq->i4_max_pic_order_cntLsb + >> 1))) + { + i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb + - ps_seq->i4_max_pic_order_cntLsb; + } + else + { + i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb; + } + + if(!u1_field_pic_flag || !u1_bottom_field_flag) + i4_top_field_order_cnt = i1_pic_msb + + ps_cur_poc->i4_pic_order_cnt_lsb; + + if(!u1_field_pic_flag) + { + i4_bottom_field_order_cnt = i4_top_field_order_cnt + + ps_cur_poc->i4_delta_pic_order_cnt_bottom; + } + else if(u1_bottom_field_flag) + { + i4_bottom_field_order_cnt = i1_pic_msb + + ps_cur_poc->i4_pic_order_cnt_lsb; + } + ps_cur_poc->i4_pic_order_cnt_msb = i1_pic_msb; + break; + + case 1: + { + /* POC TYPE 1 */ + UWORD8 i; + WORD32 prev_frame_num; + WORD32 frame_num_ofst; + WORD32 abs_frm_num; + WORD32 poc_cycle_cnt, frame_num_in_poc_cycle; + WORD32 expected_delta_poc_cycle; + WORD32 expected_poc; + + prev_frame_num = (WORD32)ps_cur_slice->u2_frame_num; + if(!u1_is_idr_slice) + { + if(ps_cur_slice->u1_mmco_equalto5) + { + prev_frame_num = 0; + i4_prev_frame_num_ofst = 0; + } + else + { + i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst; + } + } + else + i4_prev_frame_num_ofst = 0; + + /* 1. Derivation for FrameNumOffset */ + if(u1_is_idr_slice) + { + frame_num_ofst = 0; + ps_cur_poc->i4_delta_pic_order_cnt[0] = 0; + ps_cur_poc->i4_delta_pic_order_cnt[1] = 0; + } + else if(prev_frame_num > ((WORD32)u2_frame_num)) + { + frame_num_ofst = i4_prev_frame_num_ofst + + ps_seq->u2_u4_max_pic_num_minus1 + 1; + } + else + frame_num_ofst = i4_prev_frame_num_ofst; + + /* 2. Derivation for absFrameNum */ + if(0 != ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle) + abs_frm_num = frame_num_ofst + u2_frame_num; + else + abs_frm_num = 0; + if((u1_nal_ref_idc == 0) && (abs_frm_num > 0)) + abs_frm_num = abs_frm_num - 1; + + /* 4. expectedDeltaPerPicOrderCntCycle is derived as */ + expected_delta_poc_cycle = 0; + for(i = 0; i < ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle; + i++) + { + expected_delta_poc_cycle += + ps_seq->i4_ofst_for_ref_frame[i]; + } + + /* 3. When absFrameNum > 0, picOrderCntCycleCnt and + frame_num_in_poc_cycle are derived as : */ + /* 5. expectedPicOrderCnt is derived as : */ + if(abs_frm_num > 0) + { + poc_cycle_cnt = + DIV((abs_frm_num - 1), + ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle); + frame_num_in_poc_cycle = + MOD((abs_frm_num - 1), + ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle); + + expected_poc = poc_cycle_cnt + * expected_delta_poc_cycle; + for(i = 0; i <= frame_num_in_poc_cycle; i++) + { + expected_poc = expected_poc + + ps_seq->i4_ofst_for_ref_frame[i]; + } + } + else + expected_poc = 0; + + if(u1_nal_ref_idc == 0) + { + expected_poc = expected_poc + + ps_seq->i4_ofst_for_non_ref_pic; + } + + /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */ + if(!u1_field_pic_flag) + { + i4_top_field_order_cnt = expected_poc + + ps_cur_poc->i4_delta_pic_order_cnt[0]; + i4_bottom_field_order_cnt = i4_top_field_order_cnt + + ps_seq->i4_ofst_for_top_to_bottom_field + + ps_cur_poc->i4_delta_pic_order_cnt[1]; + } + else if(!u1_bottom_field_flag) + { + i4_top_field_order_cnt = expected_poc + + ps_cur_poc->i4_delta_pic_order_cnt[0]; + } + else + { + i4_bottom_field_order_cnt = expected_poc + + ps_seq->i4_ofst_for_top_to_bottom_field + + ps_cur_poc->i4_delta_pic_order_cnt[0]; + } + /* Copy the current POC info into Previous POC structure */ + ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst; + } + + break; + case 2: + { + /* POC TYPE 2 */ + WORD32 prev_frame_num; + WORD32 frame_num_ofst; + WORD32 tmp_poc; + + prev_frame_num = (WORD32)ps_cur_slice->u2_frame_num; + if(!u1_is_idr_slice) + { + if(ps_cur_slice->u1_mmco_equalto5) + { + prev_frame_num = 0; + i4_prev_frame_num_ofst = 0; + } + else + i4_prev_frame_num_ofst = ps_prev_poc->i4_prev_frame_num_ofst; + } + else + i4_prev_frame_num_ofst = 0; + + /* 1. Derivation for FrameNumOffset */ + if(u1_is_idr_slice) + { + frame_num_ofst = 0; + ps_cur_poc->i4_delta_pic_order_cnt[0] = 0; + ps_cur_poc->i4_delta_pic_order_cnt[1] = 0; + } + else if(prev_frame_num > ((WORD32)u2_frame_num)) + { + frame_num_ofst = i4_prev_frame_num_ofst + + ps_seq->u2_u4_max_pic_num_minus1 + 1; + } + else + frame_num_ofst = i4_prev_frame_num_ofst; + + /* 2. Derivation for tempPicOrderCnt */ + if(u1_is_idr_slice) + tmp_poc = 0; + else if(u1_nal_ref_idc == 0) + tmp_poc = ((frame_num_ofst + u2_frame_num) << 1) + - 1; + else + tmp_poc = ((frame_num_ofst + u2_frame_num) << 1); + + /* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */ + if(!u1_field_pic_flag) + { + i4_top_field_order_cnt = tmp_poc; + i4_bottom_field_order_cnt = tmp_poc; + } + else if(!u1_bottom_field_flag) + i4_top_field_order_cnt = tmp_poc; + else + i4_bottom_field_order_cnt = tmp_poc; + + /* Copy the current POC info into Previous POC structure */ + ps_prev_poc->i4_prev_frame_num_ofst = frame_num_ofst; + ps_cur_poc->i4_prev_frame_num_ofst = frame_num_ofst; + } + break; + default: + return ERROR_INV_POC_TYPE_T; + break; + } + + if(!u1_field_pic_flag) // or a complementary field pair + { + *pi4_poc = MIN(i4_top_field_order_cnt, i4_bottom_field_order_cnt); + ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt; + ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt; + } + else if(!u1_bottom_field_flag) + { + *pi4_poc = i4_top_field_order_cnt; + ps_pps->i4_top_field_order_cnt = i4_top_field_order_cnt; + } + else + { + *pi4_poc = i4_bottom_field_order_cnt; + ps_pps->i4_bottom_field_order_cnt = i4_bottom_field_order_cnt; + } + + ps_pps->i4_avg_poc = *pi4_poc; + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_end_of_pic_processing \endif + * + * \brief + * Performs the end of picture processing. + * + * It performs deblocking on the current picture and sets the i4_status of + * current picture as decoded. + * + * \return + * 0 on Success and Error code otherwise. + ************************************************************************** + */ +WORD32 ih264d_end_of_pic_processing(dec_struct_t *ps_dec) +{ + UWORD8 u1_pic_type, u1_nal_ref_idc; + dec_slice_params_t *ps_cur_slice = ps_dec->ps_cur_slice; + WORD32 ret; + + /* If nal_ref_idc is equal to 0 for one slice or slice data partition NAL + unit of a particular picture, it shall be equal to 0 for all slice and + slice data partition NAL units of the picture. nal_ref_idc greater + than 0 indicates that the content of the NAL unit belongs to a decoded + picture that is stored and marked for use as a reference picture in the + decoded picture buffer. */ + + /* 1. Do MMCO + 2. Add Cur Pic to list of reference pics. + */ + + /* Call MMCO */ + u1_pic_type = 0; + u1_nal_ref_idc = ps_cur_slice->u1_nal_ref_idc; + + if(u1_nal_ref_idc) + { + if(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) + { + if(ps_dec->ps_dpb_cmds->u1_long_term_reference_flag == 0) + { + ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); + + { + ret = ih264d_insert_st_node(ps_dec->ps_dpb_mgr, + ps_dec->ps_cur_pic, + ps_dec->u1_pic_buf_id, + ps_cur_slice->u2_frame_num); + if(ret != OK) + return ret; + } + } + else + { + /* Equivalent of inserting a pic directly as longterm Pic */ + + { + ret = ih264d_insert_st_node(ps_dec->ps_dpb_mgr, + ps_dec->ps_cur_pic, + ps_dec->u1_pic_buf_id, + ps_cur_slice->u2_frame_num); + if(ret != OK) + return ret; + /* Set longTermIdx = 0, MaxLongTermFrameIdx = 0 */ + ret = ih264d_delete_st_node_or_make_lt( + ps_dec->ps_dpb_mgr, + ps_cur_slice->u2_frame_num, 0, + ps_cur_slice->u1_field_pic_flag); + if(ret != OK) + return ret; + ps_dec->ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = 1; + } + } + } + else + { + + { + UWORD16 u2_pic_num = ps_cur_slice->u2_frame_num; + + + + ret = ih264d_do_mmco_buffer( + ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr, + ps_dec->ps_cur_sps->u1_num_ref_frames, + u2_pic_num, + (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1), + ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic, + ps_dec->u1_pic_buf_id, + ps_cur_slice->u1_field_pic_flag, + ps_dec->e_dec_status); + if(ret != OK) + return ret; + } + } + ih264d_update_default_index_list(ps_dec->ps_dpb_mgr); + } + + if(ps_cur_slice->u1_field_pic_flag) + { + if(ps_cur_slice->u1_bottom_field_flag) + { + if(u1_nal_ref_idc) + u1_pic_type = u1_pic_type | BOT_REF; + u1_pic_type = u1_pic_type | BOT_FLD; + } + else + { + if(u1_nal_ref_idc) + u1_pic_type = u1_pic_type | TOP_REF; + u1_pic_type = u1_pic_type | TOP_FLD; + } + } + else + u1_pic_type = TOP_REF | BOT_REF; + ps_dec->ps_cur_pic->u1_pic_type |= u1_pic_type; + +#if ROW_ACCESSES_STAT + { + H264_DEC_DEBUG_PRINT("Row_Accesses_BeforeBB = %6d, Row_Accesses_AfterBB = %6d \n\n", + gui_Row_Accesses_BeforeBB, gui_Row_Accesses_AfterBB); + gui_Row_Accesses_BeforeBBTotal += gui_Row_Accesses_BeforeBB; + gui_Row_Accesses_AfterBBTotal += gui_Row_Accesses_AfterBB; + gui_Row_Accesses_AfterBB = 0; + gui_Row_Accesses_BeforeBB = 0; + } +#endif + + if(ps_cur_slice->u1_field_pic_flag) + { + H264_DEC_DEBUG_PRINT("Toggling secondField\n"); + ps_dec->u1_second_field = 1 - ps_dec->u1_second_field; + } + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : init_dpb_size */ +/* */ +/* Description : This function calculates the DBP i4_size in frames */ +/* Inputs : ps_seq - current sequence params */ +/* */ +/* Globals : None */ +/* */ +/* Outputs : None */ +/* */ +/* Returns : DPB in frames */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 28 04 2005 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_get_dpb_size(dec_seq_params_t *ps_seq, dec_struct_t *ps_dec) +{ + WORD32 i4_size; + UWORD8 u1_level_idc; + + + u1_level_idc = ps_seq->u1_level_idc; //harcode for the time being + +#if DPB_HACK + u1_level_idc = (u1_level_idc < 30) ? 30 : u1_level_idc; + u1_level_idc = (u1_level_idc > 30) ? 30 : u1_level_idc; +#endif + + u1_level_idc = MIN(u1_level_idc, ps_dec->u4_level_at_init); + //DPB_HACK + + + switch(u1_level_idc) + { + case 10: + i4_size = 152064; + break; + case 11: + i4_size = 345600; + break; + case 12: + i4_size = 912384; + break; + case 13: + i4_size = 912384; + break; + case 20: + i4_size = 912384; + break; + case 21: + i4_size = 1824768; + break; + case 22: + i4_size = 3110400; + break; + case 30: + i4_size = 3110400; + break; + case 31: + i4_size = 6912000; + break; + case 32: + i4_size = 7864320; + break; + case 40: + i4_size = 12582912; + break; + case 41: + i4_size = 12582912; + break; + case 42: + i4_size = 12582912; + break; + case 50: + i4_size = 42393600; + break; + case 51: + i4_size = 70778880; + break; + default: + i4_size = 6912000; + break; + /* + * Not calling the error handler if the level has come wrong. + */ + /*{ + UWORD32 i4_error_code; + i4_error_code = ERROR_UNKNOWN_LEVEL ; + + } + break;*/ + } + + /* Temporary hack to run Tractor Cav/Cab/MbAff Profiler ps_bitstrm */ +#if DPB_HACK + i4_size = 6912000; +#endif + + i4_size = + i4_size + / (ps_seq->u2_frm_wd_in_mbs + * (ps_seq->u2_frm_ht_in_mbs + << (1 + - ps_seq->u1_frame_mbs_only_flag))); + i4_size = i4_size / 384; // temp / (256 * 1.5) + i4_size = MIN(i4_size, 16); + i4_size = MAX(i4_size, 1); + return (i4_size); +} + +WORD32 ih264d_get_dpb_size_new(UWORD32 u4_level_idc, + UWORD32 u2_frm_wd_in_mbs, + UWORD32 u2_frm_ht_in_mbs) +{ + + UWORD32 i4_size = 0; + + switch(u4_level_idc) + { + case 10: + i4_size = 152064; + break; + case 11: + i4_size = 345600; + break; + case 12: + i4_size = 912384; + break; + case 13: + i4_size = 912384; + break; + case 20: + i4_size = 912384; + break; + case 21: + i4_size = 1824768; + break; + case 22: + i4_size = 3110400; + break; + case 30: + i4_size = 3110400; + break; + case 31: + i4_size = 6912000; + break; + case 32: + i4_size = 7864320; + break; + case 40: + i4_size = 12582912; + break; + case 41: + i4_size = 12582912; + break; + case 42: + i4_size = 12582912; + break; + case 50: + i4_size = 42393600; + break; + case 51: + i4_size = 70778880; + break; + default: + { + return -1; + } + break; + } + + i4_size = i4_size / (u2_frm_wd_in_mbs * (u2_frm_ht_in_mbs)); + i4_size = (i4_size + 383) / 384; + i4_size = MIN(i4_size, 16); + i4_size = MAX(i4_size, 1); + return (i4_size); +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_max_possible_ref_pics */ +/* */ +/* Description : This function returns the maximum number of */ +/* reference buffers corresponding to the current Level */ +/* in accordance to "Table A-1 Level limits" in standard. */ +/* Please refer to Annex A - Profiles and Levels */ +/* Maximum Number of reference buffers are derived from */ +/* the dbpsize and max_mbs_in frame given in the table */ +/* Inputs : level number */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 19 05 2005 SWRN Draft */ +/* */ +/*****************************************************************************/ + +UWORD8 ih264d_max_possible_ref_pics(UWORD8 u1_level) +{ + switch(u1_level) + { + case H264_LEVEL_1_0: + return (MAX_REF_LEVEL_1_0); + case H264_LEVEL_1_1: + return (MAX_REF_LEVEL_1_1); + case H264_LEVEL_1_2: + return (MAX_REF_LEVEL_1_2); + case H264_LEVEL_1_3: + return (MAX_REF_LEVEL_1_3); + case H264_LEVEL_2_0: + return (MAX_REF_LEVEL_2_0); + case H264_LEVEL_2_1: + return (MAX_REF_LEVEL_2_1); + case H264_LEVEL_2_2: + return (MAX_REF_LEVEL_2_2); + case H264_LEVEL_3_0: + return (MAX_REF_LEVEL_3_0); + } + + return (H264_MAX_REF_PICS); +} + +/***************************************************************************/ +/* If change in Level or the required PicBuffers i4_size is more than the */ +/* current one FREE the current PicBuffers and allocate affresh */ +/***************************************************************************/ +UWORD8 ih264d_is_sps_changed(prev_seq_params_t * ps_prv, + dec_seq_params_t * ps_cur) +{ + + if((ps_prv->u2_frm_wd_in_mbs != ps_cur->u2_frm_wd_in_mbs) + || (ps_prv->u1_level_idc != ps_cur->u1_level_idc) + || (ps_prv->u1_profile_idc != ps_cur->u1_profile_idc) + || (ps_cur->u2_frm_ht_in_mbs != ps_prv->u2_frm_ht_in_mbs) + || (ps_cur->u1_frame_mbs_only_flag + != ps_prv->u1_frame_mbs_only_flag) + || (ps_cur->u1_direct_8x8_inference_flag + != ps_prv->u1_direct_8x8_inference_flag)) + return 1; + + return 0; +} + +/**************************************************************************/ +/* This function initialises the value of ps_dec->u1_recon_mb_grp */ +/* ps_dec->u1_recon_mb_grp must satisfy the following criteria */ +/* - multiple of 2 (required for N/2 parse-mvpred design) */ +/* - multiple of 4 (if it is not a frame_mbs_only sequence), */ +/* in this case N/2 itself needs to be even for mbpair processing */ +/* - lesser than ps_dec->u2_frm_wd_in_mbs/2 (at least 3 N-Chunks */ +/* should make a row to ensure proper MvTop transferring) */ +/**************************************************************************/ +WORD32 ih264d_init_dec_mb_grp(dec_struct_t *ps_dec) +{ + dec_seq_params_t *ps_seq = ps_dec->ps_cur_sps; + UWORD8 u1_frm = ps_seq->u1_frame_mbs_only_flag; + + ps_dec->u1_recon_mb_grp = PARSE_MB_GROUP_4; + + //NMB set to width in MBs for non-mbaff cases + if(0 == ps_seq->u1_mb_aff_flag) + ps_dec->u1_recon_mb_grp = ps_dec->u2_frm_wd_in_mbs; + + ps_dec->u1_recon_mb_grp_pair = ps_dec->u1_recon_mb_grp >> 1; + + if(!ps_dec->u1_recon_mb_grp) + { + return ERROR_MB_GROUP_ASSGN_T; + } + + ps_dec->u4_num_mbs_prev_nmb = ps_dec->u1_recon_mb_grp; + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : get_numbuf_dpb_bank \endif + * + * \brief + * Initializes the picture. + * + * \return + * 0 on Success and Error code otherwise + * + * \note + * This function is called when first slice of the + * NON -IDR picture is encountered. + ************************************************************************** + */ +static WORD32 get_numbuf_dpb_bank(dec_struct_t *ps_dec) +{ + WORD32 i4_DPB_size; + WORD32 i4_pic_size; + WORD32 i4_num_buf_alloc; + UWORD32 Ysize; + UWORD32 UVsize; + UWORD32 one_frm_size; + UWORD32 luma_height; + + luma_height = ps_dec->u2_pic_ht; + + i4_DPB_size = ps_dec->ps_mem_tab[MEM_REC_REF_PIC].u4_mem_size; + + Ysize = (ps_dec->u2_frm_wd_y) * (luma_height + (PAD_LEN_Y_V << 2)); + + UVsize = Ysize >> 2; + + { + if(ps_dec->u4_share_disp_buf == 1) + { + /* In case of buffers getting shared between application and library + there is no need of reference memtabs. Instead of setting the i4_size + to zero, it is reduced to a small i4_size to ensure that changes + in the code are minimal */ + if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU) + || (ps_dec->u1_chroma_format == IV_YUV_420P)) + { + Ysize = 64; + } + if(ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + { + UVsize = 64; + } + + } + } + + one_frm_size = (((Ysize + 127) >> 7) << 7) + + ((((UVsize << 1) + 127) >> 7) << 7); + i4_num_buf_alloc = i4_DPB_size / (one_frm_size); + + return i4_num_buf_alloc; +} +/*! + ************************************************************************** + * \if Function name : ih264d_init_pic \endif + * + * \brief + * Initializes the picture. + * + * \return + * 0 on Success and Error code otherwise + * + * \note + * This function is called when first slice of the + * NON -IDR picture is encountered. + ************************************************************************** + */ +WORD32 ih264d_init_pic(dec_struct_t *ps_dec, + UWORD16 u2_frame_num, + WORD32 i4_poc, + dec_pic_params_t *ps_pps) +{ + dec_seq_params_t *ps_seq = ps_pps->ps_sps; + prev_seq_params_t * ps_prev_seq_params = &ps_dec->s_prev_seq_params; + WORD32 i4_pic_bufs; + WORD32 ret; + + ps_dec->ps_cur_slice->u2_frame_num = u2_frame_num; + ps_dec->ps_cur_slice->i4_poc = i4_poc; + ps_dec->ps_cur_pps = ps_pps; + ps_dec->ps_cur_pps->pv_codec_handle = ps_dec; + + ps_dec->ps_cur_sps = ps_seq; + ps_dec->ps_dpb_mgr->i4_max_frm_num = ps_seq->u2_u4_max_pic_num_minus1 + + 1; + + ps_dec->ps_dpb_mgr->u2_pic_ht = ps_dec->u2_pic_ht; + ps_dec->ps_dpb_mgr->u2_pic_wd = ps_dec->u2_pic_wd; + ps_dec->i4_pic_type = -1; + ps_dec->i4_frametype = -1; + ps_dec->i4_content_type = -1; + + /*--------------------------------------------------------------------*/ + /* Get the value of MaxMbAddress and frmheight in Mbs */ + /*--------------------------------------------------------------------*/ + ps_seq->u2_max_mb_addr = + (ps_seq->u2_frm_wd_in_mbs + * (ps_dec->u2_pic_ht + >> (4 + + ps_dec->ps_cur_slice->u1_field_pic_flag))) + - 1; + ps_dec->u2_frm_ht_in_mbs = (ps_dec->u2_pic_ht + >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag)); + + + /***************************************************************************/ + /* If change in Level or the required PicBuffers i4_size is more than the */ + /* current one FREE the current PicBuffers and allocate affresh */ + /***************************************************************************/ + if(!ps_dec->u1_init_dec_flag + || ih264d_is_sps_changed(ps_prev_seq_params, ps_seq)) + { + + + ivd_video_decode_ip_t *ps_dec_in = ps_dec->pv_dec_in; + ivd_video_decode_op_t *ps_dec_out = ps_dec->pv_dec_out; + + if(ps_dec->u4_share_disp_buf == 0) + { + i4_pic_bufs = get_numbuf_dpb_bank(ps_dec); + } + else + { + i4_pic_bufs = (WORD32)ps_dec->u4_num_disp_bufs; + } + + ps_dec->u1_pic_bufs = CLIP_U8(i4_pic_bufs); + + if(ps_dec->u4_share_disp_buf == 0) + ps_dec->u1_pic_bufs = MIN(ps_dec->u1_pic_bufs, + (H264_MAX_REF_PICS * 2)); + + ps_dec->u1_max_dec_frame_buffering = ih264d_get_dpb_size(ps_seq, + ps_dec); + + if(ps_dec->u4_share_disp_buf) + ps_dec->u1_max_dec_frame_buffering = MAX( + ps_dec->u1_max_dec_frame_buffering, 5); + + ps_dec->u1_max_dec_frame_buffering = MIN( + ps_dec->u1_max_dec_frame_buffering, + ps_dec->u4_num_ref_frames_at_init); + ps_dec->u1_max_dec_frame_buffering = MIN( + ps_dec->u1_max_dec_frame_buffering, + ps_dec->u1_pic_bufs); + +// ps_dec->u1_pic_bufs = ps_dec->i1_max_dec_frame_buffering; + + /* Fix is for handling one pic in and one pic out incase of */ + /* MMCO 5 or IDR */ + + ps_dec->i4_display_delay = MIN(ps_dec->u4_num_reorder_frames_at_init, + ps_dec->u1_max_dec_frame_buffering); + + if(1 == ps_seq->u1_vui_parameters_present_flag) + { + if(ps_seq->u1_frame_mbs_only_flag == 1) + ps_dec->i4_display_delay = MIN( + (UWORD32 )ps_dec->i4_display_delay, + ((UWORD32 )ps_seq->s_vui.u4_num_reorder_frames + + 1)); + else + ps_dec->i4_display_delay = MIN( + (UWORD32 )ps_dec->i4_display_delay, + ((UWORD32 )ps_seq->s_vui.u4_num_reorder_frames + + 1) * 2); + } + + /* Temporary hack to run Tractor Cav/Cab/MbAff Profiler streams also for CAFI1_SVA_C.264 in conformance*/ + if(ps_dec->u1_init_dec_flag) + { + ih264d_release_pics_in_dpb((void *)ps_dec, + ps_dec->u1_pic_bufs); + ih264d_release_display_bufs(ps_dec); + ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr); + } + + /*********************************************************************/ + /* Configuring decoder parameters based on level and then */ + /* fresh pointer initialisation in decoder scratch and state buffers */ + /*********************************************************************/ + if(!ps_dec->u1_init_dec_flag || + ((ps_seq->u1_level_idc < H264_LEVEL_3_0) ^ (ps_prev_seq_params->u1_level_idc < H264_LEVEL_3_0))) + { + ret = ih264d_init_dec_mb_grp(ps_dec); + if(ret != OK) + return ret; + } + + ret = ih264d_create_pic_buffers(ps_dec->u1_pic_bufs, + ps_dec); + if(ret != OK) + return ret; + + ih264d_get_memory_dec_params(ps_dec); + + ret = ih264d_create_mv_bank(ps_dec, ps_dec->u2_pic_wd, + ps_dec->u2_pic_ht); + if(ret != OK) + return ret; + + /* In shared mode, set all of them as used by display */ + if(ps_dec->u4_share_disp_buf == 1) + { + WORD32 i; + + for(i = 0; i < ps_dec->u1_pic_bufs; i++) + { + ih264_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, i, + BUF_MGR_IO); + } + } + + ps_dec->u1_init_dec_flag = 1; + ps_prev_seq_params->u2_frm_wd_in_mbs = ps_seq->u2_frm_wd_in_mbs; + ps_prev_seq_params->u1_level_idc = ps_seq->u1_level_idc; + ps_prev_seq_params->u1_profile_idc = ps_seq->u1_profile_idc; + ps_prev_seq_params->u2_frm_ht_in_mbs = ps_seq->u2_frm_ht_in_mbs; + ps_prev_seq_params->u1_frame_mbs_only_flag = + ps_seq->u1_frame_mbs_only_flag; + ps_prev_seq_params->u1_direct_8x8_inference_flag = + ps_seq->u1_direct_8x8_inference_flag; + + ps_dec->i4_cur_display_seq = 0; + ps_dec->i4_prev_max_display_seq = 0; + ps_dec->i4_max_poc = 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_dec->p_ctxt_inc_mb_map - 1; + UWORD8 *pu1_temp; + WORD8 i; + 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_dec->ps_def_ctxt_mb_info = p_DefCtxt; + } + + } + /* reset DBP commands read u4_flag */ + ps_dec->ps_dpb_cmds->u1_dpb_commands_read = 0; + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_get_next_display_field */ +/* */ +/* Description : Application calls this module to get the next field */ +/* to be displayed */ +/* */ +/* Inputs : 1. IBUFAPI_Handle Hnadle to the Display buffer */ +/* 2. IH264DEC_DispUnit Pointer to the display struct */ +/* */ +/* Globals : */ +/* */ +/* */ +/* Processing : None */ +/* Outputs : None */ +/* Returns : None */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 05 2005 Ittiam Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_get_next_display_field(dec_struct_t * ps_dec, + ivd_out_bufdesc_t *ps_out_buffer, + ivd_get_display_frame_op_t *pv_disp_op) +{ + pic_buffer_t *pic_buf; + + UWORD8 i1_cur_fld; + WORD32 u4_api_ret = -1; + WORD32 i4_disp_buf_id; + iv_yuv_buf_t *ps_op_frm; + + + + ps_op_frm = &(ps_dec->s_disp_frame_info); + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + pic_buf = (pic_buffer_t *)ih264_disp_mgr_get( + (disp_mgr_t *)ps_dec->pv_disp_buf_mgr, &i4_disp_buf_id); + ps_dec->u4_num_fld_in_frm = 0; + u4_api_ret = -1; + pv_disp_op->u4_ts = -1; + pv_disp_op->e_output_format = ps_dec->u1_chroma_format; + + pv_disp_op->s_disp_frm_buf.pv_y_buf = ps_out_buffer->pu1_bufs[0]; + pv_disp_op->s_disp_frm_buf.pv_u_buf = ps_out_buffer->pu1_bufs[1]; + pv_disp_op->s_disp_frm_buf.pv_v_buf = ps_out_buffer->pu1_bufs[2]; + if(pic_buf != NULL) + { + pv_disp_op->e4_fld_type = 0; + pv_disp_op->u4_disp_buf_id = i4_disp_buf_id; + + ps_op_frm->u4_y_ht = pic_buf->u2_disp_height << 1; + ps_op_frm->u4_u_ht = ps_op_frm->u4_v_ht = ps_op_frm->u4_y_ht >> 1; + ps_op_frm->u4_y_wd = pic_buf->u2_disp_width; + + ps_op_frm->u4_u_wd = ps_op_frm->u4_v_wd = ps_op_frm->u4_y_wd >> 1; + + ps_op_frm->u4_y_strd = pic_buf->u2_frm_wd_y; + ps_op_frm->u4_u_strd = ps_op_frm->u4_v_strd = pic_buf->u2_frm_wd_uv; + + /* ! */ + pv_disp_op->u4_ts = pic_buf->u4_ts; + + /* set the start of the Y, U and V buffer pointer for display */ + ps_op_frm->pv_y_buf = pic_buf->pu1_buf1 + pic_buf->u2_crop_offset_y; + ps_op_frm->pv_u_buf = pic_buf->pu1_buf2 + pic_buf->u2_crop_offset_uv; + ps_op_frm->pv_v_buf = pic_buf->pu1_buf3 + pic_buf->u2_crop_offset_uv; + ps_dec->u4_num_fld_in_frm++; + ps_dec->u4_num_fld_in_frm++; + u4_api_ret = 0; + + if(pic_buf->u1_picturetype == 0) + pv_disp_op->u4_progressive_frame_flag = 1; + else + pv_disp_op->u4_progressive_frame_flag = 0; + + } H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + pv_disp_op->u4_error_code = u4_api_ret; + pv_disp_op->e_pic_type = 0xFFFFFFFF; //Junk; + + if(u4_api_ret) + { + pv_disp_op->u4_error_code = 1; //put a proper error code here + } + else + { + + //Release the buffer if being sent for display + UWORD32 temp; + UWORD32 dest_inc_Y = 0, dest_inc_UV = 0; + + pv_disp_op->s_disp_frm_buf.u4_y_wd = temp = MIN(ps_op_frm->u4_y_wd, + ps_op_frm->u4_y_strd); + pv_disp_op->s_disp_frm_buf.u4_u_wd = pv_disp_op->s_disp_frm_buf.u4_y_wd + >> 1; + pv_disp_op->s_disp_frm_buf.u4_v_wd = pv_disp_op->s_disp_frm_buf.u4_y_wd + >> 1; + + pv_disp_op->s_disp_frm_buf.u4_y_ht = ps_op_frm->u4_y_ht; + pv_disp_op->s_disp_frm_buf.u4_u_ht = pv_disp_op->s_disp_frm_buf.u4_y_ht + >> 1; + pv_disp_op->s_disp_frm_buf.u4_v_ht = pv_disp_op->s_disp_frm_buf.u4_y_ht + >> 1; + if(0 == ps_dec->u4_share_disp_buf) + { + pv_disp_op->s_disp_frm_buf.u4_y_strd = + pv_disp_op->s_disp_frm_buf.u4_y_wd; + pv_disp_op->s_disp_frm_buf.u4_u_strd = + pv_disp_op->s_disp_frm_buf.u4_y_wd >> 1; + pv_disp_op->s_disp_frm_buf.u4_v_strd = + pv_disp_op->s_disp_frm_buf.u4_y_wd >> 1; + + } + else + { + pv_disp_op->s_disp_frm_buf.u4_y_strd = ps_op_frm->u4_y_strd; + } + + if(ps_dec->u4_app_disp_width) + { + pv_disp_op->s_disp_frm_buf.u4_y_strd = MAX( + ps_dec->u4_app_disp_width, + pv_disp_op->s_disp_frm_buf.u4_y_strd); + } + + pv_disp_op->u4_error_code = 0; + if(pv_disp_op->e_output_format == IV_YUV_420P) + { + UWORD32 i; + pv_disp_op->s_disp_frm_buf.u4_u_strd = + pv_disp_op->s_disp_frm_buf.u4_y_strd >> 1; + pv_disp_op->s_disp_frm_buf.u4_v_strd = + pv_disp_op->s_disp_frm_buf.u4_y_strd >> 1; + + pv_disp_op->s_disp_frm_buf.u4_u_wd = ps_op_frm->u4_y_wd >> 1; + pv_disp_op->s_disp_frm_buf.u4_v_wd = ps_op_frm->u4_y_wd >> 1; + + if(1 == ps_dec->u4_share_disp_buf) + { + pv_disp_op->s_disp_frm_buf.pv_y_buf = ps_op_frm->pv_y_buf; + + for(i = 0; i < MAX_DISP_BUFS_NEW; i++) + { + UWORD8 *buf = ps_dec->disp_bufs[i].buf[0]; + buf += ps_dec->disp_bufs[i].u4_ofst[0]; + if(((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf + - pic_buf->u2_crop_offset_y) == buf) + { + buf = ps_dec->disp_bufs[i].buf[1]; + buf += ps_dec->disp_bufs[i].u4_ofst[1]; + pv_disp_op->s_disp_frm_buf.pv_u_buf = buf + + pic_buf->u2_crop_offset_uv; + + buf = ps_dec->disp_bufs[i].buf[2]; + buf += ps_dec->disp_bufs[i].u4_ofst[2]; + pv_disp_op->s_disp_frm_buf.pv_v_buf = buf + + pic_buf->u2_crop_offset_uv; + } + } + } + + } + else if((pv_disp_op->e_output_format == IV_YUV_420SP_UV) + || (pv_disp_op->e_output_format == IV_YUV_420SP_VU)) + { + pv_disp_op->s_disp_frm_buf.u4_u_strd = + pv_disp_op->s_disp_frm_buf.u4_y_strd; + pv_disp_op->s_disp_frm_buf.u4_v_strd = 0; + + if(1 == ps_dec->u4_share_disp_buf) + { + UWORD32 i; + + pv_disp_op->s_disp_frm_buf.pv_y_buf = ps_op_frm->pv_y_buf; + + for(i = 0; i < MAX_DISP_BUFS_NEW; i++) + { + UWORD8 *buf = ps_dec->disp_bufs[i].buf[0]; + buf += ps_dec->disp_bufs[i].u4_ofst[0]; + if((UWORD8 *)pv_disp_op->s_disp_frm_buf.pv_y_buf + - pic_buf->u2_crop_offset_y == buf) + { + buf = ps_dec->disp_bufs[i].buf[1]; + buf += ps_dec->disp_bufs[i].u4_ofst[1]; + pv_disp_op->s_disp_frm_buf.pv_u_buf = buf + + pic_buf->u2_crop_offset_uv; + ; + + buf = ps_dec->disp_bufs[i].buf[2]; + buf += ps_dec->disp_bufs[i].u4_ofst[2]; + pv_disp_op->s_disp_frm_buf.pv_v_buf = buf + + pic_buf->u2_crop_offset_uv; + ; + } + } + } + pv_disp_op->s_disp_frm_buf.u4_u_wd = + pv_disp_op->s_disp_frm_buf.u4_y_wd; + pv_disp_op->s_disp_frm_buf.u4_v_wd = 0; + + } + else if((pv_disp_op->e_output_format == IV_RGB_565) + || (pv_disp_op->e_output_format == IV_YUV_422ILE)) + { + + pv_disp_op->s_disp_frm_buf.u4_u_strd = 0; + pv_disp_op->s_disp_frm_buf.u4_v_strd = 0; + pv_disp_op->s_disp_frm_buf.u4_u_wd = 0; + pv_disp_op->s_disp_frm_buf.u4_v_wd = 0; + pv_disp_op->s_disp_frm_buf.u4_u_ht = 0; + pv_disp_op->s_disp_frm_buf.u4_v_ht = 0; + + } + + + } + + return u4_api_ret; +} + + +/*****************************************************************************/ +/* Function Name : ih264d_release_display_field */ +/* */ +/* Description : This function releases the display field that was returned */ +/* here. */ +/* Inputs : ps_dec - Decoder parameters */ +/* Globals : None */ +/* Processing : Refer bumping process in the standard */ +/* Outputs : Assigns display sequence number. */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 04 2005 NS Draft */ +/* */ +/*****************************************************************************/ +void ih264d_release_display_field(dec_struct_t *ps_dec, + ivd_get_display_frame_op_t *pv_disp_op) +{ + if(1 == pv_disp_op->u4_error_code) + { + if(1 == ps_dec->u1_flushfrm) + { + UWORD32 i; + + if(1 == ps_dec->u4_share_disp_buf) + { + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + for(i = 0; i < (MAX_DISP_BUFS_NEW); i++) + { + if(1 == ps_dec->u4_disp_buf_mapping[i]) + { + ih264_buf_mgr_release( + (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, i, + BUF_MGR_IO); + ps_dec->u4_disp_buf_mapping[i] = 0; + } + } H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + + memset(ps_dec->u4_disp_buf_to_be_freed, 0, + (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); + for(i = 0; i < ps_dec->u1_pic_bufs; i++) + ps_dec->u4_disp_buf_mapping[i] = 1; + } + ps_dec->u1_flushfrm = 0; + + } + } + else + { + H264_MUTEX_LOCK(&ps_dec->process_disp_mutex); + + if(0 == ps_dec->u4_share_disp_buf) + { + ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + pv_disp_op->u4_disp_buf_id, + BUF_MGR_IO); + + } + else + { + ps_dec->u4_disp_buf_mapping[pv_disp_op->u4_disp_buf_id] = 1; + } H264_MUTEX_UNLOCK(&ps_dec->process_disp_mutex); + + } +} +/*****************************************************************************/ +/* Function Name : ih264d_assign_display_seq */ +/* */ +/* Description : This function implments bumping process. Every outgoing */ +/* frame from DPB is assigned a display sequence number */ +/* which increases monotonically. System looks for this */ +/* number to display a frame. */ +/* here. */ +/* Inputs : ps_dec - Decoder parameters */ +/* Globals : None */ +/* Processing : Refer bumping process in the standard */ +/* Outputs : Assigns display sequence number. */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 04 2005 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_assign_display_seq(dec_struct_t *ps_dec) +{ + WORD32 i; + WORD32 i4_min_poc; + WORD32 i4_min_poc_buf_id; + WORD32 i4_min_index; + dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; + WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; + + i4_min_poc = 0x7fffffff; + i4_min_poc_buf_id = -1; + i4_min_index = -1; + + if(ps_dpb_mgr->i1_poc_buf_id_entries >= ps_dec->i4_display_delay) + { + for(i = 0; i < MAX_FRAMES; i++) + { + if((i4_poc_buf_id_map[i][0] != -1) + && (DO_NOT_DISP + != ps_dpb_mgr->ai4_poc_buf_id_map[i][0])) + { + if(i4_poc_buf_id_map[i][1] < i4_min_poc) + { + i4_min_poc = i4_poc_buf_id_map[i][1]; + i4_min_poc_buf_id = i4_poc_buf_id_map[i][0]; + i4_min_index = i; + } + } + } + + if((i4_min_index != -1) && (DO_NOT_DISP != i4_min_poc_buf_id)) + { + ps_dec->i4_cur_display_seq++; + ih264_disp_mgr_add( + (disp_mgr_t *)ps_dec->pv_disp_buf_mgr, + i4_min_poc_buf_id, ps_dec->i4_cur_display_seq, + ps_dec->apv_buf_id_pic_buf_map[i4_min_poc_buf_id]); + i4_poc_buf_id_map[i4_min_index][0] = -1; + i4_poc_buf_id_map[i4_min_index][1] = 0x7fffffff; + ps_dpb_mgr->i1_poc_buf_id_entries--; + } + else if(DO_NOT_DISP == i4_min_poc_buf_id) + { + WORD32 i4_error_code; + i4_error_code = ERROR_GAPS_IN_FRM_NUM; +// i4_error_code |= 1<<IVD_CORRUPTEDDATA; + return i4_error_code; + } + } + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_release_display_bufs */ +/* */ +/* Description : This function implments bumping process when mmco = 5. */ +/* Each outgoing frame from DPB is assigned a display */ +/* sequence number which increases monotonically. System */ +/* looks for this number to display a frame. */ +/* Inputs : ps_dec - Decoder parameters */ +/* Globals : None */ +/* Processing : Refer bumping process in the standard for mmco = 5 */ +/* Outputs : Assigns display sequence number. */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 27 04 2005 NS Draft */ +/* */ +/*****************************************************************************/ +void ih264d_release_display_bufs(dec_struct_t *ps_dec) +{ + WORD32 i, j; + WORD32 i4_min_poc; + WORD32 i4_min_poc_buf_id; + WORD32 i4_min_index; + dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr; + WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map; + + i4_min_poc = 0x7fffffff; + i4_min_poc_buf_id = -1; + i4_min_index = -1; + + ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr); + + for(j = 0; j < ps_dpb_mgr->i1_poc_buf_id_entries; j++) + { + i4_min_poc = 0x7fffffff; + for(i = 0; i < MAX_FRAMES; i++) + { + if(i4_poc_buf_id_map[i][0] != -1) + { + if(i4_poc_buf_id_map[i][1] < i4_min_poc) + { + i4_min_poc = i4_poc_buf_id_map[i][1]; + i4_min_poc_buf_id = i4_poc_buf_id_map[i][0]; + i4_min_index = i; + } + } + } + + if(DO_NOT_DISP != i4_min_poc_buf_id) + { + ps_dec->i4_cur_display_seq++; + ih264_disp_mgr_add( + (disp_mgr_t *)ps_dec->pv_disp_buf_mgr, + i4_min_poc_buf_id, ps_dec->i4_cur_display_seq, + ps_dec->apv_buf_id_pic_buf_map[i4_min_poc_buf_id]); + i4_poc_buf_id_map[i4_min_index][0] = -1; + i4_poc_buf_id_map[i4_min_index][1] = 0x7fffffff; + ps_dpb_mgr->ai4_poc_buf_id_map[i4_min_index][2] = 0; + } + else + { + i4_poc_buf_id_map[i4_min_index][0] = -1; + i4_poc_buf_id_map[i4_min_index][1] = 0x7fffffff; + ps_dpb_mgr->ai4_poc_buf_id_map[i4_min_index][2] = 0; + } + } + ps_dpb_mgr->i1_poc_buf_id_entries = 0; + ps_dec->i4_prev_max_display_seq = ps_dec->i4_prev_max_display_seq + + ps_dec->i4_max_poc + ps_dec->u1_max_dec_frame_buffering + + 1; + ps_dec->i4_max_poc = 0; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_assign_pic_num */ +/* */ +/* Description : This function assigns pic num to each reference frame */ +/* depending on the cur_frame_num as speified in section */ +/* 8.2.4.1 */ +/* */ +/* Inputs : ps_dec */ +/* */ +/* Globals : NO globals used */ +/* */ +/* Processing : for all ST pictures */ +/* if( FrameNum > cur_frame_num) */ +/* PicNum = FrameNum - MaxFrameNum */ +/* else */ +/* PicNum = FrameNum */ +/* */ +/* Returns : void */ +/* */ +/* Issues : NO */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 13 07 2002 Jay Draft */ +/* */ +/*****************************************************************************/ + +void ih264d_assign_pic_num(dec_struct_t *ps_dec) +{ + dpb_manager_t *ps_dpb_mgr; + struct dpb_info_t *ps_next_dpb; + WORD8 i; + WORD32 i4_cur_frame_num, i4_max_frame_num; + WORD32 i4_ref_frame_num; + UWORD8 u1_fld_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag; + + i4_max_frame_num = ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; + i4_cur_frame_num = ps_dec->ps_cur_pic->i4_frame_num; + ps_dpb_mgr = ps_dec->ps_dpb_mgr; + + /* Start from ST head */ + ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; + for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) + { + WORD32 i4_pic_num; + + i4_ref_frame_num = ps_next_dpb->ps_pic_buf->i4_frame_num; + if(i4_ref_frame_num > i4_cur_frame_num) + { + /* RefPic Buf frame_num is before Current frame_num in decode order */ + i4_pic_num = i4_ref_frame_num - i4_max_frame_num; + } + else + { + /* RefPic Buf frame_num is after Current frame_num in decode order */ + i4_pic_num = i4_ref_frame_num; + } + + ps_next_dpb->ps_pic_buf->i4_pic_num = i4_pic_num; + ps_next_dpb->i4_frame_num = i4_pic_num; + ps_next_dpb->ps_pic_buf->u1_long_term_frm_idx = MAX_REF_BUFS + 1; + if(u1_fld_pic_flag) + { + /* Assign the pic num to top fields and bot fields */ + + ps_next_dpb->s_top_field.i4_pic_num = i4_pic_num * 2 + + !(ps_dec->ps_cur_slice->u1_bottom_field_flag); + ps_next_dpb->s_bot_field.i4_pic_num = i4_pic_num * 2 + + ps_dec->ps_cur_slice->u1_bottom_field_flag; + } + /* Chase the next link */ + ps_next_dpb = ps_next_dpb->ps_prev_short; + } + + if(ps_dec->ps_cur_sps->u1_gaps_in_frame_num_value_allowed_flag + && ps_dpb_mgr->u1_num_gaps) + { + WORD32 i4_start_frm, i4_end_frm; + /* Assign pic numbers for gaps */ + for(i = 0; i < MAX_FRAMES; i++) + { + i4_start_frm = ps_dpb_mgr->ai4_gaps_start_frm_num[i]; + if(i4_start_frm != INVALID_FRAME_NUM) + { + if(i4_start_frm > i4_cur_frame_num) + { + /* gap's frame_num is before Current frame_num in + decode order */ + i4_start_frm -= i4_max_frame_num; + } + ps_dpb_mgr->ai4_gaps_start_frm_num[i] = i4_start_frm; + i4_end_frm = ps_dpb_mgr->ai4_gaps_end_frm_num[i]; + + if(i4_end_frm > i4_cur_frame_num) + { + /* gap's frame_num is before Current frame_num in + decode order */ + i4_end_frm -= i4_max_frame_num; + } + ps_dpb_mgr->ai4_gaps_end_frm_num[i] = i4_end_frm; + } + } + } +} + +/*! + ************************************************************************** + * \if Function name : ih264d_update_qp \endif + * + * \brief + * Updates the values of QP and its related entities + * + * \return + * 0 on Success and Error code otherwise + * + ************************************************************************** + */ +WORD32 ih264d_update_qp(dec_struct_t * ps_dec, const WORD8 i1_qp) +{ + WORD32 i_temp; + i_temp = (ps_dec->u1_qp + i1_qp + 52) % 52; + + if((i_temp < 0) || (i_temp > 51) || (i1_qp < -26) || (i1_qp > 25)) + return ERROR_INV_RANGE_QP_T; + + ps_dec->u1_qp = i_temp; + ps_dec->u1_qp_y_rem6 = ps_dec->u1_qp % 6; + ps_dec->u1_qp_y_div6 = ps_dec->u1_qp / 6; + i_temp = CLIP3(0, 51, ps_dec->u1_qp + ps_dec->ps_cur_pps->i1_chroma_qp_index_offset); + ps_dec->u1_qp_u_rem6 = MOD(gau1_ih264d_qp_scale_cr[12 + i_temp], 6); + ps_dec->u1_qp_u_div6 = DIV(gau1_ih264d_qp_scale_cr[12 + i_temp], 6); + + i_temp = CLIP3(0, 51, ps_dec->u1_qp + ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset); + ps_dec->u1_qp_v_rem6 = MOD(gau1_ih264d_qp_scale_cr[12 + i_temp], 6); + ps_dec->u1_qp_v_div6 = DIV(gau1_ih264d_qp_scale_cr[12 + i_temp], 6); + + ps_dec->pu2_quant_scale_y = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_y_rem6]; + ps_dec->pu2_quant_scale_u = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_u_rem6]; + ps_dec->pu2_quant_scale_v = + gau2_ih264_iquant_scale_4x4[ps_dec->u1_qp_v_rem6]; + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_decode_gaps_in_frame_num */ +/* */ +/* Description : This function decodes gaps in frame number */ +/* */ +/* Inputs : ps_dec Decoder parameters */ +/* u2_frame_num current frame number */ +/* */ +/* Globals : None */ +/* Processing : This functionality needs to be implemented */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : Not implemented */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ +WORD32 ih264d_decode_gaps_in_frame_num(dec_struct_t *ps_dec, + UWORD16 u2_frame_num) +{ + UWORD32 u4_next_frm_num, u4_start_frm_num; + UWORD32 u4_max_frm_num; + pocstruct_t s_tmp_poc; + WORD32 i4_poc; + dec_slice_params_t *ps_cur_slice; + + dec_pic_params_t *ps_pic_params; + WORD8 i1_gap_idx; + WORD32 *i4_gaps_start_frm_num; + dpb_manager_t *ps_dpb_mgr; + WORD32 i4_frame_gaps; + WORD8 *pi1_gaps_per_seq; + WORD32 ret; + + ps_cur_slice = ps_dec->ps_cur_slice; + if(ps_cur_slice->u1_field_pic_flag) + { + if(ps_dec->u2_prev_ref_frame_num == u2_frame_num) + return 0; + } + + u4_next_frm_num = ps_dec->u2_prev_ref_frame_num + 1; + u4_max_frm_num = ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1 + 1; + + // check + 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 (0); + } + + // check + if((ps_dec->u1_nal_unit_type == IDR_SLICE_NAL) + && (u4_next_frm_num >= u2_frame_num)) + { + return (0); + } + 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; + + ps_cur_slice = ps_dec->ps_cur_slice; + ps_pic_params = ps_dec->ps_cur_pps; + ps_cur_slice->u1_field_pic_flag = 0; + + i4_frame_gaps = 0; + ps_dpb_mgr = ps_dec->ps_dpb_mgr; + + /* Find a empty slot to store gap seqn info */ + i4_gaps_start_frm_num = ps_dpb_mgr->ai4_gaps_start_frm_num; + for(i1_gap_idx = 0; i1_gap_idx < MAX_FRAMES; i1_gap_idx++) + { + if(INVALID_FRAME_NUM == i4_gaps_start_frm_num[i1_gap_idx]) + break; + } + if(MAX_FRAMES == i1_gap_idx) + { + UWORD32 i4_error_code; + i4_error_code = ERROR_DBP_MANAGER_T; +// i4_error_code |= 1<<IVD_CORRUPTEDDATA; + return i4_error_code; + } + + i4_poc = 0; + i4_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) + { + ih264d_delete_nonref_nondisplay_pics(ps_dpb_mgr); + if(ps_pic_params->ps_sps->u1_pic_order_cnt_type) + { + /* allocate a picture buffer and insert it as ST node */ + ret = ih264d_decode_pic_order_cnt(0, u4_next_frm_num, + &ps_dec->s_prev_pic_poc, + &s_tmp_poc, ps_cur_slice, + ps_pic_params, 1, 0, 0, + &i4_poc); + if(ret != OK) + return ret; + + /* Display seq no calculations */ + if(i4_poc >= ps_dec->i4_max_poc) + ps_dec->i4_max_poc = i4_poc; + /* IDR Picture or POC wrap around */ + if(i4_poc == 0) + { + ps_dec->i4_prev_max_display_seq = + ps_dec->i4_prev_max_display_seq + + ps_dec->i4_max_poc + + ps_dec->u1_max_dec_frame_buffering + + 1; + ps_dec->i4_max_poc = 0; + } + + ps_cur_slice->u1_mmco_equalto5 = 0; + ps_cur_slice->u2_frame_num = u4_next_frm_num; + } + + // check + if(ps_dpb_mgr->i1_poc_buf_id_entries + >= ps_dec->u1_max_dec_frame_buffering) + { + ret = ih264d_assign_display_seq(ps_dec); + if(ret != OK) + return ret; + } + + ret = ih264d_insert_pic_in_display_list( + ps_dec->ps_dpb_mgr, (WORD8) DO_NOT_DISP, + (WORD32)(ps_dec->i4_prev_max_display_seq + i4_poc), + u4_next_frm_num); + if(ret != OK) + return ret; + + pi1_gaps_per_seq[i1_gap_idx]++; + ret = ih264d_do_mmco_for_gaps(ps_dpb_mgr, + ps_dec->ps_cur_sps->u1_num_ref_frames); + if(ret != OK) + return ret; + + ih264d_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; + } + + i4_frame_gaps++; + } + + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_create_pic_buffers \endif + * + * \brief + * This function creates Picture Buffers. + * + * \return + * 0 on Success and -1 on error + ************************************************************************** + */ +WORD32 ih264d_create_pic_buffers(UWORD8 u1_num_of_buf, + dec_struct_t *ps_dec) +{ + struct pic_buffer_t *ps_pic_buf; + UWORD8 i; + UWORD32 u4_luma_size, u4_chroma_size; + UWORD8 u1_frm = ps_dec->ps_cur_sps->u1_frame_mbs_only_flag; + WORD32 j; + UWORD32 u4_pic_buf_mem_used, u4_ref_buf_mem_used; + UWORD8 *pu1_pic_buf_mem_base, *pu1_ref_buf_mem_base; + + u4_pic_buf_mem_used = 0; + pu1_pic_buf_mem_base = ps_dec->ps_mem_tab[MEM_REC_PIC_BUF_MGR].pv_base; + + ps_dec->pv_disp_buf_mgr = (void *)(pu1_pic_buf_mem_base + + u4_pic_buf_mem_used); + u4_pic_buf_mem_used += sizeof(disp_mgr_t); + ih264_disp_mgr_init((disp_mgr_t *)ps_dec->pv_disp_buf_mgr); + + ps_dec->pv_pic_buf_mgr = + (void *)(pu1_pic_buf_mem_base + u4_pic_buf_mem_used); + u4_pic_buf_mem_used += sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); + ih264_buf_mgr_init((buf_mgr_t *)ps_dec->pv_pic_buf_mgr); + + ps_pic_buf = (pic_buffer_t *)(pu1_pic_buf_mem_base + u4_pic_buf_mem_used); + u4_pic_buf_mem_used += sizeof(struct pic_buffer_t) + * (H264_MAX_REF_PICS * 2); + + u4_luma_size = ps_dec->u2_frm_wd_y * ps_dec->u2_frm_ht_y; + u4_chroma_size = ps_dec->u2_frm_wd_uv * ps_dec->u2_frm_ht_uv; + + { + if(ps_dec->u4_share_disp_buf == 1) + { + /* In case of buffers getting shared between application and library + there is no need of reference memtabs. Instead of setting the i4_size + to zero, it is reduced to a small i4_size to ensure that changes + in the code are minimal */ + if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU) + || (ps_dec->u1_chroma_format == IV_YUV_420P)) + { + u4_luma_size = 64; + } + + if(ps_dec->u1_chroma_format == IV_YUV_420SP_UV) + + { + u4_chroma_size = 64; + } + + } + } + + pu1_ref_buf_mem_base = ps_dec->ps_mem_tab[MEM_REC_REF_PIC].pv_base; + u4_ref_buf_mem_used = 0; + + /* Allocate memory for refernce buffers */ + for(i = 0; i < u1_num_of_buf; i++) + { + UWORD32 u4_offset; + WORD32 buf_ret; + UWORD8 *pu1_luma, *pu1_chroma; + + pu1_luma = pu1_ref_buf_mem_base + u4_ref_buf_mem_used; + u4_ref_buf_mem_used += u4_luma_size; + pu1_chroma = pu1_ref_buf_mem_base + u4_ref_buf_mem_used; + u4_ref_buf_mem_used += u4_chroma_size; + + /* Offset to the start of the pic from the top left corner of the frame + buffer */ + + if((0 == ps_dec->u4_share_disp_buf) + || (NULL == ps_dec->disp_bufs[i].buf[0])) + { + UWORD32 pad_len_h, pad_len_v; + + u4_offset = ps_dec->u2_frm_wd_y * (PAD_LEN_Y_V << 1) + PAD_LEN_Y_H; + ps_pic_buf->pu1_buf1 = (UWORD8 *)(pu1_luma) + u4_offset; + + pad_len_h = MAX(PAD_LEN_UV_H, (PAD_LEN_Y_H >> 1)); + pad_len_v = MAX(PAD_LEN_UV_V, PAD_LEN_Y_V); + + u4_offset = ps_dec->u2_frm_wd_uv * pad_len_v + pad_len_h; + + ps_pic_buf->pu1_buf2 = (UWORD8 *)(pu1_chroma) + u4_offset; + ps_pic_buf->pu1_buf3 = (UWORD8 *)(NULL) + u4_offset; + + } + else + { + UWORD32 pad_len_h, pad_len_v; + u4_offset = ps_dec->u2_frm_wd_y * (PAD_LEN_Y_V << 1) + PAD_LEN_Y_H; + ps_pic_buf->pu1_buf1 = (UWORD8 *)ps_dec->disp_bufs[i].buf[0] + + u4_offset; + + ps_dec->disp_bufs[i].u4_ofst[0] = u4_offset; + + if(ps_dec->u1_chroma_format == IV_YUV_420P) + { + pad_len_h = MAX(PAD_LEN_UV_H * YUV420SP_FACTOR, + (PAD_LEN_Y_H >> 1)); + pad_len_v = MAX(PAD_LEN_UV_V, PAD_LEN_Y_V); + + u4_offset = ps_dec->u2_frm_wd_uv * pad_len_v + pad_len_h; + ps_pic_buf->pu1_buf2 = (UWORD8 *)(pu1_chroma) + u4_offset; + ps_pic_buf->pu1_buf3 = (UWORD8 *)(NULL) + u4_offset; + + ps_dec->disp_bufs[i].u4_ofst[1] = u4_offset; + ps_dec->disp_bufs[i].u4_ofst[2] = u4_offset; + + } + else + { + pad_len_h = MAX(PAD_LEN_UV_H * YUV420SP_FACTOR, + (PAD_LEN_Y_H >> 1)); + pad_len_v = MAX(PAD_LEN_UV_V, PAD_LEN_Y_V); + + u4_offset = ps_dec->u2_frm_wd_uv * pad_len_v + pad_len_h; + ps_pic_buf->pu1_buf2 = (UWORD8 *)(ps_dec->disp_bufs[i].buf[1]) + + u4_offset; + ps_pic_buf->pu1_buf3 = (UWORD8 *)(ps_dec->disp_bufs[i].buf[1]) + + u4_offset; + + ps_dec->disp_bufs[i].u4_ofst[1] = u4_offset; + ps_dec->disp_bufs[i].u4_ofst[2] = u4_offset; + + } + + } + + ps_pic_buf->u2_frm_ht_y = ps_dec->u2_frm_ht_y; + ps_pic_buf->u2_frm_ht_uv = ps_dec->u2_frm_ht_uv; + ps_pic_buf->u2_frm_wd_y = ps_dec->u2_frm_wd_y; + ps_pic_buf->u2_frm_wd_uv = ps_dec->u2_frm_wd_uv; + + ps_pic_buf->u1_pic_buf_id = i; + + buf_ret = ih264_buf_mgr_add((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, + ps_pic_buf, i); + if(0 != buf_ret) + { + ps_dec->i4_error_code = ERROR_BUF_MGR; + return ERROR_BUF_MGR; + } + + ps_dec->apv_buf_id_pic_buf_map[i] = (void *)ps_pic_buf; + ps_pic_buf++; + } + + if((u4_ref_buf_mem_used > ps_dec->ps_mem_tab[MEM_REC_REF_PIC].u4_mem_size) || + (u4_pic_buf_mem_used > ps_dec->ps_mem_tab[MEM_REC_PIC_BUF_MGR].u4_mem_size)) + { + ps_dec->i4_error_code = ERROR_BUF_MGR; + return ERROR_BUF_MGR; + } + + if(1 == ps_dec->u4_share_disp_buf) + { + for(i = 0; i < u1_num_of_buf; i++) + ps_dec->u4_disp_buf_mapping[i] = 1; + } + return OK; +} + +/*! + ************************************************************************** + * \if Function name : ih264d_get_memory_dec_params \endif + * + * \brief + * This function allocates memory required by Decoder. + * + * \param ps_dec: Pointer to dec_struct_t. + * + * \return + * Returns i4_status as returned by MemManager. + * + ************************************************************************** + */ +//WORD16 i16_res_coeff[2 * 3600 * (MB_LUM_SIZE + 2 * MB_CHROM_SIZE)]; +//pred_info_t s_pred_frame[4000 * 60]; +//pred_info_t *ps_pred_frame; + +WORD16 ih264d_get_memory_dec_params(dec_struct_t * ps_dec) +{ + struct MemReq s_MemReq; + struct MemBlock *p_MemBlock; + + pred_info_t *ps_pred_frame; + dec_mb_info_t *ps_frm_mb_info; + dec_slice_struct_t *ps_dec_slice_buf; + UWORD8 *pu1_dec_mb_map, *pu1_recon_mb_map; + UWORD16 *pu2_slice_num_map; + + WORD16 *pi16_res_coeff; + WORD16 i16_status = 0; + UWORD8 uc_frmOrFld = (1 - ps_dec->ps_cur_sps->u1_frame_mbs_only_flag); + UWORD16 u4_luma_wd = ps_dec->u2_frm_wd_y; + UWORD16 u4_chroma_wd = ps_dec->u2_frm_wd_uv; + WORD8 c_i = 0; + dec_seq_params_t *ps_sps = ps_dec->ps_cur_sps; + UWORD32 u4_total_mbs = ps_sps->u2_total_num_of_mbs << uc_frmOrFld; + UWORD32 u4_wd_mbs = ps_dec->u2_frm_wd_in_mbs; + UWORD32 u4_ht_mbs = ps_dec->u2_frm_ht_in_mbs; + UWORD32 u4_blk_wd; + UWORD32 ui_size = 0; + UWORD32 u4_int_scratch_size = 0, u4_ref_pred_size = 0; + UWORD8 *pu1_buf; + + ps_dec->ps_deblk_pic = ps_dec->ps_mem_tab[MEM_REC_DEBLK_MB_INFO].pv_base; + + ps_dec->pu1_dec_mb_map = ps_dec->ps_mem_tab[MEM_REC_PARSE_MAP].pv_base; + + ps_dec->pu1_recon_mb_map = ps_dec->ps_mem_tab[MEM_REC_PROC_MAP].pv_base; + + ps_dec->pu2_slice_num_map = + ps_dec->ps_mem_tab[MEM_REC_SLICE_NUM_MAP].pv_base; + + ps_dec->ps_dec_slice_buf = ps_dec->ps_mem_tab[MEM_REC_SLICE_HDR].pv_base; + pu1_buf = (UWORD8 *)ps_dec->ps_dec_slice_buf; + pu1_buf += sizeof(dec_slice_struct_t) * u4_total_mbs; + ps_dec->pv_map_ref_idx_to_poc_buf = (void *)pu1_buf; + + ps_dec->ps_frm_mb_info = ps_dec->ps_mem_tab[MEM_REC_MB_INFO].pv_base; + memset(ps_dec->ps_frm_mb_info, 0, ps_dec->ps_mem_tab[MEM_REC_MB_INFO].u4_mem_size); + + ps_dec->ps_pred = ps_dec->ps_mem_tab[MEM_REC_PRED_INFO].pv_base; + + ps_dec->pi2_coeff_data = ps_dec->ps_mem_tab[MEM_REC_COEFF_DATA].pv_base; + + ps_dec->pv_pic_tu_coeff_data = (void *)(ps_dec->pi2_coeff_data + MB_LUM_SIZE); + + /*scratch memory allocations*/ + { + UWORD8 *pu1_scratch_mem_base; + UWORD32 u4_scratch_mem_used; + + pu1_scratch_mem_base = + ps_dec->ps_mem_tab[MEM_REC_INTERNAL_SCRATCH].pv_base; + u4_scratch_mem_used = 0; + + ps_dec->ppv_map_ref_idx_to_poc = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + u4_scratch_mem_used += ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) + * sizeof(void *)); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + memset(ps_dec->ppv_map_ref_idx_to_poc, 0, (TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) + * sizeof(void *)); + + ps_dec->p_cabac_ctxt_table_t = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->ps_left_mb_ctxt_info = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += sizeof(ctxt_inc_mb_info_t); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->pu4_defI_wts_ofsts = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += + sizeof(UWORD32) + * (ps_sps->u1_num_ref_frames + * ps_sps->u1_num_ref_frames); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->pu1_ref_buff = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += MAX_REF_BUF_SIZE; + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + ps_dec->pi2_pred1 = + (void *)(pu1_scratch_mem_base + u4_scratch_mem_used); + u4_scratch_mem_used += ((sizeof(WORD16)) * PRED_BUFFER_WIDTH + * PRED_BUFFER_HEIGHT); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->pu1_temp_mc_buffer = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += sizeof(UWORD8) * (MB_LUM_SIZE); + + ps_dec->ps_parse_mb_data = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += sizeof(parse_pmbarams_t) + * (ps_dec->u1_recon_mb_grp); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->ps_parse_part_params = (void *)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += sizeof(parse_part_params_t) + * ((ps_dec->u1_recon_mb_grp) << 4); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = + (struct pic_buffer_t*)(pu1_scratch_mem_base + + u4_scratch_mem_used); + u4_scratch_mem_used += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); + + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = + (struct pic_buffer_t*)(pu1_scratch_mem_base + u4_scratch_mem_used); + u4_scratch_mem_used += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + ps_dec->pu4_mbaff_wt_mat = (UWORD32 *)(pu1_scratch_mem_base + u4_scratch_mem_used); + + u4_scratch_mem_used += (sizeof(UWORD32) * 3 + * (MAX_FRAMES * MAX_FRAMES)) + << 3; + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + + ps_dec->pu4_wts_ofsts_mat = (UWORD32 *)(pu1_scratch_mem_base + u4_scratch_mem_used); + u4_scratch_mem_used += sizeof(UWORD32) * 2 * 3 + * (MAX_FRAMES * MAX_FRAMES); + u4_scratch_mem_used = ALIGN64(u4_scratch_mem_used); + } + /********************************************************************/ + /* check whether deblk memory used is less than the scratch buffer */ + /* and assign deblocking pointers in the the reference buffers */ + /********************************************************************/ + { + /************************************************************/ + /* Post allocation Initialisations */ + /************************************************************/ + memset(ps_dec->ppv_map_ref_idx_to_poc, 0, + (TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *)); + ps_dec->ppv_map_ref_idx_to_poc += OFFSET_MAP_IDX_POC; + + { + UWORD32 u4_ref_size; + u4_ref_size = MAX_REF_BUF_SIZE; + + { + + ps_dec->ps_parse_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + ps_dec->ps_decode_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + ps_dec->ps_computebs_cur_slice = &(ps_dec->ps_dec_slice_buf[0]); + ps_dec->ps_parse_cur_slice->slice_header_done = 0; + + ps_dec->ps_pred_start = ps_dec->ps_pred; + ps_dec->u4_ref_buf_size = u4_ref_size; + } + } + + { + UWORD8 i; + struct pic_buffer_t *ps_init_dpb; + ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0]; + for(i = 0; i < 2 * MAX_REF_BUFS; i++) + { + ps_init_dpb->pu1_buf1 = NULL; + ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1; + ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb; + ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb; + ps_init_dpb++; + } + + ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0]; + for(i = 0; i < 2 * MAX_REF_BUFS; i++) + { + ps_init_dpb->pu1_buf1 = NULL; + ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1; + ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb; + ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb; + ps_init_dpb++; + } + } + } + + /*persistent memory allocations*/ + + { + UWORD8 *pu1_persitent_mem_base; + UWORD32 u4_persistent_mem_used; + + pu1_persitent_mem_base = + ps_dec->ps_mem_tab[MEM_REC_INTERNAL_PERSIST].pv_base; + u4_persistent_mem_used = 0; + + ps_dec->ps_deblk_top_mb = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ((u4_wd_mbs + * sizeof(deblkmb_neighbour_t)) << uc_frmOrFld); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->ps_left_mvpred_addr = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += (sizeof(neighbouradd_t) << 2); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->p_ctxt_inc_mb_map = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ((sizeof(ctxt_inc_mb_info_t)) + * (((u4_wd_mbs + 1) << uc_frmOrFld) + 1)); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->ps_mv_p[0] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += (sizeof(mv_pred_t) * ps_dec->u1_recon_mb_grp + * 16); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->ps_mv_p[1] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += (sizeof(mv_pred_t) * ps_dec->u1_recon_mb_grp + * 16); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + { + UWORD8 i; + for(i = 0; i < MV_SCRATCH_BUFS; i++) + { + + ps_dec->ps_mv_top_p[i] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += (sizeof(mv_pred_t) + * ps_dec->u1_recon_mb_grp * 4); + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + } + } + + { + UWORD32 u4_numRows = MB_SIZE << 1; + + /* Allocate memory for ping, pong and left reconstruction buffers */ + u4_blk_wd = ((ps_dec->u1_recon_mb_grp << 4) >> 1) + 8; + + ps_dec->pu1_y_scratch[0] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_y_scratch[1] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + u4_numRows = BLK8x8SIZE << 1; + u4_blk_wd = ((ps_dec->u1_recon_mb_grp << 3) >> 1) + 8; + + ps_dec->pu1_u_scratch[0] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_v_scratch[0] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_u_scratch[1] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_v_scratch[1] = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; + u4_persistent_mem_used += 32; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + } + + ps_dec->pu1_y_intra_pred_line = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * (u4_luma_wd + 16) * 2; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_u_intra_pred_line = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * (u4_chroma_wd + 16) * 2 + * YUV420SP_FACTOR; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->pu1_v_intra_pred_line = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += sizeof(UWORD8) * (u4_chroma_wd + 16) * 2; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->ps_nbr_mb_row = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + if(ps_dec->u1_separate_parse) + { + u4_persistent_mem_used += sizeof(mb_neigbour_params_t) + * ((u4_wd_mbs + 1) * u4_ht_mbs); + memset(ps_dec->ps_nbr_mb_row, 0, sizeof(mb_neigbour_params_t) + * ((u4_wd_mbs + 1) * u4_ht_mbs)); + } + else + { + u4_persistent_mem_used += sizeof(mb_neigbour_params_t) + * ((u4_wd_mbs + 1) << uc_frmOrFld); + memset(ps_dec->ps_nbr_mb_row, 0, sizeof(mb_neigbour_params_t) + * ((u4_wd_mbs + 1) << uc_frmOrFld)); + + } + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + ps_dec->s_pad_mgr.pu1_row_y = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ps_dec->u2_frm_wd_y; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->s_pad_mgr.pu1_row_u = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ps_dec->u2_frm_wd_uv; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->s_pad_mgr.pu1_row_v = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ps_dec->u2_frm_wd_uv; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->s_pad_mgr.pu1_mb_y = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ((MB_SIZE + 4) << uc_frmOrFld) * PAD_LEN_Y_H; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->s_pad_mgr.pu1_mb_u = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ((BLK8x8SIZE + 2) << uc_frmOrFld) + * PAD_LEN_UV_H; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + + ps_dec->s_pad_mgr.pu1_mb_v = (void *)(pu1_persitent_mem_base + + u4_persistent_mem_used); + u4_persistent_mem_used += ((BLK8x8SIZE + 2) << uc_frmOrFld) + * PAD_LEN_UV_H; + u4_persistent_mem_used = ALIGN64(u4_persistent_mem_used); + } + + /*Post allocation initializations*/ + memset(ps_dec->pu1_y_intra_pred_line, 0, + sizeof(UWORD8) * u4_luma_wd + PAD_LEN_Y_H); + memset(ps_dec->pu1_u_intra_pred_line, 0, + sizeof(UWORD8) * u4_chroma_wd + PAD_LEN_UV_H); + memset(ps_dec->pu1_v_intra_pred_line, 0, + sizeof(UWORD8) * u4_chroma_wd + PAD_LEN_UV_H); + + /* 0th entry of CtxtIncMbMap will be always be containing default values + for CABAC context representing MB not available */ + ps_dec->p_ctxt_inc_mb_map += 1; + /* Post allocation Increment Actions */ + + /***************************************************************************/ + /*Initialize cabac context pointers for every SE that has fixed contextIdx */ + /***************************************************************************/ + { + bin_ctxt_model_t * const p_cabac_ctxt_table_t = + ps_dec->p_cabac_ctxt_table_t; + bin_ctxt_model_t * * p_coeff_abs_level_minus1_t = + ps_dec->p_coeff_abs_level_minus1_t; + bin_ctxt_model_t * * p_cbf_t = ps_dec->p_cbf_t; + + ps_dec->p_mb_field_dec_flag_t = p_cabac_ctxt_table_t + + MB_FIELD_DECODING_FLAG; + ps_dec->p_prev_intra4x4_pred_mode_flag_t = p_cabac_ctxt_table_t + + PREV_INTRA4X4_PRED_MODE_FLAG; + ps_dec->p_rem_intra4x4_pred_mode_t = p_cabac_ctxt_table_t + + REM_INTRA4X4_PRED_MODE; + ps_dec->p_intra_chroma_pred_mode_t = p_cabac_ctxt_table_t + + INTRA_CHROMA_PRED_MODE; + ps_dec->p_mb_qp_delta_t = p_cabac_ctxt_table_t + MB_QP_DELTA; + ps_dec->p_ref_idx_t = p_cabac_ctxt_table_t + REF_IDX; + ps_dec->p_mvd_x_t = p_cabac_ctxt_table_t + MVD_X; + ps_dec->p_mvd_y_t = p_cabac_ctxt_table_t + MVD_Y; + p_cbf_t[0] = p_cabac_ctxt_table_t + CBF + 0; + p_cbf_t[1] = p_cabac_ctxt_table_t + CBF + 4; + p_cbf_t[2] = p_cabac_ctxt_table_t + CBF + 8; + p_cbf_t[3] = p_cabac_ctxt_table_t + CBF + 12; + p_cbf_t[4] = p_cabac_ctxt_table_t + CBF + 16; + ps_dec->p_cbp_luma_t = p_cabac_ctxt_table_t + CBP_LUMA; + ps_dec->p_cbp_chroma_t = p_cabac_ctxt_table_t + CBP_CHROMA; + + p_coeff_abs_level_minus1_t[LUMA_DC_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_0_OFFSET; + + p_coeff_abs_level_minus1_t[LUMA_AC_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_1_OFFSET; + + p_coeff_abs_level_minus1_t[LUMA_4X4_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_2_OFFSET; + + p_coeff_abs_level_minus1_t[CHROMA_DC_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_3_OFFSET; + + p_coeff_abs_level_minus1_t[CHROMA_AC_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1 + COEFF_ABS_LEVEL_CAT_4_OFFSET; + + p_coeff_abs_level_minus1_t[LUMA_8X8_CTXCAT] = p_cabac_ctxt_table_t + + COEFF_ABS_LEVEL_MINUS1_8X8 + + COEFF_ABS_LEVEL_CAT_5_OFFSET; + + /********************************************************/ + /* context for the high profile related syntax elements */ + /* This is maintained seperately in s_high_profile */ + /********************************************************/ + { + + ps_dec->s_high_profile.ps_transform8x8_flag = p_cabac_ctxt_table_t + + TRANSFORM_SIZE_8X8_FLAG; + + ps_dec->s_high_profile.ps_sigcoeff_8x8_frame = p_cabac_ctxt_table_t + + SIGNIFICANT_COEFF_FLAG_8X8_FRAME; + + ps_dec->s_high_profile.ps_last_sigcoeff_8x8_frame = + p_cabac_ctxt_table_t + + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FRAME; + + ps_dec->s_high_profile.ps_coeff_abs_levelminus1 = + p_cabac_ctxt_table_t + COEFF_ABS_LEVEL_MINUS1_8X8; + + ps_dec->s_high_profile.ps_sigcoeff_8x8_field = p_cabac_ctxt_table_t + + SIGNIFICANT_COEFF_FLAG_8X8_FIELD; + + ps_dec->s_high_profile.ps_last_sigcoeff_8x8_field = + p_cabac_ctxt_table_t + + LAST_SIGNIFICANT_COEFF_FLAG_8X8_FIELD; + + } + + } + return (i16_status); +} + +/*! + ************************************************************************** + * \if Function name : ih264d_create_mv_bank \endif + * + * \brief + * This function creates MV bank. + * + * \param memType : Type of memory being handled + * 0: Display Buffer + * 1: Decoder Buffer + * 2: Internal Buffer + * \param u1_num_of_buf: Number of decode or display buffers. + * \param u4_wd : Frame width. + * \param u4_ht : Frame Height. + * \param ps_pic_buf_api : Pointer to Picture Buffer API. + * \param ih264d_dec_mem_manager : Memory manager utility supplied by system. + * + * \return + * 0 on Success and -1 on error + * + ************************************************************************** + */ +WORD32 ih264d_create_mv_bank(void *pv_dec, + UWORD32 ui_width, + UWORD32 ui_height) +{ + UWORD8 i; + UWORD32 col_flag_buffer_size, mvpred_buffer_size; + UWORD8 *pu1_mv_buf_mgr_base, *pu1_mv_bank_base; + UWORD32 u4_mv_buf_mgr_mem_used, u4_mv_bank_mem_used; + col_mv_buf_t *ps_col_mv; + mv_pred_t *ps_mv; + UWORD8 *pu1_col_zero_flag_buf; + dec_struct_t *ps_dec = (dec_struct_t *)pv_dec; + WORD32 buf_ret; + + pu1_mv_buf_mgr_base = ps_dec->ps_mem_tab[MEM_REC_MV_BUF_MGR].pv_base; + u4_mv_buf_mgr_mem_used = 0; + col_flag_buffer_size = ((ui_width * ui_height) >> 4); + + pu1_mv_bank_base = ps_dec->ps_mem_tab[MEM_REC_MVBANK].pv_base; + u4_mv_bank_mem_used = 0; + mvpred_buffer_size = sizeof(mv_pred_t) + * ((ui_width * (ui_height + PAD_MV_BANK_ROW)) >> 4); + + ps_dec->pv_mv_buf_mgr = (void *)(pu1_mv_buf_mgr_base + u4_mv_buf_mgr_mem_used); + u4_mv_buf_mgr_mem_used += sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); + ih264_buf_mgr_init((buf_mgr_t *)ps_dec->pv_mv_buf_mgr); + + ps_col_mv = (col_mv_buf_t *)(pu1_mv_buf_mgr_base + u4_mv_buf_mgr_mem_used); + u4_mv_buf_mgr_mem_used += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2); + u4_mv_buf_mgr_mem_used = ALIGN128(u4_mv_buf_mgr_mem_used); + + for(i = 0 ; i < ps_dec->u1_max_dec_frame_buffering + 1; i++) + { + pu1_col_zero_flag_buf = pu1_mv_buf_mgr_base + u4_mv_buf_mgr_mem_used; + u4_mv_buf_mgr_mem_used += col_flag_buffer_size; + + ps_mv = (mv_pred_t *)(pu1_mv_bank_base + u4_mv_bank_mem_used); + u4_mv_bank_mem_used += mvpred_buffer_size; + + memset(ps_mv, 0, ((ui_width*OFFSET_MV_BANK_ROW) >> 4) * sizeof(mv_pred_t)); + ps_mv += (ui_width*OFFSET_MV_BANK_ROW) >> 4; + + ps_col_mv->pv_col_zero_flag = (void *)pu1_col_zero_flag_buf; + ps_col_mv->pv_mv = (void *)ps_mv; + buf_ret = ih264_buf_mgr_add((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, ps_col_mv, i); + if(0 != buf_ret) + { + ps_dec->i4_error_code = ERROR_BUF_MGR; + return ERROR_BUF_MGR; + } + ps_col_mv++; + } + + if((u4_mv_buf_mgr_mem_used > ps_dec->ps_mem_tab[MEM_REC_MV_BUF_MGR].u4_mem_size) || + (u4_mv_bank_mem_used > ps_dec->ps_mem_tab[MEM_REC_MVBANK].u4_mem_size)) + { + ps_dec->i4_error_code = ERROR_BUF_MGR; + return ERROR_BUF_MGR; + } + + return OK; + +} + + +void ih264d_unpack_coeff4x4_dc_4x4blk(tu_sblk4x4_coeff_data_t *ps_tu_4x4, + WORD16 *pi2_out_coeff_data, + UWORD8 *pu1_inv_scan) +{ + UWORD16 u2_sig_coeff_map = ps_tu_4x4->u2_sig_coeff_map; + WORD32 idx; + WORD16 *pi2_coeff_data = &ps_tu_4x4->ai2_level[0]; + + while(u2_sig_coeff_map) + { + idx = CLZ(u2_sig_coeff_map); + + idx = 31 - idx; + RESET_BIT(u2_sig_coeff_map,idx); + + idx = pu1_inv_scan[idx]; + pi2_out_coeff_data[idx] = *pi2_coeff_data++; + + } +} diff --git a/decoder/ih264d_utils.h b/decoder/ih264d_utils.h new file mode 100755 index 0000000..a1a64d5 --- /dev/null +++ b/decoder/ih264d_utils.h @@ -0,0 +1,101 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +*/ +#ifndef _IH264D_UTILS_H_ +#define _IH264D_UTILS_H_ +/*! +************************************************************************** +* \file ih264d_utils.h +* +* \brief +* Contains declaration of routines +* that handle of start and end of pic processing +* +* \date +* 19/12/2002 +* +* \author AI +************************************************************************** +*/ +#include "ih264d_defs.h" +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_structs.h" +#include "ih264d_parse_cavlc.h" + +void pad_frm_buff_vert(dec_struct_t *ps_dec); + +UWORD8 ih264d_is_end_of_pic(UWORD16 u2_frame_num, + UWORD8 u1_nal_ref_idc, + pocstruct_t *ps_cur_poc, + pocstruct_t *ps_prev_poc, + dec_slice_params_t * ps_prev_slice, + UWORD8 u1_pic_order_cnt_type, + UWORD8 u1_nal_unit_type, + UWORD32 u4_idr_pic_id, + UWORD8 u1_field_pic_flag, + UWORD8 u1_bottom_field_flag); + +WORD32 ih264d_end_of_pic_processing(dec_struct_t * ps_dec); + +WORD32 ih264d_init_pic(dec_struct_t *ps_dec, + UWORD16 u2_frame_num, + WORD32 i4_poc, + dec_pic_params_t * ps_pps); + +WORD32 ih264d_end_of_pic_processing(dec_struct_t * ps_dec); +WORD32 ih264d_decode_pic_order_cnt(UWORD8 u1_is_idr_slice, + UWORD32 u2_frame_num, + pocstruct_t *ps_prev_poc, + pocstruct_t *ps_cur_poc, + dec_slice_params_t *ps_cur_slice, + dec_pic_params_t * ps_pps, + UWORD8 u1_nal_ref_idc, + UWORD8 u1_bottom_field_flag, + UWORD8 u1_field_pic_flag, + WORD32 *pi4_poc); +void ih264d_release_display_bufs(dec_struct_t *ps_dec); +WORD32 ih264d_assign_display_seq(dec_struct_t *ps_dec); +void ih264d_assign_pic_num(dec_struct_t *ps_dec); + +void ih264d_unpack_coeff4x4_dc_4x4blk(tu_sblk4x4_coeff_data_t *ps_tu_4x4, + WORD16 *pi2_out_coeff_data, + UWORD8 *pu1_inv_scan); + +WORD32 ih264d_update_qp(dec_struct_t * ps_dec, const WORD8 i1_qp); +WORD32 ih264d_decode_gaps_in_frame_num(dec_struct_t *ps_dec, + UWORD16 u2_frame_num); + +WORD32 ih264d_get_next_display_field(dec_struct_t * ps_dec, + ivd_out_bufdesc_t *ps_out_buffer, + ivd_get_display_frame_op_t *pv_disp_op); + +void ih264d_release_display_field(dec_struct_t *ps_dec, + ivd_get_display_frame_op_t *pv_disp_op); +void ih264d_close_video_decoder(iv_obj_t *iv_obj_t); +WORD32 ih264d_get_dpb_size_new(UWORD32 u4_level_idc, + UWORD32 width, + UWORD32 height); +WORD32 ih264d_get_next_nal_unit(UWORD8 *pu1_buf, + UWORD32 u4_cur_pos, + UWORD32 u4_max_ofst, + UWORD32 *pu4_length_of_start_code); + +#endif /* _IH264D_UTILS_H_ */ diff --git a/decoder/ih264d_vui.c b/decoder/ih264d_vui.c new file mode 100755 index 0000000..87276bd --- /dev/null +++ b/decoder/ih264d_vui.c @@ -0,0 +1,233 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_vui.c */ +/* */ +/* Description : This file contains routines to parse VUI NAL's */ +/* */ +/* List of Functions : <List the functions defined in this file> */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 05 2005 NS Draft */ +/* */ +/*****************************************************************************/ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_vui.h" +#include "ih264d_bitstrm.h" +#include "ih264d_parse_cavlc.h" +#include "ih264d_structs.h" +#include "ih264d_error_handler.h" + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_hrd_parametres */ +/* */ +/* Description : This function parses hrd_t parametres */ +/* Inputs : ps_hrd pointer to HRD params */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : Parses HRD params */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_hrd_parametres(hrd_t *ps_hrd, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD8 u1_index; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + + ps_hrd->u4_cpb_cnt = 1 + + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf); + if(ps_hrd->u4_cpb_cnt > 31) + return ERROR_INV_SPS_PPS_T; + ps_hrd->u1_bit_rate_scale = ih264d_get_bits_h264(ps_bitstrm, 4); + ps_hrd->u1_cpb_size_scale = ih264d_get_bits_h264(ps_bitstrm, 4); + + for(u1_index = 0; u1_index < (UWORD8)ps_hrd->u4_cpb_cnt; u1_index++) + { + ps_hrd->u4_bit_rate[u1_index] = 1 + + ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_hrd->u4_cpb_size[u1_index] = 1 + + ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_hrd->u1_cbr_flag[u1_index] = ih264d_get_bits_h264(ps_bitstrm, 1); + } + + ps_hrd->u1_initial_cpb_removal_delay = 1 + + ih264d_get_bits_h264(ps_bitstrm, 5); + ps_hrd->u1_cpb_removal_delay_length = 1 + + ih264d_get_bits_h264(ps_bitstrm, 5); + ps_hrd->u1_dpb_output_delay_length = 1 + + ih264d_get_bits_h264(ps_bitstrm, 5); + ps_hrd->u1_time_offset_length = ih264d_get_bits_h264(ps_bitstrm, 5); + + return OK; +} + +/*****************************************************************************/ +/* */ +/* Function Name : ih264d_parse_vui_parametres */ +/* */ +/* Description : This function parses VUI NALs. */ +/* Inputs : ps_vu4 pointer to VUI params */ +/* ps_bitstrm Bitstream */ +/* Globals : None */ +/* Processing : Parses VUI NAL's units and stores the info */ +/* Outputs : None */ +/* Returns : None */ +/* */ +/* Issues : None */ +/* */ +/* Revision History: */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 06 05 2002 NS Draft */ +/* */ +/*****************************************************************************/ + +WORD32 ih264d_parse_vui_parametres(vui_t *ps_vu4, + dec_bit_stream_t *ps_bitstrm) +{ + UWORD8 u4_bits; + UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst; + UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer; + WORD32 ret; + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 8); + ps_vu4->u1_aspect_ratio_idc = (UWORD8)u4_bits; + if(VUI_EXTENDED_SAR == u4_bits) + { + ps_vu4->u2_sar_width = ih264d_get_bits_h264(ps_bitstrm, 16); + ps_vu4->u2_sar_height = ih264d_get_bits_h264(ps_bitstrm, 16); + } + } + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u1_overscan_appropriate_flag = ih264d_get_bits_h264( + ps_bitstrm, 1); + } + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u1_video_format = ih264d_get_bits_h264(ps_bitstrm, 3); + ps_vu4->u1_video_full_range_flag = ih264d_get_bits_h264(ps_bitstrm, + 1); + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u1_colour_primaries = ih264d_get_bits_h264(ps_bitstrm, + 8); + ps_vu4->u1_tfr_chars = ih264d_get_bits_h264(ps_bitstrm, 8); + ps_vu4->u1_matrix_coeffs = ih264d_get_bits_h264(ps_bitstrm, 8); + } + } + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u1_cr_top_field = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u1_cr_bottom_field = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + } + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u4_num_units_in_tick = ih264d_get_bits_h264(ps_bitstrm, 32); + ps_vu4->u4_time_scale = ih264d_get_bits_h264(ps_bitstrm, 32); + ps_vu4->u1_fixed_frame_rate_flag = ih264d_get_bits_h264(ps_bitstrm, + 1); + } + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + ps_vu4->u1_nal_hrd_params_present = u4_bits; + if(u4_bits) + { + ret = ih264d_parse_hrd_parametres(&ps_vu4->s_nal_hrd, ps_bitstrm); + if(ret != OK) + return ret; + } + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + ps_vu4->u1_vcl_hrd_params_present = u4_bits; + if(u4_bits) + { + ret = ih264d_parse_hrd_parametres(&ps_vu4->s_vcl_hrd, ps_bitstrm); + if(ret != OK) + return ret; + } + + if(ps_vu4->u1_nal_hrd_params_present || u4_bits) + { + ps_vu4->u1_low_delay_hrd_flag = ih264d_get_bits_h264(ps_bitstrm, 1); + } + ps_vu4->u1_pic_struct_present_flag = ih264d_get_bits_h264(ps_bitstrm, 1); + + u4_bits = ih264d_get_bits_h264(ps_bitstrm, 1); + if(u4_bits) + { + ps_vu4->u1_mv_over_pic_boundaries_flag = ih264d_get_bits_h264( + ps_bitstrm, 1); + ps_vu4->u4_max_bytes_per_pic_denom = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u4_max_bits_per_mb_denom = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u4_log2_max_mv_length_horz = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u4_log2_max_mv_length_vert = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u4_num_reorder_frames = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + ps_vu4->u4_max_dec_frame_buffering = ih264d_uev(pu4_bitstrm_ofst, + pu4_bitstrm_buf); + } + else + { + /* Setting this to a large value if not present */ + ps_vu4->u4_num_reorder_frames = 64; + } + + return OK; +} diff --git a/decoder/ih264d_vui.h b/decoder/ih264d_vui.h new file mode 100755 index 0000000..e380a5b --- /dev/null +++ b/decoder/ih264d_vui.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ih264d_vui.h */ +/* */ +/* Description : This file contains routines to parse SEI NAL's */ +/* */ +/* List of Functions : <List the functions defined in this file> */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 25 05 2005 NS Draft */ +/* */ +/*****************************************************************************/ + +#ifndef _IH264D_VUI_H_ +#define _IH264D_VUI_H_ + +#include "ih264_typedefs.h" +#include "ih264_macros.h" +#include "ih264_platform_macros.h" +#include "ih264d_bitstrm.h" + +#define VUI_EXTENDED_SAR 255 + +typedef struct +{ + UWORD32 u4_cpb_cnt; + UWORD8 u1_bit_rate_scale; + UWORD8 u1_cpb_size_scale; + UWORD32 u4_bit_rate[32]; + UWORD32 u4_cpb_size[32]; + UWORD8 u1_cbr_flag[32]; + UWORD8 u1_initial_cpb_removal_delay; + UWORD8 u1_cpb_removal_delay_length; + UWORD8 u1_dpb_output_delay_length; + UWORD8 u1_time_offset_length; +} hrd_t; + +typedef struct +{ + UWORD8 u1_aspect_ratio_idc; + UWORD16 u2_sar_width; + UWORD16 u2_sar_height; + UWORD8 u1_overscan_appropriate_flag; + UWORD8 u1_video_format; + UWORD8 u1_video_full_range_flag; + UWORD8 u1_colour_primaries; + UWORD8 u1_tfr_chars; + UWORD8 u1_matrix_coeffs; + UWORD8 u1_cr_top_field; + UWORD8 u1_cr_bottom_field; + UWORD32 u4_num_units_in_tick; + UWORD32 u4_time_scale; + UWORD8 u1_fixed_frame_rate_flag; + UWORD8 u1_nal_hrd_params_present; + hrd_t s_nal_hrd; + UWORD8 u1_vcl_hrd_params_present; + hrd_t s_vcl_hrd; + UWORD8 u1_low_delay_hrd_flag; + UWORD8 u1_pic_struct_present_flag; + UWORD8 u1_mv_over_pic_boundaries_flag; + UWORD32 u4_max_bytes_per_pic_denom; + UWORD32 u4_max_bits_per_mb_denom; + UWORD32 u4_log2_max_mv_length_horz; + UWORD32 u4_log2_max_mv_length_vert; + UWORD32 u4_num_reorder_frames; + UWORD32 u4_max_dec_frame_buffering; +} vui_t; + +WORD32 ih264d_parse_vui_parametres(vui_t *ps_vu4, + dec_bit_stream_t *ps_bitstrm); +#endif /* _SEI_H_ */ + diff --git a/decoder/iv.h b/decoder/iv.h new file mode 100755 index 0000000..3a2ebf5 --- /dev/null +++ b/decoder/iv.h @@ -0,0 +1,420 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* iv.h +* +* @brief +* This file contains all the necessary structure and enumeration +* definitions needed for the Application Program Interface(API) of the +* Ittiam Video and Image codecs +* +* @author +* 100239(RCY) +* +* @par List of Functions: +* +* @remarks +* None +* +******************************************************************************* +*/ + + +#ifndef _IV_H +#define _IV_H + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Typedefs */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ + + +/* IV_API_CALL_STATUS_T:This is only to return the FAIL/PASS status to the */ +/* application for the current API call */ + +typedef enum { + IV_STATUS_NA = 0x7FFFFFFF, + IV_SUCCESS = 0x0, + IV_FAIL = 0x1, +}IV_API_CALL_STATUS_T; + +/* IV_MEM_TYPE_T: This Enumeration defines the type of memory (Internal/Ext */ +/* -ernal) along with the cacheable/non-cacheable attributes */ + +typedef enum { + IV_NA_MEM_TYPE = 0x7FFFFFFF, + IV_INTERNAL_CACHEABLE_PERSISTENT_MEM = 0x1, + IV_INTERNAL_CACHEABLE_SCRATCH_MEM = 0x2, + IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM = 0x3, + IV_EXTERNAL_CACHEABLE_SCRATCH_MEM = 0x4, + IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM = 0x5, + IV_INTERNAL_NONCACHEABLE_SCRATCH_MEM = 0x6, + IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM = 0x7, + IV_EXTERNAL_NONCACHEABLE_SCRATCH_MEM = 0x8 +}IV_MEM_TYPE_T; + +/* IV_COLOR_FORMAT_T: This enumeration lists all the color formats which */ +/* finds usage in video/image codecs */ + +typedef enum { + IV_CHROMA_NA = 0x7FFFFFFF, + IV_YUV_420P = 0x1, + IV_YUV_422P = 0x2, + IV_420_UV_INTL = 0x3, + IV_YUV_422IBE = 0x4, + IV_YUV_422ILE = 0x5, + IV_YUV_444P = 0x6, + IV_YUV_411P = 0x7, + IV_GRAY = 0x8, + IV_RGB_565 = 0x9, + IV_RGB_24 = 0xa, + IV_YUV_420SP_UV = 0xb, + IV_YUV_420SP_VU = 0xc, + IV_RGBA_8888 = 0xd +}IV_COLOR_FORMAT_T; + +/* IV_PICTURE_CODING_TYPE_T: VOP/Frame coding type Enumeration */ + +typedef enum { + IV_NA_FRAME = 0x7FFFFFFF, + IV_I_FRAME = 0x0, + IV_P_FRAME = 0x1, + IV_B_FRAME = 0x2, + IV_IDR_FRAME = 0x3, + IV_II_FRAME = 0x4, + IV_IP_FRAME = 0x5, + IV_IB_FRAME = 0x6, + IV_PI_FRAME = 0x7, + IV_PP_FRAME = 0x8, + IV_PB_FRAME = 0x9, + IV_BI_FRAME = 0xa, + IV_BP_FRAME = 0xb, + IV_BB_FRAME = 0xc, + IV_MBAFF_I_FRAME = 0xd, + IV_MBAFF_P_FRAME = 0xe, + IV_MBAFF_B_FRAME = 0xf, + IV_MBAFF_IDR_FRAME = 0x10, + IV_NOT_CODED_FRAME = 0x11, + IV_FRAMETYPE_DEFAULT = IV_I_FRAME +}IV_PICTURE_CODING_TYPE_T; + +/* IV_FLD_TYPE_T: field type Enumeration */ + +typedef enum { + IV_NA_FLD = 0x7FFFFFFF, + IV_TOP_FLD = 0x0, + IV_BOT_FLD = 0x1, + IV_FLD_TYPE_DEFAULT = IV_TOP_FLD +}IV_FLD_TYPE_T; + +/* IV_CONTENT_TYPE_T: Video content type */ + +typedef enum { + IV_CONTENTTYPE_NA = 0x7FFFFFFF, + IV_PROGRESSIVE = 0x0, + IV_INTERLACED = 0x1, + IV_PROGRESSIVE_FRAME = 0x2, + IV_INTERLACED_FRAME = 0x3, + IV_INTERLACED_TOPFIELD = 0x4, + IV_INTERLACED_BOTTOMFIELD = 0x5, + IV_CONTENTTYPE_DEFAULT = IV_PROGRESSIVE, +}IV_CONTENT_TYPE_T; + +/* IV_API_COMMAND_TYPE_T:API command type */ +typedef enum { + IV_CMD_NA = 0x7FFFFFFF, + IV_CMD_GET_NUM_MEM_REC = 0x0, + IV_CMD_FILL_NUM_MEM_REC = 0x1, + IV_CMD_RETRIEVE_MEMREC = 0x2, + IV_CMD_INIT = 0x3, + IV_CMD_DUMMY_ELEMENT = 0x4, +}IV_API_COMMAND_TYPE_T; + +/*****************************************************************************/ +/* Structure */ +/*****************************************************************************/ + +/* IV_OBJ_T: This structure defines the handle for the codec instance */ + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * Pointer to the API function pointer table of the codec + */ + void *pv_fxns; + + /** + * Pointer to the handle of the codec + */ + void *pv_codec_handle; +}iv_obj_t; + +/* iv_mem_rec_t: This structure defines the memory record holder which will */ +/* be used by the codec to communicate its memory requirements to the */ +/* application through appropriate API functions */ + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * Pointer to the memory allocated by the application + */ + void *pv_base; + + /** + * u4_size of the memory to be allocated + */ + UWORD32 u4_mem_size; + + /** + * Alignment of the memory pointer + */ + UWORD32 u4_mem_alignment; + /** + * Nature of the memory to be allocated + */ + IV_MEM_TYPE_T e_mem_type; +}iv_mem_rec_t; + +/* IV_YUV_BUF_T: This structure defines attributes for the yuv buffer */ + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * Pointer to Luma (Y) Buffer + */ + + void *pv_y_buf; + /** + * Pointer to Chroma (Cb) Buffer + */ + void *pv_u_buf; + + /** + * Pointer to Chroma (Cr) Buffer + */ + void *pv_v_buf; + + /** + * Width of the Luma (Y) Buffer + */ + UWORD32 u4_y_wd; + + /** + * Height of the Luma (Y) Buffer + */ + UWORD32 u4_y_ht; + + /** + * Stride/Pitch of the Luma (Y) Buffer + */ + UWORD32 u4_y_strd; + + /** + * Width of the Chroma (Cb) Buffer + */ + UWORD32 u4_u_wd; + + /** + * Height of the Chroma (Cb) Buffer + */ + UWORD32 u4_u_ht; + + /** + * Stride/Pitch of the Chroma (Cb) Buffer + */ + UWORD32 u4_u_strd; + + /** + * Width of the Chroma (Cr) Buffer + */ + UWORD32 u4_v_wd; + + /** + * Height of the Chroma (Cr) Buffer + */ + UWORD32 u4_v_ht; + + /** + * Stride/Pitch of the Chroma (Cr) Buffer + */ + UWORD32 u4_v_strd; +}iv_yuv_buf_t; + +/*****************************************************************************/ +/* Get Number of Memory Records */ +/*****************************************************************************/ + +/* IV_API_COMMAND_TYPE_T::e_cmd = IV_CMD_GET_NUM_MEM_REC */ + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * cmd + */ + IV_API_COMMAND_TYPE_T e_cmd; +}iv_num_mem_rec_ip_t; + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * error code + */ + UWORD32 u4_error_code; + + /** + * num_mem_rec + */ + UWORD32 u4_num_mem_rec; +}iv_num_mem_rec_op_t; + + +/*****************************************************************************/ +/* Fill Memory Records */ +/*****************************************************************************/ + +/* IV_API_COMMAND_TYPE_T::e_cmd = IV_CMD_FILL_NUM_MEM_REC */ + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * cmd + */ + IV_API_COMMAND_TYPE_T e_cmd; + + /** + * pointer to array of memrecords structures should be filled by codec + with details of memory resource requirements + */ + iv_mem_rec_t *pv_mem_rec_location; + + /** + * maximum width for which codec should request memory requirements + */ + UWORD32 u4_max_frm_wd; + + /** + * maximum height for which codec should request memory requirements + */ + UWORD32 u4_max_frm_ht; +}iv_fill_mem_rec_ip_t; + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * error_code + */ + UWORD32 u4_error_code; + + /** + * no of memory record structures which are filled by codec + */ + UWORD32 u4_num_mem_rec_filled; +}iv_fill_mem_rec_op_t; + + +/*****************************************************************************/ +/* Retrieve Memory Records */ +/*****************************************************************************/ + +/* IV_API_COMMAND_TYPE_T::e_cmd = IV_CMD_RETRIEVE_MEMREC */ + + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * cmd + */ + IV_API_COMMAND_TYPE_T e_cmd; + + /** + * array of structures where codec should fill with all resources(memory) with it + */ + iv_mem_rec_t *pv_mem_rec_location; +}iv_retrieve_mem_rec_ip_t; + + +typedef struct { + /** + * u4_size of the structure + */ + UWORD32 u4_size; + + /** + * error_code + */ + UWORD32 u4_error_code; + + /** + * no of memory records filled by codec + */ + UWORD32 u4_num_mem_rec_filled; +}iv_retrieve_mem_rec_op_t; + + + +#endif /* _IV_H */ + diff --git a/decoder/ivd.h b/decoder/ivd.h new file mode 100755 index 0000000..955b81f --- /dev/null +++ b/decoder/ivd.h @@ -0,0 +1,585 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 : ivd.h */ +/* */ +/* Description : This file contains all the necessary structure and */ +/* enumeration definitions needed for the Application */ +/* Program Interface(API) of the Ittiam Video Decoders */ +/* */ +/* List of Functions : None */ +/* */ +/* Issues / Problems : None */ +/* */ +/* Revision History : */ +/* */ +/* DD MM YYYY Author(s) Changes (Describe the changes made) */ +/* 26 08 2010 100239(RCY) Draft */ +/* */ +/*****************************************************************************/ + +#ifndef _IVD_H +#define _IVD_H + +/*****************************************************************************/ +/* Constant Macros */ +/*****************************************************************************/ +#define IVD_VIDDEC_MAX_IO_BUFFERS 64 +/*****************************************************************************/ +/* Typedefs */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ + +/* IVD_ARCH_T: Architecture Enumeration */ +typedef enum +{ + ARCH_NA = 0x7FFFFFFF, + ARCH_ARM_NONEON = 0x0, + ARCH_ARM_A9Q, + ARCH_ARM_A9A, + ARCH_ARM_A9, + ARCH_ARM_A7, + ARCH_ARM_A5, + ARCH_ARM_A15, + ARCH_ARM_NEONINTR, + ARCH_ARMV8_GENERIC, + ARCH_X86_GENERIC = 0x100, + ARCH_X86_SSSE3, + ARCH_X86_SSE42, + ARCH_X86_AVX2, + ARCH_MIPS_GENERIC = 0x200, + ARCH_MIPS_32 +}IVD_ARCH_T; + +/* IVD_SOC_T: SOC Enumeration */ +typedef enum +{ + SOC_NA = 0x7FFFFFFF, + SOC_GENERIC = 0x0, + SOC_HISI_37X = 0x100, +}IVD_SOC_T; + +/* IVD_FRAME_SKIP_MODE_T:Skip mode Enumeration */ + +typedef enum { + IVD_SKIP_NONE = 0x7FFFFFFF, + IVD_SKIP_P = 0x1, + IVD_SKIP_B = 0x2, + IVD_SKIP_I = 0x3, + IVD_SKIP_IP = 0x4, + IVD_SKIP_IB = 0x5, + IVD_SKIP_PB = 0x6, + IVD_SKIP_IPB = 0x7, + IVD_SKIP_IDR = 0x8, + IVD_SKIP_DEFAULT = IVD_SKIP_NONE, +}IVD_FRAME_SKIP_MODE_T; + +/* IVD_VIDEO_DECODE_MODE_T: Set decoder to decode either frame worth of data */ +/* or only header worth of data */ + +typedef enum { + IVD_DECODE_MODE_NA = 0x7FFFFFFF, + + /* This enables the codec to process all decodable units */ + IVD_DECODE_FRAME = 0x0, + + /* This enables the codec to decode header only */ + IVD_DECODE_HEADER = 0x1, + + + +}IVD_VIDEO_DECODE_MODE_T; + + +/* IVD_DISPLAY_FRAME_OUT_MODE_T: Video Display Frame Output Mode */ + +typedef enum { + + IVD_DISPLAY_ORDER_NA = 0x7FFFFFFF, + /* To set codec to fill output buffers in display order */ + IVD_DISPLAY_FRAME_OUT = 0x0, + + /* To set codec to fill output buffers in decode order */ + IVD_DECODE_FRAME_OUT = 0x1, +}IVD_DISPLAY_FRAME_OUT_MODE_T; + + +/* IVD_API_COMMAND_TYPE_T:API command type */ +typedef enum { + IVD_CMD_VIDEO_NA = 0x7FFFFFFF, + IVD_CMD_VIDEO_CTL = IV_CMD_DUMMY_ELEMENT + 1, + IVD_CMD_VIDEO_DECODE, + IVD_CMD_GET_DISPLAY_FRAME, + IVD_CMD_REL_DISPLAY_FRAME, + IVD_CMD_SET_DISPLAY_FRAME +}IVD_API_COMMAND_TYPE_T; + +/* IVD_CONTROL_API_COMMAND_TYPE_T: Video Control API command type */ + +typedef enum { + IVD_CMD_NA = 0x7FFFFFFF, + IVD_CMD_CTL_GETPARAMS = 0x0, + IVD_CMD_CTL_SETPARAMS = 0x1, + IVD_CMD_CTL_RESET = 0x2, + IVD_CMD_CTL_SETDEFAULT = 0x3, + IVD_CMD_CTL_FLUSH = 0x4, + IVD_CMD_CTL_GETBUFINFO = 0x5, + IVD_CMD_CTL_GETVERSION = 0x6, + IVD_CMD_CTL_CODEC_SUBCMD_START = 0x7 +}IVD_CONTROL_API_COMMAND_TYPE_T; + + +/* IVD_ERROR_BITS_T: A UWORD32 container will be used for reporting the error*/ +/* code to the application. The first 8 bits starting from LSB have been */ +/* reserved for the codec to report internal error details. The rest of the */ +/* bits will be generic for all video decoders and each bit has an associated*/ +/* meaning as mentioned below. The unused bit fields are reserved for future */ +/* extenstions and will be zero in the current implementation */ + +typedef enum { + /* Bit 8 - Applied concealment. */ + IVD_APPLIEDCONCEALMENT = 0x8, + /* Bit 9 - Insufficient input data. */ + IVD_INSUFFICIENTDATA = 0x9, + /* Bit 10 - Data problem/corruption. */ + IVD_CORRUPTEDDATA = 0xa, + /* Bit 11 - Header problem/corruption. */ + IVD_CORRUPTEDHEADER = 0xb, + /* Bit 12 - Unsupported feature/parameter in input. */ + IVD_UNSUPPORTEDINPUT = 0xc, + /* Bit 13 - Unsupported input parameter orconfiguration. */ + IVD_UNSUPPORTEDPARAM = 0xd, + /* Bit 14 - Fatal error (stop the codec).If there is an */ + /* error and this bit is not set, the error is a recoverable one. */ + IVD_FATALERROR = 0xe, + /* Bit 15 - Invalid bitstream. Applies when Bitstream/YUV frame */ + /* buffer for encode/decode call is made with non-valid or zero u4_size */ + /* data */ + IVD_INVALID_BITSTREAM = 0xf, + /* Bit 16 */ + IVD_INCOMPLETE_BITSTREAM = 0x10, + IVD_ERROR_BITS_T_DUMMY_ELEMENT = 0x7FFFFFFF +}IVD_ERROR_BITS_T; + + +/* IVD_CONTROL_API_COMMAND_TYPE_T: Video Control API command type */ +typedef enum { + IVD_ERROR_NONE = 0x0, + IVD_NUM_MEM_REC_FAILED = 0x1, + IVD_NUM_REC_NOT_SUFFICIENT = 0x2, + IVD_FILL_MEM_REC_FAILED = 0x3, + IVD_REQUESTED_WIDTH_NOT_SUPPPORTED = 0x4, + IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED = 0x5, + IVD_INIT_DEC_FAILED = 0x6, + IVD_INIT_DEC_NOT_SUFFICIENT = 0x7, + IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED = 0x8, + IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED = 0x9, + IVD_INIT_DEC_MEM_NOT_ALIGNED = 0xa, + IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED = 0xb, + IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT = 0xc, + IVD_GET_VERSION_DATABUFFER_SZ_INSUFFICIENT = 0xd, + IVD_BUFFER_SIZE_SET_TO_ZERO = 0xe, + IVD_UNEXPECTED_END_OF_STREAM = 0xf, + IVD_SEQUENCE_HEADER_NOT_DECODED = 0x10, + IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED = 0x11, + IVD_MAX_FRAME_LIMIT_REACHED = 0x12, + IVD_IP_API_STRUCT_SIZE_INCORRECT = 0x13, + IVD_OP_API_STRUCT_SIZE_INCORRECT = 0x14, + IVD_HANDLE_NULL = 0x15, + IVD_HANDLE_STRUCT_SIZE_INCORRECT = 0x16, + IVD_INVALID_HANDLE_NULL = 0x17, + IVD_INVALID_API_CMD = 0x18, + IVD_UNSUPPORTED_API_CMD = 0x19, + IVD_MEM_REC_STRUCT_SIZE_INCORRECT = 0x1a, + IVD_DISP_FRM_ZERO_OP_BUFS = 0x1b, + IVD_DISP_FRM_OP_BUF_NULL = 0x1c, + IVD_DISP_FRM_ZERO_OP_BUF_SIZE = 0x1d, + IVD_DEC_FRM_BS_BUF_NULL = 0x1e, + IVD_SET_CONFG_INVALID_DEC_MODE = 0x1f, + IVD_SET_CONFG_UNSUPPORTED_DISP_WIDTH = 0x20, + IVD_RESET_FAILED = 0x21, + IVD_INIT_DEC_MEM_REC_OVERLAP_ERR = 0x22, + IVD_INIT_DEC_MEM_REC_BASE_NULL = 0x23, + IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR = 0x24, + IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE = 0x25, + IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE = 0x26, + IVD_DEC_NUMBYTES_INV = 0x27, + IVD_DEC_REF_BUF_NULL = 0x28, + IVD_DEC_FRM_SKIPPED = 0x29, + IVD_RES_CHANGED = 0x2a, + IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS = 0x300, +}IVD_ERROR_CODES_T; + + +/*****************************************************************************/ +/* Structure */ +/*****************************************************************************/ +/* structure for passing output buffers to codec during get display buffer */ +/* call */ +typedef struct { + + /* number of output buffers */ + UWORD32 u4_num_bufs; + + /* list of pointers to output buffers */ + UWORD8 *pu1_bufs[IVD_VIDDEC_MAX_IO_BUFFERS]; + + /* sizes of each output buffer */ + UWORD32 u4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; + +}ivd_out_bufdesc_t; + +/*****************************************************************************/ +/* Initialize decoder */ +/*****************************************************************************/ + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_INIT */ + + +typedef struct { + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + /* no memrecords which are allocated on request of codec through + fill mem records */ + UWORD32 u4_num_mem_rec; + /* maximum height for which codec should be initialized */ + UWORD32 u4_frm_max_wd; + /* maximum width for which codec should be initialized */ + UWORD32 u4_frm_max_ht; + /* format in which codec has to give out frame data for display */ + IV_COLOR_FORMAT_T e_output_format; + /* pointer to memrecord array, which contains allocated resources */ + iv_mem_rec_t *pv_mem_rec_location; +}ivd_init_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_init_op_t; + + +/*****************************************************************************/ +/* Video Decode */ +/*****************************************************************************/ + + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_DECODE */ + + +typedef struct { + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + UWORD32 u4_ts; + UWORD32 u4_num_Bytes; + void *pv_stream_buffer; + + /* output buffer desc */ + ivd_out_bufdesc_t s_out_buffer; + +}ivd_video_decode_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; + UWORD32 u4_num_bytes_consumed; + UWORD32 u4_pic_wd; + UWORD32 u4_pic_ht; + IV_PICTURE_CODING_TYPE_T e_pic_type; + UWORD32 u4_frame_decoded_flag; + UWORD32 u4_new_seq; + + UWORD32 u4_output_present; + UWORD32 u4_progressive_frame_flag; + UWORD32 u4_is_ref_flag; + IV_COLOR_FORMAT_T e_output_format; + iv_yuv_buf_t s_disp_frm_buf; + IV_FLD_TYPE_T e4_fld_type; + UWORD32 u4_ts; + UWORD32 u4_disp_buf_id; +}ivd_video_decode_op_t; + + +/*****************************************************************************/ +/* Get Display Frame */ +/*****************************************************************************/ + + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_GET_DISPLAY_FRAME */ + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + + IVD_API_COMMAND_TYPE_T e_cmd; + + /* output buffer desc */ + ivd_out_bufdesc_t s_out_buffer; + +}ivd_get_display_frame_ip_t; + + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; + UWORD32 u4_progressive_frame_flag; + IV_PICTURE_CODING_TYPE_T e_pic_type; + UWORD32 u4_is_ref_flag; + IV_COLOR_FORMAT_T e_output_format; + iv_yuv_buf_t s_disp_frm_buf; + IV_FLD_TYPE_T e4_fld_type; + UWORD32 u4_ts; + UWORD32 u4_disp_buf_id; +}ivd_get_display_frame_op_t; + +/*****************************************************************************/ +/* Set Display Frame */ +/*****************************************************************************/ + + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_SET_DISPLAY_FRAME */ + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + + IVD_API_COMMAND_TYPE_T e_cmd; + + UWORD32 num_disp_bufs; + + /* output buffer desc */ + ivd_out_bufdesc_t s_disp_buffer[IVD_VIDDEC_MAX_IO_BUFFERS]; + +}ivd_set_display_frame_ip_t; + + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_set_display_frame_op_t; + + +/*****************************************************************************/ +/* Release Display Frame */ +/*****************************************************************************/ + + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_SET_DISPLAY_FRAME */ + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + UWORD32 u4_disp_buf_id; +}ivd_rel_display_frame_ip_t; + + +typedef struct +{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_rel_display_frame_op_t; + +/*****************************************************************************/ +/* Video control Flush */ +/*****************************************************************************/ +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd = IVD_CMD_ctl_FLUSH */ + + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ivd_ctl_flush_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_ctl_flush_op_t; + +/*****************************************************************************/ +/* Video control reset */ +/*****************************************************************************/ +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd = IVD_CMD_ctl_RESET */ + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ivd_ctl_reset_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_ctl_reset_op_t; + + +/*****************************************************************************/ +/* Video control Set Params */ +/*****************************************************************************/ +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd=IVD_CMD_ctl_SETPARAMS */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd=IVD_CMD_ctl_SETDEFAULT */ + + + +typedef struct { + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + IVD_VIDEO_DECODE_MODE_T e_vid_dec_mode; + UWORD32 u4_disp_wd; + IVD_FRAME_SKIP_MODE_T e_frm_skip_mode; + IVD_DISPLAY_FRAME_OUT_MODE_T e_frm_out_mode; +}ivd_ctl_set_config_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_ctl_set_config_op_t; + +/*****************************************************************************/ +/* Video control:Get Buf Info */ +/*****************************************************************************/ + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd=IVD_CMD_ctl_GETBUFINFO */ + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ivd_ctl_getbufinfo_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; + /* no of display buffer sets required by codec */ + UWORD32 u4_num_disp_bufs; + /* no of input buffers required for codec */ + UWORD32 u4_min_num_in_bufs; + /* no of output buffers required for codec */ + UWORD32 u4_min_num_out_bufs; + /* sizes of each input buffer required */ + UWORD32 u4_min_in_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; + /* sizes of each output buffer required */ + UWORD32 u4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; +}ivd_ctl_getbufinfo_op_t; + + +/*****************************************************************************/ +/* Video control:Getstatus Call */ +/*****************************************************************************/ + + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd=IVD_CMD_ctl_GETPARAMS */ + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; +}ivd_ctl_getstatus_ip_t; + + +typedef struct{ + UWORD32 u4_size; + UWORD32 u4_error_code; + /* no of display buffer sets required by codec */ + UWORD32 u4_num_disp_bufs; + UWORD32 u4_pic_ht; + UWORD32 u4_pic_wd; + UWORD32 u4_frame_rate; + UWORD32 u4_bit_rate; + IV_CONTENT_TYPE_T e_content_type; + IV_COLOR_FORMAT_T e_output_chroma_format; + /* no of input buffers required for codec */ + UWORD32 u4_min_num_in_bufs; + /* no of output buffers required for codec */ + UWORD32 u4_min_num_out_bufs; + /* sizes of each input buffer required */ + UWORD32 u4_min_in_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; + /* sizes of each output buffer required */ + UWORD32 u4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; +}ivd_ctl_getstatus_op_t; + + +/*****************************************************************************/ +/* Video control:Get Version Info */ +/*****************************************************************************/ + +/* IVD_API_COMMAND_TYPE_T::e_cmd = IVD_CMD_VIDEO_CTL */ +/* IVD_CONTROL_API_COMMAND_TYPE_T::e_sub_cmd=IVD_CMD_ctl_GETVERSION */ + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + IVD_API_COMMAND_TYPE_T e_cmd; + IVD_CONTROL_API_COMMAND_TYPE_T e_sub_cmd; + void *pv_version_buffer; + UWORD32 u4_version_buffer_size; +}ivd_ctl_getversioninfo_ip_t; + + +typedef struct{ + /* u4_size of the structure */ + UWORD32 u4_size; + UWORD32 u4_error_code; +}ivd_ctl_getversioninfo_op_t; + +#endif /* __IVD_H__ */ + diff --git a/decoder/mips/ih264d_function_selector.c b/decoder/mips/ih264d_function_selector.c new file mode 100755 index 0000000..13680ed --- /dev/null +++ b/decoder/mips/ih264d_function_selector.c @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* imp2d_function_selector.c +* +* @brief +* Contains functions to initialize function pointers used in hevc +* +* @author +* Naveen +* +* @par List of Functions: +* @remarks +* None +* +******************************************************************************* +*/ +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" +#include "ih264d_function_selector.h" + +void ih264d_init_function_ptr(dec_struct_t *ps_codec) +{ + ih264d_init_function_ptr_generic(ps_codec); +} +void ih264d_init_arch(dec_struct_t *ps_codec) +{ + ps_codec->e_processor_arch = ARCH_NA; +} diff --git a/decoder/x86/ih264d_function_selector.c b/decoder/x86/ih264d_function_selector.c new file mode 100755 index 0000000..9fc5c39 --- /dev/null +++ b/decoder/x86/ih264d_function_selector.c @@ -0,0 +1,94 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* imp2d_function_selector.c +* +* @brief +* Contains functions to initialize function pointers used in hevc +* +* @author +* Naveen +* +* @par List of Functions: +* @remarks +* None +* +******************************************************************************* +*/ +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" +#include "ih264d_function_selector.h" + +void ih264d_init_function_ptr(dec_struct_t *ps_codec) +{ + + ih264d_init_function_ptr_generic(ps_codec); + switch(ps_codec->e_processor_arch) + { + case ARCH_X86_GENERIC: + ih264d_init_function_ptr_generic(ps_codec); + break; + case ARCH_X86_SSSE3: + ih264d_init_function_ptr_ssse3(ps_codec); + break; + case ARCH_X86_SSE42: + default: + ih264d_init_function_ptr_ssse3(ps_codec); + ih264d_init_function_ptr_sse42(ps_codec); + break; + } +} +void ih264d_init_arch(dec_struct_t *ps_codec) +{ +#ifdef DEFAULT_ARCH +#if DEFAULT_ARCH == D_ARCH_X86_SSE42 + ps_codec->e_processor_arch = ARCH_X86_SSE42; +#elif DEFAULT_ARCH == D_ARCH_X86_SSSE3 + ps_codec->e_processor_arch = ARCH_X86_SSSE3; +#elif DEFAULT_ARCH == D_ARCH_X86_AVX2 + ps_codec->e_processor_arch = D_ARCH_X86_AVX2; +#else + ps_codec->e_processor_arch = ARCH_X86_GENERIC; +#endif +#else + ps_codec->e_processor_arch = ARCH_X86_SSE42; +#endif + +} diff --git a/decoder/x86/ih264d_function_selector_sse42.c b/decoder/x86/ih264d_function_selector_sse42.c new file mode 100755 index 0000000..0c493d2 --- /dev/null +++ b/decoder/x86/ih264d_function_selector_sse42.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* ih264e_function_selector_generic.c +* +* @brief +* Contains functions to initialize function pointers of codec context +* +* @author +* Ittiam +* +* @par List of Functions: +* - ih264e_init_function_ptr_generic +* +* @remarks +* None +* +******************************************************************************* +*/ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" + + +/** +******************************************************************************* +* +* @brief Initialize the intra/inter/transform/deblk function pointers of +* codec context +* +* @par Description: the current routine initializes the function pointers of +* codec context basing on the architecture in use +* +* @param[in] ps_codec +* Codec context pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void ih264d_init_function_ptr_sse42(dec_struct_t *ps_codec) +{ + ps_codec->pf_default_weighted_pred_luma = ih264_default_weighted_pred_luma_sse42; + ps_codec->pf_default_weighted_pred_chroma = ih264_default_weighted_pred_chroma_sse42; + ps_codec->pf_weighted_pred_luma = ih264_weighted_pred_luma_sse42; + ps_codec->pf_weighted_pred_chroma = ih264_weighted_pred_chroma_sse42; + ps_codec->pf_weighted_bi_pred_luma = ih264_weighted_bi_pred_luma_sse42; + ps_codec->pf_weighted_bi_pred_chroma = ih264_weighted_bi_pred_chroma_sse42; + + ps_codec->pf_iquant_itrans_recon_luma_4x4 = ih264_iquant_itrans_recon_4x4_sse42; + ps_codec->pf_iquant_itrans_recon_chroma_4x4 = ih264_iquant_itrans_recon_chroma_4x4_sse42; + ps_codec->pf_ihadamard_scaling_4x4 = ih264_ihadamard_scaling_4x4_sse42; + return; +} diff --git a/decoder/x86/ih264d_function_selector_ssse3.c b/decoder/x86/ih264d_function_selector_ssse3.c new file mode 100755 index 0000000..1786213 --- /dev/null +++ b/decoder/x86/ih264d_function_selector_ssse3.c @@ -0,0 +1,181 @@ +/****************************************************************************** + * + * Copyright (C) 2015 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 +* ih264e_function_selector_generic.c +* +* @brief +* Contains functions to initialize function pointers of codec context +* +* @author +* Ittiam +* +* @par List of Functions: +* - ih264e_init_function_ptr_generic +* +* @remarks +* None +* +******************************************************************************* +*/ + + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System Include files */ +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> + +/* User Include files */ +#include "ih264_typedefs.h" +#include "iv.h" +#include "ivd.h" +#include "ih264_defs.h" +#include "ih264_size_defs.h" +#include "ih264_error.h" +#include "ih264_trans_quant_itrans_iquant.h" +#include "ih264_inter_pred_filters.h" + +#include "ih264d_structs.h" + + +/** +******************************************************************************* +* +* @brief Initialize the intra/inter/transform/deblk function pointers of +* codec context +* +* @par Description: the current routine initializes the function pointers of +* codec context basing on the architecture in use +* +* @param[in] ps_codec +* Codec context pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void ih264d_init_function_ptr_ssse3(dec_struct_t *ps_codec) +{ + + + + /* Init function pointers for intra pred leaf level functions luma + * Intra 16x16 */ + ps_codec->apf_intra_pred_luma_16x16[0] = ih264_intra_pred_luma_16x16_mode_vert_ssse3; + ps_codec->apf_intra_pred_luma_16x16[1] = ih264_intra_pred_luma_16x16_mode_horz_ssse3; + ps_codec->apf_intra_pred_luma_16x16[2] = ih264_intra_pred_luma_16x16_mode_dc_ssse3; + ps_codec->apf_intra_pred_luma_16x16[3] = ih264_intra_pred_luma_16x16_mode_plane_ssse3; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 4x4 */ + ps_codec->apf_intra_pred_luma_4x4[0] = ih264_intra_pred_luma_4x4_mode_vert_ssse3; + ps_codec->apf_intra_pred_luma_4x4[1] = ih264_intra_pred_luma_4x4_mode_horz_ssse3; + ps_codec->apf_intra_pred_luma_4x4[2] = ih264_intra_pred_luma_4x4_mode_dc_ssse3; + ps_codec->apf_intra_pred_luma_4x4[3] = ih264_intra_pred_luma_4x4_mode_diag_dl_ssse3; + ps_codec->apf_intra_pred_luma_4x4[4] = ih264_intra_pred_luma_4x4_mode_diag_dr_ssse3; + ps_codec->apf_intra_pred_luma_4x4[5] = ih264_intra_pred_luma_4x4_mode_vert_r_ssse3; + ps_codec->apf_intra_pred_luma_4x4[6] = ih264_intra_pred_luma_4x4_mode_horz_d_ssse3; + ps_codec->apf_intra_pred_luma_4x4[7] = ih264_intra_pred_luma_4x4_mode_vert_l_ssse3; + ps_codec->apf_intra_pred_luma_4x4[8] = ih264_intra_pred_luma_4x4_mode_horz_u_ssse3; + + /* Init function pointers for intra pred leaf level functions luma + * Intra 8x8 */ + ps_codec->apf_intra_pred_luma_8x8[0] = ih264_intra_pred_luma_8x8_mode_vert_ssse3; + ps_codec->apf_intra_pred_luma_8x8[1] = ih264_intra_pred_luma_8x8_mode_horz_ssse3; + ps_codec->apf_intra_pred_luma_8x8[2] = ih264_intra_pred_luma_8x8_mode_dc_ssse3; + ps_codec->apf_intra_pred_luma_8x8[3] = ih264_intra_pred_luma_8x8_mode_diag_dl_ssse3; + ps_codec->apf_intra_pred_luma_8x8[4] = ih264_intra_pred_luma_8x8_mode_diag_dr_ssse3; + ps_codec->apf_intra_pred_luma_8x8[5] = ih264_intra_pred_luma_8x8_mode_vert_r_ssse3; + ps_codec->apf_intra_pred_luma_8x8[6] = ih264_intra_pred_luma_8x8_mode_horz_d_ssse3; + ps_codec->apf_intra_pred_luma_8x8[7] = ih264_intra_pred_luma_8x8_mode_vert_l_ssse3; + ps_codec->apf_intra_pred_luma_8x8[8] = ih264_intra_pred_luma_8x8_mode_horz_u_ssse3; + + ps_codec->pf_intra_pred_ref_filtering = ih264_intra_pred_luma_8x8_mode_ref_filtering; + + /* Init function pointers for intra pred leaf level functions chroma + * Intra 8x8 */ + ps_codec->apf_intra_pred_chroma[0] = ih264_intra_pred_chroma_8x8_mode_vert_ssse3; + ps_codec->apf_intra_pred_chroma[1] = ih264_intra_pred_chroma_8x8_mode_horz_ssse3; + ps_codec->apf_intra_pred_chroma[2] = ih264_intra_pred_chroma_8x8_mode_dc; + ps_codec->apf_intra_pred_chroma[3] = ih264_intra_pred_chroma_8x8_mode_plane_ssse3; + + + ps_codec->pf_pad_left_luma = ih264_pad_left_luma_ssse3; + ps_codec->pf_pad_left_chroma = ih264_pad_left_chroma_ssse3; + ps_codec->pf_pad_right_luma = ih264_pad_right_luma_ssse3; + ps_codec->pf_pad_right_chroma = ih264_pad_right_chroma_ssse3; + + + ps_codec->pf_iquant_itrans_recon_luma_4x4 = ih264_iquant_itrans_recon_4x4_ssse3; + ps_codec->pf_iquant_itrans_recon_luma_4x4_dc = ih264_iquant_itrans_recon_4x4_dc_ssse3; + ps_codec->pf_iquant_itrans_recon_luma_8x8 = ih264_iquant_itrans_recon_8x8_ssse3; + ps_codec->pf_iquant_itrans_recon_luma_8x8_dc = ih264_iquant_itrans_recon_8x8_dc_ssse3; + + ps_codec->pf_iquant_itrans_recon_chroma_4x4_dc = ih264_iquant_itrans_recon_chroma_4x4_dc_ssse3; + + /* Init fn ptr luma deblocking */ + ps_codec->pf_deblk_luma_vert_bs4 = ih264_deblk_luma_vert_bs4_ssse3; + ps_codec->pf_deblk_luma_vert_bslt4 = ih264_deblk_luma_vert_bslt4_ssse3; + ps_codec->pf_deblk_luma_vert_bs4_mbaff = ih264_deblk_luma_vert_bs4_mbaff_ssse3; + ps_codec->pf_deblk_luma_vert_bslt4_mbaff = ih264_deblk_luma_vert_bslt4_mbaff_ssse3; + + ps_codec->pf_deblk_luma_horz_bs4 = ih264_deblk_luma_horz_bs4_ssse3; + ps_codec->pf_deblk_luma_horz_bslt4 = ih264_deblk_luma_horz_bslt4_ssse3; + + /* Init fn ptr chroma deblocking */ + ps_codec->pf_deblk_chroma_vert_bs4 = ih264_deblk_chroma_vert_bs4_ssse3; + ps_codec->pf_deblk_chroma_horz_bs4 = ih264_deblk_chroma_horz_bs4_ssse3; + ps_codec->pf_deblk_chroma_vert_bs4_mbaff = ih264_deblk_chroma_vert_bs4_mbaff_ssse3; + ps_codec->pf_deblk_chroma_vert_bslt4 = ih264_deblk_chroma_vert_bslt4_ssse3; + ps_codec->pf_deblk_chroma_horz_bslt4 = ih264_deblk_chroma_horz_bslt4_ssse3; + ps_codec->pf_deblk_chroma_vert_bslt4_mbaff = ih264_deblk_chroma_vert_bslt4_mbaff_ssse3; + + /* Inter pred leaf level functions */ + + ps_codec->apf_inter_pred_luma[0] = ih264_inter_pred_luma_copy_ssse3; + ps_codec->apf_inter_pred_luma[1] = ih264_inter_pred_luma_horz_qpel_ssse3; + ps_codec->apf_inter_pred_luma[2] = ih264_inter_pred_luma_horz_ssse3; + ps_codec->apf_inter_pred_luma[3] = ih264_inter_pred_luma_horz_qpel_ssse3; + ps_codec->apf_inter_pred_luma[4] = ih264_inter_pred_luma_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[5] = ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[6] = ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[7] = ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[8] = ih264_inter_pred_luma_vert_ssse3; + ps_codec->apf_inter_pred_luma[9] = ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3; + ps_codec->apf_inter_pred_luma[10] = ih264_inter_pred_luma_horz_hpel_vert_hpel_ssse3; + ps_codec->apf_inter_pred_luma[11] = ih264_inter_pred_luma_horz_qpel_vert_hpel_ssse3; + ps_codec->apf_inter_pred_luma[12] = ih264_inter_pred_luma_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[13] = ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[14] = ih264_inter_pred_luma_horz_hpel_vert_qpel_ssse3; + ps_codec->apf_inter_pred_luma[15] = ih264_inter_pred_luma_horz_qpel_vert_qpel_ssse3; + + ps_codec->pf_inter_pred_chroma = ih264_inter_pred_chroma_ssse3; + + + return; +} |