~ubuntu-branches/ubuntu/utopic/ffmpeg-debian/utopic

« back to all changes in this revision

Viewing changes to libavcodec/rv34.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-01-20 09:20:53 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120092053-izz63p40hc98qfgp
Tags: 3:0.svn20090119-1ubuntu1
* merge from debian. LP: #318501
* new version fixes CVE-2008-3230, LP: #253767

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
#include "dsputil.h"
29
29
#include "mpegvideo.h"
30
30
#include "golomb.h"
 
31
#include "mathops.h"
31
32
#include "rectangle.h"
32
33
 
33
34
#include "rv34vlc.h"
367
368
{
368
369
    int i;
369
370
    for(i = 0; i < 5; i++)
370
 
        if(rv34_mb_max_sizes[i] > mb_size)
 
371
        if(rv34_mb_max_sizes[i] >= mb_size - 1)
371
372
            break;
372
373
    return rv34_mb_bits_sizes[i];
373
374
}
564
565
    MpegEncContext *s = &r->s;
565
566
    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
566
567
    int A[2] = {0}, B[2], C[2];
567
 
    int i, j;
 
568
    int i, j, k;
568
569
    int mx, my;
569
570
    int avail_index = avail_indexes[0];
570
571
 
597
598
    my += r->dmv[0][1];
598
599
    for(j = 0; j < 2; j++){
599
600
        for(i = 0; i < 2; i++){
600
 
            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
601
 
            s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
 
601
            for(k = 0; k < 2; k++){
 
602
                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
 
603
                s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
 
604
            }
602
605
        }
603
606
    }
604
 
    if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD)
605
 
        fill_rectangle(s->current_picture_ptr->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4);
606
607
}
607
608
 
608
609
static const int chroma_coeffs[3] = { 0, 3, 5 };
644
645
        uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
645
646
        uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
646
647
    }else{
 
648
        int cx, cy;
647
649
        mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
648
650
        my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
649
651
        lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
650
652
        ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
651
 
        umx = mx >> 1;
652
 
        umy = my >> 1;
653
 
        uvmx = mx & 6;
654
 
        uvmy = my & 6;
 
653
        cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
 
654
        cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
 
655
        umx = cx >> 2;
 
656
        umy = cy >> 2;
 
657
        uvmx = (cx & 3) << 1;
 
658
        uvmy = (cy & 3) << 1;
 
659
        //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
 
660
        if(uvmx == 6 && uvmy == 6)
 
661
            uvmx = uvmy = 4;
655
662
    }
656
663
    dxy = ly*4 + lx;
657
664
    srcY = dir ? s->next_picture_ptr->data[0] : s->last_picture_ptr->data[0];
664
671
    srcY += src_y * s->linesize + src_x;
665
672
    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
666
673
    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
667
 
    if(   (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 3
668
 
       || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 3){
669
 
        uint8_t *uvbuf= s->edge_emu_buffer + 20 * s->linesize;
 
674
    if(   (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4
 
675
       || (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){
 
676
        uint8_t *uvbuf= s->edge_emu_buffer + 22 * s->linesize;
670
677
 
671
678
        srcY -= 2 + 2*s->linesize;
672
 
        ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+4, (height<<3)+4,
 
679
        ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, (width<<3)+6, (height<<3)+6,
673
680
                            src_x - 2, src_y - 2, s->h_edge_pos, s->v_edge_pos);
674
681
        srcY = s->edge_emu_buffer + 2 + 2*s->linesize;
675
682
        ff_emulated_edge_mc(uvbuf     , srcU, s->uvlinesize, (width<<2)+1, (height<<2)+1,
704
711
{
705
712
    rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30,
706
713
            r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
707
 
                    : r->s.dsp.put_h264_qpel_pixels_tab,
708
 
            r->s.dsp.put_h264_chroma_pixels_tab);
 
714
                    : r->s.dsp.put_rv40_qpel_pixels_tab,
 
715
            r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
 
716
                    : r->s.dsp.put_rv40_chroma_pixels_tab);
709
717
}
710
718
 
711
719
static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
712
720
{
713
721
    rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30,
714
722
            r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
715
 
                    : r->s.dsp.put_h264_qpel_pixels_tab,
716
 
            r->s.dsp.put_h264_chroma_pixels_tab);
 
723
                    : r->s.dsp.put_rv40_qpel_pixels_tab,
 
724
            r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
 
725
                    : r->s.dsp.put_rv40_chroma_pixels_tab);
717
726
    rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30,
718
727
            r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
719
 
                    : r->s.dsp.avg_h264_qpel_pixels_tab,
720
 
            r->s.dsp.avg_h264_chroma_pixels_tab);
 
728
                    : r->s.dsp.avg_rv40_qpel_pixels_tab,
 
729
            r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
 
730
                    : r->s.dsp.avg_rv40_chroma_pixels_tab);
721
731
}
722
732
 
