/src/libmpeg2/decoder/impeg2d_d_pic.c
Line | Count | Source |
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 | 76.6M | { |
68 | 76.6M | UWORD16 u2_dc_size; |
69 | 76.6M | WORD16 i2_dc_diff; |
70 | | |
71 | 76.6M | u2_dc_size = impeg2d_dec_vld_symbol(ps_stream,gai2_impeg2d_dct_dc_size[0], |
72 | 76.6M | MPEG2_DCT_DC_LUMA_SIZE_LEN) + |
73 | 76.6M | MPEG2_DCT_DC_SIZE_OFFSET; |
74 | 76.6M | if (u2_dc_size != 0) |
75 | 69.1M | { |
76 | 69.1M | i2_dc_diff = impeg2d_bit_stream_get(ps_stream,u2_dc_size); |
77 | 69.1M | if ((i2_dc_diff & (1 << (u2_dc_size - 1))) == 0) |
78 | 51.8M | i2_dc_diff -= (1 << u2_dc_size) - 1; |
79 | 69.1M | } |
80 | 7.45M | else |
81 | 7.45M | { |
82 | 7.45M | i2_dc_diff = 0; |
83 | 7.45M | } |
84 | 76.6M | return i2_dc_diff; |
85 | 76.6M | } |
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 | 38.3M | { |
114 | 38.3M | UWORD16 u2_dc_size; |
115 | 38.3M | WORD16 i2_dc_diff; |
116 | 38.3M | u2_dc_size = impeg2d_dec_vld_symbol(ps_stream,gai2_impeg2d_dct_dc_size[1], |
117 | 38.3M | MPEG2_DCT_DC_CHROMA_SIZE_LEN) + |
118 | 38.3M | MPEG2_DCT_DC_SIZE_OFFSET; |
119 | 38.3M | if (u2_dc_size != 0) |
120 | 19.1M | { |
121 | 19.1M | i2_dc_diff = impeg2d_bit_stream_get(ps_stream,u2_dc_size); |
122 | 19.1M | if ((i2_dc_diff & (1 << (u2_dc_size - 1))) == 0) |
123 | 11.2M | i2_dc_diff -= (1 << u2_dc_size) - 1; |
124 | 19.1M | } |
125 | 19.1M | else |
126 | 19.1M | { |
127 | 19.1M | i2_dc_diff = 0; |
128 | 19.1M | } |
129 | 38.3M | return i2_dc_diff; |
130 | 38.3M | } |
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 | 1.90M | { |
143 | 1.90M | UWORD32 i; |
144 | 1.90M | yuv_buf_t *ps_cur_frm_buf = &ps_dec->s_cur_frm_buf; |
145 | | |
146 | 1.90M | stream_t *ps_stream = &ps_dec->s_bit_stream; |
147 | 1.90M | UWORD8 *pu1_vld_buf; |
148 | | |
149 | 1.90M | WORD16 i2_dc_diff; |
150 | 1.90M | UWORD32 u4_frame_width = ps_dec->u2_frame_width; |
151 | 1.90M | UWORD32 u4_frm_offset = 0; |
152 | 1.90M | if(ps_dec->u2_picture_structure != FRAME_PICTURE) |
153 | 647 | { |
154 | 647 | u4_frame_width <<= 1; |
155 | 647 | if(ps_dec->u2_picture_structure == BOTTOM_FIELD) |
156 | 267 | { |
157 | 267 | u4_frm_offset = ps_dec->u2_frame_width; |
158 | 267 | } |
159 | 647 | } |
160 | | |
161 | 1.90M | do |
162 | 19.1M | { |
163 | | |
164 | 19.1M | UWORD32 u4_x_offset, u4_y_offset; |
165 | 19.1M | UWORD32 u4_blk_pos; |
166 | 19.1M | WORD16 i2_dc_val; |
167 | | |
168 | 19.1M | UWORD32 u4_dst_x_offset = u4_frm_offset + (ps_dec->u2_mb_x << 4); |
169 | 19.1M | UWORD32 u4_dst_y_offset = (ps_dec->u2_mb_y << 4) * u4_frame_width; |
170 | 19.1M | UWORD8 *pu1_vld_buf8 = ps_cur_frm_buf->pu1_y + u4_dst_x_offset + u4_dst_y_offset; |
171 | 19.1M | UWORD32 u4_dst_wd = u4_frame_width; |
172 | | /*------------------------------------------------------------------*/ |
173 | | /* Discard the Macroblock stuffing in case of MPEG-1 stream */ |
174 | | /*------------------------------------------------------------------*/ |
175 | 19.5M | while(impeg2d_bit_stream_nxt(ps_stream,MB_STUFFING_CODE_LEN) == MB_STUFFING_CODE && |
176 | 357k | ps_stream->u4_offset < ps_stream->u4_max_offset) |
177 | 357k | impeg2d_bit_stream_flush(ps_stream,MB_STUFFING_CODE_LEN); |
178 | | |
179 | | /*------------------------------------------------------------------*/ |
180 | | /* Flush 2 bits from bitstream [MB_Type and MacroBlockAddrIncrement]*/ |
181 | | /*------------------------------------------------------------------*/ |
182 | 19.1M | impeg2d_bit_stream_flush(ps_stream,1); |
183 | | |
184 | 19.1M | if(impeg2d_bit_stream_get(ps_stream, 1) != 0x01) |
185 | 13.2M | { |
186 | | /* Ignore and continue decoding. */ |
187 | 13.2M | } |
188 | | |
189 | | /* Process LUMA blocks of the MB */ |
190 | 95.8M | for(i = 0; i < NUM_LUMA_BLKS; ++i) |
191 | 76.6M | { |
192 | | |
193 | 76.6M | u4_x_offset = gai2_impeg2_blk_x_off[i]; |
194 | 76.6M | u4_y_offset = gai2_impeg2_blk_y_off_frm[i] ; |
195 | 76.6M | u4_blk_pos = (u4_y_offset * u4_dst_wd) + u4_x_offset; |
196 | 76.6M | pu1_vld_buf = pu1_vld_buf8 + u4_blk_pos; |
197 | | |
198 | 76.6M | i2_dc_diff = impeg2d_get_luma_dc_diff(ps_stream); |
199 | 76.6M | i2_dc_val = ps_dec->u2_def_dc_pred[Y_LUMA] + i2_dc_diff; |
200 | 76.6M | ps_dec->u2_def_dc_pred[Y_LUMA] = i2_dc_val; |
201 | 76.6M | i2_dc_val = CLIP_U8(i2_dc_val); |
202 | | |
203 | 76.6M | ps_dec->pf_memset_8bit_8x8_block(pu1_vld_buf, i2_dc_val, u4_dst_wd); |
204 | 76.6M | } |
205 | | |
206 | | |
207 | | |
208 | | /* Process U block of the MB */ |
209 | | |
210 | 19.1M | u4_dst_x_offset >>= 1; |
211 | 19.1M | u4_dst_y_offset >>= 2; |
212 | 19.1M | u4_dst_wd >>= 1; |
213 | 19.1M | pu1_vld_buf = ps_cur_frm_buf->pu1_u + u4_dst_x_offset + u4_dst_y_offset; |
214 | 19.1M | i2_dc_diff = impeg2d_get_chroma_dc_diff(ps_stream); |
215 | 19.1M | i2_dc_val = ps_dec->u2_def_dc_pred[U_CHROMA] + i2_dc_diff; |
216 | 19.1M | ps_dec->u2_def_dc_pred[U_CHROMA] = i2_dc_val; |
217 | 19.1M | i2_dc_val = CLIP_U8(i2_dc_val); |
218 | 19.1M | 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 | 19.1M | pu1_vld_buf = ps_cur_frm_buf->pu1_v + u4_dst_x_offset + u4_dst_y_offset; |
224 | 19.1M | i2_dc_diff = impeg2d_get_chroma_dc_diff(ps_stream); |
225 | 19.1M | i2_dc_val = ps_dec->u2_def_dc_pred[V_CHROMA] + i2_dc_diff; |
226 | 19.1M | ps_dec->u2_def_dc_pred[V_CHROMA] = i2_dc_val; |
227 | 19.1M | i2_dc_val = CLIP_U8(i2_dc_val); |
228 | 19.1M | 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 | 19.1M | ps_dec->u2_num_mbs_left--; |
234 | 19.1M | ps_dec->u2_mb_x++; |
235 | | |
236 | 19.1M | if(ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset) |
237 | 2.25k | { |
238 | 2.25k | return IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR; |
239 | 2.25k | } |
240 | 19.1M | else if (ps_dec->u2_mb_x == ps_dec->u2_num_horiz_mb) |
241 | 237k | { |
242 | 237k | ps_dec->u2_mb_x = 0; |
243 | 237k | ps_dec->u2_mb_y++; |
244 | | |
245 | 237k | } |
246 | | |
247 | | /* Flush end of macro block */ |
248 | 19.1M | impeg2d_bit_stream_flush(ps_stream,1); |
249 | 19.1M | } |
250 | 19.1M | while(ps_dec->u2_num_mbs_left != 0 && impeg2d_bit_stream_nxt(&ps_dec->s_bit_stream,23) != 0x0); |
251 | 1.90M | return (IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE; |
252 | 1.90M | }/* End of impeg2d_dec_d_slice() */ |