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/*****************************************************************************/ 66WORD16 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/*****************************************************************************/ 112WORD16 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*******************************************************************************/ 141IMPEG2D_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