1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19 /*----------------------------------------------------------------------------
20 ; INCLUDES
21 ----------------------------------------------------------------------------*/
22 #include "mp4dec_lib.h"
23 #include "vlc_decode.h"
24 #include "bitstream.h"
25 #include "zigzag.h"
26 #include "scaling.h"
27
doDCACPrediction(VideoDecData * video,int comp,int16 * q_block,int * direction)28 void doDCACPrediction(
29 VideoDecData *video,
30 int comp,
31 int16 *q_block,
32 int *direction
33 )
34 {
35 /*----------------------------------------------------------------------------
36 ; Define all local variables
37 ----------------------------------------------------------------------------*/
38 int i;
39 int mbnum = video->mbnum;
40 int nMBPerRow = video->nMBPerRow;
41 int x_pos = video->mbnum_col;
42 int y_pos = video->mbnum_row;
43 int16 *AC_tmp;
44 int QP_tmp;
45 int16 *QP_store = video->QPMB + mbnum;
46 int QP = video->QPMB[mbnum];
47 int QP_half = QP >> 1;
48 int32 val;
49 int flag_0 = FALSE, flag_1 = FALSE;
50 uint8 *slice_nb = video->sliceNo;
51 typeDCStore *DC_store = video->predDC + mbnum;
52 typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
53 typeDCACStore *DCAC_col = video->predDCAC_col;
54
55 uint ACpred_flag = (uint) video->acPredFlag[mbnum];
56
57 int left_bnd, up_bnd;
58
59 static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
60 static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
61
62 static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
63 static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
64 static const int Ztab[6] = {3, 2, 1, 0, 4, 5};
65
66 /* I added these to speed up comparisons */
67 static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
68 static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
69
70 static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
71 static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
72
73 // int *direction; /* 0: HORIZONTAL, 1: VERTICAL */
74 int block_A, block_B, block_C;
75 int DC_pred;
76 int y_offset, x_offset, x_tab, y_tab, z_tab; /* speedup coefficients */
77 int b_xtab, b_ytab;
78
79 if (!comp && x_pos && !(video->headerInfo.Mode[mbnum-1]&INTRA_MASK)) /* not intra */
80 {
81 oscl_memset(DCAC_col, 0, sizeof(typeDCACStore));
82 }
83 if (!comp && y_pos && !(video->headerInfo.Mode[mbnum-nMBPerRow]&INTRA_MASK)) /* not intra */
84 {
85 oscl_memset(DCAC_row, 0, sizeof(typeDCACStore));
86 }
87
88 y_offset = Ypos[comp] * nMBPerRow;
89 x_offset = Xpos[comp];
90 x_tab = Xtab[comp];
91 y_tab = Ytab[comp];
92 z_tab = Ztab[comp];
93
94 b_xtab = B_Xtab[comp];
95 b_ytab = B_Ytab[comp];
96
97 /*----------------------------------------------------------------------------
98 ; Function body here
99 ----------------------------------------------------------------------------*/
100 /* Find the direction of prediction and the DC prediction */
101
102 if (x_pos == 0 && y_pos == 0)
103 { /* top left corner */
104 block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
105 block_B = (comp == 3) ? DC_store[x_offset][z_tab] : mid_gray;
106 block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
107 }
108 else if (x_pos == 0)
109 { /* left edge */
110 up_bnd = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
111
112 block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
113 block_B = ((comp == 1 && up_bnd) || comp == 3) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
114 block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
115 }
116 else if (y_pos == 0)
117 { /* top row */
118 left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
119
120 block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
121 block_B = ((comp == 2 && left_bnd) || comp == 3) ? DC_store[y_offset + x_offset][z_tab] : mid_gray;
122 block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
123 }
124 else
125 {
126 up_bnd = Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow];
127 left_bnd = Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1];
128
129 block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
130 block_B = (((comp == 0 || comp == 4 || comp == 5) && slice_nb[mbnum] == slice_nb[mbnum-1-nMBPerRow]) ||
131 (comp == 1 && up_bnd) || (comp == 2 && left_bnd) || (comp == 3)) ? DC_store[y_offset+x_offset][z_tab] : mid_gray;
132 block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
133 }
134
135
136 if ((PV_ABS((block_A - block_B))) < (PV_ABS((block_B - block_C))))
137 {
138 DC_pred = block_C;
139 *direction = 1;
140 if (ACpred_flag == 1)
141 {
142 if (flag_1)
143 {
144 AC_tmp = DCAC_row[0][b_xtab];
145 QP_tmp = QP_store[y_offset];
146 if (QP_tmp == QP)
147 {
148 for (i = 1; i < 8; i++)
149 {
150 q_block[i] = *AC_tmp++;
151 }
152 }
153 else
154 {
155 for (i = 1; i < 8; i++)
156 {
157 val = (int32)(*AC_tmp++) * QP_tmp;
158 q_block[i] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
159 /* Vertical, top ROW of block C */
160 }
161 }
162 }
163 }
164 }
165 else
166 {
167 DC_pred = block_A;
168 *direction = 0;
169 if (ACpred_flag == 1)
170 {
171 if (flag_0)
172 {
173 AC_tmp = DCAC_col[0][b_ytab];
174 QP_tmp = QP_store[x_offset];
175 if (QP_tmp == QP)
176 {
177 for (i = 1; i < 8; i++)
178 {
179 q_block[i<<3] = *AC_tmp++;
180 }
181 }
182 else
183 {
184 for (i = 1; i < 8; i++)
185 {
186 val = (int32)(*AC_tmp++) * QP_tmp;
187 q_block[i<<3] = (val < 0) ? (int16)((val - QP_half) / QP) : (int16)((val + QP_half) / QP);
188 /* Vertical, top ROW of block C */
189 }
190 }
191 }
192 }
193 }
194
195 /* Now predict the DC coefficient */
196 QP_tmp = (comp < 4) ? video->mblock->DCScalarLum : video->mblock->DCScalarChr;
197 q_block[0] += (int16)((DC_pred + (QP_tmp >> 1)) * scale[QP_tmp] >> 18);
198 // q_block[0] += (DC_pred+(QP_tmp>>1))/QP_tmp;
199
200 /*----------------------------------------------------------------------------
201 ; Return nothing or data or data pointer
202 ----------------------------------------------------------------------------*/
203 return;
204 }
205 #ifdef PV_ANNEX_IJKT_SUPPORT
doDCACPrediction_I(VideoDecData * video,int comp,int16 * q_block)206 void doDCACPrediction_I(
207 VideoDecData *video,
208 int comp,
209 int16 *q_block
210 )
211 {
212 /*----------------------------------------------------------------------------
213 ; Define all local variables
214 ----------------------------------------------------------------------------*/
215 int mbnum = video->mbnum;
216 int nMBPerRow = video->nMBPerRow;
217 int x_pos = video->mbnum_col;
218 int y_pos = video->mbnum_row;
219 int16 *AC_tmp;
220 int flag_0 = FALSE, flag_1 = FALSE;
221 uint8 *slice_nb = video->sliceNo;
222 typeDCStore *DC_store = video->predDC + mbnum;
223 typeDCACStore *DCAC_row = video->predDCAC_row + x_pos;
224 typeDCACStore *DCAC_col = video->predDCAC_col;
225 int left_bnd, up_bnd;
226 uint8 *mode = video->headerInfo.Mode;
227 uint ACpred_flag = (uint) video->acPredFlag[mbnum];
228
229
230
231 static const int Xpos[6] = { -1, 0, -1, 0, -1, -1};
232 static const int Ypos[6] = { -1, -1, 0, 0, -1, -1};
233
234 static const int Xtab[6] = {1, 0, 3, 2, 4, 5};
235 static const int Ytab[6] = {2, 3, 0, 1, 4, 5};
236
237 /* I added these to speed up comparisons */
238 static const int Pos0[6] = { 1, 1, 0, 0, 1, 1};
239 static const int Pos1[6] = { 1, 0, 1, 0, 1, 1};
240
241 static const int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
242 static const int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
243
244 // int *direction; /* 0: HORIZONTAL, 1: VERTICAL */
245 int block_A, block_C;
246 int y_offset, x_offset, x_tab, y_tab; /* speedup coefficients */
247 int b_xtab, b_ytab;
248 y_offset = Ypos[comp] * nMBPerRow;
249 x_offset = Xpos[comp];
250 x_tab = Xtab[comp];
251 y_tab = Ytab[comp];
252
253 b_xtab = B_Xtab[comp];
254 b_ytab = B_Ytab[comp];
255
256 /*----------------------------------------------------------------------------
257 ; Function body here
258 ----------------------------------------------------------------------------*/
259 /* Find the direction of prediction and the DC prediction */
260
261 if (x_pos == 0 && y_pos == 0)
262 { /* top left corner */
263 block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
264 block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[0][y_tab] : mid_gray;
265 }
266 else if (x_pos == 0)
267 { /* left edge */
268 up_bnd = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
269 && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);;
270
271 block_A = (comp == 1 || comp == 3) ? flag_0 = TRUE, DC_store[0][x_tab] : mid_gray;
272 block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
273 }
274 else if (y_pos == 0)
275 { /* top row */
276 left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
277 && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
278
279 block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
280 block_C = (comp == 2 || comp == 3) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
281 }
282 else
283 {
284 up_bnd = (Pos0[comp] && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
285 && (mode[mbnum-nMBPerRow] == MODE_INTRA || mode[mbnum-nMBPerRow] == MODE_INTRA_Q);
286 left_bnd = (Pos1[comp] && slice_nb[mbnum] == slice_nb[mbnum-1])
287 && (mode[mbnum-1] == MODE_INTRA || mode[mbnum-1] == MODE_INTRA_Q);
288
289 block_A = (comp == 1 || comp == 3 || left_bnd) ? flag_0 = TRUE, DC_store[x_offset][x_tab] : mid_gray;
290 block_C = (comp == 2 || comp == 3 || up_bnd) ? flag_1 = TRUE, DC_store[y_offset][y_tab] : mid_gray;
291 }
292
293 if (ACpred_flag == 0)
294 {
295 if (flag_0 == TRUE)
296 {
297 if (flag_1 == TRUE)
298 {
299 q_block[0] = (int16)((block_A + block_C) >> 1);
300 }
301 else
302 {
303 q_block[0] = (int16)block_A;
304 }
305 }
306 else
307 {
308 if (flag_1 == TRUE)
309 {
310 q_block[0] = (int16)block_C;
311 }
312 else
313 {
314 q_block[0] = mid_gray;
315 }
316 }
317
318 }
319 else
320 {
321 if (video->mblock->direction == 1)
322 {
323 if (flag_1 == TRUE)
324 {
325 q_block[0] = (int16)block_C;
326
327 AC_tmp = DCAC_row[0][b_xtab];
328 q_block[1] = AC_tmp[0];
329 q_block[2] = AC_tmp[1];
330 q_block[3] = AC_tmp[2];
331 q_block[4] = AC_tmp[3];
332 q_block[5] = AC_tmp[4];
333 q_block[6] = AC_tmp[5];
334 q_block[7] = AC_tmp[6];
335 }
336 else
337 {
338 q_block[0] = mid_gray;
339 }
340 }
341 else
342 {
343 if (flag_0 == TRUE)
344 {
345 q_block[0] = (int16)block_A;
346
347 AC_tmp = DCAC_col[0][b_ytab];
348 q_block[8] = AC_tmp[0];
349 q_block[16] = AC_tmp[1];
350 q_block[24] = AC_tmp[2];
351 q_block[32] = AC_tmp[3];
352 q_block[40] = AC_tmp[4];
353 q_block[48] = AC_tmp[5];
354 q_block[56] = AC_tmp[6];
355 }
356 else
357 {
358 q_block[0] = mid_gray;
359 }
360 }
361 }
362 /*----------------------------------------------------------------------------
363 ; Return nothing or data or data pointer
364 ----------------------------------------------------------------------------*/
365 return;
366 }
367 #endif
368
369