annotate libavcodec/simple_idct.c @ 9:ea1ba68cf0ed

update to match api changes + add sscc produced source
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 05 Jun 2013 14:43:26 +0200
parents
children
rev   line source
nengel@2 1 /*
nengel@2 2 * Simple IDCT
nengel@2 3 *
nengel@2 4 * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
nengel@2 5 *
nengel@2 6 * This file is part of FFmpeg.
nengel@2 7 *
nengel@2 8 * FFmpeg is free software; you can redistribute it and/or
nengel@2 9 * modify it under the terms of the GNU Lesser General Public
nengel@2 10 * License as published by the Free Software Foundation; either
nengel@2 11 * version 2.1 of the License, or (at your option) any later version.
nengel@2 12 *
nengel@2 13 * FFmpeg is distributed in the hope that it will be useful,
nengel@2 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nengel@2 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
nengel@2 16 * Lesser General Public License for more details.
nengel@2 17 *
nengel@2 18 * You should have received a copy of the GNU Lesser General Public
nengel@2 19 * License along with FFmpeg; if not, write to the Free Software
nengel@2 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
nengel@2 21 */
nengel@2 22
nengel@2 23 /**
nengel@2 24 * @file
nengel@2 25 * simpleidct in C.
nengel@2 26 */
nengel@2 27
nengel@2 28 /*
nengel@2 29 based upon some outcommented c code from mpeg2dec (idct_mmx.c
nengel@2 30 written by Aaron Holtzman <aholtzma@ess.engr.uvic.ca>)
nengel@2 31 */
nengel@2 32 #include "avcodec.h"
nengel@2 33 #include "dsputil.h"
nengel@2 34 #include "mathops.h"
nengel@2 35 #include "simple_idct.h"
nengel@2 36
nengel@2 37 #if 0
nengel@2 38 #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
nengel@2 39 #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
nengel@2 40 #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
nengel@2 41 #define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
nengel@2 42 #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
nengel@2 43 #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
nengel@2 44 #define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
nengel@2 45 #define ROW_SHIFT 8
nengel@2 46 #define COL_SHIFT 17
nengel@2 47 #else
nengel@2 48 #define W1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 49 #define W2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 50 #define W3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 51 #define W4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 52 #define W5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 53 #define W6 8867 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 54 #define W7 4520 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
nengel@2 55 #define ROW_SHIFT 11
nengel@2 56 #define COL_SHIFT 20 // 6
nengel@2 57 #endif
nengel@2 58
nengel@2 59 static inline void idctRowCondDC (DCTELEM * row)
nengel@2 60 {
nengel@2 61 int a0, a1, a2, a3, b0, b1, b2, b3;
nengel@2 62 uint64_t temp;
nengel@2 63
nengel@2 64 #if HAVE_BIGENDIAN
nengel@2 65 #define ROW0_MASK 0xffff000000000000LL
nengel@2 66 #else
nengel@2 67 #define ROW0_MASK 0xffffLL
nengel@2 68 #endif
nengel@2 69 if(sizeof(DCTELEM)==2){
nengel@2 70 if ( ((((uint64_t *)row)[0] & ~ROW0_MASK) |
nengel@2 71 ((uint64_t *)row)[1]) == 0) {
nengel@2 72 temp = (row[0] << 3) & 0xffff;
nengel@2 73 temp += temp << 16;
nengel@2 74 temp += temp << 32;
nengel@2 75 ((uint64_t *)row)[0] = temp;
nengel@2 76 ((uint64_t *)row)[1] = temp;
nengel@2 77 return;
nengel@2 78 }
nengel@2 79 }else{
nengel@2 80 if (!(row[1]|row[2]|row[3]|row[4]|row[5]|row[6]|row[7])) {
nengel@2 81 row[0]=row[1]=row[2]=row[3]=row[4]=row[5]=row[6]=row[7]= row[0] << 3;
nengel@2 82 return;
nengel@2 83 }
nengel@2 84 }
nengel@2 85
nengel@2 86 a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1));
nengel@2 87 a1 = a0;
nengel@2 88 a2 = a0;
nengel@2 89 a3 = a0;
nengel@2 90
nengel@2 91 /* no need to optimize : gcc does it */
nengel@2 92 a0 += W2 * row[2];
nengel@2 93 a1 += W6 * row[2];
nengel@2 94 a2 -= W6 * row[2];
nengel@2 95 a3 -= W2 * row[2];
nengel@2 96
nengel@2 97 b0 = MUL16(W1, row[1]);
nengel@2 98 MAC16(b0, W3, row[3]);
nengel@2 99 b1 = MUL16(W3, row[1]);
nengel@2 100 MAC16(b1, -W7, row[3]);
nengel@2 101 b2 = MUL16(W5, row[1]);
nengel@2 102 MAC16(b2, -W1, row[3]);
nengel@2 103 b3 = MUL16(W7, row[1]);
nengel@2 104 MAC16(b3, -W5, row[3]);
nengel@2 105
nengel@2 106 temp = ((uint64_t*)row)[1];
nengel@2 107
nengel@2 108 if (temp != 0) {
nengel@2 109 a0 += W4*row[4] + W6*row[6];
nengel@2 110 a1 += - W4*row[4] - W2*row[6];
nengel@2 111 a2 += - W4*row[4] + W2*row[6];
nengel@2 112 a3 += W4*row[4] - W6*row[6];
nengel@2 113
nengel@2 114 MAC16(b0, W5, row[5]);
nengel@2 115 MAC16(b0, W7, row[7]);
nengel@2 116
nengel@2 117 MAC16(b1, -W1, row[5]);
nengel@2 118 MAC16(b1, -W5, row[7]);
nengel@2 119
nengel@2 120 MAC16(b2, W7, row[5]);
nengel@2 121 MAC16(b2, W3, row[7]);
nengel@2 122
nengel@2 123 MAC16(b3, W3, row[5]);
nengel@2 124 MAC16(b3, -W1, row[7]);
nengel@2 125 }
nengel@2 126
nengel@2 127 row[0] = (a0 + b0) >> ROW_SHIFT;
nengel@2 128 row[7] = (a0 - b0) >> ROW_SHIFT;
nengel@2 129 row[1] = (a1 + b1) >> ROW_SHIFT;
nengel@2 130 row[6] = (a1 - b1) >> ROW_SHIFT;
nengel@2 131 row[2] = (a2 + b2) >> ROW_SHIFT;
nengel@2 132 row[5] = (a2 - b2) >> ROW_SHIFT;
nengel@2 133 row[3] = (a3 + b3) >> ROW_SHIFT;
nengel@2 134 row[4] = (a3 - b3) >> ROW_SHIFT;
nengel@2 135 }
nengel@2 136
nengel@2 137 static inline void idctSparseColPut (uint8_t *dest, int line_size,
nengel@2 138 DCTELEM * col)
nengel@2 139 {
nengel@2 140 int a0, a1, a2, a3, b0, b1, b2, b3;
nengel@2 141 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
nengel@2 142
nengel@2 143 /* XXX: I did that only to give same values as previous code */
nengel@2 144 a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
nengel@2 145 a1 = a0;
nengel@2 146 a2 = a0;
nengel@2 147 a3 = a0;
nengel@2 148
nengel@2 149 a0 += + W2*col[8*2];
nengel@2 150 a1 += + W6*col[8*2];
nengel@2 151 a2 += - W6*col[8*2];
nengel@2 152 a3 += - W2*col[8*2];
nengel@2 153
nengel@2 154 b0 = MUL16(W1, col[8*1]);
nengel@2 155 b1 = MUL16(W3, col[8*1]);
nengel@2 156 b2 = MUL16(W5, col[8*1]);
nengel@2 157 b3 = MUL16(W7, col[8*1]);
nengel@2 158
nengel@2 159 MAC16(b0, + W3, col[8*3]);
nengel@2 160 MAC16(b1, - W7, col[8*3]);
nengel@2 161 MAC16(b2, - W1, col[8*3]);
nengel@2 162 MAC16(b3, - W5, col[8*3]);
nengel@2 163
nengel@2 164 if(col[8*4]){
nengel@2 165 a0 += + W4*col[8*4];
nengel@2 166 a1 += - W4*col[8*4];
nengel@2 167 a2 += - W4*col[8*4];
nengel@2 168 a3 += + W4*col[8*4];
nengel@2 169 }
nengel@2 170
nengel@2 171 if (col[8*5]) {
nengel@2 172 MAC16(b0, + W5, col[8*5]);
nengel@2 173 MAC16(b1, - W1, col[8*5]);
nengel@2 174 MAC16(b2, + W7, col[8*5]);
nengel@2 175 MAC16(b3, + W3, col[8*5]);
nengel@2 176 }
nengel@2 177
nengel@2 178 if(col[8*6]){
nengel@2 179 a0 += + W6*col[8*6];
nengel@2 180 a1 += - W2*col[8*6];
nengel@2 181 a2 += + W2*col[8*6];
nengel@2 182 a3 += - W6*col[8*6];
nengel@2 183 }
nengel@2 184
nengel@2 185 if (col[8*7]) {
nengel@2 186 MAC16(b0, + W7, col[8*7]);
nengel@2 187 MAC16(b1, - W5, col[8*7]);
nengel@2 188 MAC16(b2, + W3, col[8*7]);
nengel@2 189 MAC16(b3, - W1, col[8*7]);
nengel@2 190 }
nengel@2 191
nengel@2 192 dest[0] = cm[(a0 + b0) >> COL_SHIFT];
nengel@2 193 dest += line_size;
nengel@2 194 dest[0] = cm[(a1 + b1) >> COL_SHIFT];
nengel@2 195 dest += line_size;
nengel@2 196 dest[0] = cm[(a2 + b2) >> COL_SHIFT];
nengel@2 197 dest += line_size;
nengel@2 198 dest[0] = cm[(a3 + b3) >> COL_SHIFT];
nengel@2 199 dest += line_size;
nengel@2 200 dest[0] = cm[(a3 - b3) >> COL_SHIFT];
nengel@2 201 dest += line_size;
nengel@2 202 dest[0] = cm[(a2 - b2) >> COL_SHIFT];
nengel@2 203 dest += line_size;
nengel@2 204 dest[0] = cm[(a1 - b1) >> COL_SHIFT];
nengel@2 205 dest += line_size;
nengel@2 206 dest[0] = cm[(a0 - b0) >> COL_SHIFT];
nengel@2 207 }
nengel@2 208
nengel@2 209 static inline void idctSparseColAdd (uint8_t *dest, int line_size,
nengel@2 210 DCTELEM * col)
nengel@2 211 {
nengel@2 212 int a0, a1, a2, a3, b0, b1, b2, b3;
nengel@2 213 uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
nengel@2 214
nengel@2 215 /* XXX: I did that only to give same values as previous code */
nengel@2 216 a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
nengel@2 217 a1 = a0;
nengel@2 218 a2 = a0;
nengel@2 219 a3 = a0;
nengel@2 220
nengel@2 221 a0 += + W2*col[8*2];
nengel@2 222 a1 += + W6*col[8*2];
nengel@2 223 a2 += - W6*col[8*2];
nengel@2 224 a3 += - W2*col[8*2];
nengel@2 225
nengel@2 226 b0 = MUL16(W1, col[8*1]);
nengel@2 227 b1 = MUL16(W3, col[8*1]);
nengel@2 228 b2 = MUL16(W5, col[8*1]);
nengel@2 229 b3 = MUL16(W7, col[8*1]);
nengel@2 230
nengel@2 231 MAC16(b0, + W3, col[8*3]);
nengel@2 232 MAC16(b1, - W7, col[8*3]);
nengel@2 233 MAC16(b2, - W1, col[8*3]);
nengel@2 234 MAC16(b3, - W5, col[8*3]);
nengel@2 235
nengel@2 236 if(col[8*4]){
nengel@2 237 a0 += + W4*col[8*4];
nengel@2 238 a1 += - W4*col[8*4];
nengel@2 239 a2 += - W4*col[8*4];
nengel@2 240 a3 += + W4*col[8*4];
nengel@2 241 }
nengel@2 242
nengel@2 243 if (col[8*5]) {
nengel@2 244 MAC16(b0, + W5, col[8*5]);
nengel@2 245 MAC16(b1, - W1, col[8*5]);
nengel@2 246 MAC16(b2, + W7, col[8*5]);
nengel@2 247 MAC16(b3, + W3, col[8*5]);
nengel@2 248 }
nengel@2 249
nengel@2 250 if(col[8*6]){
nengel@2 251 a0 += + W6*col[8*6];
nengel@2 252 a1 += - W2*col[8*6];
nengel@2 253 a2 += + W2*col[8*6];
nengel@2 254 a3 += - W6*col[8*6];
nengel@2 255 }
nengel@2 256
nengel@2 257 if (col[8*7]) {
nengel@2 258 MAC16(b0, + W7, col[8*7]);
nengel@2 259 MAC16(b1, - W5, col[8*7]);
nengel@2 260 MAC16(b2, + W3, col[8*7]);
nengel@2 261 MAC16(b3, - W1, col[8*7]);
nengel@2 262 }
nengel@2 263
nengel@2 264 dest[0] = cm[dest[0] + ((a0 + b0) >> COL_SHIFT)];
nengel@2 265 dest += line_size;
nengel@2 266 dest[0] = cm[dest[0] + ((a1 + b1) >> COL_SHIFT)];
nengel@2 267 dest += line_size;
nengel@2 268 dest[0] = cm[dest[0] + ((a2 + b2) >> COL_SHIFT)];
nengel@2 269 dest += line_size;
nengel@2 270 dest[0] = cm[dest[0] + ((a3 + b3) >> COL_SHIFT)];
nengel@2 271 dest += line_size;
nengel@2 272 dest[0] = cm[dest[0] + ((a3 - b3) >> COL_SHIFT)];
nengel@2 273 dest += line_size;
nengel@2 274 dest[0] = cm[dest[0] + ((a2 - b2) >> COL_SHIFT)];
nengel@2 275 dest += line_size;
nengel@2 276 dest[0] = cm[dest[0] + ((a1 - b1) >> COL_SHIFT)];
nengel@2 277 dest += line_size;
nengel@2 278 dest[0] = cm[dest[0] + ((a0 - b0) >> COL_SHIFT)];
nengel@2 279 }
nengel@2 280
nengel@2 281 static inline void idctSparseCol (DCTELEM * col)
nengel@2 282 {
nengel@2 283 int a0, a1, a2, a3, b0, b1, b2, b3;
nengel@2 284
nengel@2 285 /* XXX: I did that only to give same values as previous code */
nengel@2 286 a0 = W4 * (col[8*0] + ((1<<(COL_SHIFT-1))/W4));
nengel@2 287 a1 = a0;
nengel@2 288 a2 = a0;
nengel@2 289 a3 = a0;
nengel@2 290
nengel@2 291 a0 += + W2*col[8*2];
nengel@2 292 a1 += + W6*col[8*2];
nengel@2 293 a2 += - W6*col[8*2];
nengel@2 294 a3 += - W2*col[8*2];
nengel@2 295
nengel@2 296 b0 = MUL16(W1, col[8*1]);
nengel@2 297 b1 = MUL16(W3, col[8*1]);
nengel@2 298 b2 = MUL16(W5, col[8*1]);
nengel@2 299 b3 = MUL16(W7, col[8*1]);
nengel@2 300
nengel@2 301 MAC16(b0, + W3, col[8*3]);
nengel@2 302 MAC16(b1, - W7, col[8*3]);
nengel@2 303 MAC16(b2, - W1, col[8*3]);
nengel@2 304 MAC16(b3, - W5, col[8*3]);
nengel@2 305
nengel@2 306 if(col[8*4]){
nengel@2 307 a0 += + W4*col[8*4];
nengel@2 308 a1 += - W4*col[8*4];
nengel@2 309 a2 += - W4*col[8*4];
nengel@2 310 a3 += + W4*col[8*4];
nengel@2 311 }
nengel@2 312
nengel@2 313 if (col[8*5]) {
nengel@2 314 MAC16(b0, + W5, col[8*5]);
nengel@2 315 MAC16(b1, - W1, col[8*5]);
nengel@2 316 MAC16(b2, + W7, col[8*5]);
nengel@2 317 MAC16(b3, + W3, col[8*5]);
nengel@2 318 }
nengel@2 319
nengel@2 320 if(col[8*6]){
nengel@2 321 a0 += + W6*col[8*6];
nengel@2 322 a1 += - W2*col[8*6];
nengel@2 323 a2 += + W2*col[8*6];
nengel@2 324 a3 += - W6*col[8*6];
nengel@2 325 }
nengel@2 326
nengel@2 327 if (col[8*7]) {
nengel@2 328 MAC16(b0, + W7, col[8*7]);
nengel@2 329 MAC16(b1, - W5, col[8*7]);
nengel@2 330 MAC16(b2, + W3, col[8*7]);
nengel@2 331 MAC16(b3, - W1, col[8*7]);
nengel@2 332 }
nengel@2 333
nengel@2 334 col[0 ] = ((a0 + b0) >> COL_SHIFT);
nengel@2 335 col[8 ] = ((a1 + b1) >> COL_SHIFT);
nengel@2 336 col[16] = ((a2 + b2) >> COL_SHIFT);
nengel@2 337 col[24] = ((a3 + b3) >> COL_SHIFT);
nengel@2 338 col[32] = ((a3 - b3) >> COL_SHIFT);
nengel@2 339 col[40] = ((a2 - b2) >> COL_SHIFT);
nengel@2 340 col[48] = ((a1 - b1) >> COL_SHIFT);
nengel@2 341 col[56] = ((a0 - b0) >> COL_SHIFT);
nengel@2 342 }
nengel@2 343
nengel@2 344 void ff_simple_idct_put(uint8_t *dest, int line_size, DCTELEM *block)
nengel@2 345 {
nengel@2 346 int i;
nengel@2 347 for(i=0; i<8; i++)
nengel@2 348 idctRowCondDC(block + i*8);
nengel@2 349
nengel@2 350 for(i=0; i<8; i++)
nengel@2 351 idctSparseColPut(dest + i, line_size, block + i);
nengel@2 352 }
nengel@2 353
nengel@2 354 void ff_simple_idct_add(uint8_t *dest, int line_size, DCTELEM *block)
nengel@2 355 {
nengel@2 356 int i;
nengel@2 357 for(i=0; i<8; i++)
nengel@2 358 idctRowCondDC(block + i*8);
nengel@2 359
nengel@2 360 for(i=0; i<8; i++)
nengel@2 361 idctSparseColAdd(dest + i, line_size, block + i);
nengel@2 362 }
nengel@2 363
nengel@2 364 void ff_simple_idct(DCTELEM *block)
nengel@2 365 {
nengel@2 366 int i;
nengel@2 367 for(i=0; i<8; i++)
nengel@2 368 idctRowCondDC(block + i*8);
nengel@2 369
nengel@2 370 for(i=0; i<8; i++)
nengel@2 371 idctSparseCol(block + i);
nengel@2 372 }