1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ***************************************************************************** 18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19 */ 20 21 #include "iv_datatypedef.h" 22 #include "impeg2_defs.h" 23 #include "impeg2_globals.h" 24 #include "impeg2_platform_macros.h" 25 #include "impeg2_inter_pred.h" 26 #include "impeg2_idct.h" 27 #include "impeg2_mem_func.h" 28 #include "impeg2_format_conv.h" 29 #include "impeg2_disp_mgr.h" 30 #include "impeg2_buf_mgr.h" 31 32 #include "impeg2d.h" 33 #include "impeg2d_bitstream.h" 34 #include "impeg2d_structs.h" 35 #include "impeg2d_vld.h" 36 #include "impeg2d_vld_tables.h" 37 38 #define BLK_SIZE 8 39 #define LUMA_BLK_SIZE (2 * (BLK_SIZE)) 40 #define CHROMA_BLK_SIZE (BLK_SIZE) 41 /*****************************************************************************/ 42 /* */ 43 /* Function Name : impeg2d_get_luma_dc_diff */ 44 /* */ 45 /* Description : Decode the DC differential value from the bitstream for */ 46 /* luma block */ 47 /* */ 48 /* Inputs : stream - Input stream */ 49 /* */ 50 /* Globals : None */ 51 /* */ 52 /* Processing : Decode the vlc for dc_diff */ 53 /* */ 54 /* Outputs : dc_diff - dc differential used in dc prediction */ 55 /* */ 56 /* Returns : dc_diff - dc differential used in dc prediction */ 57 /* */ 58 /* Issues : None */ 59 /* */ 60 /* Revision History: */ 61 /* */ 62 /* DD MM YYYY Author(s) Changes */ 63 /* 14 09 2005 Harish M First Version */ 64 /* */ 65 /*****************************************************************************/ 66 WORD16 impeg2d_get_luma_dc_diff(stream_t *ps_stream) 67 { 68 UWORD16 u2_dc_size; 69 WORD16 i2_dc_diff; 70 71 u2_dc_size = impeg2d_dec_vld_symbol(ps_stream,gai2_impeg2d_dct_dc_size[0], 72 MPEG2_DCT_DC_LUMA_SIZE_LEN) + 73 MPEG2_DCT_DC_SIZE_OFFSET; 74 if (u2_dc_size != 0) 75 { 76 i2_dc_diff = impeg2d_bit_stream_get(ps_stream,u2_dc_size); 77 if ((i2_dc_diff & (1 << (u2_dc_size - 1))) == 0) 78 i2_dc_diff -= (1 << u2_dc_size) - 1; 79 } 80 else 81 { 82 i2_dc_diff = 0; 83 } 84 return i2_dc_diff; 85 } 86 87 /*****************************************************************************/ 88 /* */ 89 /* Function Name : impeg2d_get_chroma_dc_diff */ 90 /* */ 91 /* Description : Decode the DC differential value from the bitstream for */ 92 /* chroma block */ 93 /* */ 94 /* Inputs : stream - Input stream */ 95 /* */ 96 /* Globals : None */ 97 /* */ 98 /* Processing : Decode the vlc for dc_diff */ 99 /* */ 100 /* Outputs : dc_diff - dc differential used in dc prediction */ 101 /* */ 102 /* Returns : dc_diff - dc differential used in dc prediction */ 103 /* */ 104 /* Issues : None */ 105 /* */ 106 /* Revision History: */ 107 /* */ 108 /* DD MM YYYY Author(s) Changes */ 109 /* 14 09 2005 Harish M First Version */ 110 /* */ 111 /*****************************************************************************/ 112 WORD16 impeg2d_get_chroma_dc_diff(stream_t *ps_stream) 113 { 114 UWORD16 u2_dc_size; 115 WORD16 i2_dc_diff; 116 u2_dc_size = impeg2d_dec_vld_symbol(ps_stream,gai2_impeg2d_dct_dc_size[1], 117 MPEG2_DCT_DC_CHROMA_SIZE_LEN) + 118 MPEG2_DCT_DC_SIZE_OFFSET; 119 if (u2_dc_size != 0) 120 { 121 i2_dc_diff = impeg2d_bit_stream_get(ps_stream,u2_dc_size); 122 if ((i2_dc_diff & (1 << (u2_dc_size - 1))) == 0) 123 i2_dc_diff -= (1 << u2_dc_size) - 1; 124 } 125 else 126 { 127 i2_dc_diff = 0; 128 } 129 return i2_dc_diff; 130 } 131 /******************************************************************************* 132 * Function Name : impeg2d_dec_d_slice 133 * 134 * Description : Decodes I slice 135 * 136 * Arguments : 137 * dec : Decoder state 138 * 139 * Values Returned : None 140 *******************************************************************************/ 141 IMPEG2D_ERROR_CODES_T impeg2d_dec_d_slice(dec_state_t *ps_dec) 142 { 143 UWORD32 i; 144 yuv_buf_t *ps_cur_frm_buf = &ps_dec->s_cur_frm_buf; 145 146 stream_t *ps_stream = &ps_dec->s_bit_stream; 147 UWORD8 *pu1_vld_buf; 148 149 WORD16 i2_dc_diff; 150 UWORD32 u4_frame_width = ps_dec->u2_frame_width; 151 UWORD32 u4_frm_offset = 0; 152 if(ps_dec->u2_picture_structure != FRAME_PICTURE) 153 { 154 u4_frame_width <<= 1; 155 if(ps_dec->u2_picture_structure == BOTTOM_FIELD) 156 { 157 u4_frm_offset = ps_dec->u2_frame_width; 158 } 159 } 160 161 do 162 { 163 164 UWORD32 u4_x_offset, u4_y_offset; 165 UWORD32 u4_blk_pos; 166 WORD16 i2_dc_val; 167 168 UWORD32 u4_dst_x_offset = u4_frm_offset + (ps_dec->u2_mb_x << 4); 169 UWORD32 u4_dst_y_offset = (ps_dec->u2_mb_y << 4) * u4_frame_width; 170 UWORD8 *pu1_vld_buf8 = ps_cur_frm_buf->pu1_y + u4_dst_x_offset + u4_dst_y_offset; 171 UWORD32 u4_dst_wd = u4_frame_width; 172 /*------------------------------------------------------------------*/ 173 /* Discard the Macroblock stuffing in case of MPEG-1 stream */ 174 /*------------------------------------------------------------------*/ 175 while(impeg2d_bit_stream_nxt(ps_stream,MB_STUFFING_CODE_LEN) == MB_STUFFING_CODE && 176 ps_stream->u4_offset < ps_stream->u4_max_offset) 177 impeg2d_bit_stream_flush(ps_stream,MB_STUFFING_CODE_LEN); 178 179 /*------------------------------------------------------------------*/ 180 /* Flush 2 bits from bitstream [MB_Type and MacroBlockAddrIncrement]*/ 181 /*------------------------------------------------------------------*/ 182 impeg2d_bit_stream_flush(ps_stream,1); 183 184 if(impeg2d_bit_stream_get(ps_stream, 1) != 0x01) 185 { 186 /* Ignore and continue decoding. */ 187 } 188 189 /* Process LUMA blocks of the MB */ 190 for(i = 0; i < NUM_LUMA_BLKS; ++i) 191 { 192 193 u4_x_offset = gai2_impeg2_blk_x_off[i]; 194 u4_y_offset = gai2_impeg2_blk_y_off_frm[i] ; 195 u4_blk_pos = (u4_y_offset * u4_dst_wd) + u4_x_offset; 196 pu1_vld_buf = pu1_vld_buf8 + u4_blk_pos; 197 198 i2_dc_diff = impeg2d_get_luma_dc_diff(ps_stream); 199 i2_dc_val = ps_dec->u2_def_dc_pred[Y_LUMA] + i2_dc_diff; 200 ps_dec->u2_def_dc_pred[Y_LUMA] = i2_dc_val; 201 i2_dc_val = CLIP_U8(i2_dc_val); 202 203 ps_dec->pf_memset_8bit_8x8_block(pu1_vld_buf, i2_dc_val, u4_dst_wd); 204 } 205 206 207 208 /* Process U block of the MB */ 209 210 u4_dst_x_offset >>= 1; 211 u4_dst_y_offset >>= 2; 212 u4_dst_wd >>= 1; 213 pu1_vld_buf = ps_cur_frm_buf->pu1_u + u4_dst_x_offset + u4_dst_y_offset; 214 i2_dc_diff = impeg2d_get_chroma_dc_diff(ps_stream); 215 i2_dc_val = ps_dec->u2_def_dc_pred[U_CHROMA] + i2_dc_diff; 216 ps_dec->u2_def_dc_pred[U_CHROMA] = i2_dc_val; 217 i2_dc_val = CLIP_U8(i2_dc_val); 218 ps_dec->pf_memset_8bit_8x8_block(pu1_vld_buf, i2_dc_val, u4_dst_wd); 219 220 221 /* Process V block of the MB */ 222 223 pu1_vld_buf = ps_cur_frm_buf->pu1_v + u4_dst_x_offset + u4_dst_y_offset; 224 i2_dc_diff = impeg2d_get_chroma_dc_diff(ps_stream); 225 i2_dc_val = ps_dec->u2_def_dc_pred[V_CHROMA] + i2_dc_diff; 226 ps_dec->u2_def_dc_pred[V_CHROMA] = i2_dc_val; 227 i2_dc_val = CLIP_U8(i2_dc_val); 228 ps_dec->pf_memset_8bit_8x8_block(pu1_vld_buf, i2_dc_val, u4_dst_wd); 229 230 /* Common MB processing Steps */ 231 232 233 ps_dec->u2_num_mbs_left--; 234 ps_dec->u2_mb_x++; 235 236 if(ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset) 237 { 238 return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR; 239 } 240 else if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb) 241 { 242 ps_dec->u2_mb_x = 0; 243 ps_dec->u2_mb_y++; 244 245 } 246 247 /* Flush end of macro block */ 248 impeg2d_bit_stream_flush(ps_stream,1); 249 } 250 while(ps_dec->u2_num_mbs_left != 0 && impeg2d_bit_stream_nxt(&ps_dec->s_bit_stream,23) != 0x0); 251 return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE; 252 }/* End of impeg2d_dec_d_slice() */ 253