- More work on preliminary bit rate control, just to be able to get an

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
This commit is contained in:
Juanjo 2002-02-10 06:10:50 +00:00
parent 37fbfd0a91
commit e03c341ef3
3 changed files with 40 additions and 26 deletions

View File

@ -400,7 +400,7 @@ int estimate_motion(MpegEncContext * s,
UINT8 *pix, *ppix; UINT8 *pix, *ppix;
int sum, varc, vard, mx, my, range, dmin, xx, yy; int sum, varc, vard, mx, my, range, dmin, xx, yy;
int xmin, ymin, xmax, ymax; int xmin, ymin, xmax, ymax;
range = 8 * (1 << (s->f_code - 1)); range = 8 * (1 << (s->f_code - 1));
/* XXX: temporary kludge to avoid overflow for msmpeg4 */ /* XXX: temporary kludge to avoid overflow for msmpeg4 */
if (s->out_format == FMT_H263 && !s->h263_msmpeg4) if (s->out_format == FMT_H263 && !s->h263_msmpeg4)
@ -458,9 +458,12 @@ int estimate_motion(MpegEncContext * s,
vard = vard >> 8; vard = vard >> 8;
sum = sum >> 8; sum = sum >> 8;
varc = (varc >> 8) - (sum * sum); varc = (varc >> 8) - (sum * sum);
s->avg_mb_var += varc;
#if 0 #if 0
printf("varc=%d (sum=%d) vard=%d mx=%d my=%d\n", printf("varc=%4d avg_var=%4d (sum=%4d) vard=%4d mx=%2d my=%2d\n",
varc, sum, vard, mx - xx, my - yy); varc, s->avg_mb_var, sum, vard, mx - xx, my - yy);
#endif #endif
if (vard <= 64 || vard < varc) { if (vard <= 64 || vard < varc) {
if (s->full_search != ME_ZERO) { if (s->full_search != ME_ZERO) {

View File

@ -115,6 +115,7 @@ int MPV_common_init(MpegEncContext *s)
#endif #endif
s->mb_width = (s->width + 15) / 16; s->mb_width = (s->width + 15) / 16;
s->mb_height = (s->height + 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; s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
@ -149,7 +150,7 @@ int MPV_common_init(MpegEncContext *s)
if (s->encoding) { if (s->encoding) {
/* Allocate MB type table */ /* 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) { if (s->mb_type == NULL) {
perror("malloc"); perror("malloc");
goto fail; goto fail;
@ -157,8 +158,8 @@ int MPV_common_init(MpegEncContext *s)
/* Allocate MV table */ /* Allocate MV table */
/* By now we just have one MV per MB */ /* 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[0] = malloc(s->mb_num * sizeof(INT16));
s->mv_table[1] = malloc(s->mb_width * s->mb_height * sizeof(INT16)); s->mv_table[1] = malloc(s->mb_num * sizeof(INT16));
if (s->mv_table[1] == NULL || s->mv_table[0] == NULL) { if (s->mv_table[1] == NULL || s->mv_table[0] == NULL) {
perror("malloc"); perror("malloc");
goto fail; goto fail;
@ -204,17 +205,17 @@ int MPV_common_init(MpegEncContext *s)
goto fail; goto fail;
/* which mb is a intra block */ /* 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) if (!s->mbintra_table)
goto fail; 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 */ /* default structure is frame */
s->picture_structure = PICT_FRAME; s->picture_structure = PICT_FRAME;
/* init macroblock skip table */ /* init macroblock skip table */
if (!s->encoding) { 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) if (!s->mbskip_table)
goto fail; goto fail;
} }
@ -960,22 +961,12 @@ static void encode_picture(MpegEncContext *s, int picture_number)
else else
s->gob_index = 4; 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++) { 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++) { for(mb_x=0; mb_x < s->mb_width; mb_x++) {
s->mb_x = mb_x; s->mb_x = mb_x;
s->mb_y = mb_y; 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[0][mb_y * s->mb_width + mb_x] = motion_x;
s->mv_table[1][mb_y * s->mb_width + mb_x] = motion_y; 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++) { for(mb_x=0; mb_x < s->mb_width; mb_x++) {
s->mb_x = mb_x; s->mb_x = mb_x;

View File

@ -58,8 +58,9 @@ typedef struct MpegEncContext {
int context_initialized; int context_initialized;
int picture_number; int picture_number;
int fake_picture_number; /* picture number at the bitstream frame rate */ 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_width, mb_height;
int mb_num; /* number of MBs of a picture */
int linesize; /* line size, in bytes, may be different from width */ int linesize; /* line size, in bytes, may be different from width */
UINT8 *new_picture[3]; /* picture to be compressed */ UINT8 *new_picture[3]; /* picture to be compressed */
UINT8 *last_picture[3]; /* previous picture */ UINT8 *last_picture[3]; /* previous picture */
@ -136,6 +137,7 @@ typedef struct MpegEncContext {
/* bit rate control */ /* bit rate control */
int I_frame_bits; /* wanted number of bits per I frame */ int I_frame_bits; /* wanted number of bits per I frame */
int P_frame_bits; /* same for P frame */ int P_frame_bits; /* same for P frame */
int avg_mb_var; /* average MB variance for current frame */
INT64 wanted_bits; INT64 wanted_bits;
INT64 total_bits; INT64 total_bits;