]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vc1.c
optimize IDCT of rows with mostly zero coefficients
[ffmpeg] / libavcodec / vc1.c
index cd3c0c2d6aa576e8c9d7ded01b56bcbda64aa8fa..5649484a9fecdb64e9c9ea70f94ac28d8ff0647d 100644 (file)
@@ -790,6 +790,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
     }
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     uvmy = (my + ((my & 3) == 3)) >> 1;
+    if(v->fastuvmc) {
+        uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
+        uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
+    }
     if(!dir) {
         srcY = s->last_picture.data[0];
         srcU = s->last_picture.data[1];
@@ -878,11 +882,6 @@ static void vc1_mc_1mv(VC1Context *v, int dir)
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if(v->fastuvmc) {
-        uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
-        uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
-    }
-
     if(s->mspel) {
         dxy = ((my & 3) << 2) | (mx & 3);
         dsp->put_vc1_mspel_pixels_tab[dxy](s->dest[0]    , srcY    , s->linesize, v->rnd);
@@ -1052,6 +1051,10 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
     s->current_picture.motion_val[1][s->block_index[0]][1] = ty;
     uvmx = (tx + ((tx&3) == 3)) >> 1;
     uvmy = (ty + ((ty&3) == 3)) >> 1;
+    if(v->fastuvmc) {
+        uvmx = uvmx + ((uvmx<0)?(uvmx&1):-(uvmx&1));
+        uvmy = uvmy + ((uvmy<0)?(uvmy&1):-(uvmy&1));
+    }
 
     uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
     uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
@@ -1102,11 +1105,6 @@ static void vc1_mc_4mv_chroma(VC1Context *v)
         }
     }
 
-    if(v->fastuvmc) {
-        uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
-        uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
-    }
-
     /* Chroma MC always uses qpel bilinear */
     uvdxy = ((uvmy & 3) << 2) | (uvmx & 3);
     uvmx = (uvmx&3)<<1;
@@ -1270,9 +1268,23 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
     v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
     v->broadcast = get_bits1(gb);
     v->interlace = get_bits1(gb);
+    if(v->interlace){
+        av_log(v->s.avctx, AV_LOG_ERROR, "Interlaced mode not supported (yet)\n");
+        return -1;
+    }
     v->tfcntrflag = get_bits1(gb);
     v->finterpflag = get_bits1(gb);
     get_bits1(gb); // reserved
+
+    av_log(v->s.avctx, AV_LOG_DEBUG,
+               "Advanced Profile level %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
+               "LoopFilter=%i, ChromaFormat=%i, Pulldown=%i, Interlace: %i\n"
+               "TFCTRflag=%i, FINTERPflag=%i\n",
+               v->level, v->frmrtq_postproc, v->bitrtq_postproc,
+               v->s.loop_filter, v->chromaformat, v->broadcast, v->interlace,
+               v->tfcntrflag, v->finterpflag
+               );
+
     v->psf = get_bits1(gb);
     if(v->psf) { //PsF, 6.1.13
         av_log(v->s.avctx, AV_LOG_ERROR, "Progressive Segmented Frame mode: not supported (yet)\n");
@@ -1281,15 +1293,17 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
     if(get_bits1(gb)) { //Display Info - decoding is not affected by it
         int w, h, ar = 0;
         av_log(v->s.avctx, AV_LOG_INFO, "Display extended info:\n");
-        w = get_bits(gb, 14);
-        h = get_bits(gb, 14);
+        w = get_bits(gb, 14) + 1;
+        h = get_bits(gb, 14) + 1;
         av_log(v->s.avctx, AV_LOG_INFO, "Display dimensions: %ix%i\n", w, h);
-        //TODO: store aspect ratio in AVCodecContext
         if(get_bits1(gb))
             ar = get_bits(gb, 4);
-        if(ar == 15) {
+        if(ar && ar < 14){
+            v->s.avctx->sample_aspect_ratio = vc1_pixel_aspect[ar];
+        }else if(ar == 15){
             w = get_bits(gb, 8);
             h = get_bits(gb, 8);
+            v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
         }
 
         if(get_bits1(gb)){ //framerate stuff
@@ -1325,13 +1339,13 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb)
 static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
 {
     VC1Context *v = avctx->priv_data;
-    int i;
+    int i, blink, refdist;
 
     av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
-    get_bits1(gb); // broken link
+    blink = get_bits1(gb); // broken link
     avctx->max_b_frames = 1 - get_bits1(gb); // 'closed entry' also signalize possible B-frames
     v->panscanflag = get_bits1(gb);
-    get_bits1(gb); // refdist flag
+    refdist = get_bits1(gb); // refdist flag
     v->s.loop_filter = get_bits1(gb);
     v->fastuvmc = get_bits1(gb);
     v->extended_mv = get_bits1(gb);
@@ -1361,6 +1375,13 @@ static int decode_entry_point(AVCodecContext *avctx, GetBitContext *gb)
         skip_bits(gb, 3); // UV range, ignored for now
     }
 
+    av_log(avctx, AV_LOG_DEBUG, "Entry point info:\n"
+        "BrokenLink=%i, ClosedEntry=%i, PanscanFlag=%i\n"
+        "RefDist=%i, Postproc=%i, FastUVMC=%i, ExtMV=%i\n"
+        "DQuant=%i, VSTransform=%i, Overlap=%i, Qmode=%i\n",
+        blink, 1 - avctx->max_b_frames, v->panscanflag, refdist, v->s.loop_filter,
+        v->fastuvmc, v->extended_mv, v->dquant, v->vstransform, v->overlap, v->quantizer_mode);
+
     return 0;
 }
 
@@ -1813,7 +1834,7 @@ static int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb)
     }
     /* DC Syntax */
     v->s.dc_table_index = get_bits(gb, 1);
