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

📄 fame_rate_1param.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
字号:
/*    libfame - Fast Assembly MPEG Encoder Library    Copyright (C) 2002 Yannick Vignon    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include <math.h>#include "fame.h"#include "fame_rate_1param.h"#include "fame_monitor.h"#define model_power 1.7#define power(x,y) (exp(y*log(x)))#define quant_model(coeff, rate, act) (exp(1.0/model_power*log(coeff*act/rate)))#define coeff_model(quant, rate, act) (exp(model_power*log(quant))*rate/act)static void rate_init(fame_rate_t *rate,		      int mb_width,		      int mb_height,		      int bitrate,		      char *coding,		      fame_frame_statistics_t *stats_list,		      fame_global_statistics_t *global_stats,		      unsigned int flags);static void rate_enter(fame_rate_t *rate,		       fame_yuv_t **ref,		       fame_yuv_t *current,		       unsigned char *shape,		       char coding,		       fame_frame_statistics_t *frame_stats);static void rate_leave(fame_rate_t *rate,		       int spent);FAME_CONSTRUCTOR(fame_rate_1param_t){  fame_rate_t_constructor(FAME_RATE(this));  FAME_OBJECT(this)->name = "one parameter rate estimation";  this->FAME_OVERLOADED(init) = FAME_RATE(this)->init;  FAME_RATE(this)->init = rate_init;  this->FAME_OVERLOADED(enter) = FAME_RATE(this)->enter;  FAME_RATE(this)->enter = rate_enter;  this->FAME_OVERLOADED(leave) = FAME_RATE(this)->leave;  FAME_RATE(this)->leave = rate_leave;  FAME_RATE(this)->flags = 0xffffffff;  return(this);}/*  rate_init                                                                *//*                                                                           *//*  Description:                                                             *//*    Initialise rate estimation.                                            *//*                                                                           *//*  Arguments:                                                               *//*    fame_rate_t *rate: the rate estimation                                 *//*    int mb_width: width in macroblocks                                     *//*    int mb_height: height in macroblocks                                   *//*                                                                           *//*  Return value:                                                            *//*    Rate.                                                                  */static void rate_init(fame_rate_t *rate,		      int mb_width,		      int mb_height,		      int bitrate,		      char *coding,		      fame_frame_statistics_t *stats_list,		      fame_global_statistics_t *global_stats,		      unsigned int flags){  int ni, np;  float ratio;  int i;  float factor;#ifdef HAS_MMX  asm("emms");#endif  FAME_RATE_1PARAM(rate)->FAME_OVERLOADED(init)(rate,					       mb_width,					       mb_height,					       bitrate,					       coding,					       stats_list,					       global_stats,					       flags);  if (rate->flags & FAME_RATE_SECOND_PASS) {    rate->stats_list = stats_list;    factor = 0;    ni = np = 0;    rate->total_frames= global_stats->total_frames;    for (i=0; i < global_stats->total_frames; i++) {      if(stats_list[i].spatial_activity)	factor += exp(FAME_RATE_2PASS_POWER*log(stats_list[i].spatial_activity));      if(stats_list[i].coding == 'I') ni++;      if(stats_list[i].coding == 'P') np++;    }    ratio = 1; /* change to allocate more bits for scene changes */    FAME_RATE_1PARAM(rate)->global_factor_P = (factor/(bitrate*global_stats->total_frames)) *  (np + ratio*ni) / (float)(ni + np);    FAME_RATE_1PARAM(rate)->global_factor_I = FAME_RATE_1PARAM(rate)->global_factor_P / ratio;  }   else {    ni = np = 0;    for(i = 0; i < strlen(coding); i++) {      switch(coding[i]) {      case 'I': ni++; break;      case 'P': np++; break;      case 'A': np++; break;      }    }    ratio = 1;    FAME_RATE_1PARAM(rate)->P_bits = bitrate * (np + ni) / (np + ratio * ni);    FAME_RATE_1PARAM(rate)->I_bits = ratio * FAME_RATE_1PARAM(rate)->P_bits;  }    rate->coeff1 = 1.5;  rate->coeff2 = 2.75;  FAME_RATE_1PARAM(rate)->coeff_index = 0;  FAME_RATE_1PARAM(rate)->coeff_I_index = 0;  FAME_RATE_1PARAM(rate)->I_number = 0;  FAME_RATE_1PARAM(rate)->P_number = 0;}/*  rate_enter                                                               *//*                                                                           *//*  Description:                                                             *//*    Prepare for a new frame.                                               *//*                                                                           *//*  Arguments:                                                               *//*    fame_rate_t *rate: the rate estimation                                 *//*    fame_yuv_t **ref: the reference frames (half-pel)                      *//*    fame_yuv_t *current: the current frame                                 *//*    unsigned char *shape: the current shape                                *//*                                                                           *//*  Return value:                                                            *//*    Rate.                                                                  */static void rate_enter(struct _fame_rate_t_ *rate,		       fame_yuv_t **ref,		       fame_yuv_t *current,		       unsigned char *shape,		       char coding,		       fame_frame_statistics_t *frame_stats){  int avail, old_scale, old_coding;  int i, window;  float coeff1;#ifdef HAS_MMX  asm("emms");#endif    /* Update number of available bits */  if (rate->flags & FAME_RATE_SECOND_PASS) {    if (rate->available > 0)       avail = rate->available/4;    else avail = 5*rate->available/6;    switch(coding) {    case 'I': rate->available += exp(FAME_RATE_2PASS_POWER*log(frame_stats->spatial_activity))/FAME_RATE_1PARAM(rate)->global_factor_I;    case 'P': rate->available += exp(FAME_RATE_2PASS_POWER*log(frame_stats->spatial_activity))/FAME_RATE_1PARAM(rate)->global_factor_P;    }  }  else {    avail = rate->available/2;    switch(coding) {    case 'I': rate->available += FAME_RATE_1PARAM(rate)->I_bits; break;    case 'P': rate->available += FAME_RATE_1PARAM(rate)->P_bits; break;    };  }  rate->available -= avail;  old_coding = rate->coding;  /* Common tasks */  FAME_RATE_1PARAM(rate)->FAME_OVERLOADED(enter)(rate,						 ref,						 current,						 shape,						 coding,						 frame_stats);  /* compute frame activity */  switch (rate->coding) {  case 'I':    FAME_RATE_1PARAM(rate)->activity = activity(rate->current,						rate->shape,						rate->mb_width,						rate->mb_height);#ifdef HAS_MMX  asm("emms");#endif    break;  case 'P':    if (frame_stats)       FAME_RATE_1PARAM(rate)->activity = frame_stats->spatial_activity;    else FAME_RATE_1PARAM(rate)->activity = activity2(rate->ref[0],						      rate->current,						      rate->shape,						      rate->mb_width,						      rate->mb_height);    break;  }  /* Update model parameter */  /* TODO: update window size based on activity change */  coeff1 = 0;  window = 0;  switch (rate->coding) {  case 'I' :    window = fame_min(FAME_RATE_WINDOW_SIZE, 		      FAME_RATE_1PARAM(rate)->I_number);     for(i=0; i<window; i++)       coeff1 += FAME_RATE_1PARAM(rate)->old_I_coeff1[i];    if (window == 0) coeff1 = rate->coeff2;    rate->coeff2 = coeff1;    FAME_RATE_1PARAM(rate)->P_number = 0;    break;  case 'P' :    window = fame_min(FAME_RATE_WINDOW_SIZE, 		      FAME_RATE_1PARAM(rate)->P_number);    for(i=0; i<window; i++)       coeff1 += FAME_RATE_1PARAM(rate)->old_coeff1[i];    if (window == 0) coeff1 = rate->coeff1;    rate->coeff1 = coeff1;    break;  }  if (window != 0)     coeff1 = coeff1/window;  /* Compute quantization scale */  old_scale = rate->global_scale;  if (rate->available > 0) {     rate->global_scale =quant_model(coeff1,				     rate->available,				     FAME_RATE_1PARAM(rate)->activity);  }  else    rate->global_scale = 31;     if(rate->coding == old_coding) {    /* adaptive quant scale variation */    if(rate->global_scale > old_scale+FAME_RATE_WINDOW_SIZE-window+2)      rate->global_scale = old_scale+FAME_RATE_WINDOW_SIZE-window+2;    if(rate->global_scale < old_scale-FAME_RATE_WINDOW_SIZE+window-2)      rate->global_scale = old_scale-FAME_RATE_WINDOW_SIZE+window-2;  }  //rate->global_scale = (rate->global_scale + old_scale)/2;  if( rate->global_scale < 2)  rate->global_scale = 2;  if( rate->global_scale > 31)  rate->global_scale = 31;  rate->available += avail;  }/*  rate_leave                                                               *//*                                                                           *//*  Description:                                                             *//*    Finish estimating a frame.                                             *//*                                                                           *//*  Arguments:                                                               *//*    fame_rate_t *rate: the rate estimation                                 *//*                                                                           *//*  Return value:                                                            *//*    Rate.                                                                  */static void rate_leave(fame_rate_t *rate, int spent){  #ifdef HAS_MMX  asm("emms");#endif  FAME_RATE_1PARAM(rate)->FAME_OVERLOADED(leave)(rate,						 spent);  switch(rate->coding) {  case 'I' :      FAME_RATE_1PARAM(rate)->old_I_coeff1[FAME_RATE_1PARAM(rate)->coeff_I_index] =      coeff_model(rate->global_scale,		  spent,		  FAME_RATE_1PARAM(rate)->activity);    FAME_RATE_1PARAM(rate)->coeff_I_index++;    if (FAME_RATE_1PARAM(rate)->coeff_I_index >= FAME_RATE_WINDOW_SIZE)       FAME_RATE_1PARAM(rate)->coeff_I_index = 0;    FAME_RATE_1PARAM(rate)->I_number++;    break;  case 'P':     FAME_RATE_1PARAM(rate)->old_coeff1[FAME_RATE_1PARAM(rate)->coeff_index] =      coeff_model(rate->global_scale,		  spent,		  FAME_RATE_1PARAM(rate)->activity);    FAME_RATE_1PARAM(rate)->coeff_index++;    if (FAME_RATE_1PARAM(rate)->coeff_index >= FAME_RATE_WINDOW_SIZE)       FAME_RATE_1PARAM(rate)->coeff_index = 0;    FAME_RATE_1PARAM(rate)->P_number++;    break;  }}

⌨️ 快捷键说明

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