vp8dsp.c 16.5 KB
Newer Older
1
/*
David Conrad's avatar
David Conrad committed
2 3 4
 * Copyright (C) 2010 David Conrad
 * Copyright (C) 2010 Ronald S. Bultje
 *
5
 * This file is part of Libav.
David Conrad's avatar
David Conrad committed
6
 *
7
 * Libav is free software; you can redistribute it and/or
David Conrad's avatar
David Conrad committed
8 9 10 11
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
12
 * Libav is distributed in the hope that it will be useful,
David Conrad's avatar
David Conrad committed
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with Libav; if not, write to the Free Software
David Conrad's avatar
David Conrad committed
19 20 21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

22 23 24 25 26
/**
 * @file
 * VP8 compatible video decoder
 */

David Conrad's avatar
David Conrad committed
27 28
#include "dsputil.h"
#include "vp8dsp.h"
29
#include "libavutil/common.h"
David Conrad's avatar
David Conrad committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

// TODO: Maybe add dequant
static void vp8_luma_dc_wht_c(DCTELEM block[4][4][16], DCTELEM dc[16])
{
    int i, t0, t1, t2, t3;

    for (i = 0; i < 4; i++) {
        t0 = dc[0*4+i] + dc[3*4+i];
        t1 = dc[1*4+i] + dc[2*4+i];
        t2 = dc[1*4+i] - dc[2*4+i];
        t3 = dc[0*4+i] - dc[3*4+i];

        dc[0*4+i] = t0 + t1;
        dc[1*4+i] = t3 + t2;
        dc[2*4+i] = t0 - t1;
        dc[3*4+i] = t3 - t2;
    }

    for (i = 0; i < 4; i++) {
        t0 = dc[i*4+0] + dc[i*4+3] + 3; // rounding
        t1 = dc[i*4+1] + dc[i*4+2];
        t2 = dc[i*4+1] - dc[i*4+2];
        t3 = dc[i*4+0] - dc[i*4+3] + 3; // rounding
53 54 55 56
        dc[i*4+0] = 0;
        dc[i*4+1] = 0;
        dc[i*4+2] = 0;
        dc[i*4+3] = 0;
David Conrad's avatar
David Conrad committed
57

58 59 60 61
        block[i][0][0] = (t0 + t1) >> 3;
        block[i][1][0] = (t3 + t2) >> 3;
        block[i][2][0] = (t0 - t1) >> 3;
        block[i][3][0] = (t3 - t2) >> 3;
David Conrad's avatar
David Conrad committed
62 63 64
    }
}

65 66 67 68 69 70 71 72 73 74 75 76
static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16])
{
    int i, val = (dc[0] + 3) >> 3;
    dc[0] = 0;

    for (i = 0; i < 4; i++) {
        block[i][0][0] = val;
        block[i][1][0] = val;
        block[i][2][0] = val;
        block[i][3][0] = val;
    }
}
David Conrad's avatar
David Conrad committed
77 78 79 80

#define MUL_20091(a) ((((a)*20091) >> 16) + (a))
#define MUL_35468(a)  (((a)*35468) >> 16)

81
static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
David Conrad's avatar
David Conrad committed
82 83 84 85 86 87 88 89 90
{
    int i, t0, t1, t2, t3;
    DCTELEM tmp[16];

    for (i = 0; i < 4; i++) {
        t0 = block[0*4+i] + block[2*4+i];
        t1 = block[0*4+i] - block[2*4+i];
        t2 = MUL_35468(block[1*4+i]) - MUL_20091(block[3*4+i]);
        t3 = MUL_20091(block[1*4+i]) + MUL_35468(block[3*4+i]);
91 92 93 94
        block[0*4+i] = 0;
        block[1*4+i] = 0;
        block[2*4+i] = 0;
        block[3*4+i] = 0;
David Conrad's avatar
David Conrad committed
95 96 97 98 99 100 101 102 103 104 105 106 107

        tmp[i*4+0] = t0 + t3;
        tmp[i*4+1] = t1 + t2;
        tmp[i*4+2] = t1 - t2;
        tmp[i*4+3] = t0 - t3;
    }

    for (i = 0; i < 4; i++) {
        t0 = tmp[0*4+i] + tmp[2*4+i];
        t1 = tmp[0*4+i] - tmp[2*4+i];
        t2 = MUL_35468(tmp[1*4+i]) - MUL_20091(tmp[3*4+i]);
        t3 = MUL_20091(tmp[1*4+i]) + MUL_35468(tmp[3*4+i]);

108 109 110 111
        dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3));
        dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3));
        dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3));
        dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3));
David Conrad's avatar
David Conrad committed
112 113 114 115
        dst += stride;
    }
}

116
static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride)
David Conrad's avatar
David Conrad committed
117 118
{
    int i, dc = (block[0] + 4) >> 3;
119
    block[0] = 0;
David Conrad's avatar
David Conrad committed
120 121

    for (i = 0; i < 4; i++) {
122 123 124 125
        dst[0] = av_clip_uint8(dst[0] + dc);
        dst[1] = av_clip_uint8(dst[1] + dc);
        dst[2] = av_clip_uint8(dst[2] + dc);
        dst[3] = av_clip_uint8(dst[3] + dc);
David Conrad's avatar
David Conrad committed
126 127 128 129
        dst += stride;
    }
}

130
static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
131
{
132 133 134 135 136 137
    vp8_idct_dc_add_c(dst+stride*0+0, block[0], stride);
    vp8_idct_dc_add_c(dst+stride*0+4, block[1], stride);
    vp8_idct_dc_add_c(dst+stride*4+0, block[2], stride);
    vp8_idct_dc_add_c(dst+stride*4+4, block[3], stride);
}

138
static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride)
139 140 141 142 143
{
    vp8_idct_dc_add_c(dst+ 0, block[0], stride);
    vp8_idct_dc_add_c(dst+ 4, block[1], stride);
    vp8_idct_dc_add_c(dst+ 8, block[2], stride);
    vp8_idct_dc_add_c(dst+12, block[3], stride);
144
}
David Conrad's avatar
David Conrad committed
145 146 147 148 149 150 151 152 153 154 155 156

// because I like only having two parameters to pass functions...
#define LOAD_PIXELS\
    int av_unused p3 = p[-4*stride];\
    int av_unused p2 = p[-3*stride];\
    int av_unused p1 = p[-2*stride];\
    int av_unused p0 = p[-1*stride];\
    int av_unused q0 = p[ 0*stride];\
    int av_unused q1 = p[ 1*stride];\
    int av_unused q2 = p[ 2*stride];\
    int av_unused q3 = p[ 3*stride];

157 158
#define clip_int8(n) (cm[n+0x80]-0x80)

159
static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride, int is4tap)
David Conrad's avatar
David Conrad committed
160 161 162
{
    LOAD_PIXELS
    int a, f1, f2;
163
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
David Conrad's avatar
David Conrad committed
164 165 166 167

    a = 3*(q0 - p0);

    if (is4tap)
168
        a += clip_int8(p1 - q1);
David Conrad's avatar
David Conrad committed
169

170
    a = clip_int8(a);
David Conrad's avatar
David Conrad committed
171 172 173 174 175 176 177 178

    // We deviate from the spec here with c(a+3) >> 3
    // since that's what libvpx does.
    f1 = FFMIN(a+4, 127) >> 3;
    f2 = FFMIN(a+3, 127) >> 3;

    // Despite what the spec says, we do need to clamp here to
    // be bitexact with libvpx.
179 180
    p[-1*stride] = cm[p0 + f2];
    p[ 0*stride] = cm[q0 - f1];
David Conrad's avatar
David Conrad committed
181 182 183 184

    // only used for _inner on blocks without high edge variance
    if (!is4tap) {
        a = (f1+1)>>1;
185 186
        p[-2*stride] = cm[p1 + a];
        p[ 1*stride] = cm[q1 - a];
David Conrad's avatar
David Conrad committed
187 188 189
    }
}

