vp8dsp.c 16.3 KB
Newer Older
David Conrad's avatar
David Conrad committed
1 2 3 4 5 6
/**
 * VP8 compatible video decoder
 *
 * Copyright (C) 2010 David Conrad
 * Copyright (C) 2010 Ronald S. Bultje
 *
7
 * This file is part of Libav.
David Conrad's avatar
David Conrad committed
8
 *
9
 * Libav is free software; you can redistribute it and/or
David Conrad's avatar
David Conrad committed
10 11 12 13
 * 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.
 *
14
 * Libav is distributed in the hope that it will be useful,
David Conrad's avatar
David Conrad committed
15 16 17 18 19
 * 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
20
 * License along with Libav; if not, write to the Free Software
David Conrad's avatar
David Conrad committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#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
49 50 51 52
        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
53

54 55 56 57
        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
58 59 60
    }
}

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

#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;
80
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
David Conrad's avatar
David Conrad committed
81 82 83 84 85 86 87
    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]);
88 89 90 91
        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
92 93 94 95 96 97 98 99 100 101 102 103 104

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

105 106 107 108
        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
109 110 111 112 113 114 115
        dst += stride;
    }
}

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

    for (i = 0; i < 4; i++) {
120 121 122 123
        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
124 125 126 127
        dst += stride;
    }
}

128
static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], int stride)
129
{
130 131 132 133 134 135 136 137 138 139 140 141
    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);
142
}
David Conrad's avatar
David Conrad committed
143 144 145 146 147 148 149 150 151 152 153 154

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

155 156
#define clip_int8(n) (cm[n+0x80]-0x80)

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

    a = 3*(q0 - p0);

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

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

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

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

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
201
    return simple_limit(p, stride, E)
David Conrad's avatar
David Conrad committed
202 203 204 205 206 207 208 209 210 211 212 213 214 215
        && 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;
216
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
David Conrad's avatar
David Conrad committed
217 218 219

    LOAD_PIXELS

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

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

227 228 229 230 231 232
    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
233 234
}

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

265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
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
285 286 287 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

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 },
};

314 315
#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
316 317
    int i; \
    for (i = 0; i < h; i++, dst+= dststride, src+= srcstride) { \
318 319 320 321 322 323 324
        memcpy(dst, src, WIDTH); \
    } \
}

PUT_PIXELS(16)
PUT_PIXELS(8)
PUT_PIXELS(4)
David Conrad's avatar
David Conrad committed
325 326

#define FILTER_6TAP(src, F, stride) \
327 328
    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
329 330

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

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

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

David Conrad's avatar
David Conrad committed
415 416 417 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
#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
470
#define VP8_MC_FUNC(IDX, SIZE) \
471
    dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
David Conrad's avatar
David Conrad committed
472 473 474 475 476 477 478 479 480
    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
481 482 483 484 485 486 487 488 489 490 491
#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
492 493
av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
{
494
    dsp->vp8_luma_dc_wht    = vp8_luma_dc_wht_c;
495
    dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
496 497 498 499
    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
500

501 502 503 504
    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
505

506 507 508 509
    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
510 511 512 513 514 515 516

    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
517 518 519 520

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

522
    if (HAVE_MMX)
523
        ff_vp8dsp_init_x86(dsp);
David Conrad's avatar
David Conrad committed
524 525
    if (HAVE_ALTIVEC)
        ff_vp8dsp_init_altivec(dsp);
526 527
    if (ARCH_ARM)
        ff_vp8dsp_init_arm(dsp);
David Conrad's avatar
David Conrad committed
528
}