Revision c55e0d34

View differences:

libavcodec/vp8.c
31 31
typedef struct {
32 32
    uint8_t filter_level;
33 33
    uint8_t inner_limit;
34
    uint8_t inner_filter;
34 35
} VP8FilterStrength;
35 36

  
36 37
typedef struct {
......
89 90

  
90 91
    uint8_t *intra4x4_pred_mode;
91 92
    uint8_t *intra4x4_pred_mode_base;
93
    uint8_t *segmentation_map;
92 94
    int b4_stride;
93 95

  
94 96
    /**
......
212 214
    av_freep(&s->top_nnz);
213 215
    av_freep(&s->edge_emu_buffer);
214 216
    av_freep(&s->top_border);
217
    av_freep(&s->segmentation_map);
215 218

  
216 219
    s->macroblocks        = NULL;
217 220
    s->intra4x4_pred_mode = NULL;
......
236 239
    s->mb_stride = s->mb_width+1;
237 240
    s->b4_stride = 4*s->mb_stride;
238 241

  
239
    s->macroblocks_base        = av_mallocz(s->mb_stride*(s->mb_height+1)*sizeof(*s->macroblocks));
242
    s->macroblocks_base        = av_mallocz((s->mb_stride+s->mb_height*2+2)*sizeof(*s->macroblocks));
240 243
    s->filter_strength         = av_mallocz(s->mb_stride*sizeof(*s->filter_strength));
241 244
    s->intra4x4_pred_mode_base = av_mallocz(s->b4_stride*(4*s->mb_height+1));
242 245
    s->top_nnz                 = av_mallocz(s->mb_width*sizeof(*s->top_nnz));
243 246
    s->top_border              = av_mallocz((s->mb_width+1)*sizeof(*s->top_border));
247
    s->segmentation_map        = av_mallocz(s->mb_stride*s->mb_height);
244 248

  
245
    if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_base || !s->top_nnz || !s->top_border)
249
    if (!s->macroblocks_base || !s->filter_strength || !s->intra4x4_pred_mode_base ||
250
        !s->top_nnz || !s->top_border || !s->segmentation_map)
246 251
        return AVERROR(ENOMEM);
247 252

  
248
    s->macroblocks        = s->macroblocks_base        + 1 + s->mb_stride;
253
    s->macroblocks        = s->macroblocks_base + 1;
249 254
    s->intra4x4_pred_mode = s->intra4x4_pred_mode_base + 4 + s->b4_stride;
250 255

  
251 256
    memset(s->intra4x4_pred_mode_base, DC_PRED, s->b4_stride);
......
530 535
static void find_near_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
531 536
                          VP56mv near[2], VP56mv *best, uint8_t cnt[4])
532 537
{
533
    int mb_stride = s->mb_stride;
534
    VP8Macroblock *mb_edge[3] = { mb - mb_stride     /* top */,
535
                                  mb - 1             /* left */,
536
                                  mb - mb_stride - 1 /* top-left */ };
538
    VP8Macroblock *mb_edge[3] = { mb + 2 /* top */,
539
                                  mb - 1 /* left */,
540
                                  mb + 1 /* top-left */ };
537 541
    enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT };
538 542
    VP56mv near_mv[4]  = {{ 0 }};
539 543
    enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
......
629 633
    int part_idx = mb->partitioning =
630 634
        vp8_rac_get_tree(c, vp8_mbsplit_tree, vp8_mbsplit_prob);
631 635
    int n, num = vp8_mbsplit_count[part_idx];
632
    VP8Macroblock *top_mb  = &mb[-s->mb_stride];
636
    VP8Macroblock *top_mb  = &mb[2];
633 637
    VP8Macroblock *left_mb = &mb[-1];
634 638
    const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning],
635 639
                  *mbsplits_top = vp8_mbsplits[top_mb->partitioning],
636 640
                  *mbsplits_cur = vp8_mbsplits[part_idx],
637 641
                  *firstidx = vp8_mbfirstidx[part_idx];
638
    VP56mv *top_mv   = top_mb->bmv;
