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
...@@ -458,9 +458,12 @@ int estimate_motion(MpegEncContext * s, ...@@ -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) {
......
...@@ -115,6 +115,7 @@ int MPV_common_init(MpegEncContext *s) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
...@@ -961,21 +962,11 @@ static void encode_picture(MpegEncContext *s, int picture_number) ...@@ -961,21 +962,11 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->gob_index = 4; s->gob_index = 4;
} }
for(mb_y=0; mb_y < s->mb_height; mb_y++) { /* Reset the average MB variance */
/* Put GOB header based on RTP MTU */ s->avg_mb_var = 0;
/* 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;
}
}
}
/* Estimate motion for every MB */
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
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,6 +986,24 @@ static void encode_picture(MpegEncContext *s, int picture_number) ...@@ -995,6 +986,24 @@ 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++) {
......
...@@ -60,6 +60,7 @@ typedef struct MpegEncContext { ...@@ -60,6 +60,7 @@ typedef struct MpegEncContext {
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 { ...@@ -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;
......
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