📄 fame_rate_simple.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_simple.h"#include "fame_monitor.h"#define power(x,y) (exp(y*log(x)))#define quant_model(coeff, rate, act) (coeff*act/rate)#define coeff_model(quant, rate, act) (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_simple_t){ fame_rate_t_constructor(FAME_RATE(this)); FAME_OBJECT(this)->name = "simple 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; int ratio; int i;#ifdef HAS_MMX asm("emms");#endif FAME_RATE_SIMPLE(rate)->FAME_OVERLOADED(init)(rate, mb_width, mb_height, bitrate, coding, stats_list, global_stats, flags); 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_SIMPLE(rate)->P_bits = bitrate * (np + ni) / (np + ratio * ni); FAME_RATE_SIMPLE(rate)->I_bits = ratio * FAME_RATE_SIMPLE(rate)->P_bits; rate->coeff1 = 1/6.0; FAME_RATE_SIMPLE(rate)->I_coeff1 = 1;}/* 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 old_scale;#ifdef HAS_MMX asm("emms");#endif /* Update number of available bits */ switch(coding) { case 'I': rate->available += FAME_RATE_SIMPLE(rate)->I_bits; break; case 'P': rate->available += FAME_RATE_SIMPLE(rate)->P_bits; break; }; /* Common tasks */ FAME_RATE_SIMPLE(rate)->FAME_OVERLOADED(enter)(rate, ref, current, shape, coding, frame_stats); /* compute frame activity */ if (frame_stats) FAME_RATE_SIMPLE(rate)->activity = frame_stats->spatial_activity; else FAME_RATE_SIMPLE(rate)->activity = activity2(rate->ref[0], rate->current, rate->shape, rate->mb_width, rate->mb_height); /* Compute quantization scale */ old_scale = rate->global_scale; if (rate->available > 0) { switch (coding) { case 'I': rate->global_scale = quant_model(FAME_RATE_SIMPLE(rate)->I_coeff1, rate->available, FAME_RATE_SIMPLE(rate)->activity); break; case 'P': rate->global_scale = quant_model(rate->coeff1, rate->available, FAME_RATE_SIMPLE(rate)->activity); break; } } else rate->global_scale = 31; if( rate->global_scale < 2) rate->global_scale = 2; if( rate->global_scale > 31) rate->global_scale = 31; rate->global_scale = (rate->global_scale + old_scale)/2;}/* 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_SIMPLE(rate)->FAME_OVERLOADED(leave)(rate, spent); switch(rate->coding) { case 'I' : FAME_RATE_SIMPLE(rate)->I_coeff1 = coeff_model(rate->global_scale, spent, FAME_RATE_SIMPLE(rate)->activity); break; case 'P': rate->coeff1 = coeff_model(rate->global_scale, spent, FAME_RATE_SIMPLE(rate)->activity); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -