Revision 7a095ea6 libavcodec/vp3.c

View differences:

libavcodec/vp3.c
122 122

  
123 123
};
124 124

  
125
static const uint8_t hilbert_offset[16][2] = {
126
    {0,0}, {1,0}, {1,1}, {0,1},
127
    {0,2}, {0,3}, {1,3}, {1,2},
128
    {2,2}, {2,3}, {3,3}, {3,2},
129
    {3,1}, {2,1}, {2,0}, {3,0}
130
};
131

  
125 132
#define MIN_DEQUANT_VAL 2
126 133

  
127 134
typedef struct Vp3DecodeContext {
......
1369 1376

  
1370 1377
/*
1371 1378
 * Perform the final rendering for a particular slice of data.
1372
 * The slice number ranges from 0..(macroblock_height - 1).
1379
 * The slice number ranges from 0..(c_superblock_height - 1).
1373 1380
 */
1374 1381
static void render_slice(Vp3DecodeContext *s, int slice)
1375 1382
{
1376
    int x;
1383
    int x, y, i, j;
1377 1384
    int16_t *dequantizer;
1378 1385
    LOCAL_ALIGNED_16(DCTELEM, block, [64]);
1379 1386
    int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
1380 1387
    int motion_halfpel_index;
1381 1388
    uint8_t *motion_source;
1382
    int plane;
1389
    int plane, first_pixel;
1383 1390

  
1384
    if (slice >= s->macroblock_height)
1391
    if (slice >= s->c_superblock_height)
1385 1392
        return;
1386 1393

  
1387 1394
    for (plane = 0; plane < 3; plane++) {
......
1391 1398
        int stride            = s->current_frame.linesize[plane];
1392 1399
        int plane_width       = s->width  >> !!plane;
1393 1400
        int plane_height      = s->height >> !!plane;
1394
        int y =        slice *  FRAGMENT_PIXELS << !plane ;
1395
        int slice_height = y + (FRAGMENT_PIXELS << !plane);
1396
        int i = s->fragment_start[plane] + (y>>3)*(s->fragment_width>>!!plane);
1401

  
1402
        int sb_x, sb_y        = slice << !plane;
1403
        int slice_height      = sb_y + (plane ? 1 : 2);
1404
        int slice_width       = plane ? s->c_superblock_width : s->y_superblock_width;
1405

  
1406
        int fragment_width    = s->fragment_width  >> !!plane;
1407
        int fragment_height   = s->fragment_height >> !!plane;
1408
        int fragment_start    = s->fragment_start[plane];
1397 1409

  
1398 1410
        if (!s->flipped_image) stride = -stride;
1399 1411
        if (CONFIG_GRAY && plane && (s->avctx->flags & CODEC_FLAG_GRAY))
......
1403 1415
        if(FFABS(stride) > 2048)
1404 1416
            return; //various tables are fixed size
1405 1417

  
1406
        /* for each fragment row in the slice (both of them)... */
1407
        for (; y < slice_height; y += 8) {
1418
        /* for each superblock row in the slice (both of them)... */
1419
        for (; sb_y < slice_height; sb_y++) {
1408 1420

  
1409
            /* for each fragment in a row... */
1410
            for (x = 0; x < plane_width; x += 8, i++) {
1411
                int first_pixel = y*stride + x;
1421
            /* for each superblock in a row... */
1422
            for (sb_x = 0; sb_x < slice_width; sb_x++) {
1412 1423

  
1413
                if ((i < 0) || (i >= s->fragment_count)) {
1414
                    av_log(s->avctx, AV_LOG_ERROR, "  vp3:render_slice(): bad fragment number (%d)\n", i);
1415
                    return;
1416
                }
1424
                /* for each block in a superblock... */
1425
                for (j = 0; j < 16; j++) {
1426
                    x = 4*sb_x + hilbert_offset[j][0];
1427
                    y = 4*sb_y + hilbert_offset[j][1];
1428

  
1429
                    i = fragment_start + y*fragment_width + x;
1430

  
1431
                    // bounds check
1432
                    if (x >= fragment_width || y >= fragment_height)
1433
                        continue;
1434

  
1435
                first_pixel = 8*y*stride + 8*x;
1417 1436

  
1418 1437
                /* transform if this block was coded */
1419 1438
                if (s->all_fragments[i].coding_method != MODE_COPY) {
......
1439 1458
                            motion_y= (motion_y>>1) | (motion_y&1);
1440 1459
                        }
1441 1460

  
1442
                        src_x= (motion_x>>1) + x;
1443
                        src_y= (motion_y>>1) + y;
1461
                        src_x= (motion_x>>1) + 8*x;
1462
                        src_y= (motion_y>>1) + 8*y;
1444 1463
                        if ((motion_x == 127) || (motion_y == 127))
1445 1464
                            av_log(s->avctx, AV_LOG_ERROR, " help! got invalid motion vector! (%X, %X)\n", motion_x, motion_y);
1446 1465

  
......
1526 1545
                        stride, 8);
1527 1546

  
1528 1547
                }
1548
                }
1529 1549
            }
1530
            // Filter the previous block row. We can't filter the current row yet
1531
            // since it needs pixels from the next row
1532
            if (y > 0)
1533
                apply_loop_filter(s, plane, (y>>3)-1, (y>>3));
1550

  
1551
            // Filter up to the last row in the superblock row
1552
            apply_loop_filter(s, plane, 4*sb_y - !!sb_y, FFMIN(4*sb_y+3, fragment_height-1));
1534 1553
        }
1535 1554
    }
1536 1555

  
......
1542 1561
      *     dispatch (slice - 1);
1543 1562
      */
1544 1563

  
1545
    // now that we've filtered the last rows, they're safe to display
1546
    if (slice)
1547
        vp3_draw_horiz_band(s, 16*slice);
1564
    vp3_draw_horiz_band(s, 64*slice + 64-16);
1548 1565
}
1549 1566

  
1550 1567
/*
......
1875 1892
    }
1876 1893

  
1877 1894
    s->last_slice_end = 0;
1878
    for (i = 0; i < s->macroblock_height; i++)
1895
    for (i = 0; i < s->c_superblock_height; i++)
1879 1896
        render_slice(s, i);
1880 1897

  
1881 1898
    // filter the last row

Also available in: Unified diff