vp8dsp.c 16.3 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#include "dsputil.h"
#include "vp8dsp.h"

// 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
52 53 54 55
        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
56

57 58 59 60
        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
61 62 63
    }
}

64 65 66 67 68 69 70 71 72 73 74 75
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
76 77 78 79 80 81 82

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

static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride)
{
    int i, t0, t1, t2, t3;
83
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
David Conrad's avatar
David Conrad committed
84 85 86 87 88 89 90
    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] = cm[dst[0] + ((t0 + t3 + 4) >> 3)];
        dst[1] = cm[dst[1] + ((t1 + t2 + 4) >> 3)];
        dst[2] = cm[dst[2] + ((t1 - t2 + 4) >> 3)];
        dst[3] = cm[dst[3] + ((t0 - t3 + 4) >> 3)];
David Conrad's avatar
David Conrad committed
112 113 114 115 116 117 118
        dst += stride;
    }
}

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

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

131
static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], int stride)
132
{
133 134 135 136 137 138 139 140 141 142 143 144
    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);
}

static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], int stride)
{
    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);
145
}
David Conrad's avatar
David Conrad committed
146 147 148 149 150 151 152 153 154 155 156 157

// 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];

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

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

    a = 3*(q0 - p0);

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

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

    // 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.
180 181
    p[-1*stride] = cm[p0 + f2];
    p[ 0*stride] = cm[q0 - f1];
David Conrad's avatar
David Conrad committed
182 183 184 185

    // only used for _inner on blocks without high edge variance
    if (!is4tap) {
        a = (f1+1)>>1;
186 187
        p[-2*stride] = cm[p1 + a];
        p[ 1*stride] = cm[q1 - a];
David Conrad's avatar
David Conrad committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    }
}

static av_always_inline int simple_limit(uint8_t *p, int stride, int flim)
{
    LOAD_PIXELS
    return 2*FFABS(p0-q0) + (FFABS(p1-q1) >> 1) <= flim;
}

/**
 * E - limit at the macroblock edge
 * I - limit for interior difference
 */
static av_always_inline int normal_limit(uint8_t *p, int stride, int E, int I)
{
    LOAD_PIXELS
204
    return simple_limit(p, stride, E)
David Conrad's avatar
David Conrad committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218
        && 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
static av_always_inline int hev(uint8_t *p, int stride, int thresh)
{
    LOAD_PIXELS
    return FFABS(p1-p0) > thresh || FFABS(q1-q0) > thresh;
}

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

    LOAD_PIXELS

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

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

230 231 232 233 234 235
    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
236 237
}

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

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
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) \
static void vp8_ ## dir ## _loop_filter8uv_c(uint8_t *dstU, uint8_t *dstV, int stride,\
                                      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);\
}\
static void vp8_ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, uint8_t *dstV, int stride,\
                                      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
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

static void vp8_v_loop_filter_simple_c(uint8_t *dst, int stride, int flim)
{
    int i;

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

static void vp8_h_loop_filter_simple_c(uint8_t *dst, int stride, int flim)
{
    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 },
};

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

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

#define FILTER_6TAP(src, F, stride) \
330 331
    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
332 333

#define FILTER_4TAP(src, F, stride) \
334 335
    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
336

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

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
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
417

David Conrad's avatar
David Conrad committed
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 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 472
#define VP8_BILINEAR(SIZE) \
static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \
{ \
    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; \
    } \
} \
static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \
{ \
    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; \
    } \
} \
\
static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \
{ \
    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
473
#define VP8_MC_FUNC(IDX, SIZE) \
474
    dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
David Conrad's avatar
David Conrad committed
475 476 477 478 479 480 481 482 483
    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
484 485 486 487 488 489 490 491 492 493 494
#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
495 496
av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
{
497
    dsp->vp8_luma_dc_wht    = vp8_luma_dc_wht_c;
498
    dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
499 500 501 502
    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
503

504 505 506 507
    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
508

509 510 511 512
    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
513 514 515 516 517 518 519

    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
520 521 522 523

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

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