190
static av_always_inline int simple_limit(uint8_t *p, ptrdiff_t stride, int flim)
David Conrad's avatar
David Conrad committed
191 192 193 194 195 196 197 198 199
{
    LOAD_PIXELS
    return 2*FFABS(p0-q0) + (FFABS(p1-q1) >> 1) <= flim;
}

/**
 * E - limit at the macroblock edge
 * I - limit for interior difference
 */
200
static av_always_inline int normal_limit(uint8_t *p, ptrdiff_t stride, int E, int I)
David Conrad's avatar
David Conrad committed
201 202
{
    LOAD_PIXELS
203
    return simple_limit(p, stride, E)
David Conrad's avatar
David Conrad committed
204 205 206 207 208
        && FFABS(p3-p2) <= I && FFABS(p2-p1) <= I && FFABS(p1-p0) <= I
        && FFABS(q3-q2) <= I && FFABS(q2-q1) <= I && FFABS(q1-q0) <= I;
}

// high edge variance
209
static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
David Conrad's avatar
David Conrad committed
210 211 212 213 214
{
    LOAD_PIXELS
    return FFABS(p1-p0) > thresh || FFABS(q1-q0) > thresh;
}

215
static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
David Conrad's avatar
David Conrad committed
216 217
{
    int a0, a1, a2, w;
218
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
David Conrad's avatar
David Conrad committed
219 220 221

    LOAD_PIXELS

222 223
    w = clip_int8(p1-q1);
    w = clip_int8(w + 3*(q0-p0));
David Conrad's avatar
David Conrad committed
224 225 226 227 228

    a0 = (27*w + 63) >> 7;
    a1 = (18*w + 63) >> 7;
    a2 = ( 9*w + 63) >> 7;

229 230 231 232 233 234
    p[-3*stride] = cm[p2 + a2];
    p[-2*stride] = cm[p1 + a1];
    p[-1*stride] = cm[p0 + a0];
    p[ 0*stride] = cm[q0 - a0];
    p[ 1*stride] = cm[q1 - a1];
    p[ 2*stride] = cm[q2 - a2];
David Conrad's avatar
David Conrad committed
235 236
}

237
#define LOOP_FILTER(dir, size, stridea, strideb, maybe_inline) \
238
static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, ptrdiff_t stride,\
David Conrad's avatar
David Conrad committed
239 240 241 242 243 244 245 246 247 248 249 250 251
                                     int flim_E, int flim_I, int hev_thresh)\
{\
    int i;\
\
    for (i = 0; i < size; i++)\
        if (normal_limit(dst+i*stridea, strideb, flim_E, flim_I)) {\
            if (hev(dst+i*stridea, strideb, hev_thresh))\
                filter_common(dst+i*stridea, strideb, 1);\
            else\
                filter_mbedge(dst+i*stridea, strideb);\
        }\
}\
\
252
static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, ptrdiff_t stride,\
David Conrad's avatar
David Conrad committed
253 254
                                      int flim_E, int flim_I, int hev_thresh)\
{\
255
    int i;\
David Conrad's avatar
David Conrad committed
256 257 258
\
    for (i = 0; i < size; i++)\
        if (normal_limit(dst+i*stridea, strideb, flim_E, flim_I)) {\
259 260 261 262 263
            int hv = hev(dst+i*stridea, strideb, hev_thresh);\
            if (hv) \
                filter_common(dst+i*stridea, strideb, 1);\
            else \
                filter_common(dst+i*stridea, strideb, 0);\
David Conrad's avatar
David Conrad committed
264 265 266
        }\
}

267 268 269 270 271
LOOP_FILTER(v, 16, 1, stride,)
LOOP_FILTER(h, 16, stride, 1,)

#define UV_LOOP_FILTER(dir, stridea, strideb) \
LOOP_FILTER(dir, 8, stridea, strideb, av_always_inline) \
272
static void vp8_ ## dir ## _loop_filter8uv_c(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,\
273 274 275 276 277
                                      int fE, int fI, int hev_thresh)\
{\
  vp8_ ## dir ## _loop_filter8_c(dstU, stride, fE, fI, hev_thresh);\
  vp8_ ## dir ## _loop_filter8_c(dstV, stride, fE, fI, hev_thresh);\
}\
278
static void vp8_ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,\
279 280 281 282 283 284 285 286
                                      int fE, int fI, int hev_thresh)\
{\
  vp8_ ## dir ## _loop_filter8_inner_c(dstU, stride, fE, fI, hev_thresh);\
  vp8_ ## dir ## _loop_filter8_inner_c(dstV, stride, fE, fI, hev_thresh);\
}

