Commit a7d5d350 authored by pulento's avatar pulento

- 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.


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@294 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent e1667c47
......@@ -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) {
......
......@@ -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;
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment