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 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 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