UV_LOOP_FILTER(v, 1, stride)
UV_LOOP_FILTER(h, stride, 1)
David Conrad's avatar
David Conrad committed
287

288
static void vp8_v_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, int flim)
David Conrad's avatar
David Conrad committed
289 290 291 292 293 294 295 296
{
    int i;

    for (i = 0; i < 16; i++)
        if (simple_limit(dst+i, stride, flim))
            filter_common(dst+i, stride, 1);
}

297
static void vp8_h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, int flim)
David Conrad's avatar
David Conrad committed
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
{
    int i;

    for (i = 0; i < 16; i++)
        if (simple_limit(dst+i*stride, 1, flim))
            filter_common(dst+i*stride, 1, 1);
}

static const uint8_t subpel_filters[7][6] = {
    { 0,   6, 123,  12,   1,   0 },
    { 2,  11, 108,  36,   8,   1 },
    { 0,   9,  93,  50,   6,   0 },
    { 3,  16,  77,  77,  16,   3 },
    { 0,   6,  50,  93,   9,   0 },
    { 1,   8,  36, 108,  11,   2 },
    { 0,   1,  12, 123,   6,   0 },
};

316
#define PUT_PIXELS(WIDTH) \
317
static void put_vp8_pixels ## WIDTH ##_c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int x, int y) { \
Jason Garrett-Glaser's avatar
Jason Garrett-Glaser committed
318 319
    int i; \
    for (i = 0; i < h; i++, dst+= dststride, src+= srcstride) { \
320 321 322 323 324 325 326
        memcpy(dst, src, WIDTH); \
    } \
}

PUT_PIXELS(16)
PUT_PIXELS(8)
PUT_PIXELS(4)
David Conrad's avatar
David Conrad committed
327 328

#define FILTER_6TAP(src, F, stride) \
329 330
    cm[(F[2]*src[x+0*stride] - F[1]*src[x-1*stride] + F[0]*src[x-2*stride] + \
        F[3]*src[x+1*stride] - F[4]*src[x+2*stride] + F[5]*src[x+3*stride] + 64) >> 7]
David Conrad's avatar
David Conrad committed
331 332

#define FILTER_4TAP(src, F, stride) \
333 334
    cm[(F[2]*src[x+0*stride] - F[1]*src[x-1*stride] + \
        F[3]*src[x+1*stride] - F[4]*src[x+2*stride] + 64) >> 7]
David Conrad's avatar
David Conrad committed
335

336
#define VP8_EPEL_H(SIZE, TAPS) \
337
static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
338 339
{ \
    const uint8_t *filter = subpel_filters[mx-1]; \
340
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
David Conrad's avatar
David Conrad committed
341 342 343 344
    int x, y; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
345
            dst[x] = FILTER_ ## TAPS ## TAP(src, filter, 1); \
346 347
        dst += dststride; \
        src += srcstride; \
David Conrad's avatar
David Conrad committed
348 349
    } \
}
350
#define VP8_EPEL_V(SIZE, TAPS) \
351
static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
352 353
{ \
    const uint8_t *filter = subpel_filters[my-1]; \
354
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
David Conrad's avatar
David Conrad committed
355 356 357 358
    int x, y; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
359
            dst[x] = FILTER_ ## TAPS ## TAP(src, filter, srcstride); \
360 361
        dst += dststride; \
        src += srcstride; \
David Conrad's avatar
David Conrad committed
362 363
    } \
}
364
#define VP8_EPEL_HV(SIZE, HTAPS, VTAPS) \
365
static void put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
366 367
{ \
    const uint8_t *filter = subpel_filters[mx-1]; \
368
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \
David Conrad's avatar
David Conrad committed
369
    int x, y; \
370
    uint8_t tmp_array[(2*SIZE+VTAPS-1)*SIZE]; \
David Conrad's avatar
David Conrad committed
371
    uint8_t *tmp = tmp_array; \
372
    src -= (2-(VTAPS==4))*srcstride; \
David Conrad's avatar
David Conrad committed
373
\
374
    for (y = 0; y < h+VTAPS-1; y++) { \
David Conrad's avatar
David Conrad committed
375
        for (x = 0; x < SIZE; x++) \
376
            tmp[x] = FILTER_ ## HTAPS ## TAP(src, filter, 1); \
David Conrad's avatar
David Conrad committed
377
        tmp += SIZE; \
378
        src += srcstride; \
David Conrad's avatar
David Conrad committed
379 380
    } \
\
381
    tmp = tmp_array + (2-(VTAPS==4))*SIZE; \
David Conrad's avatar
David Conrad committed
382 383 384 385
    filter = subpel_filters[my-1]; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
386
            dst[x] = FILTER_ ## VTAPS ## TAP(tmp, filter, SIZE); \
387
        dst += dststride; \
David Conrad's avatar
David Conrad committed
388 389 390 391
        tmp += SIZE; \
    } \
}

