Commit 3aa102be authored by Michael Niedermayer's avatar Michael Niedermayer

new ratecontrol code

Originally committed as revision 862 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 7806197d
......@@ -80,14 +80,28 @@ static AVOutputFormat *file_oformat;
static int frame_width = 160;
static int frame_height = 128;
static int frame_rate = 25 * FRAME_RATE_BASE;
static int video_bit_rate = 200000;
static int video_bit_rate_tolerance = 200000;
static int video_bit_rate = 200*1000;
static int video_bit_rate_tolerance = 4000*1000;
static int video_qscale = 0;
static int video_qmin = 3;
static int video_qmax = 15;
static int video_qmin = 2;
static int video_qmax = 31;
static int video_qdiff = 3;
static float video_qblur = 0.5;
static float video_qcomp = 0.5;
static float video_rc_qsquish=1.0;
static float video_rc_qmod_amp=0;
static int video_rc_qmod_freq=0;
static char *video_rc_override_string=NULL;
static char *video_rc_eq="tex^qComp";
static int video_rc_buffer_size=0;
static float video_rc_buffer_aggressivity=1.0;
static int video_rc_max_rate=0;
static int video_rc_min_rate=0;
static float video_rc_initial_cplx=0;
static float video_b_qfactor = 1.25;
static float video_b_qoffset = 1.25;
static float video_i_qfactor = 0.8;
static float video_i_qoffset = 0.0;
static int me_method = 0;
static int video_disable = 0;
static int video_codec_id = CODEC_ID_NONE;
......@@ -1334,6 +1348,22 @@ void opt_video_bitrate_tolerance(const char *arg)
video_bit_rate_tolerance = atoi(arg) * 1000;
}
void opt_video_bitrate_max(const char *arg)
{
video_rc_max_rate = atoi(arg) * 1000;
}
void opt_video_bitrate_min(const char *arg)
{
video_rc_min_rate = atoi(arg) * 1000;
}
void opt_video_rc_eq(char *arg)
{
video_rc_eq = arg;
}
void opt_workaround_bugs(const char *arg)
{
workaround_bugs = atoi(arg);
......@@ -1754,6 +1784,14 @@ void opt_output_file(const char *filename)
video_enc->max_qdiff = video_qdiff;
video_enc->qblur = video_qblur;
video_enc->qcompress = video_qcomp;
video_enc->rc_eq = video_rc_eq;
video_enc->rc_max_rate = video_rc_max_rate;
video_enc->rc_min_rate = video_rc_min_rate;
video_enc->rc_buffer_size = video_rc_buffer_size;
video_enc->i_quant_factor = video_i_qfactor;
video_enc->b_quant_factor = video_b_qfactor;
video_enc->i_quant_offset = video_i_qoffset;
video_enc->b_quant_offset = video_b_qoffset;
if (do_psnr)
video_enc->get_psnr = 1;
......@@ -2097,7 +2135,10 @@ const OptionDef options[] = {
{ "qdiff", HAS_ARG | OPT_EXPERT, {(void*)opt_qdiff}, "max difference between the quantiser scale (VBR)", "q" },
{ "qblur", HAS_ARG | OPT_EXPERT, {(void*)opt_qblur}, "video quantiser scale blur (VBR)", "blur" },
{ "qcomp", HAS_ARG | OPT_EXPERT, {(void*)opt_qcomp}, "video quantiser scale compression (VBR)", "compression" },
{ "rc_eq", HAS_ARG | OPT_EXPERT, {(void*)opt_video_rc_eq}, "", "equation" },
{ "bt", HAS_ARG, {(void*)opt_video_bitrate_tolerance}, "set video bitrate tolerance (in kbit/s)", "tolerance" },
{ "maxrate", HAS_ARG, {(void*)opt_video_bitrate_max}, "set max video bitrate tolerance (in kbit/s)", "bitrate" },
{ "minrate", HAS_ARG, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
{ "vd", HAS_ARG | OPT_EXPERT, {(void*)opt_video_device}, "set video grab device", "device" },
{ "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec", "codec" },
{ "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method",
......
......@@ -15,7 +15,7 @@ OBJS= common.o utils.o mem.o allcodecs.o \
mpegaudio.o ac3enc.o mjpeg.o resample.o dsputil.o \
motion_est.o imgconvert.o imgresample.o msmpeg4.o \
mpeg12.o h263dec.o svq1.o rv10.o mpegaudiodec.o pcm.o simple_idct.o \
ratecontrol.o adpcm.o
ratecontrol.o adpcm.o eval.o
ASM_OBJS=
# currently using liba52 for ac3 decoding
......
......@@ -32,6 +32,8 @@ void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
void (*gmc1)(UINT8 *dst, UINT8 *src, int srcStride, int h, int x16, int y16, int rounder);
void (*clear_blocks)(DCTELEM *blocks);
int (*pix_sum)(UINT8 * pix, int line_size);
int (*pix_norm1)(UINT8 * pix, int line_size);
op_pixels_abs_func pix_abs16x16;
op_pixels_abs_func pix_abs16x16_x2;
......@@ -159,6 +161,52 @@ static void build_zigzag_end(void)
}
}
int pix_sum_c(UINT8 * pix, int line_size)
{
int s, i, j;
s = 0;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j += 8) {
s += pix[0];
s += pix[1];
s += pix[2];
s += pix[3];
s += pix[4];
s += pix[5];
s += pix[6];
s += pix[7];
pix += 8;
}
pix += line_size - 16;
}
return s;
}
int pix_norm1_c(UINT8 * pix, int line_size)
{
int s, i, j;
UINT32 *sq = squareTbl + 256;
s = 0;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j += 8) {
s += sq[pix[0]];
s += sq[pix[1]];
s += sq[pix[2]];
s += sq[pix[3]];
s += sq[pix[4]];
s += sq[pix[5]];
s += sq[pix[6]];
s += sq[pix[7]];
pix += 8;
}
pix += line_size - 16;
}
return s;
}
void get_pixels_c(DCTELEM *restrict block, const UINT8 *pixels, int line_size)
{
int i;
......@@ -241,7 +289,6 @@ void add_pixels_clamped_c(const DCTELEM *block, UINT8 *restrict pixels,
block += 8;
}
}
#if 0
#define PIXOP2(OPNAME, OP) \
......@@ -569,7 +616,6 @@ void (*OPNAME ## _no_rnd_pixels_tab[4])(uint8_t *block, const uint8_t *pixels, i
};
#define op_avg(a, b) a = ( ((a)|(b)) - ((((a)^(b))&0xFEFEFEFEUL)>>1) )
#endif
#define op_put(a, b) a = b
PIXOP2(avg, op_avg)
......@@ -684,8 +730,11 @@ void (*OPNAME ## _pixels_tab[4])(BTYPE *block, const UINT8 *pixels, int line_siz
#define op_avg(a, b) a = avg2(a, b)
#define op_sub(a, b) a -= b
#define op_put(a, b) a = b
PIXOP(DCTELEM, sub, op_sub, 8)
PIXOP(uint8_t, avg, op_avg, line_size)
PIXOP(uint8_t, put, op_put, line_size)
/* not rounding primitives */
#undef avg2
......@@ -693,6 +742,8 @@ PIXOP(DCTELEM, sub, op_sub, 8)
#define avg2(a,b) ((a+b)>>1)
#define avg4(a,b,c,d) ((a+b+c+d+1)>>2)
PIXOP(uint8_t, avg_no_rnd, op_avg, line_size)
PIXOP(uint8_t, put_no_rnd, op_put, line_size)
/* motion estimation */
#undef avg2
......@@ -1261,6 +1312,8 @@ void dsputil_init(void)
add_pixels_clamped = add_pixels_clamped_c;
gmc1= gmc1_c;
clear_blocks= clear_blocks_c;
pix_sum= pix_sum_c;
pix_norm1= pix_norm1_c;
pix_abs16x16 = pix_abs16x16_c;
pix_abs16x16_x2 = pix_abs16x16_x2_c;
......
......@@ -62,6 +62,9 @@ extern void (*put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_
extern void (*add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);
extern void (*gmc1)(UINT8 *dst, UINT8 *src, int srcStride, int h, int x16, int y16, int rounder);
extern void (*clear_blocks)(DCTELEM *blocks);
extern int (*pix_sum)(UINT8 * pix, int line_size);
extern int (*pix_norm1)(UINT8 * pix, int line_size);
void get_pixels_c(DCTELEM *block, const UINT8 *pixels, int line_size);
......
/*
* simple arithmetic expression evaluator
*
* Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* see http://joe.hotchkiss.com/programming/eval/eval.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define STACK_SIZE 100
typedef struct Parser{
double stack[STACK_SIZE];
int stack_index;
char *s;
double *const_value;
char **const_name; // NULL terminated
double (**func1)(void *, double a); // NULL terminated
char **func1_name; // NULL terminated
double (**func2)(void *, double a, double b); // NULL terminated
char **func2_name; // NULL terminated
void *opaque;
} Parser;
static void evalExpression(Parser *p);
static void push(Parser *p, double d){
if(p->stack_index+1>= STACK_SIZE){
fprintf(stderr, "stack overflow in the parser\n");
return;
}
p->stack[ p->stack_index++ ]= d;
//printf("push %f\n", d); fflush(stdout);
}
static double pop(Parser *p){
if(p->stack_index<=0){
fprintf(stderr, "stack underflow in the parser\n");
return NAN;
}
//printf("pop\n"); fflush(stdout);
return p->stack[ --p->stack_index ];
}
static int strmatch(char *s, char *prefix){
int i;
for(i=0; prefix[i]; i++){
if(prefix[i] != s[i]) return 0;
}
return 1;
}
static void evalPrimary(Parser *p){
double d, d2=NAN;
char *next= p->s;
int i;
/* number */
d= strtod(p->s, &next);
if(next != p->s){
push(p, d);
p->s= next;
return;
}
/* named constants */
for(i=0; p->const_name[i]; i++){
if(strmatch(p->s, p->const_name[i])){
push(p, p->const_value[i]);
p->s+= strlen(p->const_name[i]);
return;
}
}
p->s= strchr(p->s, '(');
if(p->s==NULL){
fprintf(stderr, "Parser: missing ( in \"%s\"\n", next);
return;
}
p->s++; // "("
evalExpression(p);
d= pop(p);
p->s++; // ")" or ","
if(p->s[-1]== ','){
evalExpression(p);
d2= pop(p);
p->s++; // ")"
}
if( strmatch(next, "sinh" ) ) d= sinh(d);
else if( strmatch(next, "cosh" ) ) d= cosh(d);
else if( strmatch(next, "tanh" ) ) d= tanh(d);
else if( strmatch(next, "sin" ) ) d= sin(d);
else if( strmatch(next, "cos" ) ) d= cos(d);
else if( strmatch(next, "tan" ) ) d= tan(d);
else if( strmatch(next, "exp" ) ) d= exp(d);
else if( strmatch(next, "log" ) ) d= log(d);
else if( strmatch(next, "squish") ) d= 1/(1+exp(4*d));
else if( strmatch(next, "gauss" ) ) d= exp(-d*d/2)/sqrt(2*M_PI);
else if( strmatch(next, "abs" ) ) d= abs(d);
else if( strmatch(next, "max" ) ) d= d > d2 ? d : d2;
else if( strmatch(next, "min" ) ) d= d < d2 ? d : d2;
else if( strmatch(next, "gt" ) ) d= d > d2 ? 1.0 : 0.0;
else if( strmatch(next, "lt" ) ) d= d > d2 ? 0.0 : 1.0;
else if( strmatch(next, "eq" ) ) d= d == d2 ? 1.0 : 0.0;
// else if( strmatch(next, "l1" ) ) d= 1 + d2*(d - 1);
// else if( strmatch(next, "sq01" ) ) d= (d >= 0.0 && d <=1.0) ? 1.0 : 0.0;
else{
int error=1;
for(i=0; p->func1_name && p->func1_name[i]; i++){
if(strmatch(next, p->func1_name[i])){
d= p->func1[i](p->opaque, d);
error=0;
break;
}
}
for(i=0; p->func2_name && p->func2_name[i]; i++){
if(strmatch(next, p->func2_name[i])){
d= p->func2[i](p->opaque, d, d2);
error=0;
break;
}
}
if(error){
fprintf(stderr, "Parser: unknown function in \"%s\"\n", next);
return;
}
}
if(p->s[-1]!= ')'){
fprintf(stderr, "Parser: missing ) in \"%s\"\n", next);
return;
}
push(p, d);
}
static void evalPow(Parser *p){
int neg= 0;
if(p->s[0]=='+') p->s++;
if(p->s[0]=='-'){
neg= 1;
p->s++;
}
if(p->s[0]=='('){
p->s++;;
evalExpression(p);
if(p->s[0]!=')')
fprintf(stderr, "Parser: missing )\n");
p->s++;
}else{
evalPrimary(p);
}
if(neg) push(p, -pop(p));
}
static void evalFactor(Parser *p){
evalPow(p);
while(p->s[0]=='^'){
double d;
p->s++;
evalPow(p);
d= pop(p);
push(p, pow(pop(p), d));
}
}
static void evalTerm(Parser *p){
evalFactor(p);
while(p->s[0]=='*' || p->s[0]=='/'){
int inv= p->s[0]=='/';
double d;
p->s++;
evalFactor(p);
d= pop(p);
if(inv) d= 1.0/d;
push(p, d * pop(p));
}
}
static void evalExpression(Parser *p){
evalTerm(p);
while(p->s[0]=='+' || p->s[0]=='-'){
int sign= p->s[0]=='-';
double d;
p->s++;
evalTerm(p);
d= pop(p);
if(sign) d= -d;
push(p, d + pop(p));
}
}
double ff_eval(char *s, double *const_value, char **const_name,
double (**func1)(void *, double), char **func1_name,
double (**func2)(void *, double, double), char **func2_name,
void *opaque){
Parser p;
p.stack_index=0;
p.s= s;
p.const_value= const_value;
p.const_name = const_name;
p.func1 = func1;
p.func1_name = func1_name;
p.func2 = func2;
p.func2_name = func2_name;
p.opaque = opaque;
evalExpression(&p);
return pop(&p);
}
......@@ -41,28 +41,6 @@
#define P_MV1 P[9]
static int pix_sum(UINT8 * pix, int line_size)
{
int s, i, j;
s = 0;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j += 8) {
s += pix[0];
s += pix[1];
s += pix[2];
s += pix[3];
s += pix[4];
s += pix[5];
s += pix[6];
s += pix[7];
pix += 8;
}
pix += line_size - 16;
}
return s;
}
static int pix_dev(UINT8 * pix, int line_size, int mean)
{
int s, i, j;
......@@ -85,29 +63,6 @@ static int pix_dev(UINT8 * pix, int line_size, int mean)
return s;
}
static int pix_norm1(UINT8 * pix, int line_size)
{
int s, i, j;
UINT32 *sq = squareTbl + 256;
s = 0;
for (i = 0; i < 16; i++) {
for (j = 0; j < 16; j += 8) {
s += sq[pix[0]];
s += sq[pix[1]];
s += sq[pix[2]];
s += sq[pix[3]];
s += sq[pix[4]];
s += sq[pix[5]];
s += sq[pix[6]];
s += sq[pix[7]];
pix += 8;
}
pix += line_size - 16;
}
return s;
}
static int pix_norm(UINT8 * pix1, UINT8 * pix2, int line_size)
{
int s, i, j;
......@@ -1578,9 +1533,7 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
fbmin= bidir_refine(s, mb_x, mb_y);
if(s->flags&CODEC_FLAG_HQ){
type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT;
}else{
{
int score= dmin;
type=MB_TYPE_DIRECT;
......@@ -1596,9 +1549,15 @@ void ff_estimate_b_frame_motion(MpegEncContext * s,
score=fbmin;
type= MB_TYPE_BIDIR;
}
score= (score*score)>>8;
s->mc_mb_var_sum += score;
s->mc_mb_var[mb_y*s->mb_width + mb_x] = score;
s->mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD
}
if(s->flags&CODEC_FLAG_HQ){
type= MB_TYPE_FORWARD | MB_TYPE_BACKWARD | MB_TYPE_BIDIR | MB_TYPE_DIRECT; //FIXME something smarter
}
/*
{
static int count=0;
......
......@@ -226,6 +226,8 @@ int MPV_common_init(MpegEncContext *s)
CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE);
CHECKED_ALLOCZ( s->pb2_buffer, PB_BUFFER_SIZE);
}
CHECKED_ALLOCZ(s->avctx->stats_out, 256);
}
if (s->out_format == FMT_H263 || s->encoding) {
......@@ -328,7 +330,8 @@ void MPV_common_end(MpegEncContext *s)
av_freep(&s->pb2_buffer);
av_freep(&s->edge_emu_buffer);
av_freep(&s->non_b_mv4_table);
av_freep(&s->avctx->stats_out);
for(i=0;i<3;i++) {
int j;
if(!(s->flags&CODEC_FLAG_DR1)){
......@@ -377,13 +380,10 @@ int MPV_encode_init(AVCodecContext *avctx)
s->max_qdiff= avctx->max_qdiff;
s->qcompress= avctx->qcompress;
s->qblur= avctx->qblur;
s->b_quant_factor= avctx->b_quant_factor;
s->b_quant_offset= avctx->b_quant_offset;
s->avctx = avctx;
s->aspect_ratio_info= avctx->aspect_ratio_info;
s->flags= avctx->flags;
s->max_b_frames= avctx->max_b_frames;
s->rc_strategy= avctx->rc_strategy;
s->b_frame_strategy= avctx->b_frame_strategy;
s->codec_id= avctx->codec->id;
s->luma_elim_threshold = avctx->luma_elim_threshold;
......@@ -678,7 +678,6 @@ void MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
avctx->dr_opaque_frame= s->next_dr_opaque;
}
}
/* set dequantizer, we cant do it during init as it might change for mpeg4
and we cant do it in the header decode as init isnt called for mpeg4 there yet */
if(s->out_format == FMT_H263){
......@@ -703,10 +702,9 @@ void MPV_frame_end(MpegEncContext *s)
}
emms_c();
s->last_pict_type = s->pict_type;
if(s->pict_type!=B_TYPE){
s->last_non_b_pict_type= s->pict_type;
s->last_non_b_qscale= s->qscale;
s->last_non_b_mc_mb_var= s->mc_mb_var_sum;
s->num_available_buffers++;
if(s->num_available_buffers>2) s->num_available_buffers= 2;
}
......@@ -873,13 +871,21 @@ int MPV_encode_picture(AVCodecContext *avctx,
flush_put_bits(&s->pb);
s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8;
if(s->pict_type==B_TYPE) s->pb_frame_bits+= s->frame_bits;
else s->pb_frame_bits= s->frame_bits;
s->total_bits += s->frame_bits;
avctx->frame_bits = s->frame_bits;
//printf("fcode: %d, type: %d, head: %d, mv: %d, misc: %d, frame: %d, itex: %d, ptex: %d\n",
//s->f_code, avctx->key_frame, s->header_bits, s->mv_bits, s->misc_bits, s->frame_bits, s->i_tex_bits, s->p_tex_bits);
#if 0 //dump some stats to stats.txt for testing/debuging
if(s->max_b_frames==0)
{
static FILE *f=NULL;
if(!f) f= fopen("stats.txt", "wb");
get_psnr(pict->data, s->current_picture,
pict->linesize, s->linesize, avctx);
fprintf(f, "%7d, %7d, %2.4f\n", pbBufPtr(&s->pb) - s->pb.buf, s->qscale, avctx->psnr_y);
}
#endif
if (avctx->get_psnr) {
/* At this point pict->data should have the original frame */
......@@ -2010,6 +2016,25 @@ static void encode_picture(MpegEncContext *s, int picture_number)
memset(s->motion_val[0], 0, sizeof(INT16)*(s->mb_width*2 + 2)*(s->mb_height*2 + 2)*2);
memset(s->p_mv_table , 0, sizeof(INT16)*(s->mb_width+2)*(s->mb_height+2)*2);
memset(s->mb_type , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height);
if(!s->fixed_qscale){
/* finding spatial complexity for I-frame rate control */
for(mb_y=0; mb_y < s->mb_height; mb_y++) {
for(mb_x=0; mb_x < s->mb_width; mb_x++) {
int xx = mb_x * 16;
int yy = mb_y * 16;
uint8_t *pix = s->new_picture[0] + (yy * s->linesize) + xx;
int varc;
int sum = pix_sum(pix, s->linesize);
sum= (sum+8)>>4;
varc = (pix_norm1(pix, s->linesize) - sum*sum + 500 + 128)>>8;
s->mb_var[s->mb_width * mb_y + mb_x] = varc;
s->mb_var_sum += varc;
}
}
}
}
if(s->scene_change_score > 0 && s->pict_type == P_TYPE){
s->pict_type= I_TYPE;
......@@ -2018,7 +2043,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->input_pict_type= I_TYPE;
s->input_picture_in_gop_number=0;
}
//printf("Scene change detected, encoding as I Frame\n");
//printf("Scene change detected, encoding as I Frame %d %d\n", s->mb_var_sum, s->mc_mb_var_sum);
}
if(s->pict_type==P_TYPE || s->pict_type==S_TYPE)
......@@ -2037,9 +2062,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
//printf("f_code %d ///\n", s->f_code);
// printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);
if(s->flags&CODEC_FLAG_PASS2)
s->qscale = ff_rate_estimate_qscale_pass2(s);
else if (!s->fixed_qscale)
if (!s->fixed_qscale)
s->qscale = ff_rate_estimate_qscale(s);
if (s->out_format == FMT_MJPEG) {
......@@ -2675,7 +2698,7 @@ void ff_conceal_past_errors(MpegEncContext *s, int unknown_pos)
int i, intra_count=0, inter_count=0;
int intra_conceal= s->msmpeg4_version ? 50 : 50; //FIXME finetune
int inter_conceal= s->msmpeg4_version ? 50 : 50;
// for last block
if(mb_x>=s->mb_width) mb_x= s->mb_width -1;
if(mb_y>=s->mb_height) mb_y= s->mb_height-1;
......
......@@ -61,12 +61,34 @@ typedef struct RateControlEntry{
UINT64 expected_bits;
int new_pict_type;
float new_qscale;
int mc_mb_var_sum;
int mb_var_sum;
int i_count;
int f_code;
int b_code;
}RateControlEntry;
typedef struct RateControlContext{
FILE *stats_file;
int num_entries;
int num_entries; /* number of RateControlEntries */
RateControlEntry *entry;
int buffer_index; /* amount of bits in the video/audio buffer */
Predictor pred[5];
double short_term_qsum; /* sum of recent qscales */
double short_term_qcount; /* count of recent qscales */
double pass1_bits; /* bits outputted by the pass1 code (including complexity init) */
double pass1_wanted_bits; /* bits which should have been outputed by the pass1 code (including complexity init) */
double last_qscale;
double last_qscale_for[5]; /* last qscale for a specific pict type */
double next_non_b_qscale;
double next_p_qscale;
int last_mc_mb_var_sum;
int last_mb_var_sum;
UINT64 i_cplx_sum[5];
UINT64 p_cplx_sum[5];
UINT64 mv_bits_sum[5];
UINT64 qscale_sum[5];
int frame_count[5];
}RateControlContext;
typedef struct ReorderBuffer{
......@@ -107,9 +129,6 @@ typedef struct MpegEncContext {
int flags; /* AVCodecContext.flags (HQ, MV4, ...) */
int force_input_type;/* 0= no force, otherwise I_TYPE, P_TYPE, ... */
int max_b_frames; /* max number of b-frames for encoding */
float b_quant_factor;/* qscale factor between ips and b frames */
float b_quant_offset;/* qscale offset between ips and b frames */
int rc_strategy;
int b_frame_strategy;
int luma_elim_threshold;
int chroma_elim_threshold;
......@@ -170,8 +189,8 @@ typedef struct MpegEncContext {
int input_pict_type; /* pict_type prior to reordering of frames */
int force_type; /* 0= no force, otherwise I_TYPE, P_TYPE, ... */
int qscale; /* QP */
int last_non_b_qscale; /* QP of last non b frame used for b frame qscale*/
int pict_type; /* I_TYPE, P_TYPE, B_TYPE, ... */
int last_pict_type;
int last_non_b_pict_type; /* used for mpeg4 gmc b-frames & ratecontrol */
int frame_rate_index;
/* motion compensation */
......@@ -271,18 +290,10 @@ typedef struct MpegEncContext {
int I_frame_bits; //FIXME used in mpeg12 ...
int mb_var_sum; /* sum of MB variance for current frame */
int mc_mb_var_sum; /* motion compensated MB variance for current frame */
int last_non_b_mc_mb_var;/* motion compensated MB variance for last non b frame */
INT64 wanted_bits;
INT64 total_bits;
int frame_bits; /* bits used for the current frame */
int pb_frame_bits; /* bits of the last b...bp group */
Predictor i_pred;
Predictor p_pred;
double qsum; /* sum of qscales */
double qcount; /* count of qscales */
double short_term_qsum; /* sum of recent qscales */
double short_term_qcount; /* count of recent qscales */
RateControlContext rc_context;
RateControlContext rc_context; // contains stuff only accessed in ratecontrol.c
/* statistics, used for 2-pass encoding */
int mv_bits;
......@@ -590,5 +601,10 @@ int ff_rate_estimate_qscale(MpegEncContext *s);
int ff_rate_estimate_qscale_pass2(MpegEncContext *s);
void ff_write_pass1_stats(MpegEncContext *s);
void ff_rate_control_uninit(MpegEncContext *s);
double ff_eval(char *s, double *const_value, char **const_name,
double (**func1)(void *, double), char **func1_name,
double (**func2)(void *, double, double), char **func2_name,
void *opaque);
#endif /* AVCODEC_MPEGVIDEO_H */
This diff is collapsed.
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