/******************************************************************************
 *
 *   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
 *
 *****************************************************************************/

#ifndef __XVID_VBR_H__
#define __XVID_VBR_H__

#define VBR_VERSION 0
#define AVG_LOOKUP 5
/******************************************************************************
 * Function types used in the vbr controler
 *****************************************************************************/

typedef int (vbr_init_function) (void *state);
typedef vbr_init_function *vbr_init_function_ptr;

typedef int (vbr_get_quant_function) (void *state);
typedef vbr_get_quant_function *vbr_get_quant_function_ptr;

typedef int (vbr_get_intra_function) (void *state);
typedef vbr_get_intra_function *vbr_get_intra_function_ptr;

typedef int (vbr_update_function) (void *state,
				   int quant,
				   int intra,
				   int header_bytes,
				   int total_bytes,
				   int kblocks, int mblocks, int ublocks);
typedef vbr_update_function *vbr_update_function_ptr;

typedef int (vbr_finish_function) (void *state);
typedef vbr_finish_function *vbr_finish_function_ptr;

/******************************************************************************
 * The VBR CONTROLER structure - the spin of the library
 *****************************************************************************/

typedef struct _vbr_control_t
{

  /* All modes - specifies what VBR algorithm has to be used */
  int mode;

  /* All modes - specifies what fps the movie uses */
  float fps;

  /* All modes */
  int debug;

  /*
   * For VBR_MODE_2PASS_1/2 - specifies from/to what file the vbr
   * controller has to write/read stats
   */
  char *filename;

  /* For VBR_MODE_2PASS_2 - Target size */
  int desired_bitrate;

  /* For VBR_MODE_2PASS_2 - Credits parameters */
  int credits_mode;
  int credits_start;
  int credits_start_begin;
  int credits_start_end;
  int credits_end;
  int credits_end_begin;
  int credits_end_end;
  int credits_quant_ratio;
  int credits_fixed_quant;
  int credits_quant_i;
  int credits_quant_p;
  int credits_start_size;
  int credits_end_size;

  /* For VBR_MODE_2PASS_2 - keyframe parameters */
  int keyframe_boost;
  int kftreshold;
  int kfreduction;
  int min_key_interval;
  int max_key_interval;

  /* For VBR_MODE_2PASS_2 - Normal curve */
  int curve_compression_high;
  int curve_compression_low;

  /* For VBR_MODE_2PASS_2 - Alternate curve parameters */
  int use_alt_curve;
  int alt_curve_type;
  int alt_curve_low_dist;
  int alt_curve_high_dist;
  int alt_curve_min_rel_qual;
  int alt_curve_use_auto;
  int alt_curve_auto_str;
  int alt_curve_use_auto_bonus_bias;
  int alt_curve_bonus_bias;
  int bitrate_payback_method;
  int bitrate_payback_delay;
  int max_iquant;
  int min_iquant;
  int max_pquant;
  int min_pquant;
  int twopass_max_bitrate;
  int twopass_max_overflow_improvement;
  int twopass_max_overflow_degradation;

  /*
   * For VBR_MODE_FIXED_QUANT - the quantizer that has to be used for all
   * frames
   */
  int fixed_quant;

  /* ----------- Internal data - Do not modify ----------- */
  void *debug_file;
  void *pass1_file;

  long long desired_size;

  int cur_frame;
  int nb_frames;
  int nb_keyframes;

  int *keyframe_locations;
  int last_keyframe;

  double credits_start_curve;
  double credits_end_curve;
  double movie_curve;
  double average_frame;
  double alt_curve_low;
  double alt_curve_low_diff;
  double alt_curve_high;
  double alt_curve_high_diff;
  double alt_curve_mid_qual;
  double alt_curve_qual_dev;
  double curve_bias_bonus;
  double curve_comp_scale;
  double curve_comp_error;

  int pass1_quant;
  int pass1_intra;
  int pass1_bytes;

  int bytes1;
  int bytes2;
  int desired_bytes2;
  int max_framesize;
  int last_quant;
  int quant_count[32];
  double quant_error[32];

  int overflow;
  int KFoverflow;
  int KFoverflow_partial;
  int KF_idx;

  int debug_quant_count[32];

  /* ----------- Internal data - do not modify ----------- */
  vbr_init_function_ptr init;
  vbr_get_quant_function_ptr getquant;
  vbr_get_intra_function_ptr getintra;
  vbr_update_function_ptr update;
  vbr_finish_function_ptr finish;

	/*------------ Meanx Bitrate clipping ---------------------*/
  int roundup;			// round-up of fps : 24/25/30
  int maxAllowedBitrate;	// max allowed bitrate in byte / sec
  //int b_per_sec[60];                            //
  int *size;			// we will store size of frames here
  int *kf;
  int *type;			// I=1 P =2 B=3
  int qinc;
  //int underflow_warning;                        // Means we get under thresh underflow
  //int  thresh_underflow;                        // Level in byte to underflow (~ 700 kbytes/s for SVCD)
  //int allow_quant_skew;                 // allow diff between I / P / B quant mods
  //int avg_br;                                   // average bitrate
  int vbv_buffer_size;		// <- MUST BE FILLED BY USER
  int vbv_fullness;		//
  int bits_per_image;		//
  float compr[AVG_LOOKUP];
} vbr_control_t;
#define THRESH_UNDERFLOW ((700*1000)>>3)	// in BYTES ! around 600 kbits
//#define BOOST_KF  1 // allow KF boots for mpeg1/2
/******************************************************************************
 * Constants
 *****************************************************************************/
/* Bitrate limiter */
#define LIMITER_ANTICIPATING 	2
#define LIMITER_LOW_WARNING	2
#define LIMITER_WARNING		3
#define LIMITER_MAX_INC		3

/* Constants for the mode member */
#define VBR_MODE_1PASS       0x01
#define VBR_MODE_2PASS_1     0x02
#define VBR_MODE_2PASS_2     0x04
#define VBR_MODE_FIXED_QUANT 0x08

/* Constants for the credits mode */
#define VBR_CREDITS_MODE_RATE  0x01
#define VBR_CREDITS_MODE_QUANT 0x02
#define VBR_CREDITS_MODE_SIZE  0x04

/* Alternate curve treatment types */
#define VBR_ALT_CURVE_SOFT      0x01
#define VBR_ALT_CURVE_LINEAR    0x02
#define VBR_ALT_CURVE_AGGRESIVE 0x04

/* Payback modes */
#define VBR_PAYBACK_BIAS            0x01
#define VBR_PAYBACK_PROPORTIONAL    0x02

/******************************************************************************
 * VBR API
 *****************************************************************************/

extern int vbrSetDefaults (vbr_control_t * state);
extern int vbrInit (vbr_control_t * state);
extern int vbrGetQuant (vbr_control_t * state);
extern int vbrGetIntra (vbr_control_t * state);
extern int vbrUpdate (vbr_control_t * state,
		      int quant,
		      int intra,
		      int header_bytes,
		      int total_bytes, int kblocks, int mblocks, int ublocks);
extern int vbrFinish (vbr_control_t * state);
/*	Meanx
*/
int vbr_next_intra (void *sstate);
#endif
