| /****************************************************************************** |
| * |
| * 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 <stdio.h> |
| |
| #include "iv_datatypedef.h" |
| #include "iv.h" |
| |
| #include "impeg2_buf_mgr.h" |
| #include "impeg2_disp_mgr.h" |
| #include "impeg2_defs.h" |
| #include "impeg2_platform_macros.h" |
| #include "impeg2_inter_pred.h" |
| #include "impeg2_idct.h" |
| #include "impeg2_globals.h" |
| #include "impeg2_mem_func.h" |
| #include "impeg2_format_conv.h" |
| #include "impeg2_macros.h" |
| |
| #include "ivd.h" |
| #include "impeg2d.h" |
| #include "impeg2d_bitstream.h" |
| #include "impeg2d_structs.h" |
| #include "impeg2d_globals.h" |
| #include "impeg2d_vld_tables.h" |
| #include "impeg2d_pic_proc.h" |
| #include "impeg2d_debug.h" |
| #include "impeg2d_mv_dec.h" |
| #include "impeg2d_mc.h" |
| |
| /******************************************************************************* |
| * Function name : impeg2d_dec_1mv |
| * |
| * Description : Decodes a motion vector and updates the predictors |
| * |
| * Arguments : |
| * stream : Bitstream |
| * predMv : Prediction for the motion vectors |
| * mv : Motion vectors |
| * fCode : fcode to the used for the decoding |
| * shift : Shift value to be used. This will be equal to |
| * (mv_format == "field") && (picture_structure == "Frame picture") |
| * i : 0 - MV_X and 1 - MV_Y |
| * |
| * Value Returned: None |
| *******************************************************************************/ |
| INLINE void impeg2d_dec_1mv(stream_t *ps_stream, WORD16 ai2_pred_mv[], WORD16 ai2_mv[],UWORD16 au2_fCode[], |
| UWORD16 u2_mv_y_shift, WORD16 ai2_dmv[]) |
| { |
| WORD16 i2_f; |
| WORD16 i2_r_size; |
| WORD16 i2_high,i2_low,i2_range; |
| UWORD32 u4_mv_code; |
| WORD16 i2_delta; |
| UWORD16 u2_first_bit; |
| WORD32 i; |
| WORD32 ai2_shifts[2]; |
| UWORD32 u4_buf; |
| UWORD32 u4_buf_nxt; |
| UWORD32 u4_offset; |
| UWORD32 *pu4_buf_aligned; |
| |
| ai2_shifts[0] = 0; |
| ai2_shifts[1] = u2_mv_y_shift; |
| |
| |
| GET_TEMP_STREAM_DATA(u4_buf,u4_buf_nxt,u4_offset,pu4_buf_aligned,ps_stream) |
| for(i = 0; i < 2; i++) |
| { |
| WORD32 i4_shift = ai2_shifts[i]; |
| /* Decode the motion_code */ |
| IBITS_NXT(u4_buf, u4_buf_nxt, u4_offset, u4_mv_code, MV_CODE_LEN) |
| u2_first_bit = (u4_mv_code >> (MV_CODE_LEN - 1)) & 0x01; |
| if(u2_first_bit == 1) /* mvCode == 0 */ |
| { |
| i2_delta = 0; |
| FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,1,pu4_buf_aligned) |
| |
| ai2_mv[i] = (ai2_pred_mv[i] >> i4_shift); |
| |
| ai2_pred_mv[i] = (ai2_mv[i] << i4_shift); |
| |
| } |
| else |
| { |
| UWORD16 u2_index; |
| UWORD16 u2_value; |
| UWORD16 u2_mv_len; |
| UWORD16 u2_abs_mvcode_minus1; |
| UWORD16 u2_sign_bit; |
| |
| i2_r_size = au2_fCode[i] - 1; |
| i2_f = 1 << i2_r_size; |
| i2_high = (16 * i2_f) - 1; |
| i2_low = ((-16) * i2_f); |
| i2_range = (32 * i2_f); |
| |
| u2_index = (u4_mv_code >> 1) & 0x1FF; |
| u2_value = gau2_impeg2d_mv_code[u2_index]; |
| u2_mv_len = (u2_value & 0x0F); |
| u2_abs_mvcode_minus1 = (u2_value >> 8) & 0x0FF; |
| u4_mv_code >>= (MV_CODE_LEN - u2_mv_len - 1); |
| u2_sign_bit = u4_mv_code & 0x1; |
| |
| FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,(u2_mv_len + 1),pu4_buf_aligned) |
| i2_delta = u2_abs_mvcode_minus1 * i2_f + 1; |
| if(i2_r_size) |
| { |
| UWORD32 val; |
| IBITS_GET(u4_buf, u4_buf_nxt, u4_offset, val, pu4_buf_aligned, i2_r_size) |
| i2_delta += val; |
| } |
| |
| if(u2_sign_bit) |
| i2_delta = -i2_delta; |
| |
| ai2_mv[i] = (ai2_pred_mv[i] >> i4_shift) + i2_delta; |
| |
| if(ai2_mv[i] < i2_low) |
| { |
| ai2_mv[i] += i2_range; |
| } |
| |
| if(ai2_mv[i] > i2_high) |
| { |
| ai2_mv[i] -= i2_range; |
| } |
| ai2_pred_mv[i] = (ai2_mv[i] << i4_shift); |
| |
| } |
| if(ai2_dmv) |
| { |
| UWORD32 u4_val; |
| ai2_dmv[i] = 0; |
| IBITS_GET(u4_buf, u4_buf_nxt, u4_offset, u4_val, pu4_buf_aligned, 1) |
| if(u4_val) |
| { |
| IBITS_GET(u4_buf, u4_buf_nxt, u4_offset, u4_val, pu4_buf_aligned, 1) |
| ai2_dmv[i] = gai2_impeg2d_dec_mv[u4_val]; |
| } |
| } |
| } |
| PUT_TEMP_STREAM_DATA(u4_buf, u4_buf_nxt, u4_offset, pu4_buf_aligned, ps_stream) |
| |
| } |
| /******************************************************************************* |
| * Function name : impeg2d_dec_mv |
| * |
| * Description : Decodes a motion vector and updates the predictors |
| * |
| * Arguments : |
| * stream : Bitstream |
| * predMv : Prediction for the motion vectors |
| * mv : Motion vectors |
| * fCode : fcode to the used for the decoding |
| * shift : Shift value to be used. This will be equal to |
| * (mv_format == "field") && (picture_structure == "Frame picture") |
| * |
| * Value Returned: None |
| *******************************************************************************/ |
| e_field_t impeg2d_dec_mv(stream_t *ps_stream, WORD16 ai2_pred_mv[], WORD16 ai2_mv[],UWORD16 au2_f_code[], |
| UWORD16 u2_shift, UWORD16 u2_fld_sel) |
| { |
| e_field_t e_fld; |
| if(u2_fld_sel) |
| { |
| e_fld = (e_field_t)impeg2d_bit_stream_get_bit(ps_stream); |
| } |
| else |
| { |
| e_fld = TOP; |
| } |
| |
| impeg2d_dec_1mv(ps_stream,ai2_pred_mv,ai2_mv,au2_f_code,u2_shift,NULL); |
| |
| return(e_fld); |
| } |
| |
| /***************************************************************************** |
| * Function Name : impeg2d_dec_1mv_mb |
| * |
| * Description : Decodes mc params for 1 MV MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *****************************************************************************/ |
| void impeg2d_dec_1mv_mb(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| e_field_t e_fld; |
| mb_mc_params_t *ps_mc; |
| e_pred_direction_t e_ref_pic; |
| |
| |
| ps_stream = &ps_dec->s_bit_stream; |
| e_ref_pic = ps_dec->e_mb_pred; |
| /************************************************************************/ |
| /* Decode the motion vector */ |
| /************************************************************************/ |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[FORW][FIRST]; |
| e_fld = impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[e_ref_pic][FIRST],pi2_mv, |
| ps_dec->au2_f_code[e_ref_pic],0, ps_dec->u2_fld_pic); |
| |
| ps_dec->ai2_pred_mv[e_ref_pic][SECOND][MV_X] = ps_dec->ai2_pred_mv[e_ref_pic][FIRST][MV_X]; |
| ps_dec->ai2_pred_mv[e_ref_pic][SECOND][MV_Y] = ps_dec->ai2_pred_mv[e_ref_pic][FIRST][MV_Y]; |
| /************************************************************************/ |
| /* Set the motion vector params */ |
| /************************************************************************/ |
| ps_mc = &ps_dec->as_mb_mc_params[e_ref_pic][FIRST]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[e_ref_pic][e_fld]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, 0, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| |
| } |
| |
| /***************************************************************************** |
| * Function Name : impeg2d_dec_2mv_fw_or_bk_mb |
| * |
| * Description : Decodes first part of params for 2 MV Interpolated MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *****************************************************************************/ |
| void impeg2d_dec_2mv_fw_or_bk_mb(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| e_field_t e_fld; |
| mb_mc_params_t *ps_mc; |
| e_pred_direction_t e_ref_pic; |
| UWORD16 i; |
| |
| ps_stream = &ps_dec->s_bit_stream; |
| e_ref_pic = ps_dec->e_mb_pred; |
| for(i = 0; i < 2; i++) |
| { |
| /********************************************************************/ |
| /* Decode the first motion vector */ |
| /********************************************************************/ |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[FORW][i]; |
| e_fld = impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[e_ref_pic][i],pi2_mv, |
| ps_dec->au2_f_code[e_ref_pic],ps_dec->u2_frm_pic, 1); |
| |
| /********************************************************************/ |
| /* Set the motion vector params */ |
| /********************************************************************/ |
| ps_mc = &ps_dec->as_mb_mc_params[FORW][i]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[e_ref_pic][e_fld]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, i, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| } |
| } |
| |
| /***************************************************************************** |
| * Function Name : impeg2d_dec_frm_dual_prime |
| * |
| * Description : Decodes first part of params for 2 MV Interpolated MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *****************************************************************************/ |
| void impeg2d_dec_frm_dual_prime(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| mb_mc_params_t *ps_mc; |
| |
| WORD16 ai2_dmv[2]; |
| WORD16 *pi2_mv1, *pi2_mv2, *pi2_mv3, *pi2_mv4; |
| UWORD16 i,j; |
| |
| pi2_mv1 = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]); |
| pi2_mv2 = (WORD16 *)&(ps_dec->ai2_mv[FORW][SECOND]); |
| pi2_mv3 = (WORD16 *)&(ps_dec->ai2_mv[BACK][FIRST]); |
| pi2_mv4 = (WORD16 *)&(ps_dec->ai2_mv[BACK][SECOND]); |
| |
| |
| |
| ps_stream = &ps_dec->s_bit_stream; |
| |
| /************************************************************************/ |
| /* Decode the motion vector MV_X, MV_Y and dmv[0], dmv[1] */ |
| /************************************************************************/ |
| impeg2d_dec_1mv(ps_stream,ps_dec->ai2_pred_mv[FORW][FIRST],pi2_mv1,ps_dec->au2_f_code[FORW],ps_dec->u2_frm_pic,ai2_dmv); |
| |
| { |
| WORD16 ai2_m[2][2]; |
| |
| if(ps_dec->u2_top_field_first) |
| { |
| ai2_m[1][0] = 1; |
| ai2_m[0][1] = 3; |
| } |
| else |
| { |
| ai2_m[1][0] = 3; |
| ai2_m[0][1] = 1; |
| } |
| |
| pi2_mv2[MV_X] = pi2_mv1[MV_X]; |
| pi2_mv2[MV_Y] = pi2_mv1[MV_Y]; |
| |
| pi2_mv3[MV_X] = ai2_dmv[0] + DIV_2_RND(pi2_mv1[MV_X] * ai2_m[1][0]); |
| pi2_mv4[MV_X] = ai2_dmv[0] + DIV_2_RND(pi2_mv1[MV_X] * ai2_m[0][1]); |
| |
| pi2_mv3[MV_Y] = ai2_dmv[1] + DIV_2_RND(pi2_mv1[MV_Y] * ai2_m[1][0]) - 1; |
| pi2_mv4[MV_Y] = ai2_dmv[1] + DIV_2_RND(pi2_mv1[MV_Y] * ai2_m[0][1]) + 1; |
| } |
| |
| ps_dec->ai2_pred_mv[FORW][SECOND][MV_X] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X]; |
| ps_dec->ai2_pred_mv[FORW][SECOND][MV_Y] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y]; |
| |
| /************************************************************************/ |
| /* Set the motion vector params */ |
| /************************************************************************/ |
| for(j = 0; j < 2; j++) |
| { |
| for(i = 0; i < 2; i++) |
| { |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[j][i]; |
| ps_mc = &ps_dec->as_mb_mc_params[j][i]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[FORW][(i ^ j) & 1]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, i, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| } |
| } |
| |
| } |
| /***************************************************************************** |
| * Function Name : impeg2d_dec_fld_dual_prime |
| * |
| * Description : Decodes first part of params for 2 MV Interpolated MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *****************************************************************************/ |
| void impeg2d_dec_fld_dual_prime(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| mb_mc_params_t *ps_mc; |
| |
| WORD16 *pi2_mv1, *pi2_mv2; |
| WORD16 ai2_dmv[2]; |
| |
| |
| pi2_mv1 = (WORD16 *)&(ps_dec->ai2_mv[FORW][FIRST]); |
| pi2_mv2 = (WORD16 *)&(ps_dec->ai2_mv[FORW][SECOND]); |
| ps_stream = &ps_dec->s_bit_stream; |
| |
| /************************************************************************/ |
| /* Decode the motion vector MV_X, MV_Y and dmv[0], dmv[1] */ |
| /************************************************************************/ |
| impeg2d_dec_1mv(ps_stream,ps_dec->ai2_pred_mv[FORW][FIRST],pi2_mv1,ps_dec->au2_f_code[FORW],0,ai2_dmv); |
| |
| |
| pi2_mv2[MV_X] = ai2_dmv[0] + DIV_2_RND(pi2_mv1[MV_X]); |
| pi2_mv2[MV_Y] = ai2_dmv[1] + DIV_2_RND(pi2_mv1[MV_Y]); |
| |
| if(ps_dec->u2_picture_structure == TOP_FIELD) |
| pi2_mv2[MV_Y] -= 1; |
| else |
| pi2_mv2[MV_Y] += 1; |
| |
| ps_dec->ai2_pred_mv[FORW][SECOND][MV_X] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_X]; |
| ps_dec->ai2_pred_mv[FORW][SECOND][MV_Y] = ps_dec->ai2_pred_mv[FORW][FIRST][MV_Y]; |
| |
| /************************************************************************/ |
| /* Set the motion vector params */ |
| /************************************************************************/ |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[FORW][0]; |
| ps_mc = &ps_dec->as_mb_mc_params[FORW][0]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[FORW][ps_dec->u2_fld_parity]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, 0, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[FORW][1]; |
| ps_mc = &ps_dec->as_mb_mc_params[FORW][1]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[FORW][!ps_dec->u2_fld_parity]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, 0, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| |
| |
| } |
| /***************************************************************************** |
| * Function Name : impeg2d_dec_4mv_mb |
| * |
| * Description : Decodes first part of params for 2 MV Interpolated MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *****************************************************************************/ |
| void impeg2d_dec_4mv_mb(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| e_field_t e_fld; |
| mb_mc_params_t *ps_mc; |
| |
| UWORD16 i,j; |
| |
| ps_stream = &ps_dec->s_bit_stream; |
| |
| /***********************************************/ |
| /* loop for FW & BK */ |
| /***********************************************/ |
| for(j = 0; j < 2; j++) |
| { |
| /***********************************************/ |
| /* loop for decoding 2 mvs of same reference frame*/ |
| /***********************************************/ |
| for(i = 0; i < 2; i++) |
| { |
| /****************************************************************/ |
| /* Decode the first motion vector */ |
| /****************************************************************/ |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[j][i]; |
| e_fld = impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[j][i],pi2_mv, |
| ps_dec->au2_f_code[j],ps_dec->u2_frm_pic, 1); |
| |
| /****************************************************************/ |
| /* Set the motion vector params */ |
| /****************************************************************/ |
| ps_mc = &ps_dec->as_mb_mc_params[j][i]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[j][e_fld]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type, i, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| } |
| } |
| |
| } |
| /******************************************************************************* |
| * Function Name : impeg2d_dec_2mv_interp_mb |
| * |
| * Description : Decodes first part of params for 2 MV Interpolated MB |
| * |
| * Arguments : |
| * dec : Decoder state |
| * |
| * Values Returned : None |
| *******************************************************************************/ |
| void impeg2d_dec_2mv_interp_mb(dec_state_t *ps_dec) |
| { |
| stream_t *ps_stream; |
| WORD16 *pi2_mv; |
| e_field_t e_fld; |
| mb_mc_params_t *ps_mc; |
| UWORD16 i; |
| |
| ps_stream = &ps_dec->s_bit_stream; |
| |
| for(i = 0; i < 2; i++) |
| { |
| /********************************************************************/ |
| /* Decode the first motion vector */ |
| /********************************************************************/ |
| pi2_mv = (WORD16 *)&ps_dec->ai2_mv[i][FIRST]; |
| e_fld = impeg2d_dec_mv(ps_stream,ps_dec->ai2_pred_mv[i][FIRST],pi2_mv, |
| ps_dec->au2_f_code[i],0, ps_dec->u2_fld_pic); |
| |
| ps_dec->ai2_pred_mv[i][SECOND][MV_X] = ps_dec->ai2_pred_mv[i][FIRST][MV_X]; |
| ps_dec->ai2_pred_mv[i][SECOND][MV_Y] = ps_dec->ai2_pred_mv[i][FIRST][MV_Y]; |
| /********************************************************************/ |
| /* Set the motion vector params */ |
| /********************************************************************/ |
| ps_mc = &ps_dec->as_mb_mc_params[i][FIRST]; |
| ps_mc->s_ref = ps_dec->as_ref_buf[i][e_fld]; |
| impeg2d_set_mc_params(&ps_mc->s_luma, &ps_mc->s_chroma, ps_dec->s_mb_type,i, |
| pi2_mv, ps_dec->u2_mb_x, ps_dec->u2_mb_y, ps_dec->u2_frame_width, ps_dec->u2_frame_height,ps_dec->u2_picture_width); |
| } |
| |
| } |