639
    VP56mv *left_mv  = left_mb->bmv;
640
    VP56mv *cur_mv   = mb->bmv;
642
    VP56mv *top_mv  = top_mb->bmv;
643
    VP56mv *left_mv = left_mb->bmv;
644
    VP56mv *cur_mv  = mb->bmv;
641 645

  
642 646
    for (n = 0; n < num; n++) {
643 647
        int k = firstidx[n];
......
698 702
}
699 703

  
700 704
static void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
701
                           uint8_t *intra4x4)
705
                           uint8_t *intra4x4, uint8_t *segment)
702 706
{
703 707
    VP56RangeCoder *c = &s->c;
704 708

  
705 709
    if (s->segmentation.update_map)
706
        mb->segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
710
        *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
711
    mb->segment = *segment;
707 712

  
708 713
    mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
709 714

  
......
1256 1261

  
1257 1262
    f->filter_level = filter_level;
1258 1263
    f->inner_limit = interior_limit;
1264
    f->inner_filter = !mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT;
1259 1265
}
1260 1266

  
1261
static void filter_mb(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb, VP8FilterStrength *f, int mb_x, int mb_y)
1267
static void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f, int mb_x, int mb_y)
1262 1268
{
1263 1269
    int mbedge_lim, bedge_lim, hev_thresh;
1264 1270
    int filter_level = f->filter_level;
1265 1271
    int inner_limit = f->inner_limit;
1272
    int inner_filter = f->inner_filter;
1266 1273

  
1267 1274
    if (!filter_level)
1268 1275
        return;
......
1288 1295
                                       mbedge_lim, inner_limit, hev_thresh);
1289 1296
    }
1290 1297

  
1291
    if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
1298
    if (inner_filter) {
1292 1299
        s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0]+ 4, s->linesize, bedge_lim,
1293 1300
                                             inner_limit,   hev_thresh);
1294 1301
        s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0]+ 8, s->linesize, bedge_lim,
......
1307 1314
                                       mbedge_lim, inner_limit, hev_thresh);
1308 1315
    }
1309 1316

  
1310
    if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
1317
    if (inner_filter) {
1311 1318
        s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0]+ 4*s->linesize,
1312 1319
                                             s->linesize,   bedge_lim,
1313 1320
                                             inner_limit,   hev_thresh);
......
1324 1331
    }
