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

📄 xvid_vbr.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * *   XviD VBR Library *    *   Copyright (C) 2002 Edouard Gomez <ed.gomez@wanadoo.fr> * *   The curve treatment algorithm is based on work done by Foxer <email?> and *   Dirk Knop <dknop@gwdg.de> for the XviD vfw dynamic library. * *  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 * *****************************************************************************//* Standard Headers */#include <stdio.h>#include <string.h>#include <fcntl.h>#include <stdlib.h>#include <math.h>/* Local headers */#include "xvid_vbr.h"/****************************************************************************** * Build time constants *****************************************************************************//* * Portability note * Perhaps the msvc headers define Pi with another constant name */#define DEG2RAD (M_PI / 180.0)/* Defaults settings will be computed with the help of these constants */#define DEFAULT_DESIRED_SIZE    700#define DEFAULT_AUDIO_BITRATE   128#define DEFAULT_MOVIE_LENGTH      2#define DEFAULT_TWOPASS_BOOST  1000#define DEFAULT_FPS           25.0f#define DEFAULT_CREDITS_SIZE      0#define DEFAULT_XVID_DBG_FILE   "xvid.dbg"#define DEFAULT_XVID_STATS_FILE "xvid.stats"/****************************************************************************** * Local prototypes *****************************************************************************//* Sub vbrInit cases functions */static vbr_init_function vbr_init_dummy;static vbr_init_function vbr_init_2pass1;static vbr_init_function vbr_init_2pass2;static vbr_init_function vbr_init_fixedquant;/* Sub vbrGetQuant cases functions */static vbr_get_quant_function vbr_getquant_1pass;static vbr_get_quant_function vbr_getquant_2pass1;static vbr_get_quant_function vbr_getquant_2pass2;static vbr_get_quant_function vbr_getquant_fixedquant;/* Sub vbrGetIntra cases functions */static vbr_get_intra_function vbr_getintra_1pass;static vbr_get_intra_function vbr_getintra_2pass1;static vbr_get_intra_function vbr_getintra_2pass2;static vbr_get_intra_function vbr_getintra_fixedquant;/* Sub vbrUpdate prototypes */static vbr_update_function vbr_update_dummy;static vbr_update_function vbr_update_2pass1;static vbr_update_function vbr_update_2pass2;/* Sub vbrFinish cases functions */static vbr_finish_function vbr_finish_dummy;static vbr_finish_function vbr_finish_2pass1;static vbr_finish_function vbr_finish_2pass2;/* Is the encoder in the credits */#define FRAME_TYPE_NORMAL_MOVIE     0x00#define FRAME_TYPE_STARTING_CREDITS 0x01#define FRAME_TYPE_ENDING_CREDITS   0x02/****************************************************************************** * Inline utility functions *****************************************************************************/static __inline int util_frametype(vbr_control_t *state){	if(state->credits_start) {		if(state->cur_frame >= state->credits_start_begin &&		   state->cur_frame < state->credits_start_end)			return(FRAME_TYPE_STARTING_CREDITS);	}	if(state->credits_end) {		if(state->cur_frame >= state->credits_end_begin &&		   state->cur_frame < state->credits_end_end)			return(FRAME_TYPE_ENDING_CREDITS);	}	return(FRAME_TYPE_NORMAL_MOVIE);}static __inline int util_creditsframes(vbr_control_t *state){	int frames = 0;	if(state->credits_start)		frames += state->credits_start_end - state->credits_start_begin;	if(state->credits_end)		frames += state->credits_end_end - state->credits_end_begin;	return(frames);}/****************************************************************************** * Functions *****************************************************************************//***************************************************************************** * Function description : * * This function initialiazes the vbr_control_t with safe defaults for all * modes. * * Return Values : *   = 0 ****************************************************************************/int vbrSetDefaults(vbr_control_t *state){	/* Set all the structure to zero */	memset(state, 0, sizeof(state));	/* Default mode is CBR */	state->mode = VBR_MODE_1PASS;	/* Default statistic filename */	state->filename = DEFAULT_XVID_STATS_FILE;	/*	 * Default is a 2hour movie on 700Mo CD-ROM + 128kbit sound track	 * This represents a target bitrate of 687kbit/s	 */	state->desired_size = DEFAULT_DESIRED_SIZE*1024*1024 -		DEFAULT_MOVIE_LENGTH*3600*DEFAULT_AUDIO_BITRATE*1000/8;	state->desired_bitrate = state->desired_size*8/(DEFAULT_MOVIE_LENGTH*3600);	/* Credits */	state->credits_mode = VBR_CREDITS_MODE_RATE;	state->credits_start = 0;	state->credits_start_begin = 0;	state->credits_start_end = 0;	state->credits_end = 0;	state->credits_end_begin = 0;	state->credits_end_end = 0;	state->credits_quant_ratio = 20;	state->credits_fixed_quant = 20;	state->credits_quant_i = 20;	state->credits_quant_p = 20;	state->credits_start_size = DEFAULT_CREDITS_SIZE*1024*1024;	state->credits_end_size = DEFAULT_CREDITS_SIZE*1024*1024;	/* Keyframe boost */	state->keyframe_boost = 0;	state->kftreshold = 10;	state->kfreduction = 30;	state->min_key_interval = 1;	state->max_key_interval = (int)DEFAULT_FPS*10;	/* Normal curve treatment */	state->curve_compression_high = 25;	state->curve_compression_low = 10;	/* Alt curve */	state->use_alt_curve = 1;	state->alt_curve_type = VBR_ALT_CURVE_LINEAR; 	state->alt_curve_low_dist = 90;	state->alt_curve_high_dist = 500;	state->alt_curve_min_rel_qual = 50;	state->alt_curve_use_auto = 1;	state->alt_curve_auto_str = 30;	state->alt_curve_use_auto_bonus_bias = 1;	state->alt_curve_bonus_bias = 50;	state->bitrate_payback_method = VBR_PAYBACK_BIAS;	state->bitrate_payback_delay = 250;	state->twopass_max_bitrate = DEFAULT_TWOPASS_BOOST*state->desired_bitrate;	state->twopass_max_overflow_improvement = 60;	state->twopass_max_overflow_degradation = 60;	state->max_iquant = 31;	state->min_iquant = 2;	state->max_pquant = 31;	state->min_pquant = 2;	state->fixed_quant = 3;	state->max_framesize = (1.0/(float)DEFAULT_FPS) * state->twopass_max_bitrate / 8;	state->fps = (float)DEFAULT_FPS;	return(0);}/***************************************************************************** * Function description : * * This function initialiaze the vbr_control_t state passed in parameter. *  * The initialization depends on state->mode, there are 4 modes allowed. * Each mode description is done in the README file shipped with the lib. * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrInit(vbr_control_t *state){	if(state == NULL) return(-1);	/* Function pointers safe initialization */	state->init     = NULL;	state->getquant = NULL;	state->getintra = NULL;	state->update   = NULL;	state->finish   = NULL;	if(state->debug) {		state->debug_file = fopen(DEFAULT_XVID_DBG_FILE, "w+");		if(state->debug_file == NULL)			return(-1);		fprintf(state->debug_file, "# XviD Debug output\n");		fprintf(state->debug_file, "# quant | intra | header bytes"			"| total bytes | kblocks | mblocks | ublocks"			"| vbr overflow | vbr kf overflow"			"| vbr kf partial overflow\n\n");	}	/* Function pointers sub case initialization */	switch(state->mode) {	case VBR_MODE_1PASS:		state->init     = vbr_init_dummy;		state->getquant = vbr_getquant_1pass;		state->getintra = vbr_getintra_1pass;		state->update   = vbr_update_dummy;		state->finish   = vbr_finish_dummy;		break;	case VBR_MODE_2PASS_1:		state->init     = vbr_init_2pass1;		state->getquant = vbr_getquant_2pass1;		state->getintra = vbr_getintra_2pass1;		state->update   = vbr_update_2pass1;		state->finish   = vbr_finish_2pass1;		break;	case VBR_MODE_FIXED_QUANT:		state->init     = vbr_init_fixedquant;		state->getquant = vbr_getquant_fixedquant;		state->getintra = vbr_getintra_fixedquant;		state->update   = vbr_update_dummy;		state->finish   = vbr_finish_dummy;		break;	case VBR_MODE_2PASS_2:		state->init     = vbr_init_2pass2;		state->getintra = vbr_getintra_2pass2;		state->getquant = vbr_getquant_2pass2;		state->update   = vbr_update_2pass2;		state->finish   = vbr_finish_2pass2;		break;	default:		return(-1);	}		return(state->init(state));}/****************************************************************************** * Function description : * * This function returns an adapted quantizer according to the current vbr * controler state * * Return values : *  the quantizer value (0 <= value <= 31) *  (0 is a special case, means : let XviD decide) * *****************************************************************************/int vbrGetQuant(vbr_control_t *state){	/* Returns Zero, so XviD decides alone */	if(state == NULL || state->getquant == NULL) return(0);	return(state->getquant(state));}/****************************************************************************** * Function description : * * This function returns the type of the frame to be encoded next (I or P/B) * * Return values : *  = -1 let the XviD encoder decide wether or not the next frame is I *  =  0 no I frame *  =  1 force keyframe * *****************************************************************************/int vbrGetIntra(vbr_control_t *state){	/* Returns -1, means let XviD decide */	if(state == NULL || state->getintra == NULL) return(-1);	return(state->getintra(state));}/****************************************************************************** * Function description : * * This function updates the vbr control state according to collected statistics * from XviD core * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrUpdate(vbr_control_t *state,	      int quant,	      int intra,	      int header_bytes,	      int total_bytes,	      int kblocks,	      int mblocks,	      int ublocks){	if(state == NULL || state->update == NULL) return(-1);	if(state->debug && state->debug_file != NULL) {		int idx;		fprintf(state->debug_file, "%d %d %d %d %d %d %d %d %d %d\n",			quant, intra, header_bytes, total_bytes, kblocks,			mblocks, ublocks, state->overflow, state->KFoverflow,			state->KFoverflow_partial);		idx = quant;		if(quant < 1)			idx = 1;		if(quant > 31)			idx = 31;		idx--;		state->debug_quant_count[idx]++; 	}	return(state->update(state, quant, intra, header_bytes, total_bytes,			     kblocks, mblocks, ublocks));}/****************************************************************************** * Function description : * * This function stops the vbr controller * * Return values : * *    =  0 on success *    = -1 on error *****************************************************************************/int vbrFinish(vbr_control_t *state){	if(state == NULL || state->finish == NULL) return(-1);	if(state->debug && state->debug_file != NULL) {		int i;		fprintf(state->debug_file, "\n\n");		for(i=0; i<79; i++)			fprintf(state->debug_file, "#");		fprintf(state->debug_file, "\n# Quantizer distribution :\n\n");		for(i=0;i<32; i++) {			fprintf(state->debug_file, "# quant %d : %d\n",				i+1,				state->debug_quant_count[i]);		}		fclose(state->debug_file);	}	return(state->finish(state));}/****************************************************************************** * Dummy functions - Used when a mode does not need such a function *****************************************************************************/static int vbr_init_dummy(void *sstate){	vbr_control_t *state = sstate;	state->cur_frame = 0;	return(0);}static int vbr_update_dummy(void *state,			    int quant,			    int intra,			    int header_bytes,			    int total_bytes,			    int kblocks,			    int mblocks,			    int ublocks){	((vbr_control_t*)state)->cur_frame++;	return(0);}static int vbr_finish_dummy(void *state){	return(0);}/****************************************************************************** * 1 pass mode - XviD will do its job alone. *****************************************************************************/static int vbr_getquant_1pass(void *state){	return(0);}static int vbr_getintra_1pass(void *state){	return(-1);}/****************************************************************************** * 2 pass mode - first pass functions *****************************************************************************/static int vbr_init_2pass1(void *sstate){	FILE *f;	vbr_control_t *state = sstate;	/* Check the filename */	if(state->filename == NULL || state->filename[0] == '\0')		return(-1);	/* Initialize safe defaults for 2pass 1 */ 	state->pass1_file = NULL;	state->nb_frames = 0;	state->nb_keyframes = 0;	state->cur_frame = 0;	/* Open the 1st pass file */	if((f = fopen(state->filename, "w+")) == NULL)		return(-1);	/*	 * The File Header	 *	 * The extra white spaces will be used during the vbrFinish to write	 * the resulting number of frames and keyframes (10 spaces == maximum	 * string length of an int on 32bit machines, i don't think anyone is	 * encoding more than 4 billion frames :-)	 */	fprintf(f, "# ASCII XviD vbr stat file version %d\n#\n", VBR_VERSION);	fprintf(f, "# frames    :           \n");	fprintf(f, "# keyframes :           \n");	fprintf(f, "#\n# quant | intra | header bytes | total bytes | kblocks |"		" mblocks | ublocks\n\n"); 	/* Save file pointer */	state->pass1_file   = f;	return(0);}static int vbr_getquant_2pass1(void *state){	return(2);}static int vbr_getintra_2pass1(void *state){

⌨️ 快捷键说明

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