392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
VP8_EPEL_H(16, 4)
VP8_EPEL_H(8,  4)
VP8_EPEL_H(4,  4)
VP8_EPEL_H(16, 6)
VP8_EPEL_H(8,  6)
VP8_EPEL_H(4,  6)
VP8_EPEL_V(16, 4)
VP8_EPEL_V(8,  4)
VP8_EPEL_V(4,  4)
VP8_EPEL_V(16, 6)
VP8_EPEL_V(8,  6)
VP8_EPEL_V(4,  6)
VP8_EPEL_HV(16, 4, 4)
VP8_EPEL_HV(8,  4, 4)
VP8_EPEL_HV(4,  4, 4)
VP8_EPEL_HV(16, 4, 6)
VP8_EPEL_HV(8,  4, 6)
VP8_EPEL_HV(4,  4, 6)
VP8_EPEL_HV(16, 6, 4)
VP8_EPEL_HV(8,  6, 4)
VP8_EPEL_HV(4,  6, 4)
VP8_EPEL_HV(16, 6, 6)
VP8_EPEL_HV(8,  6, 6)
VP8_EPEL_HV(4,  6, 6)
David Conrad's avatar
David Conrad committed
416

David Conrad's avatar
David Conrad committed
417
#define VP8_BILINEAR(SIZE) \
418
static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
419 420 421 422 423 424 425 426 427 428 429
{ \
    int a = 8-mx, b = mx; \
    int x, y; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
            dst[x] = (a*src[x] + b*src[x+1] + 4) >> 3; \
        dst += stride; \
        src += stride; \
    } \
} \
430
static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
431 432 433 434 435 436 437 438 439 440 441 442
{ \
    int c = 8-my, d = my; \
    int x, y; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
            dst[x] = (c*src[x] + d*src[x+stride] + 4) >> 3; \
        dst += stride; \
        src += stride; \
    } \
} \
\
443
static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \
David Conrad's avatar
David Conrad committed
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
{ \
    int a = 8-mx, b = mx; \
    int c = 8-my, d = my; \
    int x, y; \
    uint8_t tmp_array[(2*SIZE+1)*SIZE]; \
    uint8_t *tmp = tmp_array; \
\
    for (y = 0; y < h+1; y++) { \
        for (x = 0; x < SIZE; x++) \
            tmp[x] = (a*src[x] + b*src[x+1] + 4) >> 3; \
        tmp += SIZE; \
        src += stride; \
    } \
\
    tmp = tmp_array; \
\
    for (y = 0; y < h; y++) { \
        for (x = 0; x < SIZE; x++) \
            dst[x] = (c*tmp[x] + d*tmp[x+SIZE] + 4) >> 3; \
        dst += stride; \
        tmp += SIZE; \
    } \
}

VP8_BILINEAR(16)
VP8_BILINEAR(8)
VP8_BILINEAR(4)

David Conrad's avatar
David Conrad committed
472
#define VP8_MC_FUNC(IDX, SIZE) \
473
    dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
