summaryrefslogtreecommitdiffstats
path: root/xvid_vbr.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-10-31 00:04:18 +0300
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:16:55 +0200
commit389c32b5c72897a8b1b3c929c8f278e8980f2290 (patch)
tree47f7784ec12f9d53172f7ad326ed78f2f9889f74 /xvid_vbr.c
parent8939645dcf39c398e1b70b851b3410299ca619ce (diff)
downloadmpv-389c32b5c72897a8b1b3c929c8f278e8980f2290.tar.bz2
mpv-389c32b5c72897a8b1b3c929c8f278e8980f2290.tar.xz
Remove MEncoder
Disable MEncoder compilation and remove files used by MEncoder only. There's no attempt to remove all references to MEncoder from the build system, documentation etc at this point. Removed files: (muxers, audio/video encoders, misc) mencoder.c cfg-mencoder.h parser-mecmd.[ch] xvid_vbr.[ch] libmpdemux/muxer* libmpcodecs/ae* libmpcodecs/ve* libmpcodecs/native/rtjpegn.[ch] libmpcodecs/native/mmx.h // was used by rtjpegn only Rationale: MEncoder is still useful for some people, but there's not much potential for further development; in the long run almost all use cases can be handled better by solutions based on something else (for example using FFmpeg or encoding MPlayer output). FFmpeg is already getting video filtering support which should work for some common MEncoder uses. Keeping MEncoder working takes extra work that is away from player development. While that amount of work is not huge (mostly MEncoder can be just ignored), it's not completely insignificant either. MEncoder is still maintained to some degree in the svn tree, so if necessary it's possible to use it from there for now. This tree has never had major improvements for the MEncoder side, so using svn MEncoder instead should be no major loss.
Diffstat (limited to 'xvid_vbr.c')
-rw-r--r--xvid_vbr.c1648
1 files changed, 0 insertions, 1648 deletions
diff --git a/xvid_vbr.c b/xvid_vbr.c
deleted file mode 100644
index 08053248fc..0000000000
--- a/xvid_vbr.c
+++ /dev/null
@@ -1,1648 +0,0 @@
-/******************************************************************************
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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)
-{
-
- return(-1);
-
-}
-
-static int vbr_update_2pass1(void *sstate,
- int quant,
- int intra,
- int header_bytes,
- int total_bytes,
- int kblocks,
- int mblocks,
- int ublocks)
-
-
-{
-
- vbr_control_t *state = sstate;
-
- if(state->pass1_file == NULL)
- return(-1);
-
- /* Writes the resulting statistics */
- fprintf(state->pass1_file, "%d %d %d %d %d %d %d\n",
- quant,
- intra,
- header_bytes,
- total_bytes,
- kblocks,
- mblocks,
- ublocks);
-
- /* Update vbr control state */
- if(intra) state->nb_keyframes++;
- state->nb_frames++;
- state->cur_frame++;
-
- return(0);
-
-}
-
-static int vbr_finish_2pass1(void *sstate)
-{
-
- int c, i;
- vbr_control_t *state = sstate;
-
- if(state->pass1_file == NULL)
- return(-1);
-
- /* Goto to the file beginning */
- fseek(state->pass1_file, 0, SEEK_SET);
-
- /* Skip the version line and the empty line */
- c = i = 0;
- do {
- c = fgetc(state->pass1_file);
-
- if(c == EOF) return(-1);
- if(c == '\n') i++;
-
- }while(i < 2);
-
- /* Prepare to write to the stream */
- fseek( state->pass1_file, 0L, SEEK_CUR );
-
- /* Overwrite the frame field - safe as we have written extra spaces */
- fprintf(state->pass1_file, "# frames : %.10d\n", state->nb_frames);
-
- /* Overwrite the keyframe field */
- fprintf(state->pass1_file, "# keyframes : %.10d\n",
- state->nb_keyframes);
-
- /* Close the file */
- if(fclose(state->pass1_file) != 0)
- return(-1);
-
- return(0);
-
-}
-
-/******************************************************************************
- * 2 pass mode - 2nd pass functions (Need to be finished)
- *****************************************************************************/
-
-static int vbr_init_2pass2(void *sstate)
-{
-
- FILE *f;
- int c, n, pos_firstframe, credits_frames;
- long long credits1_bytes;
- long long credits2_bytes;
- long long desired;
- long long total_bytes;
- long long itotal_bytes;
- long long start_curved;
- long long end_curved;
- double total1;
- double total2;
-
- vbr_control_t *state = sstate;
-
- /* Check the filename */
- if(state->filename == NULL || state->filename[0] == '\0')
- return(-1);
-
- /* Initialize safe defaults for 2pass 2 */
- state->pass1_file = NULL;
- state->nb_frames = 0;
- state->nb_keyframes = 0;
-
- /* Open the 1st pass file */
- if((f = fopen(state->filename, "r")) == NULL)
- return(-1);
-
- state->pass1_file = f;
-
- /* Get the file version and check against current version */
- fscanf(state->pass1_file, "# ASCII XviD vbr stat file version %d\n", &n);
-
- if(n != VBR_VERSION) {
- fclose(state->pass1_file);
- state->pass1_file = NULL;
- return(-1);
- }
-
- /* Skip the blank commented line */
- c = n = 0;
- do {
-
- c = fgetc(state->pass1_file);
-
- if(c == EOF) {
- fclose(state->pass1_file);
- state->pass1_file = NULL;
- return(-1);
- }
-
- if(c == '\n') n++;
-
- }while(n < 1);
-
-
- /* Get the number of frames */
- fscanf(state->pass1_file, "# frames : %d\n", &state->nb_frames);
-
- /* Compute the desired size */
- state->desired_size = (long long)
- (((long long)state->nb_frames * (long long)state->desired_bitrate) /
- (state->fps * 8.0));
-
- /* Get the number of keyframes */
- fscanf(state->pass1_file, "# keyframes : %d\n", &state->nb_keyframes);
-
- /* Allocate memory space for the keyframe_location array */
- if((state->keyframe_locations
- = malloc((state->nb_keyframes+1)*sizeof(int))) == NULL) {
- fclose(state->pass1_file);
- state->pass1_file = NULL;
- return(-1);
- }
-
- /* Skip the blank commented line and the colum description */
- c = n = 0;
- do {
-
- c = fgetc(state->pass1_file);
-
- if(c == EOF) {
- fclose(state->pass1_file);
- state->pass1_file = NULL;
- return(-1);
- }
-
- if(c == '\n') n++;
-
- }while(n < 2);
-
- /* Save position for future use */
- pos_firstframe = ftell(state->pass1_file);
-
- /* Read and initialize some variables */
- credits1_bytes = credits2_bytes = 0;
- total_bytes = itotal_bytes = 0;
- start_curved = end_curved = 0;
- credits_frames = 0;
-
- for(state->cur_frame = c = 0; state->cur_frame<state->nb_frames; state->cur_frame++) {
-
- int quant, keyframe, frame_hbytes, frame_bytes;
- int kblocks, mblocks, ublocks;
-
- fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",
- &quant, &keyframe, &frame_hbytes, &frame_bytes,
- &kblocks, &mblocks, &ublocks);
-
- /* Is the frame in the beginning credits */
- if(util_frametype(state) == FRAME_TYPE_STARTING_CREDITS) {
- credits1_bytes += frame_bytes;
- credits_frames++;
- continue;
- }
-
- /* Is the frame in the eding credits */
- if(util_frametype(state) == FRAME_TYPE_ENDING_CREDITS) {
- credits2_bytes += frame_bytes;
- credits_frames++;
- continue;
- }
-
- /* We only care about Keyframes when not in credits */
- if(keyframe) {
- itotal_bytes += frame_bytes + frame_bytes *
- state->keyframe_boost / 100;
- total_bytes += frame_bytes *
- state->keyframe_boost / 100;
- state->keyframe_locations[c++] = state->cur_frame;
- }
-
- total_bytes += frame_bytes;
-
- }
-
- /*
- * Last frame is treated like an I Frame so we can dispatch overflow
- * all other the last film segment
- */
- state->keyframe_locations[c] = state->cur_frame;
-
- desired = state->desired_size;
-
- switch(state->credits_mode) {
- case VBR_CREDITS_MODE_QUANT :
-
- state->movie_curve = (double)
- (total_bytes - credits1_bytes - credits2_bytes) /
- (desired - credits1_bytes - credits2_bytes);
-
- start_curved = credits1_bytes;
- end_curved = credits2_bytes;
-
- break;
- case VBR_CREDITS_MODE_SIZE:
-
- /* start curve = (start / start desired size) */
- state->credits_start_curve = (double)
- (credits1_bytes / state->credits_start_size);
-
- /* end curve = (end / end desired size) */
- state->credits_end_curve = (double)
- (credits2_bytes / state->credits_end_size);
-
- start_curved = (long long)
- (credits1_bytes / state->credits_start_curve);
-
- end_curved = (long long)
- (credits2_bytes / state->credits_end_curve);
-
- /* movie curve=(total-credits)/(desired_size-curved credits) */
- state->movie_curve = (double)
- (total_bytes - credits1_bytes - credits2_bytes) /
- (desired - start_curved - end_curved);
-
- break;
- case VBR_CREDITS_MODE_RATE:
- default:
-
- /* credits curve = (total/desired_size)*(100/credits_rate) */
- state->credits_start_curve = state->credits_end_curve =
- ((double)total_bytes / desired) *
- ((double)100 / state->credits_quant_ratio);
-
- start_curved =
- (long long)(credits1_bytes/state->credits_start_curve);
-
- end_curved =
- (long long)(credits2_bytes/state->credits_end_curve);
-
- state->movie_curve = (double)
- (total_bytes - credits1_bytes - credits2_bytes) /
- (desired - start_curved - end_curved);
-
- break;
- }
-
- /*
- * average frame size = (desired - curved credits - curved keyframes) /
- * (frames - credits frames - keyframes)
- */
- state->average_frame = (double)
- (desired - start_curved - end_curved -
- (itotal_bytes / state->movie_curve)) /
- (state->nb_frames - util_creditsframes(state) -
- state->nb_keyframes);
-
- /* Initialize alt curve parameters */
- if (state->use_alt_curve) {
-
- state->alt_curve_low =
- state->average_frame - state->average_frame *
- (double)(state->alt_curve_low_dist / 100.0);
-
- state->alt_curve_low_diff =
- state->average_frame - state->alt_curve_low;
-
- state->alt_curve_high =
- state->average_frame + state->average_frame *
- (double)(state->alt_curve_high_dist / 100.0);
-
- state->alt_curve_high_diff =
- state->alt_curve_high - state->average_frame;
-
- if (state->alt_curve_use_auto) {
-
- if (state->movie_curve > 1.0) {
-
- state->alt_curve_min_rel_qual =
- (int)(100.0 - (100.0 - 100.0 / state->movie_curve) *
- (double)state->alt_curve_auto_str / 100.0);
-
- if (state->alt_curve_min_rel_qual < 20)
- state->alt_curve_min_rel_qual = 20;
- }
- else {
- state->alt_curve_min_rel_qual = 100;
- }
-
- }
-
- state->alt_curve_mid_qual =
- (1.0 + (double)state->alt_curve_min_rel_qual / 100.0) / 2.0;
-
- state->alt_curve_qual_dev = 1.0 - state->alt_curve_mid_qual;
-
- if (state->alt_curve_low_dist > 100) {
-
- switch(state->alt_curve_type) {
- case VBR_ALT_CURVE_AGGRESIVE:
- /* Sine Curve (high aggressiveness) */
- state->alt_curve_qual_dev *=
- 2.0 /
- (1.0 + sin(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff)));
-
- state->alt_curve_mid_qual =
- 1.0 - state->alt_curve_qual_dev *
- sin(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff));
- break;
-
- default:
- case VBR_ALT_CURVE_LINEAR:
- /* Linear (medium aggressiveness) */
- state->alt_curve_qual_dev *=
- 2.0 /
- (1.0 + state->average_frame / state->alt_curve_low_diff);
-
- state->alt_curve_mid_qual =
- 1.0 - state->alt_curve_qual_dev *
- state->average_frame / state->alt_curve_low_diff;
-
- break;
-
- case VBR_ALT_CURVE_SOFT:
- /* Cosine Curve (low aggressiveness) */
- state->alt_curve_qual_dev *=
- 2.0 /
- (1.0 + (1.0 - cos(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff))));
-
- state->alt_curve_mid_qual =
- 1.0 - state->alt_curve_qual_dev *
- (1.0 - cos(DEG2RAD * (state->average_frame * 90.0 / state->alt_curve_low_diff)));
-
- break;
- }
- }
- }
-
- /* Go to the first non credits frame stats line into file */
- fseek(state->pass1_file, pos_firstframe, SEEK_SET);
-
- /* Perform prepass to compensate for over/undersizing */
- total1 = total2 = 0.0;
- for(state->cur_frame=0; state->cur_frame<state->nb_frames; state->cur_frame++) {
-
- int quant, keyframe, frame_hbytes, frame_bytes;
- int kblocks, mblocks, ublocks;
-
- fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",
- &quant, &keyframe, &frame_hbytes, &frame_bytes,
- &kblocks, &mblocks, &ublocks);
-
- if(util_frametype(state) != FRAME_TYPE_NORMAL_MOVIE)
- continue;
-
- if(!keyframe) {
-
- double dbytes = frame_bytes / state->movie_curve;
- total1 += dbytes;
-
- if (state->use_alt_curve) {
-
- if (dbytes > state->average_frame) {
-
- if (dbytes >= state->alt_curve_high) {
- total2 += dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev);
- }
- else {
-
- switch(state->alt_curve_type) {
- case VBR_ALT_CURVE_AGGRESIVE:
-
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff)));
- break;
- default:
- case VBR_ALT_CURVE_LINEAR:
-
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (dbytes - state->average_frame) / state->alt_curve_high_diff);
- break;
- case VBR_ALT_CURVE_SOFT:
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff))));
- }
- }
- }
- else {
-
- if (dbytes <= state->alt_curve_low) {
- total2 += dbytes;
- }
- else {
-
- switch(state->alt_curve_type) {
- case VBR_ALT_CURVE_AGGRESIVE:
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_low_diff)));
- break;
- default:
- case VBR_ALT_CURVE_LINEAR:
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (dbytes - state->average_frame) / state->alt_curve_low_diff);
- break;
- case VBR_ALT_CURVE_SOFT:
- total2 +=
- dbytes *
- (state->alt_curve_mid_qual + state->alt_curve_qual_dev *
- (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_low_diff))));
- }
- }
- }
- }
- else {
- if (dbytes > state->average_frame) {
- total2 +=
- ((double)dbytes +
- (state->average_frame - dbytes) *
- state->curve_compression_high / 100.0);
- }
- else {
- total2 +=
- ((double)dbytes +
- (state->average_frame - dbytes) *
- state->curve_compression_low / 100.0);
- }
- }
- }
- }
-
- state->curve_comp_scale = total1 / total2;
-
- if (state->use_alt_curve) {
-
- double curve_temp, dbytes;
- int newquant, percent;
- int oldquant = 1;
-
- if (state->alt_curve_use_auto_bonus_bias)
- state->alt_curve_bonus_bias = state->alt_curve_min_rel_qual;
-
- state->curve_bias_bonus =
- (total1 - total2) * (double)state->alt_curve_bonus_bias /
- (100.0 * (double)(state->nb_frames - util_creditsframes(state) - state->nb_keyframes));
- state->curve_comp_scale =
- ((total1 - total2) * (1.0 - (double)state->alt_curve_bonus_bias / 100.0) + total2) /
- total2;
-
-
- for (n=1; n <= (int)(state->alt_curve_high*2) + 1; n++) {
- dbytes = n;
- if (dbytes > state->average_frame)
- {
- if (dbytes >= state->alt_curve_high) {
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev);
- }
- else {
- switch(state->alt_curve_type) {
- case VBR_ALT_CURVE_AGGRESIVE:
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff)));
- break;
- default:
- case VBR_ALT_CURVE_LINEAR:
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (dbytes - state->average_frame) / state->alt_curve_high_diff);
- break;
- case VBR_ALT_CURVE_SOFT:
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_high_diff))));
- }
- }
- }
- else {
- if (dbytes <= state->alt_curve_low) {
- curve_temp = dbytes;
- }
- else {
- switch(state->alt_curve_type) {
- case VBR_ALT_CURVE_AGGRESIVE:
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- sin(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_low_diff)));
- break;
- default:
- case VBR_ALT_CURVE_LINEAR:
- curve_temp = dbytes * (state->alt_curve_mid_qual - state->alt_curve_qual_dev *
- (dbytes - state->average_frame) / state->alt_curve_low_diff);
- break;
- case VBR_ALT_CURVE_SOFT:
- curve_temp = dbytes * (state->alt_curve_mid_qual + state->alt_curve_qual_dev *
- (1.0 - cos(DEG2RAD * ((dbytes - state->average_frame) * 90.0 / state->alt_curve_low_diff))));
- }
- }
- }
-
- if (state->movie_curve > 1.0)
- dbytes *= state->movie_curve;
-
- newquant = (int)(dbytes * 2.0 / (curve_temp * state->curve_comp_scale + state->curve_bias_bonus));
- if (newquant > 1)
- {
- if (newquant != oldquant)
- {
- oldquant = newquant;
- percent = (int)((n - state->average_frame) * 100.0 / state->average_fra