| /****************************************************************************** |
| * |
| * 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) |
| { |
| WORD32 mb_x; |
| WORD32 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 */ |
| /*--------------------------------------------------------------------*/ |
| mb_x = (WORD16)ps_dec->u2_mbx; |
| mb_y = (WORD16)ps_dec->u2_mby; |
| |
| ps_dec->u2_cur_mb_addr = u2_cur_mb_address; |
| |
| mb_x++; |
| |
| if(mb_x == u2_frm_width_in_mb) |
| { |
| mb_x = 0; |
| mb_y++; |
| } |
| if(mb_y > ps_dec->i2_prev_slice_mby) |
| { |
| /* if not in the immemdiate row of prev slice end then top |
| will be available */ |
| if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) |
| i2_prev_slice_mbx = -1; |
| |
| if(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((mb_x > (i2_prev_slice_mbx - 1)) |
| && (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(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(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 + mb_x; |
| ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1; |
| ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x; |
| ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + 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 = mb_y; |
| ps_dec->u2_mbx = mb_x; |
| ps_cur_mb_info->u2_mbx = mb_x; |
| ps_cur_mb_info->u2_mby = 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; |
| |
| 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 mb_x; |
| WORD32 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 */ |
| /*--------------------------------------------------------------------*/ |
| mb_x = (WORD16)ps_dec->u2_mbx; |
| mb_y = (WORD16)ps_dec->u2_mby; |
| |
| ps_dec->u2_cur_mb_addr = u2_cur_mb_address; |
| |
| mb_x++; |
| if((UWORD32)mb_x == u2_frm_width_in_mb) |
| { |
| mb_x = 0; |
| mb_y++; |
| } |
| /*********************************************************************/ |
| /* Cabac Context Initialisations */ |
| /*********************************************************************/ |
| ps_dec->ps_curr_ctxt_mb_info = p_ctx_inc_mb_map + 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(mb_y > ps_dec->i2_prev_slice_mby) |
| { |
| /* if not in the immemdiate row of prev slice end then top |
| will be available */ |
| if(mb_y > (ps_dec->i2_prev_slice_mby + 1)) |
| i2_prev_slice_mbx = -1; |
| |
| if(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((mb_x > (i2_prev_slice_mbx - 1)) |
| && ((UWORD32)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(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(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 + mb_x; |
| ps_cur_mb_info->ps_left_mb = ps_cur_mb_row + mb_x - 1; |
| ps_cur_mb_info->ps_top_mb = ps_top_mb_row + mb_x; |
| ps_cur_mb_info->ps_top_right_mb = ps_top_mb_row + 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 = mb_y; |
| ps_dec->u2_mbx = mb_x; |
| ps_cur_mb_info->u2_mbx = mb_x; |
| ps_cur_mb_info->u2_mby = 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) |
| { |
| WORD32 mb_x; |
| WORD32 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 */ |
| /*--------------------------------------------------------------------*/ |
| mb_x = (WORD16)ps_dec->u2_mbx; |
| mb_y = (WORD16)ps_dec->u2_mby; |
| |
| 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; |
| |
| mb_x++; |
| |
| if(mb_x == u2_frm_width_in_mb) |
| { |
| mb_x = 0; |
| mb_y += 2; |
| } |
| |
| ps_curr_ctxt = p_ctx_inc_mb_map + (mb_x << 1); |
| if(mb_y > ps_dec->i2_prev_slice_mby) |
| { |
| UWORD8 u1_cur_mb_fld_flag_known = 0; |
| /* Next row */ |
| if(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[(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(mb_y > (ps_dec->i2_prev_slice_mby + 2)) |
| i2_prev_slice_mbx = -1; |
| if(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[(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((mb_x > (i2_prev_slice_mbx - 1)) |
| && (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(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(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[(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 = mb_y; |
| ps_dec->u2_mbx = 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 + (mb_x << 1) + 1; |
| |
| if(u1_mb_ngbr_avail & LEFT_MB_AVAILABLE_MASK) |
| { |
| u4_left_mb_pair_fld = ps_cur_mb_row[(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 = mb_x; |
| ps_cur_mb_info->u2_mby = 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 UWORD8 u1_num_mbs, |
| 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. u1_num_mbs 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); |
| |
| 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 += (u1_num_mbs << 4); |
| } |
| |
| /* Increment deblock parameters pointer in external memory */ |
| |
| if(ps_dec->u1_separate_parse == 0) |
| { |
| ps_dec->ps_deblk_mbn += u1_num_mbs; |
| } |
| |
| } |
| |