1325 1332
}
1326 1333

  
1327
static void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Macroblock *mb, VP8FilterStrength *f, int mb_x, int mb_y)
1334
static void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f, int mb_x, int mb_y)
1328 1335
{
1329 1336
    int mbedge_lim, bedge_lim;
1330 1337
    int filter_level = f->filter_level;
1331 1338
    int inner_limit = f->inner_limit;
1339
    int inner_filter = f->inner_filter;
1332 1340

  
1333 1341
    if (!filter_level)
1334 1342
        return;
......
1338 1346

  
1339 1347
    if (mb_x)
1340 1348
        s->vp8dsp.vp8_h_loop_filter_simple(dst, s->linesize, mbedge_lim);
1341
    if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
1349
    if (inner_filter) {
1342 1350
        s->vp8dsp.vp8_h_loop_filter_simple(dst+ 4, s->linesize, bedge_lim);
1343 1351
        s->vp8dsp.vp8_h_loop_filter_simple(dst+ 8, s->linesize, bedge_lim);
1344 1352
        s->vp8dsp.vp8_h_loop_filter_simple(dst+12, s->linesize, bedge_lim);
......
1346 1354

  
1347 1355
    if (mb_y)
1348 1356
        s->vp8dsp.vp8_v_loop_filter_simple(dst, s->linesize, mbedge_lim);
1349
    if (!mb->skip || mb->mode == MODE_I4x4 || mb->mode == VP8_MVMODE_SPLIT) {
1357
    if (inner_filter) {
1350 1358
        s->vp8dsp.vp8_v_loop_filter_simple(dst+ 4*s->linesize, s->linesize, bedge_lim);
1351 1359
        s->vp8dsp.vp8_v_loop_filter_simple(dst+ 8*s->linesize, s->linesize, bedge_lim);
1352 1360
        s->vp8dsp.vp8_v_loop_filter_simple(dst+12*s->linesize, s->linesize, bedge_lim);
......
1356 1364
static void filter_mb_row(VP8Context *s, int mb_y)
1357 1365
{
1358 1366
    VP8FilterStrength *f = s->filter_strength;
1359
    VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
1360 1367
    uint8_t *dst[3] = {
1361 1368
        s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize,
1362 1369
        s->framep[VP56_FRAME_CURRENT]->data[1] +  8*mb_y*s->uvlinesize,
......
1366 1373

  
1367 1374
    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1368 1375
        backup_mb_border(s->top_border[mb_x+1], dst[0], dst[1], dst[2], s->linesize, s->uvlinesize, 0);
1369
        filter_mb(s, dst, mb++, f++, mb_x, mb_y);
1376
        filter_mb(s, dst, f++, mb_x, mb_y);
1370 1377
        dst[0] += 16;
1371 1378
        dst[1] += 8;
1372 1379
        dst[2] += 8;
......
1376 1383
static void filter_mb_row_simple(VP8Context *s, int mb_y)
1377 1384
{
1378 1385
    VP8FilterStrength *f = s->filter_strength;
1379
    VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
1380 1386
    uint8_t *dst = s->framep[VP56_FRAME_CURRENT]->data[0] + 16*mb_y*s->linesize;
1381 1387
    int mb_x;
1382 1388

  
1383 1389
    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1384 1390
        backup_mb_border(s->top_border[mb_x+1], dst, NULL, NULL, s->linesize, 0, 1);
1385
        filter_mb_simple(s, dst, mb++, f++, mb_x, mb_y);
1391
        filter_mb_simple(s, dst, f++, mb_x, mb_y);
1386 1392
        dst += 16;
1387 1393
    }
1388 1394
}
......
1446 1452

  
1447 1453
    memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz));
1448 1454

  
1455
    /* Zero macroblock structures for top/left prediction from outside the frame. */
1456
    memset(s->macroblocks, 0, (s->mb_width + s->mb_height*2)*sizeof(*s->macroblocks));
1457

  
1449 1458
    // top edge of 127 for intra prediction
1450 1459
    memset(s->top_border, 127, (s->mb_width+1)*sizeof(*s->top_border));
1451 1460

  
1452 1461
    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
1453 1462
        VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)];
1454
        VP8Macroblock *mb = s->macroblocks + mb_y*s->mb_stride;
1463
        VP8Macroblock *mb = s->macroblocks + (s->mb_height - mb_y - 1)*2;
1455 1464
        uint8_t *intra4x4 = s->intra4x4_pred_mode + 4*mb_y*s->b4_stride;
1465
        uint8_t *segment_map = s->segmentation_map + mb_y*s->mb_stride;
1456 1466
        uint8_t *dst[3] = {
1457 1467
            curframe->data[0] + 16*mb_y*s->linesize,
1458 1468
            curframe->data[1] +  8*mb_y*s->uvlinesize,
......
1471 1481

  
1472 1482
        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
1473 1483
            uint8_t *intra4x4_mb = s->keyframe ? intra4x4 + 4*mb_x : s->intra4x4_pred_mode_mb;
1484
            uint8_t *segment_mb = segment_map+mb_x;
1474 1485

  
1475 1486
            /* Prefetch the current frame, 4 MBs ahead */
1476 1487
            s->dsp.prefetch(dst[0] + (mb_x&3)*4*s->linesize + 64, s->linesize, 4);
1477 1488
            s->dsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2);
1478 1489

  
1479
            decode_mb_mode(s, mb, mb_x, mb_y, intra4x4_mb);
1490
            decode_mb_mode(s, mb, mb_x, mb_y, intra4x4_mb, segment_mb);
1480 1491

  
1481 1492
            if (!mb->skip)
1482 1493
                decode_mb_coeffs(s, c, mb, s->top_nnz[mb_x], s->left_nnz);

Also available in: Unified diff