⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ratecontrol.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Rate control for video encoders * * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * * FFmpeg 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.1 of the License, or (at your option) any later version. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file ratecontrol.c * Rate control for video encoders. */#include "avcodec.h"#include "dsputil.h"#include "ratecontrol.h"#include "mpegvideo.h"#include "eval.h"#undef NDEBUG // Always check asserts, the speed effect is far too small to disable them.#include <assert.h>#ifndef M_E#define M_E 2.718281828#endifstatic int init_pass2(MpegEncContext *s);static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num);void ff_write_pass1_stats(MpegEncContext *s){    snprintf(s->avctx->stats_out, 256, "in:%d out:%d type:%d q:%d itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d;\n",            s->current_picture_ptr->display_picture_number, s->current_picture_ptr->coded_picture_number, s->pict_type,            s->current_picture.quality, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits,            s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count, s->skip_count, s->header_bits);}static inline double qp2bits(RateControlEntry *rce, double qp){    if(qp<=0.0){        av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n");    }    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ qp;}static inline double bits2qp(RateControlEntry *rce, double bits){    if(bits<0.9){        av_log(NULL, AV_LOG_ERROR, "bits<0.9\n");    }    return rce->qscale * (double)(rce->i_tex_bits + rce->p_tex_bits+1)/ bits;}int ff_rate_control_init(MpegEncContext *s){    RateControlContext *rcc= &s->rc_context;    int i;    const char *error = NULL;    static const char * const const_names[]={        "PI",        "E",        "iTex",        "pTex",        "tex",        "mv",        "fCode",        "iCount",        "mcVar",        "var",        "isI",        "isP",        "isB",        "avgQP",        "qComp",/*        "lastIQP",        "lastPQP",        "lastBQP",        "nextNonBQP",*/        "avgIITex",        "avgPITex",        "avgPPTex",        "avgBPTex",        "avgTex",        NULL    };    static double (*func1[])(void *, double)={        (void *)bits2qp,        (void *)qp2bits,        NULL    };    static const char * const func1_names[]={        "bits2qp",        "qp2bits",        NULL    };    emms_c();#ifndef __CW32__    rcc->rc_eq_eval = ff_parse(s->avctx->rc_eq, const_names, func1, func1_names, NULL, NULL, &error);#else    rcc->rc_eq_eval = ff_parse(s->avctx->rc_eq, (const char**)const_names, func1, (const char**)func1_names, NULL, NULL, &error);#endif    if (!rcc->rc_eq_eval) {        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\": %s\n", s->avctx->rc_eq, error? error : "");        return -1;    }    for(i=0; i<5; i++){        rcc->pred[i].coeff= FF_QP2LAMBDA * 7.0;        rcc->pred[i].count= 1.0;        rcc->pred[i].decay= 0.4;        rcc->i_cplx_sum [i]=        rcc->p_cplx_sum [i]=        rcc->mv_bits_sum[i]=        rcc->qscale_sum [i]=        rcc->frame_count[i]= 1; // 1 is better because of 1/0 and such        rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;    }    rcc->buffer_index= s->avctx->rc_initial_buffer_occupancy;    if(s->flags&CODEC_FLAG_PASS2){        int i;        char *p;        /* find number of pics */        p= s->avctx->stats_in;        for(i=-1; p; i++){            p= strchr(p+1, ';');        }        i+= s->max_b_frames;        if(i<=0 || i>=INT_MAX / sizeof(RateControlEntry))            return -1;        rcc->entry = av_mallocz(i*sizeof(RateControlEntry));        rcc->num_entries= i;        /* init all to skipped p frames (with b frames we might have a not encoded frame at the end FIXME) */        for(i=0; i<rcc->num_entries; i++){            RateControlEntry *rce= &rcc->entry[i];            rce->pict_type= rce->new_pict_type=FF_P_TYPE;            rce->qscale= rce->new_qscale=FF_QP2LAMBDA * 2;            rce->misc_bits= s->mb_num + 10;            rce->mb_var_sum= s->mb_num*100;        }        /* read stats */        p= s->avctx->stats_in;        for(i=0; i<rcc->num_entries - s->max_b_frames; i++){            RateControlEntry *rce;            int picture_number;            int e;            char *next;            next= strchr(p, ';');            if(next){                (*next)=0; //sscanf in unbelievably slow on looong strings //FIXME copy / do not write                next++;            }            e= sscanf(p, " in:%d ", &picture_number);            assert(picture_number >= 0);            assert(picture_number < rcc->num_entries);            rce= &rcc->entry[picture_number];            e+=sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d skipcount:%d hbits:%d",                   &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits, &rce->mv_bits, &rce->misc_bits,                   &rce->f_code, &rce->b_code, &rce->mc_mb_var_sum, &rce->mb_var_sum, &rce->i_count, &rce->skip_count, &rce->header_bits);            if(e!=14){                av_log(s->avctx, AV_LOG_ERROR, "statistics are damaged at line %d, parser out=%d\n", i, e);                return -1;            }            p= next;        }        if(init_pass2(s) < 0) return -1;        //FIXME maybe move to end        if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {#ifdef CONFIG_LIBXVID            return ff_xvid_rate_control_init(s);#else            av_log(s->avctx, AV_LOG_ERROR, "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");            return -1;#endif        }    }    if(!(s->flags&CODEC_FLAG_PASS2)){        rcc->short_term_qsum=0.001;        rcc->short_term_qcount=0.001;        rcc->pass1_rc_eq_output_sum= 0.001;        rcc->pass1_wanted_bits=0.001;        if(s->avctx->qblur > 1.0){            av_log(s->avctx, AV_LOG_ERROR, "qblur too large\n");            return -1;        }        /* init stuff with the user specified complexity */        if(s->avctx->rc_initial_cplx){            for(i=0; i<60*30; i++){                double bits= s->avctx->rc_initial_cplx * (i/10000.0 + 1.0)*s->mb_num;                RateControlEntry rce;                double q;                if     (i%((s->gop_size+3)/4)==0) rce.pict_type= FF_I_TYPE;                else if(i%(s->max_b_frames+1))    rce.pict_type= FF_B_TYPE;                else                              rce.pict_type= FF_P_TYPE;                rce.new_pict_type= rce.pict_type;                rce.mc_mb_var_sum= bits*s->mb_num/100000;                rce.mb_var_sum   = s->mb_num;                rce.qscale   = FF_QP2LAMBDA * 2;                rce.f_code   = 2;                rce.b_code   = 1;                rce.misc_bits= 1;                if(s->pict_type== FF_I_TYPE){                    rce.i_count   = s->mb_num;                    rce.i_tex_bits= bits;                    rce.p_tex_bits= 0;                    rce.mv_bits= 0;                }else{                    rce.i_count   = 0; //FIXME we do know this approx                    rce.i_tex_bits= 0;                    rce.p_tex_bits= bits*0.9;                    rce.mv_bits= bits*0.1;                }                rcc->i_cplx_sum [rce.pict_type] += rce.i_tex_bits*rce.qscale;                rcc->p_cplx_sum [rce.pict_type] += rce.p_tex_bits*rce.qscale;                rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;                rcc->frame_count[rce.pict_type] ++;                bits= rce.i_tex_bits + rce.p_tex_bits;                q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i);                rcc->pass1_wanted_bits+= s->bit_rate/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps            }        }    }    return 0;}void ff_rate_control_uninit(MpegEncContext *s){    RateControlContext *rcc= &s->rc_context;    emms_c();    ff_eval_free(rcc->rc_eq_eval);    av_freep(&rcc->entry);#ifdef CONFIG_LIBXVID    if((s->flags&CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID)        ff_xvid_rate_control_uninit(s);#endif}int ff_vbv_update(MpegEncContext *s, int frame_size){    RateControlContext *rcc= &s->rc_context;    const double fps= 1/av_q2d(s->avctx->time_base);    const int buffer_size= s->avctx->rc_buffer_size;    const double min_rate= s->avctx->rc_min_rate/fps;    const double max_rate= s->avctx->rc_max_rate/fps;//printf("%d %f %d %f %f\n", buffer_size, rcc->buffer_index, frame_size, min_rate, max_rate);    if(buffer_size){        int left;        rcc->buffer_index-= frame_size;        if(rcc->buffer_index < 0){            av_log(s->avctx, AV_LOG_ERROR, "rc buffer underflow\n");            rcc->buffer_index= 0;        }        left= buffer_size - rcc->buffer_index - 1;        rcc->buffer_index += av_clip(left, min_rate, max_rate);        if(rcc->buffer_index > buffer_size){            int stuffing= ceil((rcc->buffer_index - buffer_size)/8);            if(stuffing < 4 && s->codec_id == CODEC_ID_MPEG4)                stuffing=4;            rcc->buffer_index -= 8*stuffing;            if(s->avctx->debug & FF_DEBUG_RC)                av_log(s->avctx, AV_LOG_DEBUG, "stuffing %d bytes\n", stuffing);            return stuffing;        }    }    return 0;}/** * modifies the bitrate curve from pass1 for one frame */static double get_qscale(MpegEncContext *s, RateControlEntry *rce, double rate_factor, int frame_num){    RateControlContext *rcc= &s->rc_context;    AVCodecContext *a= s->avctx;    double q, bits;    const int pict_type= rce->new_pict_type;    const double mb_num= s->mb_num;    int i;#ifndef __CW32__    double const_values[]={        M_PI,        M_E,        rce->i_tex_bits*rce->qscale,        rce->p_tex_bits*rce->qscale,        (rce->i_tex_bits + rce->p_tex_bits)*(double)rce->qscale,        rce->mv_bits/mb_num,        rce->pict_type == FF_B_TYPE ? (rce->f_code + rce->b_code)*0.5 : rce->f_code,        rce->i_count/mb_num,        rce->mc_mb_var_sum/mb_num,        rce->mb_var_sum/mb_num,        rce->pict_type == FF_I_TYPE,        rce->pict_type == FF_P_TYPE,        rce->pict_type == FF_B_TYPE,        rcc->qscale_sum[pict_type] / (double)rcc->frame_count[pict_type],        a->qcompress,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -