fixing hq mode with mpeg1 and 2-pass
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 17 Apr 2002 18:19:50 +0000 (18:19 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 17 Apr 2002 18:19:50 +0000 (18:19 +0000)
Originally committed as revision 405 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/mpegvideo.c

index f1725ccdafd1cc71c08667a8d2ff3a87a78ae83a..af1d1c33968f0309577bc076b4da7e3f91a8eab8 100644 (file)
@@ -1393,20 +1393,81 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
 
 static void copy_bits(PutBitContext *pb, UINT8 *src, int length)
 {
+#if 1
+    int bytes= length>>4;
+    int bits= length&15;
+    int i;
+
+    for(i=0; i<bytes; i++) put_bits(pb, 16, be2me_16(((uint16_t*)src)[i]));
+    put_bits(pb, bits, be2me_16(((uint16_t*)src)[i])>>(16-bits));
+#else
     int bytes= length>>3;
     int bits= length&7;
     int i;
 
     for(i=0; i<bytes; i++) put_bits(pb, 8, src[i]);
     put_bits(pb, bits, src[i]>>(8-bits));
+#endif
 }
 
+static void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){
+    int i;
+
+    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
+
+    /* mpeg1 */
+    d->mb_incr= s->mb_incr;
+    for(i=0; i<3; i++)
+        d->last_dc[i]= s->last_dc[i];
+    
+    /* statistics */
+    d->mv_bits= s->mv_bits;
+    d->i_tex_bits= s->i_tex_bits;
+    d->p_tex_bits= s->p_tex_bits;
+    d->i_count= s->i_count;
+    d->p_count= s->p_count;
+    d->skip_count= s->skip_count;
+    d->misc_bits= s->misc_bits;
+    d->last_bits= s->last_bits;
+}
+
+static void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){
+    int i;
+
+    memcpy(d->mv, s->mv, 2*4*2*sizeof(int)); 
+    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?
+    
+    /* mpeg1 */
+    d->mb_incr= s->mb_incr;
+    for(i=0; i<3; i++)
+        d->last_dc[i]= s->last_dc[i];
+    
+    /* statistics */
+    d->mv_bits= s->mv_bits;
+    d->i_tex_bits= s->i_tex_bits;
+    d->p_tex_bits= s->p_tex_bits;
+    d->i_count= s->i_count;
+    d->p_count= s->p_count;
+    d->skip_count= s->skip_count;
+    d->misc_bits= s->misc_bits;
+    d->last_bits= s->last_bits;
+
+    d->mb_intra= s->mb_intra;
+    d->mv_type= s->mv_type;
+    d->mv_dir= s->mv_dir;
+    d->pb= s->pb;
+    d->block= s->block;
+    for(i=0; i<6; i++)
+        d->block_last_index[i]= s->block_last_index[i];
+}
+
+
 static void encode_picture(MpegEncContext *s, int picture_number)
 {
     int mb_x, mb_y, last_gob, pdif = 0;
     int i;
     int bits;
-    MpegEncContext best_s;
+    MpegEncContext best_s, backup_s;
     UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB
 
     s->picture_number = picture_number;
@@ -1585,10 +1646,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
             s->block_index[3]+=2;
             s->block_index[4]++;
             s->block_index[5]++;
-
             if(mb_type & (mb_type-1)){ // more than 1 MB type possible
                 pb= s->pb;
                 s->mv_dir = MV_DIR_FORWARD;
+
+                copy_context_before_encode(&backup_s, s, -1);
+
                 if(mb_type&MB_TYPE_INTER){
                     int xy= (mb_y+1) * (s->mb_width+2) + mb_x + 1;
                     s->mv_type = MV_TYPE_16X16;
@@ -1603,18 +1666,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
                     if(d<dmin){
                         flush_put_bits(&s->pb);
                         dmin=d;
-                        best_s.mv[0][0][0]= s->mv[0][0][0];
-                        best_s.mv[0][0][1]= s->mv[0][0][1];
-                        best_s.mb_intra= 0;
-                        best_s.mv_type = MV_TYPE_16X16;
-                        best_s.pb=s->pb;
-                        best_s.block= s->block;
+                        copy_context_after_encode(&best_s, s, MB_TYPE_INTER);
                         best=1;
-                        for(i=0; i<6; i++)
-                            best_s.block_last_index[i]= s->block_last_index[i];
                     }
                 }
-                if(mb_type&MB_TYPE_INTER4V){
+                if(mb_type&MB_TYPE_INTER4V){                 
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_INTER4V);
                     s->mv_type = MV_TYPE_8X8;
                     s->mb_intra= 0;
                     for(i=0; i<4; i++){
@@ -1629,20 +1686,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
                     if(d<dmin && 0){
                         flush_put_bits(&s->pb);
                         dmin=d;
-                        for(i=0; i<4; i++){
-                            best_s.mv[0][i][0] = s->mv[0][i][0];
-                            best_s.mv[0][i][1] = s->mv[0][i][1];
-                        }
-                        best_s.mb_intra= 0;
-                        best_s.mv_type = MV_TYPE_8X8;
-                        best_s.pb=s->pb;
-                        best_s.block= s->block;
+                        copy_context_after_encode(&best_s, s, MB_TYPE_INTER4V);
                         best=2;
-                        for(i=0; i<6; i++)
-                            best_s.block_last_index[i]= s->block_last_index[i];
                     }
                 }
                 if(mb_type&MB_TYPE_INTRA){
+                    copy_context_before_encode(s, &backup_s, MB_TYPE_INTRA);
                     s->mv_type = MV_TYPE_16X16;
                     s->mb_intra= 1;
                     s->mv[0][0][0] = 0;
@@ -1655,29 +1704,15 @@ static void encode_picture(MpegEncContext *s, int picture_number)
                     if(d<dmin){
                         flush_put_bits(&s->pb);
                         dmin=d;
-                        best_s.mv[0][0][0]= 0;
-                        best_s.mv[0][0][1]= 0;
-                        best_s.mb_intra= 1;
-                        best_s.mv_type = MV_TYPE_16X16;
-                        best_s.pb=s->pb;
-                        best_s.block= s->block;
-                        for(i=0; i<6; i++)
-                            best_s.block_last_index[i]= s->block_last_index[i];
+                        copy_context_after_encode(&best_s, s, MB_TYPE_INTRA);
                         best=0;
                     }
-                    /* force cleaning of ac/dc if needed ... */
-                    s->mbintra_table[mb_x + mb_y*s->mb_width]=1;
-                }
-                for(i=0; i<4; i++){
-                   s->mv[0][i][0] =  best_s.mv[0][i][0];
-                   s->mv[0][i][1] =  best_s.mv[0][i][1];
+                    /* force cleaning of ac/dc pred stuff if needed ... */
+                    if(s->h263_pred || s->h263_aic)
+                        s->mbintra_table[mb_x + mb_y*s->mb_width]=1;
                 }
-                s->mb_intra= best_s.mb_intra;
-                s->mv_type= best_s.mv_type;
-                for(i=0; i<6; i++)
-                   s->block_last_index[i]= best_s.block_last_index[i];
+                copy_context_after_encode(s, &best_s, -1);
                 copy_bits(&pb, bit_buf[best], dmin);
-                s->block= best_s.block;
                 s->pb= pb;
             } else {
                 int motion_x, motion_y;