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

📄 plugin_2pass2.c

📁 这是一个压缩解压包,用C语言进行编程的,里面有详细的源代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * *  XviD Bit Rate Controller Library *  - VBR 2 pass bitrate controller implementation - * *  Copyright (C)      2002 Foxer <email?> *                     2002 Dirk Knop <dknop@gwdg.de> *                2002-2003 Edouard Gomez <ed.gomez@free.fr> *                     2003 Pete Ross <pross@xvid.org> * *  This curve treatment algorithm is the one originally implemented by Foxer *  and tuned by Dirk Knop for the XviD vfw frontend. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program 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 General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * $Id: plugin_2pass2.c,v 1.7 2005/03/27 03:59:42 suxen_drol Exp $ * *****************************************************************************/#define BQUANT_PRESCALE#undef COMPENSATE_FORMULA/* forces second pass not to be bigger than first */#undef PASS_SMALLER/* automatically alters overflow controls (strength and improvement/degradation)	to fight most common problems without user's knowladge */#define SMART_OVERFLOW_SETTING#include <stdio.h>#include <math.h>#include <limits.h>#include "../xvid.h"#include "../image/image.h"/***************************************************************************** * Some default settings ****************************************************************************/#define DEFAULT_KEYFRAME_BOOST 0#define DEFAULT_OVERFLOW_CONTROL_STRENGTH 10#define DEFAULT_CURVE_COMPRESSION_HIGH 0#define DEFAULT_CURVE_COMPRESSION_LOW 0#define DEFAULT_MAX_OVERFLOW_IMPROVEMENT 10#define DEFAULT_MAX_OVERFLOW_DEGRADATION 10/* Keyframe settings */#define DEFAULT_KFREDUCTION 20#define DEFAULT_KFTHRESHOLD 1/***************************************************************************** * Some default constants (can be tuned) ****************************************************************************//* Specify the invariant part of the headers bits (header+MV) * as  hlength/cst */#define INVARIANT_HEADER_PART_IVOP 1 /* factor 1.0f   */#define INVARIANT_HEADER_PART_PVOP 2 /* factor 0.5f   */#define INVARIANT_HEADER_PART_BVOP 8 /* factor 0.125f *//***************************************************************************** * Structures ****************************************************************************//* Statistics */typedef struct {	int type;               /* first pass type */	int quant;              /* first pass quant */	int blks[3];            /* k,m,y blks */	int length;             /* first pass length */	int invariant;          /* what we assume as being invariant between the two passes, it's a sub part of header + MV bits */	int scaled_length;      /* scaled length */	int desired_length;     /* desired length; calculated during encoding */	int error;	int zone_mode;   /* XVID_ZONE_xxx */	double weight;} twopass_stat_t;/* Context struct */typedef struct{	xvid_plugin_2pass2_t param;	/*----------------------------------	 * constant statistical data	 *--------------------------------*/	/* Number of frames of the sequence */	int num_frames;	/* Number of Intra frames of the sequence */	int num_keyframes;	/* Target filesize to reach */	uint64_t target;	/* Count of each frame types */	int count[3];	/* Total length of each frame types (1st pass) */	uint64_t tot_length[3];	uint64_t tot_invariant[3];	/* Average length of each frame types (used first for 1st pass data and	 * then for scaled averages */	double avg_length[3];	/* Minimum frame length allowed for each frame type */	int min_length[3];	/* Total bytes per frame type once the curve has been scaled	 * NB: advanced parameters do not change this value. This field	 *     represents the total scaled w/o any advanced settings */	uint64_t tot_scaled_length[3];	/* Maximum observed frame size observed during the first pass, the RC	 * will try tp force all frame sizes in the second pass to be under that	 * limit */	int max_length;	/*----------------------------------	 * Zones statistical data	 *--------------------------------*/	/* Total length used by XVID_ZONE_QUANT zones */	uint64_t tot_quant;	uint64_t tot_quant_invariant;	/* Holds the total amount of frame bytes, zone weighted (only scalable	 * part of frame bytes) */	uint64_t tot_weighted;	/*----------------------------------	 * Advanced settings helper ratios	 *--------------------------------*/	/* This the ratio that has to be applied to all p/b frames in order	 * to reserve/retrieve bits for/from keyframe boosting and consecutive	 * keyframe penalty */	double pb_iboost_tax_ratio;	/* This the ratio to apply to all b/p frames in order to respect the	 * assymetric curve compression while respecting a target filesize	 * NB: The assymetric delta gain has to be computed before this ratio	 *     is applied, and then the delta is added to the scaled size */	double assymetric_tax_ratio;	/*----------------------------------	 * Data from the stats file kept	 * into RAM for easy access	 *--------------------------------*/	/* Array of keyframe locations	 * eg: rc->keyframe_locations[100] returns the frame number of the 100th	 *     keyframe */	int *keyframe_locations;	/* Index of the last keyframe used in the keyframe_location */	int KF_idx;	/* Array of all 1st pass data file -- see the twopass_stat_t structure	 * definition for more details */	twopass_stat_t * stats;	/*----------------------------------	 * Hysteresis helpers	 *--------------------------------*/	/* This field holds the int2float conversion errors of each quant per	 * frame type, this allow the RC to keep track of rouding error and thus	 * increase or decrease the chosen quant according to this residue */	double quant_error[3][32];	/* This fields stores the count of each quant usage per frame type	 * No real role but for debugging */	int quant_count[3][32];	/* Last valid quantizer used per frame type, it allows quantizer	 * increament/decreament limitation in order to avoid big image quality	 * "jumps" */	int last_quant[3];	/*----------------------------------	 * Overflow control	 *--------------------------------*/	/* Current overflow that has to be distributed to p/b frames */	double overflow;	/* Total overflow for keyframes -- not distributed directly */	double KFoverflow;	/* Amount of keyframe overflow to introduce to the global p/b frame	 * overflow counter at each encoded frame */	double KFoverflow_partial;	/* Unknown ???	 * ToDo: description */	double fq_error;	int min_quant; /* internal minimal quant, prevents wrong quants from being used */	/*----------------------------------	 * Debug	 *--------------------------------*/	double desired_total;	double real_total;} rc_2pass2_t;/***************************************************************************** * Sub plugin functions prototypes ****************************************************************************/static int rc_2pass2_create(xvid_plg_create_t * create, rc_2pass2_t ** handle);static int rc_2pass2_before(rc_2pass2_t * rc, xvid_plg_data_t * data);static int rc_2pass2_after(rc_2pass2_t * rc, xvid_plg_data_t * data);static int rc_2pass2_destroy(rc_2pass2_t * rc, xvid_plg_destroy_t * destroy);/***************************************************************************** * Plugin definition ****************************************************************************/intxvid_plugin_2pass2(void * handle, int opt, void * param1, void * param2){	switch(opt) {	case XVID_PLG_INFO :	case XVID_PLG_FRAME :		return 0;	case XVID_PLG_CREATE :		return rc_2pass2_create((xvid_plg_create_t*)param1, param2);	case XVID_PLG_DESTROY :		return rc_2pass2_destroy((rc_2pass2_t*)handle, (xvid_plg_destroy_t*)param1);	case XVID_PLG_BEFORE :		return rc_2pass2_before((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);	case XVID_PLG_AFTER :		return rc_2pass2_after((rc_2pass2_t*)handle, (xvid_plg_data_t*)param1);	}	return XVID_ERR_FAIL;}/***************************************************************************** * Sub plugin functions definitions ****************************************************************************//* First a few local helping function prototypes */static  int statsfile_count_frames(rc_2pass2_t * rc, char * filename);static  int statsfile_load(rc_2pass2_t *rc, char * filename);static void zone_process(rc_2pass2_t *rc, const xvid_plg_create_t * create);static void first_pass_stats_prepare_data(rc_2pass2_t * rc);static void first_pass_scale_curve_internal(rc_2pass2_t *rc);static void scaled_curve_apply_advanced_parameters(rc_2pass2_t * rc);static  int check_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps);static  int scale_curve_for_vbv_compliancy(rc_2pass2_t * rc, const float fps);#if 0static void stats_print(rc_2pass2_t * rc);#endif/*---------------------------------------------------------------------------- *--------------------------------------------------------------------------*/static intrc_2pass2_create(xvid_plg_create_t * create, rc_2pass2_t **handle){	xvid_plugin_2pass2_t * param = (xvid_plugin_2pass2_t *)create->param;	rc_2pass2_t * rc;	int i;	rc = malloc(sizeof(rc_2pass2_t));	if (rc == NULL)		return XVID_ERR_MEMORY;	/* v1.0.x */	rc->param.version = param->version;	rc->param.bitrate = param->bitrate;	rc->param.filename = param->filename;	rc->param.keyframe_boost = param->keyframe_boost;	rc->param.curve_compression_high = param->curve_compression_high;	rc->param.curve_compression_low = param->curve_compression_low;	rc->param.overflow_control_strength = param->overflow_control_strength;	rc->param.max_overflow_improvement = param->max_overflow_improvement;	rc->param.max_overflow_degradation = param->max_overflow_degradation;	rc->param.kfreduction = param->kfreduction;	rc->param.kfthreshold = param->kfthreshold;	rc->param.container_frame_overhead = param->container_frame_overhead;	if (XVID_VERSION_MINOR(param->version) >= 1) {		rc->param.vbv_size = param->vbv_size;		rc->param.vbv_initial = param->vbv_initial;		rc->param.vbv_maxrate = param->vbv_maxrate;		rc->param.vbv_peakrate = param->vbv_peakrate;	}else{		rc->param.vbv_size =		rc->param.vbv_initial =		rc->param.vbv_maxrate =		rc->param.vbv_peakrate = 0;	}	/* Initialize all defaults */#define _INIT(a, b) if((a) <= 0) (a) = (b)	/* Let's set our defaults if needed */	_INIT(rc->param.keyframe_boost, DEFAULT_KEYFRAME_BOOST);	_INIT(rc->param.overflow_control_strength, DEFAULT_OVERFLOW_CONTROL_STRENGTH);	_INIT(rc->param.curve_compression_high, DEFAULT_CURVE_COMPRESSION_HIGH);	_INIT(rc->param.curve_compression_low, DEFAULT_CURVE_COMPRESSION_LOW);	_INIT(rc->param.max_overflow_improvement, DEFAULT_MAX_OVERFLOW_IMPROVEMENT);	_INIT(rc->param.max_overflow_degradation,  DEFAULT_MAX_OVERFLOW_DEGRADATION);	/* Keyframe settings */	_INIT(rc->param.kfreduction, DEFAULT_KFREDUCTION);	_INIT(rc->param.kfthreshold, DEFAULT_KFTHRESHOLD);#undef _INIT	/* Initialize some stuff to zero */	for(i=0; i<3; i++) {		int j;		for (j=0; j<32; j++) {			rc->quant_error[i][j] = 0;			rc->quant_count[i][j] = 0;		}	}	for (i=0; i<3; i++) rc->last_quant[i] = 0;	rc->fq_error = 0;	rc->min_quant = 1;	/* Count frames (and intra frames) in the stats file, store the result into	 * the rc structure */	if (statsfile_count_frames(rc, param->filename) == -1) {		DPRINTF(XVID_DEBUG_RC,"[xvid rc] -- ERROR: fopen %s failed\n", param->filename);		free(rc);		return(XVID_ERR_FAIL);	}	/* Allocate the stats' memory */	if ((rc->stats = malloc(rc->num_frames * sizeof(twopass_stat_t))) == NULL) {		free(rc);		return(XVID_ERR_MEMORY);	}	/* Allocate keyframes location's memory	 * PS: see comment in pre_process0 for the +1 location requirement */	rc->keyframe_locations = malloc((rc->num_keyframes + 1) * sizeof(int));	if (rc->keyframe_locations == NULL) {		free(rc->stats);		free(rc);		return(XVID_ERR_MEMORY);	}	/* Load the first pass stats */	if (statsfile_load(rc, param->filename) == -1) {		DPRINTF(XVID_DEBUG_RC,"[xvid rc] -- ERROR: fopen %s failed\n", param->filename);		free(rc->keyframe_locations);		free(rc->stats);		free(rc);		return XVID_ERR_FAIL;	}	/* Compute the target filesize */	if (rc->param.bitrate<0) {		/* if negative, bitrate equals the target (in kbytes) */		rc->target = ((uint64_t)(-rc->param.bitrate)) * 1024;	} else if (rc->num_frames  < create->fbase/create->fincr) {		/* Source sequence is less than 1s long, we do as if it was 1s long */		rc->target = rc->param.bitrate / 8;	} else {		/* Target filesize = bitrate/8 * numframes / framerate */		rc->target =			((uint64_t)rc->param.bitrate * (uint64_t)rc->num_frames * \			 (uint64_t)create->fincr) / \			((uint64_t)create->fbase * 8);	}	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Frame rate: %d/%d (%ffps)\n",			create->fbase, create->fincr,			(double)create->fbase/(double)create->fincr);	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Number of frames: %d\n", rc->num_frames);	if(rc->param.bitrate>=0)		DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Target bitrate: %ld\n", rc->param.bitrate);	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Target filesize: %lld\n", rc->target);	/* Compensate the average frame overhead caused by the container */	rc->target -= rc->num_frames*rc->param.container_frame_overhead;	DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- Container Frame overhead: %d\n", rc->param.container_frame_overhead);	if(rc->param.container_frame_overhead)		DPRINTF(XVID_DEBUG_RC, "[xvid rc] -- New target filesize after container compensation: %lld\n", rc->target);	/* When bitrate is not given it means it has been scaled by an external	 * application */	if (rc->param.bitrate) {		/* Apply zone settings		 * - set rc->tot_quant which represents the total num of bytes spent in		 *   fixed quant zones		 * - set rc->tot_weighted which represents the total amount of bytes		 *   spent in normal or weighted zones in first pass (normal zones can		 *   be considered weight=1)		 * - set rc->tot_quant_invariant which represents the total num of bytes		 *   spent in fixed quant zones for headers */		zone_process(rc, create);	} else {		/* External scaling -- zones are ignored */		for (i=0;i<rc->num_frames;i++) {			rc->stats[i].zone_mode = XVID_ZONE_WEIGHT;			rc->stats[i].weight = 1.0;		}		rc->tot_quant = 0;	}	/* Gathers some information about first pass stats:	 *  - finds the minimum frame length for each frame type during 1st pass.	 *     rc->min_size[]	 *  - determines the maximum frame length observed (no frame type distinction).	 *     rc->max_size	 *  - count how many times each frame type has been used.	 *     rc->count[]	 *  - total bytes used per frame type	 *     rc->tot_length[]	 *  - total bytes considered invariant between the 2 passes	 *  - store keyframe location	 *     rc->keyframe_locations[]	 */	first_pass_stats_prepare_data(rc);	/* If we have a user bitrate, it means it's an internal curve scaling */	if (rc->param.bitrate) {		/* Perform internal curve scaling */		first_pass_scale_curve_internal(rc);	}	/* Apply advanced curve options, and compute some parameters in order to	 * shape the curve in the BEFORE/AFTER pair of functions */	scaled_curve_apply_advanced_parameters(rc);	/* Check curve for VBV compliancy and rescale if necessary */#ifdef VBV_FORCE	if (rc->param.vbv_size==0) {		rc->param.vbv_size      =  3145728;		rc->param.vbv_initial   =  2359296;		rc->param.vbv_maxrate   =  4854000;		rc->param.vbv_peakrate  =  8000000;	}#endif	/* vbv_size==0 switches VBV check off */

⌨️ 快捷键说明

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