David Conrad's avatar
David Conrad committed
474 475 476 477 478 479 480 481 482
    dsp->put_vp8_epel_pixels_tab[IDX][0][1] = put_vp8_epel ## SIZE ## _h4_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][0][2] = put_vp8_epel ## SIZE ## _h6_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][1][0] = put_vp8_epel ## SIZE ## _v4_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][1][1] = put_vp8_epel ## SIZE ## _h4v4_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][1][2] = put_vp8_epel ## SIZE ## _h6v4_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][2][0] = put_vp8_epel ## SIZE ## _v6_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][2][1] = put_vp8_epel ## SIZE ## _h4v6_c; \
    dsp->put_vp8_epel_pixels_tab[IDX][2][2] = put_vp8_epel ## SIZE ## _h6v6_c

David Conrad's avatar
David Conrad committed
483 484 485 486 487 488 489 490 491 492 493
#define VP8_BILINEAR_MC_FUNC(IDX, SIZE) \
    dsp->put_vp8_bilinear_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][0][1] = put_vp8_bilinear ## SIZE ## _h_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][0][2] = put_vp8_bilinear ## SIZE ## _h_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][1][0] = put_vp8_bilinear ## SIZE ## _v_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][1][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][1][2] = put_vp8_bilinear ## SIZE ## _hv_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][2][0] = put_vp8_bilinear ## SIZE ## _v_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][2][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
    dsp->put_vp8_bilinear_pixels_tab[IDX][2][2] = put_vp8_bilinear ## SIZE ## _hv_c

David Conrad's avatar
David Conrad committed
494 495
av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
{
496
    dsp->vp8_luma_dc_wht    = vp8_luma_dc_wht_c;
497
    dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
498 499 500 501
    dsp->vp8_idct_add       = vp8_idct_add_c;
    dsp->vp8_idct_dc_add    = vp8_idct_dc_add_c;
    dsp->vp8_idct_dc_add4y  = vp8_idct_dc_add4y_c;
    dsp->vp8_idct_dc_add4uv = vp8_idct_dc_add4uv_c;
David Conrad's avatar
David Conrad committed
502

503 504 505 506
    dsp->vp8_v_loop_filter16y = vp8_v_loop_filter16_c;
    dsp->vp8_h_loop_filter16y = vp8_h_loop_filter16_c;
    dsp->vp8_v_loop_filter8uv = vp8_v_loop_filter8uv_c;
    dsp->vp8_h_loop_filter8uv = vp8_h_loop_filter8uv_c;
David Conrad's avatar
David Conrad committed
507

508 509 510 511
    dsp->vp8_v_loop_filter16y_inner = vp8_v_loop_filter16_inner_c;
    dsp->vp8_h_loop_filter16y_inner = vp8_h_loop_filter16_inner_c;
    dsp->vp8_v_loop_filter8uv_inner = vp8_v_loop_filter8uv_inner_c;
    dsp->vp8_h_loop_filter8uv_inner = vp8_h_loop_filter8uv_inner_c;
David Conrad's avatar
David Conrad committed
512 513 514 515 516 517 518

    dsp->vp8_v_loop_filter_simple = vp8_v_loop_filter_simple_c;
    dsp->vp8_h_loop_filter_simple = vp8_h_loop_filter_simple_c;

    VP8_MC_FUNC(0, 16);
    VP8_MC_FUNC(1, 8);
    VP8_MC_FUNC(2, 4);
David Conrad's avatar
David Conrad committed
519 520 521 522

    VP8_BILINEAR_MC_FUNC(0, 16);
    VP8_BILINEAR_MC_FUNC(1, 8);
    VP8_BILINEAR_MC_FUNC(2, 4);
523

524
    if (ARCH_X86)
525
        ff_vp8dsp_init_x86(dsp);
David Conrad's avatar
David Conrad committed
526 527
    if (HAVE_ALTIVEC)
        ff_vp8dsp_init_altivec(dsp);
528 529
    if (ARCH_ARM)
        ff_vp8dsp_init_arm(dsp);
David Conrad's avatar
David Conrad committed
530
}