1 /* 2 * Copyright (C) 2009 The Android Open Source Project 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 express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /*------------------------------------------------------------------------------ 18 19 Table of contents 20 21 1. Include headers 22 2. External compiler flags 23 3. Module defines 24 4. Local function prototypes 25 5. Functions 26 h264bsdProcessBlock 27 h264bsdProcessLumaDc 28 h264bsdProcessChromaDc 29 30 ------------------------------------------------------------------------------*/ 31 32 /*------------------------------------------------------------------------------ 33 1. Include headers 34 ------------------------------------------------------------------------------*/ 35 36 #include "basetype.h" 37 #include "h264bsd_transform.h" 38 #include "h264bsd_util.h" 39 40 /*------------------------------------------------------------------------------ 41 2. External compiler flags 42 -------------------------------------------------------------------------------- 43 44 -------------------------------------------------------------------------------- 45 3. Module defines 46 ------------------------------------------------------------------------------*/ 47 48 /* Switch off the following Lint messages for this file: 49 * Info 701: Shift left of signed quantity (int) 50 * Info 702: Shift right of signed quantity (int) 51 */ 52 /*lint -e701 -e702 */ 53 54 /* LevelScale function */ 55 static const i32 levelScale[6][3] = { 56 {10,13,16}, {11,14,18}, {13,16,20}, {14,18,23}, {16,20,25}, {18,23,29}}; 57 58 /* qp % 6 as a function of qp */ 59 static const u8 qpMod6[52] = {0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5, 60 0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3}; 61 62 /* qp / 6 as a function of qp */ 63 static const u8 qpDiv6[52] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3, 64 4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8,8,8,8}; 65 66 /*------------------------------------------------------------------------------ 67 4. Local function prototypes 68 ------------------------------------------------------------------------------*/ 69 70 /*------------------------------------------------------------------------------ 71 72 Function: h264bsdProcessBlock 73 74 Functional description: 75 Function performs inverse zig-zag scan, inverse scaling and 76 inverse transform for a luma or a chroma residual block 77 78 Inputs: 79 data pointer to data to be processed 80 qp quantization parameter 81 skip skip processing of data[0], set to non-zero value 82 if dc coeff hanled separately 83 coeffMap 16 lsb's indicate which coeffs are non-zero, 84 bit 0 (lsb) for coeff 0, bit 1 for coeff 1 etc. 85 86 Outputs: 87 data processed data 88 89 Returns: 90 HANTRO_OK success 91 HANTRO_NOK processed data not in valid range [-512, 511] 92 93 ------------------------------------------------------------------------------*/ 94 u32 h264bsdProcessBlock(i32 *data, u32 qp, u32 skip, u32 coeffMap) 95 { 96 97 /* Variables */ 98 99 i32 tmp0, tmp1, tmp2, tmp3; 100 i32 d1, d2, d3; 101 u32 row,col; 102 u32 qpDiv; 103 i32 *ptr; 104 105 /* Code */ 106 107 qpDiv = qpDiv6[qp]; 108 tmp1 = levelScale[qpMod6[qp]][0] << qpDiv; 109 tmp2 = levelScale[qpMod6[qp]][1] << qpDiv; 110 tmp3 = levelScale[qpMod6[qp]][2] << qpDiv; 111 112 if (!skip) 113 data[0] = (data[0] * tmp1); 114 115 /* at least one of the rows 1, 2 or 3 contain non-zero coeffs, mask takes 116 * the scanning order into account */ 117 if (coeffMap & 0xFF9C) 118 { 119 /* do the zig-zag scan and inverse quantization */ 120 d1 = data[1]; 121 d2 = data[14]; 122 d3 = data[15]; 123 data[1] = (d1 * tmp2); 124 data[14] = (d2 * tmp2); 125 data[15] = (d3 * tmp3); 126 127 d1 = data[2]; 128 d2 = data[5]; 129 d3 = data[4]; 130 data[4] = (d1 * tmp2); 131 data[2] = (d2 * tmp1); 132 data[5] = (d3 * tmp3); 133 134 d1 = data[8]; 135 d2 = data[3]; 136 d3 = data[6]; 137 tmp0 = (d1 * tmp2); 138 data[8] = (d2 * tmp1); 139 data[3] = (d3 * tmp2); 140 d1 = data[7]; 141 d2 = data[12]; 142 d3 = data[9]; 143 data[6] = (d1 * tmp2); 144 data[7] = (d2 * tmp3); 145 data[12] = (d3 * tmp2); 146 data[9] = tmp0; 147 148 d1 = data[10]; 149 d2 = data[11]; 150 d3 = data[13]; 151 data[13] = (d1 * tmp3); 152 data[10] = (d2 * tmp1); 153 data[11] = (d3 * tmp2); 154 155 /* horizontal transform */ 156 for (row = 4, ptr = data; row--; ptr += 4) 157 { 158 tmp0 = ptr[0] + ptr[2]; 159 tmp1 = ptr[0] - ptr[2]; 160 tmp2 = (ptr[1] >> 1) - ptr[3]; 161 tmp3 = ptr[1] + (ptr[3] >> 1); 162 ptr[0] = tmp0 + tmp3; 163 ptr[1] = tmp1 + tmp2; 164 ptr[2] = tmp1 - tmp2; 165 ptr[3] = tmp0 - tmp3; 166 } 167 168 /*lint +e661 +e662*/ 169 /* then vertical transform */ 170 for (col = 4; col--; data++) 171 { 172 tmp0 = data[0] + data[8]; 173 tmp1 = data[0] - data[8]; 174 tmp2 = (data[4] >> 1) - data[12]; 175 tmp3 = data[4] + (data[12] >> 1); 176 data[0 ] = (tmp0 + tmp3 + 32)>>6; 177 data[4 ] = (tmp1 + tmp2 + 32)>>6; 178 data[8 ] = (tmp1 - tmp2 + 32)>>6; 179 data[12] = (tmp0 - tmp3 + 32)>>6; 180 /* check that each value is in the range [-512,511] */ 181 if (((u32)(data[0] + 512) > 1023) || 182 ((u32)(data[4] + 512) > 1023) || 183 ((u32)(data[8] + 512) > 1023) || 184 ((u32)(data[12] + 512) > 1023) ) 185 return(HANTRO_NOK); 186 } 187 } 188 else /* rows 1, 2 and 3 are zero */ 189 { 190 /* only dc-coeff is non-zero, i.e. coeffs at original positions 191 * 1, 5 and 6 are zero */ 192 if ((coeffMap & 0x62) == 0) 193 { 194 tmp0 = (data[0] + 32) >> 6; 195 /* check that value is in the range [-512,511] */ 196 if ((u32)(tmp0 + 512) > 1023) 197 return(HANTRO_NOK); 198 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] = 199 data[6] = data[7] = data[8] = data[9] = data[10] = 200 data[11] = data[12] = data[13] = data[14] = data[15] = 201 tmp0; 202 } 203 else /* at least one of the coeffs 1, 5 or 6 is non-zero */ 204 { 205 data[1] = (data[1] * tmp2); 206 data[2] = (data[5] * tmp1); 207 data[3] = (data[6] * tmp2); 208 tmp0 = data[0] + data[2]; 209 tmp1 = data[0] - data[2]; 210 tmp2 = (data[1] >> 1) - data[3]; 211 tmp3 = data[1] + (data[3] >> 1); 212 data[0] = (tmp0 + tmp3 + 32)>>6; 213 data[1] = (tmp1 + tmp2 + 32)>>6; 214 data[2] = (tmp1 - tmp2 + 32)>>6; 215 data[3] = (tmp0 - tmp3 + 32)>>6; 216 data[4] = data[8] = data[12] = data[0]; 217 data[5] = data[9] = data[13] = data[1]; 218 data[6] = data[10] = data[14] = data[2]; 219 data[7] = data[11] = data[15] = data[3]; 220 /* check that each value is in the range [-512,511] */ 221 if (((u32)(data[0] + 512) > 1023) || 222 ((u32)(data[1] + 512) > 1023) || 223 ((u32)(data[2] + 512) > 1023) || 224 ((u32)(data[3] + 512) > 1023) ) 225 return(HANTRO_NOK); 226 } 227 } 228 229 return(HANTRO_OK); 230 231 } 232 233 /*------------------------------------------------------------------------------ 234 235 Function: h264bsdProcessLumaDc 236 237 Functional description: 238 Function performs inverse zig-zag scan, inverse transform and 239 inverse scaling for a luma DC coefficients block 240 241 Inputs: 242 data pointer to data to be processed 243 qp quantization parameter 244 245 Outputs: 246 data processed data 247 248 Returns: 249 none 250 251 ------------------------------------------------------------------------------*/ 252 void h264bsdProcessLumaDc(i32 *data, u32 qp) 253 { 254 255 /* Variables */ 256 257 i32 tmp0, tmp1, tmp2, tmp3; 258 u32 row,col; 259 u32 qpMod, qpDiv; 260 i32 levScale; 261 i32 *ptr; 262 263 /* Code */ 264 265 qpMod = qpMod6[qp]; 266 qpDiv = qpDiv6[qp]; 267 268 /* zig-zag scan */ 269 tmp0 = data[2]; 270 data[2] = data[5]; 271 data[5] = data[4]; 272 data[4] = tmp0; 273 274 tmp0 = data[8]; 275 data[8] = data[3]; 276 data[3] = data[6]; 277 data[6] = data[7]; 278 data[7] = data[12]; 279 data[12] = data[9]; 280 data[9] = tmp0; 281 282 tmp0 = data[10]; 283 data[10] = data[11]; 284 data[11] = data[13]; 285 data[13] = tmp0; 286 287 /* horizontal transform */ 288 for (row = 4, ptr = data; row--; ptr += 4) 289 { 290 tmp0 = ptr[0] + ptr[2]; 291 tmp1 = ptr[0] - ptr[2]; 292 tmp2 = ptr[1] - ptr[3]; 293 tmp3 = ptr[1] + ptr[3]; 294 ptr[0] = tmp0 + tmp3; 295 ptr[1] = tmp1 + tmp2; 296 ptr[2] = tmp1 - tmp2; 297 ptr[3] = tmp0 - tmp3; 298 } 299 300 /*lint +e661 +e662*/ 301 /* then vertical transform and inverse scaling */ 302 levScale = levelScale[ qpMod ][0]; 303 if (qp >= 12) 304 { 305 levScale <<= (qpDiv-2); 306 for (col = 4; col--; data++) 307 { 308 tmp0 = data[0] + data[8 ]; 309 tmp1 = data[0] - data[8 ]; 310 tmp2 = data[4] - data[12]; 311 tmp3 = data[4] + data[12]; 312 data[0 ] = ((tmp0 + tmp3)*levScale); 313 data[4 ] = ((tmp1 + tmp2)*levScale); 314 data[8 ] = ((tmp1 - tmp2)*levScale); 315 data[12] = ((tmp0 - tmp3)*levScale); 316 } 317 } 318 else 319 { 320 i32 tmp; 321 tmp = ((1 - qpDiv) == 0) ? 1 : 2; 322 for (col = 4; col--; data++) 323 { 324 tmp0 = data[0] + data[8 ]; 325 tmp1 = data[0] - data[8 ]; 326 tmp2 = data[4] - data[12]; 327 tmp3 = data[4] + data[12]; 328 data[0 ] = ((tmp0 + tmp3)*levScale+tmp) >> (2-qpDiv); 329 data[4 ] = ((tmp1 + tmp2)*levScale+tmp) >> (2-qpDiv); 330 data[8 ] = ((tmp1 - tmp2)*levScale+tmp) >> (2-qpDiv); 331 data[12] = ((tmp0 - tmp3)*levScale+tmp) >> (2-qpDiv); 332 } 333 } 334 335 } 336 337 /*------------------------------------------------------------------------------ 338 339 Function: h264bsdProcessChromaDc 340 341 Functional description: 342 Function performs inverse transform and inverse scaling for a 343 chroma DC coefficients block 344 345 Inputs: 346 data pointer to data to be processed 347 qp quantization parameter 348 349 Outputs: 350 data processed data 351 352 Returns: 353 none 354 355 ------------------------------------------------------------------------------*/ 356 void h264bsdProcessChromaDc(i32 *data, u32 qp) 357 { 358 359 /* Variables */ 360 361 i32 tmp0, tmp1, tmp2, tmp3; 362 u32 qpDiv; 363 i32 levScale; 364 u32 levShift; 365 366 /* Code */ 367 368 qpDiv = qpDiv6[qp]; 369 levScale = levelScale[ qpMod6[qp] ][0]; 370 371 if (qp >= 6) 372 { 373 levScale <<= (qpDiv-1); 374 levShift = 0; 375 } 376 else 377 { 378 levShift = 1; 379 } 380 381 tmp0 = data[0] + data[2]; 382 tmp1 = data[0] - data[2]; 383 tmp2 = data[1] - data[3]; 384 tmp3 = data[1] + data[3]; 385 data[0] = ((tmp0 + tmp3) * levScale) >> levShift; 386 data[1] = ((tmp0 - tmp3) * levScale) >> levShift; 387 data[2] = ((tmp1 + tmp2) * levScale) >> levShift; 388 data[3] = ((tmp1 - tmp2) * levScale) >> levShift; 389 tmp0 = data[4] + data[6]; 390 tmp1 = data[4] - data[6]; 391 tmp2 = data[5] - data[7]; 392 tmp3 = data[5] + data[7]; 393 data[4] = ((tmp0 + tmp3) * levScale) >> levShift; 394 data[5] = ((tmp0 - tmp3) * levScale) >> levShift; 395 data[6] = ((tmp1 + tmp2) * levScale) >> levShift; 396 data[7] = ((tmp1 - tmp2) * levScale) >> levShift; 397 398 } 399 400 /*lint +e701 +e702 */ 401 402 403