OSDN Git Service

- More work on preliminary bit rate control, just to be able to get an
authorJuanjo <pulento@users.sourceforge.net>
Sun, 10 Feb 2002 06:10:50 +0000 (06:10 +0000)
committerJuanjo <pulento@users.sourceforge.net>
Sun, 10 Feb 2002 06:10:50 +0000 (06:10 +0000)
average variance for picture's MBs so we can adjust qscale on the MB layer.

Originally committed as revision 294 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/motion_est.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h

index 71a30dd..8e215f9 100644 (file)
@@ -400,7 +400,7 @@ int estimate_motion(MpegEncContext * s,
     UINT8 *pix, *ppix;
     int sum, varc, vard, mx, my, range, dmin, xx, yy;
     int xmin, ymin, xmax, ymax;
-
+    
     range = 8 * (1 << (s->f_code - 1));
     /* XXX: temporary kludge to avoid overflow for msmpeg4 */
     if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
@@ -458,9 +458,12 @@ int estimate_motion(MpegEncContext * s,
     vard = vard >> 8;
     sum = sum >> 8;
     varc = (varc >> 8) - (sum * sum);
+    
+    s->avg_mb_var += varc;
+     
 #if 0
-    printf("varc=%d (sum=%d) vard=%d mx=%d my=%d\n",
-          varc, sum, vard, mx - xx, my - yy);
+    printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
+          varc, s->avg_mb_var, sum, vard, mx - xx, my - yy);
 #endif
     if (vard <= 64 || vard < varc) {
         if (s->full_search != ME_ZERO) {
index f41666b..f38ee13 100644 (file)
@@ -115,6 +115,7 @@ int MPV_common_init(MpegEncContext *s)
 #endif
     s->mb_width = (s->width + 15) / 16;
     s->mb_height = (s->height + 15) / 16;
+    s->mb_num = s->mb_width * s->mb_height;
     s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
 
     for(i=0;i<3;i++) {
@@ -149,7 +150,7 @@ int MPV_common_init(MpegEncContext *s)
     
     if (s->encoding) {
         /* Allocate MB type table */
-        s->mb_type = malloc(s->mb_width * s->mb_height * sizeof(char));
+        s->mb_type = malloc(s->mb_num * sizeof(char));
         if (s->mb_type == NULL) {
             perror("malloc");
             goto fail;
@@ -157,8 +158,8 @@ int MPV_common_init(MpegEncContext *s)
     
         /* Allocate MV table */
         /* By now we just have one MV per MB */
-        s->mv_table[0] = malloc(s->mb_width * s->mb_height * sizeof(INT16));
-        s->mv_table[1] = malloc(s->mb_width * s->mb_height * sizeof(INT16));
+        s->mv_table[0] = malloc(s->mb_num * sizeof(INT16));
+        s->mv_table[1] = malloc(s->mb_num * sizeof(INT16));
         if (s->mv_table[1] == NULL || s->mv_table[0] == NULL) {
             perror("malloc");
             goto fail;
@@ -204,17 +205,17 @@ int MPV_common_init(MpegEncContext *s)
             goto fail;
 
         /* which mb is a intra block */
-        s->mbintra_table = av_mallocz(s->mb_width * s->mb_height);
+        s->mbintra_table = av_mallocz(s->mb_num);
         if (!s->mbintra_table)
             goto fail;
-        memset(s->mbintra_table, 1, s->mb_width * s->mb_height);
+        memset(s->mbintra_table, 1, s->mb_num);
     }
     /* default structure is frame */
     s->picture_structure = PICT_FRAME;
 
     /* init macroblock skip table */
     if (!s->encoding) {
-        s->mbskip_table = av_mallocz(s->mb_width * s->mb_height);
+        s->mbskip_table = av_mallocz(s->mb_num);
         if (!s->mbskip_table)
             goto fail;
     }
@@ -960,22 +961,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
         else
             s->gob_index = 4;
     }
-        
+    
+    /* Reset the average MB variance */
+    s->avg_mb_var = 0;
+    
+    /* Estimate motion for every MB */
     for(mb_y=0; mb_y < s->mb_height; mb_y++) {
-        /* Put GOB header based on RTP MTU */
-        /* TODO: Put all this stuff in a separate generic function */
-        if (s->rtp_mode) {
-            if (!mb_y) {
-                s->ptr_lastgob = s->pb.buf;
-                s->ptr_last_mb_line = s->pb.buf;
-            } else if (s->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4 && !(mb_y % s->gob_index)) {
-                last_gob = h263_encode_gob_header(s, mb_y);
-                if (last_gob) {
-                    s->first_gob_line = 1;
-                }
-            }
-        }
-        
         for(mb_x=0; mb_x < s->mb_width; mb_x++) {
             s->mb_x = mb_x;
             s->mb_y = mb_y;
@@ -995,7 +986,25 @@ static void encode_picture(MpegEncContext *s, int picture_number)
             s->mv_table[0][mb_y * s->mb_width + mb_x] = motion_x;
             s->mv_table[1][mb_y * s->mb_width + mb_x] = motion_y;
         }
-                    
+    }
+    
+    s->avg_mb_var = s->avg_mb_var / s->mb_num;        
+    
+    for(mb_y=0; mb_y < s->mb_height; mb_y++) {
+        /* Put GOB header based on RTP MTU */
+        /* TODO: Put all this stuff in a separate generic function */
+        if (s->rtp_mode) {
+            if (!mb_y) {
+                s->ptr_lastgob = s->pb.buf;
+                s->ptr_last_mb_line = s->pb.buf;
+            } else if (s->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4 && !(mb_y % s->gob_index)) {
+                last_gob = h263_encode_gob_header(s, mb_y);
+                if (last_gob) {
+                    s->first_gob_line = 1;
+                }
+            }
+        }
+        
         for(mb_x=0; mb_x < s->mb_width; mb_x++) {
 
             s->mb_x = mb_x;
index 0eec0b7..626bf8f 100644 (file)
@@ -58,8 +58,9 @@ typedef struct MpegEncContext {
     int context_initialized;
     int picture_number;
     int fake_picture_number; /* picture number at the bitstream frame rate */
-    int gop_picture_number; /* index of the first picture of a GOP */
+    int gop_picture_number;  /* index of the first picture of a GOP */
     int mb_width, mb_height;
+    int mb_num;                /* number of MBs of a picture */
     int linesize;              /* line size, in bytes, may be different from width */
     UINT8 *new_picture[3];     /* picture to be compressed */
     UINT8 *last_picture[3];    /* previous picture */
@@ -136,6 +137,7 @@ typedef struct MpegEncContext {
     /* bit rate control */
     int I_frame_bits;    /* wanted number of bits per I frame */
     int P_frame_bits;    /* same for P frame */
+    int avg_mb_var;        /* average MB variance for current frame */
     INT64 wanted_bits;
     INT64 total_bits;