723
733
static void rv34_mc_2mv_skip(RV34DecContext *r)
727
737
        for(i = 0; i < 2; i++){
728
738
             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
729
739
                    r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
730
 
                            : r->s.dsp.put_h264_qpel_pixels_tab,
731
 
                    r->s.dsp.put_h264_chroma_pixels_tab);
 
740
                            : r->s.dsp.put_rv40_qpel_pixels_tab,
 
741
                    r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
 
742
                            : r->s.dsp.put_rv40_chroma_pixels_tab);
732
743
             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
733
744
                    r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
734
 
                            : r->s.dsp.avg_h264_qpel_pixels_tab,
735
 
                    r->s.dsp.avg_h264_chroma_pixels_tab);
 
745
                            : r->s.dsp.avg_rv40_qpel_pixels_tab,
 
746
                    r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
 
747
                            : r->s.dsp.avg_rv40_chroma_pixels_tab);
736
748
        }
737
749
}
738
750
 
953
965
        itype = ittrans16[intra_types[0]];
954
966
        itype = adjust_pred16(itype, r->avail_cache[5-4], r->avail_cache[5-1]);
955
967
        r->h.pred16x16[itype](Y, s->linesize);
956
 
        dsp->add_pixels_clamped(s->block[0], Y,     s->current_picture.linesize[0]);
957
 
        dsp->add_pixels_clamped(s->block[1], Y + 8, s->current_picture.linesize[0]);
958
 
        Y += s->current_picture.linesize[0] * 8;
959
 
        dsp->add_pixels_clamped(s->block[2], Y,     s->current_picture.linesize[0]);
960
 
        dsp->add_pixels_clamped(s->block[3], Y + 8, s->current_picture.linesize[0]);
 
968
        dsp->add_pixels_clamped(s->block[0], Y,     s->linesize);
 
969
        dsp->add_pixels_clamped(s->block[1], Y + 8, s->linesize);
 
970
        Y += s->linesize * 8;
 
971
        dsp->add_pixels_clamped(s->block[2], Y,     s->linesize);
 
972
        dsp->add_pixels_clamped(s->block[3], Y + 8, s->linesize);
961
973
 
962
974
        itype = ittrans16[intra_types[0]];
963
975
        if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
1046
1058
 * mask for retrieving all bits in coded block pattern
1047
1059
 * corresponding to one 8x8 block
1048
1060
 */
1049
 
#define LUMA_CBP_BLOCK_MASK 0x303
 
1061
#define LUMA_CBP_BLOCK_MASK 0x33
1050
1062
 
1051
1063
#define U_CBP_MASK 0x0F0000
1052
1064
#define V_CBP_MASK 0xF00000
1059
1071
    int i;
1060
1072
 
1061
1073
    for(i = 0; i < 4; i++)
1062
 
        if(cbp & (LUMA_CBP_BLOCK_MASK << shifts[i]))
 
1074
        if((cbp & (LUMA_CBP_BLOCK_MASK << shifts[i])) || r->block_type == RV34_MB_P_MIX16x16)
1063
1075
            s->dsp.add_pixels_clamped(s->block[i], s->dest[0] + (i & 1)*8 + (i&2)*4*s->linesize, s->linesize);
1064
1076
    if(cbp & U_CBP_MASK)
1065
1077
        s->dsp.add_pixels_clamped(s->block[4], s->dest[1], s->uvlinesize);
1089
1101
        for(i = 0; i < 2; i++){
1090
1102
            if(is_mv_diff_gt_3(motion_val + i, 1))
1091
1103
                vmvmask |= 0x11 << (j + i*2);
1092
 
            if(is_mv_diff_gt_3(motion_val + i, s->b8_stride))
 
1104
            if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
1093
1105
                hmvmask |= 0x03 << (j + i*2);
1094
1106
        }
1095
1107
        motion_val += s->b8_stride;
1098
1110
        hmvmask &= ~0x000F;
1099
1111
    if(!s->mb_x)
1100
1112
        vmvmask &= ~0x1111;
1101
 
    return hmvmask | vmvmask; //XXX: should be stored separately for RV3
 
1113
    if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
 
1114
        vmvmask |= (vmvmask & 0x4444) >> 1;
 
1115
        hmvmask |= (hmvmask & 0x0F00) >> 4;
 
1116
        if(s->mb_x)
 
1117
            r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
 
1118
        if(!s->first_slice_line)
 
1119
            r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
 
1120
    }
 
1121
    return hmvmask | vmvmask;
1102
1122
}
1103
1123
 
1104
1124
static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
1129
1149
 
1130
1150
    s->qscale = r->si.quant;
1131
1151
    cbp = cbp2 = rv34_decode_mb_header(r, intra_types);
1132
 
    r->cbp_luma  [s->mb_x + s->mb_y * s->mb_stride] = cbp;
