summaryrefslogtreecommitdiffstats
path: root/xvid_vbr.c
diff options
context:
space:
mode:
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_frame);
- }
-
- }
-
- }
-
- }
-
- state->overflow = 0;
- state->KFoverflow = 0;
- state->KFoverflow_partial = 0;
- state->KF_idx = 1;
-
- for (n=0 ; n < 32 ; n++) {
- state->quant_error[n] = 0.0;
- state->quant_count[n] = 0;
- }
-
- state->curve_comp_error = 0.0;
- state->last_quant = 0;
-
- /*
- * Above this frame size limit, normal vbr rules will not apply
- * This means :
- * 1 - Quant can de/increase more than -/+2 between 2 frames
- * 2 - Leads to artifacts because of 1
- */
- state->max_framesize = state->twopass_max_bitrate/state->fps;
-
- /* Get back to the beginning of frame statistics */
- fseek(state->pass1_file, pos_firstframe, SEEK_SET);
-
- /*
- * Small hack : We have to get next frame stats before the
- * getintra/quant calls
- * User clients update the data when they call vbrUpdate
- * we are just bypassing this because we don't have to update
- * the overflow and so on...
- */
- {
-
- /* Fake vars */
- int next_hbytes, next_kblocks, next_mblocks, next_ublocks;
-
- fscanf(state->pass1_file, "%d %d %d %d %d %d %d\n",
- &state->pass1_quant, &state->pass1_intra, &next_hbytes,
- &state->pass1_bytes, &next_kblocks, &next_mblocks,
- &next_ublocks);
-
- }
-
- /* Initialize the frame counter */
- state->cur_frame = 0;
- state->last_keyframe = 0;
-
- return(0);
-
-}
-
-static int vbr_getquant_2pass2(void *sstate)
-{
-