-    if (v->s.pict_type == I_TYPE && v->dquant) {
+    if ((v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE) && v->dquant) {
         av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
         vop_dquant_decoding(v);
     }
@@ -2061,6 +2082,10 @@ static void vc1_interp_mc(VC1Context *v)
     my = s->mv[1][0][1];
     uvmx = (mx + ((mx & 3) == 3)) >> 1;
     uvmy = (my + ((my & 3) == 3)) >> 1;
+    if(v->fastuvmc) {
+        uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
+        uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
+    }
     srcY = s->next_picture.data[0];
     srcU = s->next_picture.data[1];
     srcV = s->next_picture.data[2];
@@ -2123,11 +2148,6 @@ static void vc1_interp_mc(VC1Context *v)
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if(v->fastuvmc) {
-        uvmx = uvmx + ((uvmx<0)?-(uvmx&1):(uvmx&1));
-        uvmy = uvmy + ((uvmy<0)?-(uvmy&1):(uvmy&1));
-    }
-
     mx >>= 1;
     my >>= 1;
     dxy = ((my & 1) << 1) | (mx & 1);
@@ -2143,7 +2163,7 @@ static void vc1_interp_mc(VC1Context *v)
     dsp->avg_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);
 }
 
-static always_inline int scale_mv(int value, int bfrac, int inv, int qs)
+static av_always_inline int scale_mv(int value, int bfrac, int inv, int qs)
 {
     int n = bfrac;
 
@@ -3075,8 +3095,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int c
         ac_val -= 16 * s->block_wrap[n];
 
     q1 = s->current_picture.qscale_table[mb_pos];
-    if(dc_pred_dir && c_avail) q2 = s->current_picture.qscale_table[mb_pos - 1];
-    if(!dc_pred_dir && a_avail) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
+    if(dc_pred_dir && c_avail && mb_pos) q2 = s->current_picture.qscale_table[mb_pos - 1];
+    if(!dc_pred_dir && a_avail && mb_pos >= s->mb_stride) q2 = s->current_picture.qscale_table[mb_pos - s->mb_stride];
     if(n && n<4) q2 = q1;
 
     if(coded) {
@@ -4063,9 +4083,12 @@ static void vc1_decode_blocks(VC1Context *v)
             vc1_decode_p_blocks(v);
         break;
     case B_TYPE:
-        if(v->bi_type)
-            vc1_decode_i_blocks(v);
-        else
+        if(v->bi_type){
+            if(v->profile == PROFILE_ADVANCED)
+                vc1_decode_i_blocks_adv(v);
+            else
+                vc1_decode_i_blocks(v);
+        }else
             vc1_decode_b_blocks(v);
         break;
     }
@@ -4131,7 +4154,7 @@ static int vc1_decode_init(AVCodecContext *avctx)
         }
         while(edata_size > 8) {
             // test if we've found header
-            if(BE_32(edata) == 0x0000010F) {
+            if(AV_RB32(edata) == 0x0000010F) {
                 edata += 4;
                 edata_size -= 4;
                 break;
@@ -4147,7 +4170,7 @@ static int vc1_decode_init(AVCodecContext *avctx)
 
         while(edata_size > 8) {
             // test if we've found entry point
-            if(BE_32(edata) == 0x0000010E) {
+            if(AV_RB32(edata) == 0x0000010E) {
                 edata += 4;
                 edata_size -= 4;
                 break;