Revision 64233e70

View differences:

libavcodec/vp8.c
1193 1193
                       s->filter.simple, 0);
1194 1194
}
1195 1195

  
1196
static const uint8_t subpel_idx[3][8] = {
1197
    { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
1198
                                // also function pointer index
1199
    { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
1200
    { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
1201
};
1202

  
1196 1203
/**
1197 1204
 * Generic MC function.
1198 1205
 *
......
1211 1218
 * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
1212 1219
 */
1213 1220
static av_always_inline
1214
void vp8_mc(VP8Context *s, int luma,
1215
            uint8_t *dst, uint8_t *src, const VP56mv *mv,
1216
            int x_off, int y_off, int block_w, int block_h,
1217
            int width, int height, int linesize,
1218
            vp8_mc_func mc_func[3][3])
1221
void vp8_mc_luma(VP8Context *s, uint8_t *dst, uint8_t *src, const VP56mv *mv,
1222
                 int x_off, int y_off, int block_w, int block_h,
1223
                 int width, int height, int linesize,
1224
                 vp8_mc_func mc_func[3][3])
1219 1225
{
1220 1226
    if (AV_RN32A(mv)) {
1221
        static const uint8_t idx[3][8] = {
1222
            { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
1223
                                        // also function pointer index
1224
            { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
1225
            { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
1226
        };
1227
        int mx = (mv->x << luma)&7, mx_idx = idx[0][mx];
1228
        int my = (mv->y << luma)&7, my_idx = idx[0][my];
1229 1227

  
1230
        x_off += mv->x >> (3 - luma);
1231
        y_off += mv->y >> (3 - luma);
1228
        int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx];
1229
        int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my];
1230

  
1231
        x_off += mv->x >> 2;
1232
        y_off += mv->y >> 2;
1232 1233

  
1233 1234
        // edge emulation
1234 1235
        src += y_off * linesize + x_off;
1235
        if (x_off < mx_idx || x_off >= width  - block_w - idx[2][mx] ||
1236
            y_off < my_idx || y_off >= height - block_h - idx[2][my]) {
1236
        if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
1237
            y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
1237 1238
            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
1238
                                block_w + idx[1][mx], block_h + idx[1][my],
1239
                                x_off - mx_idx, y_off - my_idx, width, height);
1239
                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
1240
                                    x_off - mx_idx, y_off - my_idx, width, height);
1240 1241
            src = s->edge_emu_buffer + mx_idx + linesize * my_idx;
1241 1242
        }
1242 1243
        mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
......
1245 1246
}
1246 1247

  
1247 1248
static av_always_inline
1249
void vp8_mc_chroma(VP8Context *s, uint8_t *dst1, uint8_t *dst2, uint8_t *src1,
1250
                   uint8_t *src2, const VP56mv *mv, int x_off, int y_off,
1251
                   int block_w, int block_h, int width, int height, int linesize,
1252
                   vp8_mc_func mc_func[3][3])
1253
{
1254
    if (AV_RN32A(mv)) {
1255
        int mx = mv->x&7, mx_idx = subpel_idx[0][mx];
1256
        int my = mv->y&7, my_idx = subpel_idx[0][my];
1257

  
1258
        x_off += mv->x >> 3;
1259
        y_off += mv->y >> 3;
1260

  
1261
        // edge emulation
1262
        src1 += y_off * linesize + x_off;
1263
        src2 += y_off * linesize + x_off;
1264
        if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
1265
            y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
1266
            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
1267
                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
1268
                                    x_off - mx_idx, y_off - my_idx, width, height);
1269
            src1 = s->edge_emu_buffer + mx_idx + linesize * my_idx;
1270
            mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
1271

  
1272
            s->dsp.emulated_edge_mc(s->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
1273
                                    block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
1274
                                    x_off - mx_idx, y_off - my_idx, width, height);
1275
            src2 = s->edge_emu_buffer + mx_idx + linesize * my_idx;
1276
            mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
1277
        } else {
1278
            mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
1279
            mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
1280
        }
1281
    } else {
1282
        mc_func[0][0](dst1, linesize, src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1283
        mc_func[0][0](dst2, linesize, src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
1284
    }
1285
}
1286

  
1287
static av_always_inline
1248 1288
void vp8_mc_part(VP8Context *s, uint8_t *dst[3],
1249 1289
                 AVFrame *ref_frame, int x_off, int y_off,
1250 1290
                 int bx_off, int by_off,
......
1254 1294
    VP56mv uvmv = *mv;
1255 1295

  
1256 1296
    /* Y */
1257
    vp8_mc(s, 1, dst[0] + by_off * s->linesize + bx_off,
1258
           ref_frame->data[0], mv, x_off + bx_off, y_off + by_off,
1259
           block_w, block_h, width, height, s->linesize,
1260
           s->put_pixels_tab[block_w == 8]);
1297
    vp8_mc_luma(s, dst[0] + by_off * s->linesize + bx_off,
1298
                ref_frame->data[0], mv, x_off + bx_off, y_off + by_off,
1299
                block_w, block_h, width, height, s->linesize,
1300
                s->put_pixels_tab[block_w == 8]);
1261 1301

  
1262 1302
    /* U/V */
1263 1303
    if (s->profile == 3) {
......
1268 1308
    bx_off  >>= 1; by_off  >>= 1;
1269 1309
    width   >>= 1; height  >>= 1;
1270 1310
    block_w >>= 1; block_h >>= 1;
1271
    vp8_mc(s, 0, dst[1] + by_off * s->uvlinesize + bx_off,
1272
           ref_frame->data[1], &uvmv, x_off + bx_off, y_off + by_off,
1273
           block_w, block_h, width, height, s->uvlinesize,
1274
           s->put_pixels_tab[1 + (block_w == 4)]);
1275
    vp8_mc(s, 0, dst[2] + by_off * s->uvlinesize + bx_off,
1276
           ref_frame->data[2], &uvmv, x_off + bx_off, y_off + by_off,
1277
           block_w, block_h, width, height, s->uvlinesize,
1278
           s->put_pixels_tab[1 + (block_w == 4)]);
1311
    vp8_mc_chroma(s, dst[1] + by_off * s->uvlinesize + bx_off,
1312
                  dst[2] + by_off * s->uvlinesize + bx_off, ref_frame->data[1],
1313
                  ref_frame->data[2], &uvmv, x_off + bx_off, y_off + by_off,
1314
                  block_w, block_h, width, height, s->uvlinesize,
1315
                  s->put_pixels_tab[1 + (block_w == 4)]);
1279 1316
}
1280 1317

  
1281 1318
/* Fetch pixels for estimated mv 4 macroblocks ahead.
......
1319 1356
        /* Y */
1320 1357
        for (y = 0; y < 4; y++) {
1321 1358
            for (x = 0; x < 4; x++) {
1322
                vp8_mc(s, 1, dst[0] + 4*y*s->linesize + x*4,
1323
                       ref->data[0], &bmv[4*y + x],
1324
                       4*x + x_off, 4*y + y_off, 4, 4,
1325
                       width, height, s->linesize,
1326
                       s->put_pixels_tab[2]);
1359
                vp8_mc_luma(s, dst[0] + 4*y*s->linesize + x*4,
1360
                            ref->data[0], &bmv[4*y + x],
1361
                            4*x + x_off, 4*y + y_off, 4, 4,
1362
                            width, height, s->linesize,
1363
                            s->put_pixels_tab[2]);
1327 1364
            }
1328 1365
        }
1329 1366

  
......
1345 1382
                    uvmv.x &= ~7;
1346 1383
                    uvmv.y &= ~7;
1347 1384
                }
1348
                vp8_mc(s, 0, dst[1] + 4*y*s->uvlinesize + x*4,
1349
                       ref->data[1], &uvmv,
1350
                       4*x + x_off, 4*y + y_off, 4, 4,
1351
                       width, height, s->uvlinesize,
1352
                       s->put_pixels_tab[2]);
1353
                vp8_mc(s, 0, dst[2] + 4*y*s->uvlinesize + x*4,
1354
                       ref->data[2], &uvmv,
1355
                       4*x + x_off, 4*y + y_off, 4, 4,
1356
                       width, height, s->uvlinesize,
1357
                       s->put_pixels_tab[2]);
1385
                vp8_mc_chroma(s, dst[1] + 4*y*s->uvlinesize + x*4,
1386
                              dst[2] + 4*y*s->uvlinesize + x*4,
1387
                              ref->data[1], ref->data[2], &uvmv,
1388
                              4*x + x_off, 4*y + y_off, 4, 4,
1389
                              width, height, s->uvlinesize,
1390
                              s->put_pixels_tab[2]);
1358 1391
            }
1359 1392
        }
1360 1393
        break;

Also available in: Unified diff