1133
 
    r->cbp_chroma[s->mb_x + s->mb_y * s->mb_stride] = cbp >> 16;
 
1152
    r->cbp_luma  [mb_pos] = cbp;
 
1153
    r->cbp_chroma[mb_pos] = cbp >> 16;
1134
1154
    if(s->pict_type == FF_I_TYPE)
1135
 
        r->deblock_coefs[mb_pos] = 0;
 
1155
        r->deblock_coefs[mb_pos] = 0xFFFF;
1136
1156
    else
1137
 
        r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r);
1138
 
    s->current_picture.qscale_table[s->mb_x + s->mb_y * s->mb_stride] = s->qscale;
 
1157
        r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
 
1158
    s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
1139
1159
 
1140
1160
    if(cbp == -1)
1141
1161
        return -1;
1169
1189
        rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
1170
1190
        rv34_inv_transform(s->block[blknum] + blkoff);
1171
1191
    }
1172
 
    if(IS_INTRA(s->current_picture_ptr->mb_type[s->mb_x + s->mb_y*s->mb_stride]))
 
1192
    if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos]))
1173
1193
        rv34_output_macroblock(r, intra_types, cbp2, r->is16);
1174
1194
    else
1175
1195
        rv34_apply_differences(r, cbp2);
1201
1221
           si1->pts    != si2->pts;
1202
1222
}
1203
1223
 
1204
 
static int rv34_decode_slice(RV34DecContext *r, int end, uint8_t* buf, int buf_size)
 
1224
static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
1205
1225
{
1206
1226
    MpegEncContext *s = &r->s;
1207
1227
    GetBitContext *gb = &s->gb;
1234
1254
        if(MPV_frame_start(s, s->avctx) < 0)
1235
1255
            return -1;
1236
1256
        ff_er_frame_start(s);
1237
 
        s->current_picture_ptr = &s->current_picture;
1238
1257
        r->cur_pts = r->si.pts;
1239
1258
        if(s->pict_type != FF_B_TYPE){
1240
1259
            r->last_pts = r->next_pts;
1276
1295
 
1277
1296
            memmove(r->intra_types_hist, r->intra_types, s->b4_stride * 4 * sizeof(*r->intra_types_hist));
1278
1297
            memset(r->intra_types, -1, s->b4_stride * 4 * sizeof(*r->intra_types_hist));
 
1298
 
 
1299
            if(r->loop_filter && s->mb_y >= 2)
 
1300
                r->loop_filter(r, s->mb_y - 2);
1279
1301
        }
1280
1302
        if(s->mb_x == s->resync_mb_x)
1281
1303
            s->first_slice_line=0;
1331
1353
    return 0;
1332
1354
}
1333
1355
 
1334
 
static int get_slice_offset(AVCodecContext *avctx, uint8_t *buf, int n)
 
1356
static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
1335
1357
{
1336
1358
    if(avctx->slice_count) return avctx->slice_offset[n];
1337
1359
    else                   return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) :  AV_RB32(buf + n*8);
1339
1361
 
1340
1362
int ff_rv34_decode_frame(AVCodecContext *avctx,
1341
1363
                            void *data, int *data_size,
1342
 
                            uint8_t *buf, int buf_size)
 
1364
                            const uint8_t *buf, int buf_size)
1343
1365
{
1344
1366
    RV34DecContext *r = avctx->priv_data;
1345
1367
    MpegEncContext *s = &r->s;
1347
1369
    SliceInfo si;
1348
1370
    int i;
1349
1371
    int slice_count;
1350
 
    uint8_t *slices_hdr = NULL;
 
1372
    const uint8_t *slices_hdr = NULL;
1351
1373
    int last = 0;
1352
1374
 
1353
1375
    /* no supplementary picture */
1377
1399
        else
1378
1400
            size= get_slice_offset(avctx, slices_hdr, i+1) - offset;
1379
1401
 
 
1402
        if(offset > buf_size){
 
1403
            av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");
 
1404
            break;
 
1405
        }
 
1406
 
1380
1407
        r->si.end = s->mb_width * s->mb_height;
1381
1408
        if(i+1 < slice_count){
1382
1409
            init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);
1388
1415
            }else
1389
1416
                r->si.end = si.start;
1390
1417
        }
 
1418
        if(!i && si.type == FF_B_TYPE && (!s->last_picture_ptr || !s->last_picture_ptr->data[0]))
 
1419
            return -1;
1391
1420
        last = rv34_decode_slice(r, r->si.end, buf + offset, size);
1392
1421
        s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
1393
1422
        if(last)
1396
1425
 
1397
1426
    if(last){
1398
1427
        if(r->loop_filter)
1399
 
            r->loop_filter(r);
 
1428
            r->loop_filter(r, s->mb_height - 1);
1400
1429
        ff_er_frame_end(s);
1401
1430
        MPV_frame_end(s);
1402
1431
        if (s->pict_type == FF_B_TYPE || s->low_delay) {