construct object construct object
Home sweet home
Nav
hide
S1
S2
S3
Name: Requant-Script
Typ: bash
benötigt: M2VRequantiser von Metakine
Dient zur Verkleinerung der Videodateien (*.m2v), Audio-Dateien lassen sich nicht verkleinern.

Details: Zur Verkleinerung der Video-Dateien habe ich nur ein Programm gefunden, dass keine gravierenden bzw. kaum Qualitätseinbußen bewirkt. Es stammt von Metakine, welches den Code unter der GPL weitergibt, da Code verwendet wird, der selber unter der Lizenz steht. Es waren nur wenige Änderungen nötig (ich habe vergessen welche) um den Code auf meinem System zu kompilieren. Informationen findet man in einem Online-Artikel der ct. Kompilieren läßt sich das Programm wie folgt:
  gcc main.c -o requant -lm
Da das Programm etwas lästig aufzurufen ist, ist das requantWrapper Script entstanden. Der Wrapper:
hide
requantWrapper
echo "Wrapper arround requant from Metakine"
echo "Call " $0 " faktor filename.m2v"
echo "example: faktor 1.1 means that the size of m2v file is reduced by faktor 1/1.1"
echo "Beachte: nur 4482 MB Platz auf der DVD"
echo "- Vorsicht dazu noch Bilder und Menus (wahrscheinlich < 20 MB)";
#spaeter vielleicht mal eine Empfehlung berechnen lassen
echo "Bechung nach  (neueGröße=größe*1/faktor:"
echo "Hinweis wollen Sie die m2v um b bytes reduzieren so sollte sich der"
echo "faktor  aus size/(size - b) berechnen lassen"
echo "bzw faktor= size/newsize" 
file=$2
faktor=$1
size=$(du "$file" | cut -f 1)
fileOut=${file%.m2v}_requant.m2v
echo "cat $file | requant $faktor 0 $size > $fileOut"
date 
cat "$file" | requant $faktor 0 $size > $fileOut
date
 
Parsed using GeSHi 1.0.8.6
Download / View Source / Run it   (depends on file type)
Der Downloadlink enthält den Wrapper und den Quellcode des Programms.

und das Programm selbst
show
requant/M2VRequantiser/main.c
// Code from libmpeg2 and mpeg2enc copyright by their respective owners
// New code and modifications copyright Antoine Missout
// Thanks to Sven Goethel for error resilience patches
// Released under GPL license, see gnu.org
 
// toggles:
 
// #define LOG_RATE_CONTROL // some stats
#undef DEMO // demo mode
// #define STAT // print stats on exit
// #define USE_FD // use 2 lasts args for input/output paths
 
#define NDEBUG // turns off asserts
#define REMOVE_BYTE_STUFFING	// removes series of 0x00
 
 
#if defined(__ppc__) || defined(__ppc64__)
	#define USE_GLOBAL_REGISTER // assign registers to bit buffers
#elif defined(__i386__)
	// #define USE_GLOBAL_REGISTER // assign registers to bit buffers
#else
	//#error "Unknown Architecture"
#endif
 
#define MAX_ERRORS 0 // if above copy slice
 
//#define CHANGE_BRIGHTNESS //add a param to command line, changing brightness: _will_not_recompress_, disables max_errors
//#define WIN // for windows fixes, use with USE_FD
 
// params:
 
// if not defined, non intra block in p frames are requantised
// if defined and >= 0, we keep coeff. in pos 0..n-1 in scan order
// and coeff which would have been non-null if requantised
// if defined and < 0 we drop max 1/x coeffs.
// experimental, looks better when undefined
// #define P_FRAME_NON_INTRA_DROP 8
 
// params for fact = 1.0, fact = 3.0 and fact = 5.0
// we'll make a linear interpolation between
static const int i_factors[3] = {  5, 15,  65 };
static const int p_factors[3] = {  5, 25,  85 };
static const int b_factors[3] = { 25, 45, 105 };
 
static const double i_min_stresses[3] = { 0.80, 0.50, 0.00 };
static const double p_min_stresses[3] = { 0.60, 0.35, 0.00 };
static const double b_min_stresses[3] = { 0.00, 0.00, 0.00 };
 
// factor up to which alt table will be used
// (though alt_table gives better psnr up to factor around ~2.5
// the result is less pleasing to watch than normal table
// so this is disabled)
static const double max_alt_table = 0.00;
 
// includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
 
#ifndef USE_FD
#include <unistd.h>
#include <fcntl.h>
#endif
 
// quant table
#include "qTable.h"
 
// useful constants
#define I_TYPE 1
#define P_TYPE 2
#define B_TYPE 3
 
#ifdef WIN
	#define MINLINE
#else
	#define MINLINE inline
#endif
 
// gcc
#ifdef HAVE_BUILTIN_EXPECT
	#define likely(x) __builtin_expect ((x) != 0, 1)
	#define unlikely(x) __builtin_expect ((x) != 0, 0)
#else
	#define likely(x) (x)
	#define unlikely(x) (x)
#endif
 
// user defined types
typedef unsigned int		uint;
typedef unsigned char		uint8;
typedef unsigned short		uint16;
typedef unsigned int		uint32;
#ifdef WIN
typedef __int64				uint64;
#else
typedef unsigned long long	uint64;
#endif
 
typedef char				int8;
typedef short				int16;
typedef int					int32;
#ifdef WIN
typedef __int64				int64;
#else
typedef long long			int64;
#endif
 
 
typedef signed int			sint;
typedef signed char			sint8;
typedef signed short		sint16;
typedef signed int			sint32;
#ifdef WIN
typedef __int64				sint64;
#else
typedef signed long long	sint64;
#endif
 
#define BITS_IN_BUF (8)
 
 
 
 
// global variables
static uint8	*cbuf, *rbuf, *wbuf, *orbuf, *owbuf;
#ifdef USE_GLOBAL_REGISTER
	register int	inbitcnt	asm ("r13");
	register int	outbitcnt   asm ("r14");
	register uint32	inbitbuf	asm ("r15");
	register uint32	outbitbuf   asm ("r16");
#else
	static int		inbitcnt, outbitcnt;
	static uint32	inbitbuf, outbitbuf;
#endif
static uint64	inbytecnt, outbytecnt;
static float	fact_x;
static int		mloka1, mloka2, eof;
 
static int64 orim2vsize;
static int64 bytediff;
static double stress_factor;	//	from 0.0 to 1.0
 
static int i_factor;
static int p_factor;
static int b_factor;
static double i_min_stress;
static double p_min_stress;
static double b_min_stress;
 
static short quant_table_id_data[4096];
static short *quant_table_id = &quant_table_id_data[2048];
 
#ifdef USE_FD
static FILE *ifd, *ofd;
#endif
 
#ifdef STAT
static uint64 ori_i, ori_p, ori_b;
static uint64 new_i, new_p, new_b;
static uint64 cnt_i, cnt_p, cnt_b;
static uint64 cnt_p_i, cnt_p_ni;
static uint64 cnt_b_i, cnt_b_ni;
#endif
 
#ifdef DEMO // gopCount variable
int gopCount;
#endif
 
#ifdef LOG_RATE_CONTROL
FILE* LOG_FILE;
#endif
 
#ifdef CHANGE_BRIGHTNESS
int delta_bright;
int dc_reset;
int old_dc_pred, new_dc_pred;
#endif
 
// mpeg2 state
	// seq header
	static uint horizontal_size_value;
	static uint vertical_size_value;
 
	// pic header
	static uint picture_coding_type;
 
	// pic code ext
	static uint f_code[2][2];
	static uint intra_dc_precision;
	static uint picture_structure;
	static uint frame_pred_frame_dct;
	static uint concealment_motion_vectors;
	static uint q_scale_type;
	static uint intra_vlc_format;
	static uint alternate_scan;
 
	// error
	static int validPicHeader;
	static int validSeqHeader;
	static int validExtHeader;
	static int sliceError;
 
	// slice or mb
	static uint quantizer_scale;
	static uint new_quantizer_scale;
	static uint last_coded_scale;
	static int  h_offset, v_offset;
	static int  mb_skip, mb_add;
	static int  mb_out;
 
	static int  mb_sav_run, mb_sav_lev, mb_sav_c;
	static short *curTable;
 
	// block data
	typedef struct
	{
		uint8 run;
		short level;
	} RunLevel;
 
	static RunLevel block[6][65]; // terminated by level = 0, so we need 64+1
// end mpeg2 state
 
#ifndef NDEBUG
	#define DEB(msg) fprintf (stderr, "%s:%d " msg, __FILE__, __LINE__)
	#define DEBF(format, args...) fprintf (stderr, "%s:%d " format, __FILE__, __LINE__, args)
#else
	#define DEB(msg)
	#ifdef WIN
		#define DEBF(format, args)
	#else
		#define DEBF(format, args...)
	#endif
#endif
 
#define LOG(msg) fprintf (stderr, msg)
#ifdef WIN
	#define LOGF(format, arg1) fprintf (stderr, format, arg1)
#else
	#define LOGF(format, args...) fprintf (stderr, format, args)
#endif
 
 
#define BUF_SIZE (16*1024*1024)
#define MIN_READ (4*1024*1024)
#define MIN_WRITE (8*1024*1024)
#define MAX_READ (10*1024*1024)
 
#define MOV_READ \
	mloka1 = rbuf - cbuf; if (mloka1) memmove(orbuf, cbuf, mloka1);\
	cbuf = rbuf = orbuf; rbuf += mloka1;
 
#ifdef USE_FD
 
	#define WRITE \
		mloka1 = wbuf - owbuf; \
		fwrite(owbuf, mloka1, 1, ofd); \
		outbytecnt += mloka1; \
		wbuf = owbuf;
 
	#define LOCK(x) \
		while (unlikely(x > (rbuf-cbuf))) \
		{ \
			if (!eof)\
			{ \
				mloka2 = MIN_READ; \
				while (mloka2) \
				{\
					assert(rbuf + mloka2 < orbuf + BUF_SIZE); \
					mloka1 = fread(rbuf, 1, mloka2, ifd); \
					if (mloka1 <= 0) { eof = 1; break; } \
					inbytecnt += mloka1; \
					rbuf += mloka1; \
					mloka2 -= mloka1; \
				}\
			} else { RETURN } \
		}
 
#else
 
	#define WRITE \
		mloka1 = wbuf - owbuf; \
		write(1, owbuf, mloka1); \
		outbytecnt += mloka1; \
		wbuf = owbuf; \
		mloka1 = rbuf - cbuf; if (mloka1) memmove(orbuf, cbuf, mloka1);\
		cbuf = rbuf = orbuf; rbuf += mloka1;
 
	#define LOCK(x) \
		while (unlikely(x > (rbuf-cbuf))) \
		{ \
			if (!eof)\
			{ \
				mloka2 = MIN_READ; \
				while (mloka2) \
				{\
					assert(rbuf + mloka2 < orbuf + BUF_SIZE); \
					mloka1 = read(0, rbuf, mloka2); \
					if (mloka1 <= 0) { eof = 1; break; } \
					inbytecnt += mloka1; \
					rbuf += mloka1; \
					mloka2 -= mloka1; \
				}\
			} else { RETURN } \
		}
 
#endif
 
#ifdef STAT
 
	#define RETURN \
		assert(rbuf >= cbuf);\
		mloka1 = rbuf - cbuf;\
		if (mloka1) { COPY(mloka1); }\
		WRITE \
		free(orbuf); \
		free(owbuf); \
		\
		LOG("Stats:\n");\
		\
		LOGF("Wanted fact_x: %.1f\n", fact_x);\
		\
		LOGF("cnt_i: %.0f ", (float)cnt_i); \
		if (cnt_i) LOGF("ori_i: %.0f new_i: %.0f fact_i: %.1f\n", (float)ori_i, (float)new_i, (float)ori_i/(float)new_i); \
		else LOG("\n");\
		\
		LOGF("cnt_p: %.0f ", (float)cnt_p); \
		if (cnt_p) LOGF("ori_p: %.0f new_p: %.0f fact_p: %.1f cnt_p_i: %.0f cnt_p_ni: %.0f propor: %.1f i\n", \
			(float)ori_p, (float)new_p, (float)ori_p/(float)new_p, (float)cnt_p_i, (float)cnt_p_ni, (float)cnt_p_i/((float)cnt_p_i+(float)cnt_p_ni)); \
		else LOG("\n");\
		\
		LOGF("cnt_b: %.0f ", (float)cnt_b); \
		if (cnt_b) LOGF("ori_b: %.0f new_b: %.0f fact_b: %.1f cnt_b_i: %.0f cnt_b_ni: %.0f propor: %.1f i\n", \
			(float)ori_b, (float)new_b, (float)ori_b/(float)new_b, (float)cnt_b_i, (float)cnt_b_ni, (float)cnt_b_i/((float)cnt_b_i+(float)cnt_b_ni)); \
		else LOG("\n");\
		\
		LOGF("Final fact_x: %.1f\n", (float)inbytecnt/(float)outbytecnt);\
		exit(0);
 
#else
 
	#define RETURN \
		assert(rbuf >= cbuf);\
		mloka1 = rbuf - cbuf;\
		if (mloka1) { COPY(mloka1); }\
		WRITE \
		free(orbuf); \
		free(owbuf); \
		exit(0);
 
#endif
 
#define COPY(x)\
		assert(x > 0); \
		assert(wbuf + x < owbuf + BUF_SIZE); \
		assert(cbuf + x < orbuf + BUF_SIZE); \
		assert(cbuf + x >= orbuf); \
		assert(wbuf + x >= orbuf); \
		memcpy(wbuf, cbuf, x);\
		cbuf += x; \
		wbuf += x;
 
#define SEEKR(x)\
		cbuf += x; \
		assert (cbuf <= rbuf); \
		assert (cbuf < orbuf + BUF_SIZE); \
		assert (cbuf >= orbuf);
 
#define SEEKW(x)\
		wbuf += x; \
		assert (wbuf < owbuf + BUF_SIZE); \
		assert (wbuf >= owbuf);
 
static MINLINE void putbits(uint val, int n)
{
	assert(n < 32);
	assert(!(val & (0xffffffffU << n)));
 
	while (unlikely(n >= outbitcnt))
	{
		wbuf[0] = (outbitbuf << outbitcnt ) | (val >> (n - outbitcnt));
		SEEKW(1);
		n -= outbitcnt;
		outbitbuf = 0;
		val &= ~(0xffffffffU << n);
		outbitcnt = BITS_IN_BUF;
	}
 
	if (likely(n))
	{
		outbitbuf = (outbitbuf << n) | val;
		outbitcnt -= n;
	}
 
	assert(outbitcnt > 0);
	assert(outbitcnt <= BITS_IN_BUF);
}
 
static MINLINE void Refill_bits(void)
{
	assert((rbuf - cbuf) >= 1);
	inbitbuf |= cbuf[0] << (24 - inbitcnt);
	inbitcnt += 8;
	SEEKR(1)
}
 
static MINLINE void Flush_Bits(uint n)
{
	assert(inbitcnt >= n);
 
	inbitbuf <<= n;
	inbitcnt -= n;
 
	assert( (!n) || ((n>0) && !(inbitbuf & 0x1)) );
 
	while (unlikely(inbitcnt < 24)) Refill_bits();
}
 
static MINLINE uint Show_Bits(uint n)
{
	return ((unsigned int)inbitbuf) >> (32 - n);
}
 
static MINLINE uint Get_Bits(uint n)
{
	uint Val = Show_Bits(n);
	Flush_Bits(n);
	return Val;
}
 
static MINLINE uint Copy_Bits(uint n)
{
	uint Val = Get_Bits(n);
	putbits(Val, n);
	return Val;
}
 
static MINLINE void flush_read_buffer()
{
	int i = inbitcnt & 0x7;
	if (i)
	{
		if (inbitbuf >> (32 - i))
		{
			DEBF("illegal inbitbuf: 0x%08X, %i, 0x%02X, %i\n", inbitbuf, inbitcnt, (inbitbuf >> (32 - i)), i);
			sliceError++;
		}
 
		inbitbuf <<= i;
		inbitcnt -= i;
	}
	SEEKR(-1 * (inbitcnt >> 3));
	inbitcnt = 0;
}
 
static MINLINE void flush_write_buffer()
{
	if (outbitcnt != 8) putbits(0, outbitcnt);
}
 
/////---- begin ext mpeg code
 
const uint8 non_linear_mquant_table[32] =
{
	0, 1, 2, 3, 4, 5, 6, 7,
	8,10,12,14,16,18,20,22,
	24,28,32,36,40,44,48,52,
	56,64,72,80,88,96,104,112
};
const uint8 map_non_linear_mquant[113] =
{
	0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,
	16,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22,
	22,22,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26,
	26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,29,
	29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,31,31
};
 
static int scale_quant(double quant )
{
	int iquant;
	if (q_scale_type)
	{
		iquant = (int) floor(quant+0.5);
		/* clip mquant to legal (linear) range */
		if (iquant<1) iquant = 1;
		if (iquant>112) iquant = 112;
		iquant = non_linear_mquant_table[map_non_linear_mquant[iquant]];
	}
	else
	{
		/* clip mquant to legal (linear) range */
		iquant = (int)floor(quant+0.5);
		if (iquant<2) iquant = 2;
		if (iquant>62) iquant = 62;
		iquant = (iquant/2)*2; // Must be *even*
	}
	return iquant;
}
 
static int increment_quant(int quant)
{
	if (q_scale_type)
	{
		if (quant < 1 || quant > 112)
		{
			DEBF("illegal quant: %d\n", quant);
			if (quant > 112) quant = 112;
			else if (quant < 1) quant = 1;
			DEBF("illegal quant changed to : %d\n", quant);
			sliceError++;
		}
		quant = map_non_linear_mquant[quant] + 1;
		if (quant > 31) quant = 31;
		quant = non_linear_mquant_table[quant];
	}
	else
	{
		if ((quant & 1) || (quant < 2) || (quant > 62))
		{
			DEBF("illegal quant: %d\n", quant);
			if (quant & 1) quant--;
			if (quant > 62) quant = 62;
			else if (quant < 2) quant = 2;
			DEBF("illegal quant changed to : %d\n", quant);
			sliceError++;
		}
		quant += 2;
		if (quant > 62) quant = 62;
	}
	return quant;
}
 
static MINLINE int intmax( register int x, register int y )
{ return x < y ? y : x; }
 
static MINLINE int intmin( register int x, register int y )
{ return x < y ? x : y; }
 
 
static int getNewQuant(int curQuant, int intra)
{
#ifdef CHANGE_BRIGHTNESS
	return curQuant;
#else
	int mquant = 0;
	double cStress;
 
	switch (picture_coding_type)
	{
		case I_TYPE:
			cStress = (stress_factor - i_min_stress) / (1.0 - i_min_stress);
			mquant = intmax(scale_quant(curQuant + i_factor*cStress), increment_quant(curQuant));
			break;
 
		case P_TYPE:
			cStress = (stress_factor - p_min_stress) / (1.0 - p_min_stress);
			if (intra) // since it might be used as a ref, treat it as an I frame block
				mquant = intmax(scale_quant(curQuant + i_factor*cStress), increment_quant(curQuant));
			else
				mquant = intmax(scale_quant(curQuant + p_factor*cStress), increment_quant(curQuant));
			break;
 
		case B_TYPE:
			cStress = (stress_factor - b_min_stress) / (1.0 - b_min_stress);
			mquant = intmax(scale_quant(curQuant + b_factor*cStress), increment_quant(curQuant));
			break;
 
		default:
			assert(0);
			break;
	}
 
	assert(mquant >= curQuant);
 
	return mquant;
#endif
}
 
static MINLINE int isNotEmpty(RunLevel *blk)
{
	return (blk->level);
}
 
#include "putvlc.h"
 
// return != 0 if error
int putAC(int run, int signed_level, int vlcformat)
{
	int level, len;
	const VLCtable *ptab = NULL;
 
	level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */
 
	// assert(!(run<0 || run>63 || level==0 || level>2047));
	if(run<0 || run>63)
	{
		DEBF("illegal run: %d\n", run);
		sliceError++;
		return 1;
	}
	if(level==0 || level>2047)
	{
		DEBF("illegal level: %d\n", level);
		sliceError++;
		return 1;
	}
 
	len = 0;
 
	if (run<2 && level<41)
	{
		if (vlcformat)  ptab = &dct_code_tab1a[run][level-1];
		else ptab = &dct_code_tab1[run][level-1];
		len = ptab->len;
	}
	else if (run<32 && level<6)
	{
		if (vlcformat) ptab = &dct_code_tab2a[run-2][level-1];
		else ptab = &dct_code_tab2[run-2][level-1];
		len = ptab->len;
	}
 
	if (len) /* a VLC code exists */
	{
		putbits(ptab->code, len);
		putbits(signed_level<0, 1); /* sign */
	}
	else
	{
		putbits(1l, 6); /* Escape */
		putbits(run, 6); /* 6 bit code for run */
		putbits(((uint)signed_level) & 0xFFF, 12);
	}
 
	return 0;
}
 
// return != 0 if error
static MINLINE int putACfirst(int run, int val)
{
	if (run==0 && (val==1 || val==-1))
	{
		putbits(2|((val<0) ? 1 : 0), 2);
		return 0;
	}
	else return putAC(run,val,0);
}
 
void putnonintrablk(RunLevel *blk)
{
	assert(blk->level);
 
	if (putACfirst(blk->run, blk->level)) return;
	blk++;
 
	while(blk->level)
	{
		if (putAC(blk->run, blk->level, 0)) return;
		blk++;
	}
 
	putbits(2,2);
}
 
static MINLINE void putcbp(int cbp)
{
	assert(cbp > 0 && cbp < 64);
	putbits(cbptable[cbp].code,cbptable[cbp].len);
}
 
static void putmbtype(int mb_type)
{
	putbits(mbtypetab[picture_coding_type-1][mb_type].code,
			mbtypetab[picture_coding_type-1][mb_type].len);
}
 
#ifndef WIN
#include <inttypes.h>
#else
typedef uint8	uint8_t;
typedef int8	int8_t;
typedef uint32	uint32_t;
typedef int32	int32_t;
#endif
#include "getvlc.h"
 
static int non_linear_quantizer_scale [] =
{
     0,  1,  2,  3,  4,  5,   6,   7,
     8, 10, 12, 14, 16, 18,  20,  22,
    24, 28, 32, 36, 40, 44,  48,  52,
    56, 64, 72, 80, 88, 96, 104, 112
};
 
static MINLINE int get_macroblock_modes ()
{
    int macroblock_modes;
    const MBtab * tab;
 
    switch (picture_coding_type)
	{
		case I_TYPE:
 
			tab = MB_I + UBITS (bit_buf, 1);
			DUMPBITS (bit_buf, bits, tab->len);
			macroblock_modes = tab->modes;
 
			if ((! (frame_pred_frame_dct)) && (picture_structure == FRAME_PICTURE))
			{
				macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
				DUMPBITS (bit_buf, bits, 1);
			}
 
			return macroblock_modes;
 
		case P_TYPE:
 
			tab = MB_P + UBITS (bit_buf, 5);
			DUMPBITS (bit_buf, bits, tab->len);
			macroblock_modes = tab->modes;
 
			if (picture_structure != FRAME_PICTURE)
			{
				if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
				{
					macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
					DUMPBITS (bit_buf, bits, 2);
				}
				return macroblock_modes;
			}
			else if (frame_pred_frame_dct)
			{
				if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
					macroblock_modes |= MC_FRAME;
				return macroblock_modes;
			}
			else
			{
				if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
				{
					macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
					DUMPBITS (bit_buf, bits, 2);
				}
				if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
				{
					macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
					DUMPBITS (bit_buf, bits, 1);
				}
				return macroblock_modes;
			}
 
		case B_TYPE:
 
			tab = MB_B + UBITS (bit_buf, 6);
			DUMPBITS (bit_buf, bits, tab->len);
			macroblock_modes = tab->modes;
 
			if (picture_structure != FRAME_PICTURE)
			{
				if (! (macroblock_modes & MACROBLOCK_INTRA))
				{
					macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
					DUMPBITS (bit_buf, bits, 2);
				}
				return macroblock_modes;
			}
			else if (frame_pred_frame_dct)
			{
				/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
				macroblock_modes |= MC_FRAME;
				return macroblock_modes;
			}
			else
			{
				if (macroblock_modes & MACROBLOCK_INTRA) goto intra;
				macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
				DUMPBITS (bit_buf, bits, 2);
				if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
				{
					intra:
					macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
					DUMPBITS (bit_buf, bits, 1);
				}
				return macroblock_modes;
			}
 
		default:
			return 0;
    }
 
}
 
static MINLINE int get_quantizer_scale ()
{
    int quantizer_scale_code;
 
    quantizer_scale_code = UBITS (bit_buf, 5);
	DUMPBITS (bit_buf, bits, 5); 
 
	if (!quantizer_scale_code)
    {
		DEBF("illegal quant scale code: %d\n", quantizer_scale_code);
		sliceError++;
		quantizer_scale_code++;
    }
 
	if (q_scale_type) return non_linear_quantizer_scale[quantizer_scale_code];
    else return quantizer_scale_code << 1;
}
 
static MINLINE void get_motion_delta (const int f_code)
{
#define bit_buf (inbitbuf)
    const MVtab * tab;
 
    if (bit_buf & 0x80000000)
	{
		COPYBITS (bit_buf, bits, 1);
		return;
    }
	else if (bit_buf >= 0x0c000000)
	{
 
		tab = MV_4 + UBITS (bit_buf, 4);
		COPYBITS (bit_buf, bits, tab->len + 1);
		if (f_code) COPYBITS (bit_buf, bits, f_code);
		return;
    }
	else
	{
 
		tab = MV_10 + UBITS (bit_buf, 10);
		COPYBITS (bit_buf, bits, tab->len + 1);
		if (f_code) COPYBITS (bit_buf, bits, f_code);
		return;
    }
}
 
 
static MINLINE void get_dmv ()
{
    const DMVtab * tab;
    tab = DMV_2 + UBITS (bit_buf, 2);
    COPYBITS (bit_buf, bits, tab->len);
    return;
}
 
static MINLINE int get_coded_block_pattern ()
{
#define bit_buf (inbitbuf)
    const CBPtab * tab;
 
    if (bit_buf >= 0x20000000)
	{
		tab = CBP_7 + (UBITS (bit_buf, 7) - 16);
		DUMPBITS (bit_buf, bits, tab->len);
		return tab->cbp;
    }
	else
	{
		tab = CBP_9 + UBITS (bit_buf, 9);
		DUMPBITS (bit_buf, bits, tab->len);
		return tab->cbp;
    }
}
 
static MINLINE int get_luma_dc_dct_diff ()
{
#define bit_buf (inbitbuf)
#ifdef CHANGE_BRIGHTNESS
	#define DOBITS(x, y, z) DUMPBITS(x, y, z)
#else
	#define DOBITS(x, y, z) COPYBITS(x, y, z)
#endif
    const DCtab * tab;
    int size;
    int dc_diff;
 
    if (bit_buf < 0xf8000000)
	{
		tab = DC_lum_5 + UBITS (bit_buf, 5);
		size = tab->size;
		if (size)
		{
			DOBITS (bit_buf, bits, tab->len);
			//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
			dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
			DOBITS (bit_buf, bits, size);
			return dc_diff;
		}
		else
		{
			DOBITS (bit_buf, bits, 3);
			return 0;
		}
    }
	else
	{
		tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0);
		size = tab->size;
		DOBITS (bit_buf, bits, tab->len);
		//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
		dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
		DOBITS (bit_buf, bits, size);
		return dc_diff;
    }
}
 
static MINLINE int get_chroma_dc_dct_diff ()
{
#define bit_buf (inbitbuf)
 
    const DCtab * tab;
    int size;
    int dc_diff;
 
    if (bit_buf < 0xf8000000)
	{
		tab = DC_chrom_5 + UBITS (bit_buf, 5);
		size = tab->size;
		if (size)
		{
			COPYBITS (bit_buf, bits, tab->len);
			//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
			dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
			COPYBITS (bit_buf, bits, size);
			return dc_diff;
		} else
		{
			COPYBITS (bit_buf, bits, 2);
			return 0;
		}
    }
	else
	{
		tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0);
		size = tab->size;
		COPYBITS (bit_buf, bits, tab->len + 1);
		//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
		dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
		COPYBITS (bit_buf, bits, size);
		return dc_diff;
    }
}
 
#define UPDATE_VAL \
	val = curTable[val];
 
static void get_intra_block_B14 ()
{
#define bit_buf (inbitbuf)
    int i, li;
    int val;
    const DCTtab * tab;
 
    li = i = 0;
 
    while (1)
	{
		if (bit_buf >= 0x28000000)
		{
			tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
 
			i += tab->run;
			if (i >= 64) break;	/* end of block */
 
	normal_code:
			DUMPBITS (bit_buf, bits, tab->len);
			val = tab->level;
			val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
			UPDATE_VAL
			if (val)
			{
				if (putAC(i - li - 1, val, 0)) break;
				li = i;
			}
 
			DUMPBITS (bit_buf, bits, 1);
 
			continue;
		}
		else if (bit_buf >= 0x04000000)
		{
			tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
 
			i += tab->run;
			if (i < 64) goto normal_code;
 
			/* escape code */
			i += (UBITS (bit_buf, 12) & 0x3F) - 64;
			if (i >= 64) 
			{
				sliceError++;
				break;	/* illegal, check needed to avoid buffer overflow */
			}
 
			DUMPBITS (bit_buf, bits, 12);
			val = SBITS (bit_buf, 12);
			UPDATE_VAL
			if (val)
			{
				if (putAC(i - li - 1, val, 0)) break;
				li = i;
			}
 
			DUMPBITS (bit_buf, bits, 12);
 
			continue;
		}
		else if (bit_buf >= 0x02000000)
		{
			tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00800000)
		{
			tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00200000)
		{
			tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else
		{
			tab = DCT_16 + UBITS (bit_buf, 16);
			DUMPBITS (bit_buf, bits, 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		sliceError++;
		break;	/* illegal, check needed to avoid buffer overflow */
	}
 
	COPYBITS (bit_buf, bits, 2);	/* end of block code */
}
 
static void get_intra_block_B15 ()
{
#define bit_buf (inbitbuf)
    int i, li;
    int val;
    const DCTtab * tab;
 
    li = i = 0;
 
    while (1)
	{
		if (bit_buf >= 0x04000000)
		{
			tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4);
 
			i += tab->run;
			if (i < 64)
			{
	normal_code:
				DUMPBITS (bit_buf, bits, tab->len);
 
				val = tab->level;
				val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
				UPDATE_VAL
				if (val)
				{
					if (putAC(i - li - 1, val, 1)) break;
					li = i;
				}
 
				DUMPBITS (bit_buf, bits, 1);
 
				continue;
			}
			else
			{
				if (i >= 128) break; /* end of block */
 
				i += (UBITS (bit_buf, 12) & 0x3F) - 64;
 
				if (i >= 64)
				{
					sliceError++;
					break;	/* illegal, check against buffer overflow */
				}
 
				DUMPBITS (bit_buf, bits, 12);
				val = SBITS (bit_buf, 12);
				UPDATE_VAL
				if (val)
				{
					if (putAC(i - li - 1, val, 1)) break;
					li = i;
				}
 
				DUMPBITS (bit_buf, bits, 12);
 
				continue;
			}
		}
		else if (bit_buf >= 0x02000000)
		{
			tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00800000)
		{
			tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00200000)
		{
			tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else
		{
			tab = DCT_16 + UBITS (bit_buf, 16);
			DUMPBITS (bit_buf, bits, 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		sliceError++;
		break;	/* illegal, check needed to avoid buffer overflow */
	}
 
	COPYBITS (bit_buf, bits, 4);	/* end of block code */
}
 
static int get_non_intra_block_rq (RunLevel *blk)
{
#define bit_buf (inbitbuf)
	//int q = quantizer_scale;
	//int nq = new_quantizer_scale, tst = (nq / q) + ((nq % q) ? 1 : 0);
    int i, li;
    int val;
    const DCTtab * tab;
 
    li = i = -1;
 
    if (bit_buf >= 0x28000000)
	{
		tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
		goto entry_1;
    }
	else goto entry_2;
 
    while (1)
	{
		if (bit_buf >= 0x28000000)
		{
			tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
 
	entry_1:
			i += tab->run;
			if (i >= 64)
			break;	/* end of block */
 
	normal_code:
 
			DUMPBITS (bit_buf, bits, tab->len);
			val = tab->level;
			val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
			UPDATE_VAL
			if (val)
			{
				blk->level = val;
				blk->run = i - li - 1;
				li = i;
				blk++;
			}
 
			DUMPBITS (bit_buf, bits, 1);
 
			continue;
		}
 
	entry_2:
		if (bit_buf >= 0x04000000)
		{
			tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
 
			i += tab->run;
			if (i < 64) goto normal_code;
 
			/* escape code */
 
			i += (UBITS (bit_buf, 12) & 0x3F) - 64;
 
			if (i >= 64)
			{
				sliceError++;
				break;	/* illegal, check needed to avoid buffer overflow */
			}
 
			DUMPBITS (bit_buf, bits, 12);
			val = SBITS (bit_buf, 12);
			UPDATE_VAL
			if (val)
			{
				blk->level = val;
				blk->run = i - li - 1;
				li = i;
				blk++;
			}
 
			DUMPBITS (bit_buf, bits, 12);
 
			continue;
		}
		else if (bit_buf >= 0x02000000)
		{
			tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00800000)
		{
			tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00200000)
		{
			tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else
		{
			tab = DCT_16 + UBITS (bit_buf, 16);
			DUMPBITS (bit_buf, bits, 16);
 
			i += tab->run;
			if (i < 64) goto normal_code;
		}
 
		sliceError++;
		break;	/* illegal, check needed to avoid buffer overflow */
	}
    DUMPBITS (bit_buf, bits, 2);	/* dump end of block code */
 
	blk->level = 0;
 
    return i;
}
 
#ifdef P_FRAME_NON_INTRA_DROP
	#if (P_FRAME_NON_INTRA_DROP < 0)
		#undef UPDATE_VAL
		#define UPDATE_VAL
		#define SAVE_VAL
		#define WRITE_VAL \
			blk->level = val; \
			blk->run = i - li - 1; \
			li = i; \
			blk++;
	#else
		#define SAVE_VAL oval = val;
		#define WRITE_VAL \
			if ((val) || (i < P_FRAME_NON_INTRA_DROP)) \
			{ \
				blk->level = oval; \
				blk->run = i - li - 1; \
				li = i; \
				blk++; \
			}
	#endif
#else
	#define SAVE_VAL
	#define WRITE_VAL \
		if (val) \
		{ \
			blk->level = val; \
			blk->run = i - li - 1; \
			li = i; \
			blk++; \
		}
#endif
 
static int get_non_intra_block_sav (RunLevel *blk, int cc)
{
#define bit_buf (inbitbuf)
    int i, li;
    int val;
    const DCTtab * tab;
 
#ifdef P_FRAME_NON_INTRA_DROP
	#if (P_FRAME_NON_INTRA_DROP < 0)
		RunLevel *oblk = blk;
	#else
		int oval;
	#endif
#endif
 
    li = i = -1;
 
    if (bit_buf >= 0x28000000)
	{
		tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
		goto entry_1;
    }
	else goto entry_2;
 
    while (1)
	{
		if (bit_buf >= 0x28000000)
		{
			tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
 
	entry_1:
			i += tab->run;
			if (i >= 64)
			break;	/* end of block */
 
	normal_code:
 
			DUMPBITS (bit_buf, bits, tab->len);
			val = tab->level;
			val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
			SAVE_VAL
			if (li == -1)
			{
				if (abs(val) < abs(mb_sav_lev))
				{
					mb_sav_c = cc;
					mb_sav_lev = val;
					mb_sav_run = i - li - 1;
				}
			}
			UPDATE_VAL
			WRITE_VAL
 
			DUMPBITS (bit_buf, bits, 1);
 
			continue;
		}
 
	entry_2:
		if (bit_buf >= 0x04000000)
		{
			tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
 
			i += tab->run;
			if (i < 64) goto normal_code;
 
			/* escape code */
 
			i += (UBITS (bit_buf, 12) & 0x3F) - 64;
 
			if (i >= 64)
			{
				sliceError++;
				break;	/* illegal, check needed to avoid buffer overflow */
			}
 
			DUMPBITS (bit_buf, bits, 12);
			val = SBITS (bit_buf, 12);
			SAVE_VAL
			if (li == -1)
			{
				if (abs(val) < abs(mb_sav_lev))
				{
					mb_sav_c = cc;
					mb_sav_lev = val;
					mb_sav_run = i - li - 1;
				}
			}
			UPDATE_VAL
			WRITE_VAL
 
			DUMPBITS (bit_buf, bits, 12);
 
			continue;
		}
		else if (bit_buf >= 0x02000000)
		{
			tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00800000)
		{
			tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00200000)
		{
			tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else
		{
			tab = DCT_16 + UBITS (bit_buf, 16);
			DUMPBITS (bit_buf, bits, 16);
 
			i += tab->run;
			if (i < 64) goto normal_code;
		}
 
		sliceError++;
		break;	/* illegal, check needed to avoid buffer overflow */
	}
    DUMPBITS (bit_buf, bits, 2);	/* dump end of block code */
 
#ifdef P_FRAME_NON_INTRA_DROP
	#if (P_FRAME_NON_INTRA_DROP < 0)
		blk -= (int)((blk - oblk) * (stress_factor / P_FRAME_NON_INTRA_DROP));
		#ifdef DEMO // P_FRAME_NON_INTRA_DROP
			if ((gopCount & 0x7F) < 10) blk = oblk;
		#endif
	#endif
#endif
 
	blk->level = 0;
 
    return i;
}
 
#ifdef P_FRAME_NON_INTRA_DROP
static int get_non_intra_block_drop (RunLevel *blk, int cc)
{
#define bit_buf (inbitbuf)
    int i, li;
    int val;
    const DCTtab * tab;
	#if (P_FRAME_NON_INTRA_DROP < 0)
		RunLevel *oblk = blk;
	#else
		int oval;
	#endif
 
    li = i = -1;
 
    if (bit_buf >= 0x28000000)
	{
		tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5);
		goto entry_1;
    }
	else goto entry_2;
 
    while (1)
	{
		if (bit_buf >= 0x28000000)
		{
			tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5);
 
	entry_1:
			i += tab->run;
			if (i >= 64)
			break;	/* end of block */
 
	normal_code:
 
			DUMPBITS (bit_buf, bits, tab->len);
			val = tab->level;
			val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
			SAVE_VAL
			UPDATE_VAL
			WRITE_VAL
 
			DUMPBITS (bit_buf, bits, 1);
 
			continue;
		}
 
	entry_2:
		if (bit_buf >= 0x04000000)
		{
			tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
 
			i += tab->run;
			if (i < 64) goto normal_code;
 
			/* escape code */
 
			i += (UBITS (bit_buf, 12) & 0x3F) - 64;
 
			if (i >= 64)
			{
				sliceError++;
				break;	/* illegal, check needed to avoid buffer overflow */
			}
 
			DUMPBITS (bit_buf, bits, 12);
			val = SBITS (bit_buf, 12);
			SAVE_VAL
			UPDATE_VAL
			WRITE_VAL
 
			DUMPBITS (bit_buf, bits, 12);
 
			continue;
		}
		else if (bit_buf >= 0x02000000)
		{
			tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00800000)
		{
			tab = DCT_13 + (UBITS (bit_buf, 13) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else if (bit_buf >= 0x00200000)
		{
			tab = DCT_15 + (UBITS (bit_buf, 15) - 16);
			i += tab->run;
			if (i < 64) goto normal_code;
		}
		else
		{
			tab = DCT_16 + UBITS (bit_buf, 16);
			DUMPBITS (bit_buf, bits, 16);
 
			i += tab->run;
			if (i < 64) goto normal_code;
		}
 
		sliceError++;
		break;	/* illegal, check needed to avoid buffer overflow */
	}
    DUMPBITS (bit_buf, bits, 2);	/* dump end of block code */
 
	#if (P_FRAME_NON_INTRA_DROP < 0)
		blk -= (int)((blk - oblk) * (stress_factor / P_FRAME_NON_INTRA_DROP));
		#ifdef DEMO // P_FRAME_NON_INTRA_DROP
			if ((gopCount & 0x7F) < 10) blk = oblk;
		#endif
	#endif
 
	blk->level = 0;
 
    return i;
}
#endif
 
#ifdef CHANGE_BRIGHTNESS
static void putDC(const sVLCtable *tab, int val)
{
	int absval, size;
	absval = abs(val);
	size = 0;
	while (absval)
	{
		absval >>= 1;
		size++;
	}
	putbits(tab[size].code,tab[size].len);
	if (size!=0)
	{
		if (val>=0) absval = val;
		else absval = val + (1<<size) - 1; /* val + (2 ^ size) - 1 */
		putbits(absval,size);
	}
}
#endif
static MINLINE void slice_intra_DCT (const int cc)
{
#ifdef CHANGE_BRIGHTNESS
    if (cc == 0)
	{
		int val;
		int bri = get_luma_dc_dct_diff();
		if (dc_reset)
		{
			val = bri + (128 << intra_dc_precision);
			old_dc_pred = val;
 
				val += delta_bright << intra_dc_precision;
				if (val > (255 << intra_dc_precision)) val = 255 << intra_dc_precision;
				else if (val < 0) val = 0;
 
			bri = val - (128 << intra_dc_precision);
			new_dc_pred = val;
 
			dc_reset = 0;
		}
		else
		{
			val = bri + old_dc_pred;
			old_dc_pred = val;
 
				val += delta_bright << intra_dc_precision;
				if (val > (255 << intra_dc_precision)) val = 255 << intra_dc_precision;
				else if (val < 0) val = 0;
 
			bri = val - new_dc_pred;
			new_dc_pred = val;
		}
		putDC(DClumtab, bri);
	}
#else
	if (cc == 0)	get_luma_dc_dct_diff ();
#endif
    else			get_chroma_dc_dct_diff ();
 
    if (intra_vlc_format) get_intra_block_B15 ();
    else get_intra_block_B14 ();
}
 
static MINLINE void slice_non_intra_DCT (int cur_block)
{
#ifdef P_FRAME_NON_INTRA_DROP
	if (picture_coding_type == P_TYPE)
	{
		if ((h_offset == 0) || (h_offset == horizontal_size_value - 16))
			get_non_intra_block_sav(block[cur_block], cur_block);
		else
			get_non_intra_block_drop(block[cur_block], cur_block);
	}
	else
		get_non_intra_block_rq(block[cur_block]);
#else
	if ((picture_coding_type == P_TYPE) && ((h_offset == 0) || (h_offset == horizontal_size_value - 16)))
		get_non_intra_block_sav(block[cur_block], cur_block);
	else
		get_non_intra_block_rq(block[cur_block]);
#endif
}
 
static void motion_fr_frame ( uint f_code[2] )
{
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
}
 
static void motion_fr_field ( uint f_code[2] )
{
    COPYBITS (bit_buf, bits, 1);
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
 
    COPYBITS (bit_buf, bits, 1);
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
}
 
static void motion_fr_dmv ( uint f_code[2] )
{
    get_motion_delta (f_code[0]);
	get_dmv ();
 
	get_motion_delta (f_code[1]);
	get_dmv ();
}
 
static void motion_fr_conceal ( )
{
	get_motion_delta (f_code[0][0]);
	get_motion_delta (f_code[0][1]);
 
    COPYBITS (bit_buf, bits, 1);
}
 
static void motion_fi_field ( uint f_code[2] )
{
    COPYBITS (bit_buf, bits, 1);
 
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
}
 
static void motion_fi_16x8 ( uint f_code[2] )
{
    COPYBITS (bit_buf, bits, 1);
 
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
 
    COPYBITS (bit_buf, bits, 1);
 
	get_motion_delta (f_code[0]);
	get_motion_delta (f_code[1]);
}
 
static void motion_fi_dmv ( uint f_code[2] )
{
	get_motion_delta (f_code[0]);
    get_dmv ();
 
    get_motion_delta (f_code[1]);
	get_dmv ();
}
 
static void motion_fi_conceal ()
{
    COPYBITS (bit_buf, bits, 1);
 
	get_motion_delta (f_code[0][0]);
	get_motion_delta (f_code[0][1]);
 
    COPYBITS (bit_buf, bits, 1);
}
 
#define MOTION_CALL(routine,direction) 						\
do {														\
    if ((direction) & MACROBLOCK_MOTION_FORWARD)			\
		routine (f_code[0]);								\
    if ((direction) & MACROBLOCK_MOTION_BACKWARD)			\
		routine (f_code[1]);								\
} while (0)
 
#define NEXT_MACROBLOCK											\
do {															\
    h_offset += 16;												\
    if (h_offset == horizontal_size_value) 						\
	{															\
		v_offset += 16;											\
		if (v_offset > (vertical_size_value - 16)) return;		\
		h_offset = 0;											\
    }															\
} while (0)
 
void putmbdata(int macroblock_modes)
{
		putmbtype(macroblock_modes & 0x1F);
 
		/*switch (picture_coding_type)
		{
			case I_TYPE:
				if ((! (frame_pred_frame_dct)) && (picture_structure == FRAME_PICTURE))
					putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1);
				break;
 
			case P_TYPE:
				if (picture_structure != FRAME_PICTURE)
				{
					if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
						putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
					break;
				}
				else if (frame_pred_frame_dct) break;
				else
				{
					if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
						putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
					if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
						putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1);
					break;
				}
 
			case B_TYPE:
				if (picture_structure != FRAME_PICTURE)
				{
					if (! (macroblock_modes & MACROBLOCK_INTRA))
						putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
					break;
				}
				else if (frame_pred_frame_dct) break;
				else
				{
					if (macroblock_modes & MACROBLOCK_INTRA) goto intra;
					putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
					if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
					{
						intra:
						putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1);
					}
					break;
				}
		}*/
 
		if (macroblock_modes & (MACROBLOCK_MOTION_FORWARD | MACROBLOCK_MOTION_BACKWARD))
		{
			if (picture_structure == FRAME_PICTURE)
			{
				if (frame_pred_frame_dct == 0)
				{
					putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
				}
			}
			else
			{
				putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2);
			}
		}
		if ((picture_structure == FRAME_PICTURE) && (frame_pred_frame_dct == 0) && (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)))
		{
			putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1);
		}
}
 
static MINLINE void put_quantiser(int quantiser)
{
	putbits(q_scale_type ? map_non_linear_mquant[quantiser] : quantiser >> 1, 5);
	last_coded_scale = quantiser;
}
 
static void putaddrinc(int addrinc)
{
  mb_out += addrinc;
  //LOGF("mb_out: %i\n", mb_out);
  if (mb_out > (horizontal_size_value >> 4))
  {
    sliceError++;
	//LOGF("mb_out: %i, hsv: %i, curo: %i\n", mb_out, horizontal_size_value, (int)outbytecnt + (wbuf - owbuf));
  }
  while (addrinc>33)
  {
    putbits(0x08,11); /* macroblock_escape */
    addrinc-= 33;
  }
  assert( addrinc >= 1 && addrinc <= 33 );
  putbits(addrinctab[addrinc-1].code,addrinctab[addrinc-1].len);
}
 
static MINLINE int slice_init (int code)
{
#define bit_buf (inbitbuf)
 
    int offset;
    const MBAtab * mba;
 
	mb_out = 0;
    v_offset = (code - 1) * 16;
 
    quantizer_scale = get_quantizer_scale ();
	new_quantizer_scale = getNewQuant(quantizer_scale, 0);
	put_quantiser(new_quantizer_scale);
 
 
    /* ignore intra_slice and all the extra data */
    while (bit_buf & 0x80000000)
	{
		DUMPBITS (bit_buf, bits, 9);
    }
 
    /* decode initial macroblock address increment */
    offset = 0;
    while (1)
	{
		if (bit_buf >= 0x08000000)
		{
			mba = MBA_5 + (UBITS (bit_buf, 6) - 2);
			break;
		}
		else if (bit_buf >= 0x01800000)
		{
			mba = MBA_11 + (UBITS (bit_buf, 12) - 24);
			break;
		}
		else switch (UBITS (bit_buf, 12))
		{
			case 8:		/* macroblock_escape */
				offset += 33;
				DUMPBITS (bit_buf, bits, 11);
				continue;
			default:	/* error */
				sliceError++;
				return 1;
		}
    }
	mb_add = offset + mba->mba + 1;
	mb_skip = 0;
	COPYBITS (bit_buf, bits, 1);
	DUMPBITS(bit_buf, bits, mba->len);
 
    h_offset = (offset + mba->mba) << 4;
 
    while (h_offset - (int)horizontal_size_value >= 0)
	{
		h_offset -= horizontal_size_value;
		v_offset += 16;
    }
 
    if (v_offset > (vertical_size_value - 16)) return 1;
 
    return 0;
 
}
 
void mpeg2_slice ( const int code )
{
#define bit_buf (inbitbuf)
 
#ifdef CHANGE_BRIGHTNESS
	dc_reset = 1;
#endif
 
    if (slice_init (code)) return;
 
    while (1)
	{
		int macroblock_modes;
		int mba_inc;
		const MBAtab * mba;
 
		macroblock_modes = get_macroblock_modes ();
		if (macroblock_modes & MACROBLOCK_QUANT) quantizer_scale = get_quantizer_scale ();
 
		if (macroblock_modes & MACROBLOCK_INTRA)
		{
#ifdef STAT
			if (picture_coding_type == P_TYPE) cnt_p_i++;
			else if (picture_coding_type == B_TYPE) cnt_b_i++;
#endif
 
			new_quantizer_scale = getNewQuant(quantizer_scale, 1);
			if (last_coded_scale == new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT
			else macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT
 
			putaddrinc(mb_add + mb_skip); mb_skip = 0;
			putmbdata(macroblock_modes);
			if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser(new_quantizer_scale);
 
			if (concealment_motion_vectors)
			{
				if (picture_structure == FRAME_PICTURE) motion_fr_conceal ();
				else motion_fi_conceal ();
			}
 
			curTable = quant_tables[quant_equ[quantizer_scale]][quant_equ[new_quantizer_scale]];
			if (!curTable)
			{
				/*DEBF("Inv. curTable: qs: %i nqs: %i qe_qs: %i qe_nqs: %i\n", 
						quantizer_scale, new_quantizer_scale,
						quant_equ[quantizer_scale], quant_equ[new_quantizer_scale]);*/
				curTable = quant_table_id;
			}
 
			slice_intra_DCT ( 0);
			slice_intra_DCT ( 0);
			slice_intra_DCT ( 0);
			slice_intra_DCT ( 0);
#ifdef DEMO
			if ((gopCount & 0x7F) < 10)
			{
				// save write state
				uint8 *savedWbuf = wbuf;
				int savedOutbitcnt = outbitcnt;
				uint32 savedOutbitbuf = outbitbuf;
 
				// process u block
				slice_intra_DCT ( 1);
 
				//int dump = (wbuf - owbuf == 201);
				//if (dump) fprintf(stderr, "=====\nbyte 0x%02X, cnt %i, outbitbuf 0x%02X, outbitcnt %i\n",
				//						wbuf[-1], wbuf - savedWbuf, outbitbuf, outbitcnt);
 
				// remember how much data was converted
				int bitsToSkip = BITS_IN_BUF - savedOutbitcnt;
				int postBitsWritten = BITS_IN_BUF - outbitcnt;
				int bitsWritten = (wbuf - savedWbuf) * 8 + postBitsWritten - bitsToSkip;
 
				if (postBitsWritten) putbits(0, outbitcnt);
				int bytesToCopy = wbuf - savedWbuf;
 
				// copy the bytes into temp buffer
				uint8 tempBuf[1024];
				memcpy(tempBuf, savedWbuf, bytesToCopy);
 
				//if (dump) fprintf(stderr, "pos %i, byte 0x%02X, bitsToSkip %i, postBitsWritten %i, bitsWritten %i, bytesToCopy %i\n",
				//					wbuf - owbuf, savedWbuf[0], bitsToSkip, postBitsWritten, bitsWritten, bytesToCopy);
 
 
				// reset write buffer
				{
					wbuf = savedWbuf;
					outbitcnt = savedOutbitcnt;
					outbitbuf = savedOutbitbuf;
				}
 
				// process v block
				slice_intra_DCT ( 2);
 
				// copy bits back from temp buffer
				{
					int bi = bitsToSkip, bm = bi + bitsWritten, p = 0;
					while(bi < bm)
					{
						int to = bm - bi;
 
						int bmod = bi % 8;
						if (bmod)
						{
							if (to > 8 - bmod) to = 8 - bmod;
							putbits((tempBuf[p] & ((1 << to) - 1)) >> (8 - bmod - to), to);
							bi += to; p++; continue;
						}
 
						if (to >= 8)
						{
							putbits(tempBuf[p], 8);
							bi += 8; p++; continue;
						}
 
						putbits(tempBuf[p] >> (8 - to), to);
						bi += to; p++; continue;
					}
				}
 
				//if (dump) fprintf(stderr, "byte 0x%02X, cnt %i, outbitbuf 0x%02X, outbitcnt %i\n",
				//						wbuf[-1], wbuf - savedWbuf, outbitbuf, outbitcnt);
 
 
			}
			else
#endif
			{
				slice_intra_DCT ( 1);
				slice_intra_DCT ( 2);
			}
		}
		else
		{
			int new_coded_block_pattern = 0;
 
			// begin saving data
			int batb;
			uint8	n_owbuf[32], *n_wbuf, *o_owbuf, *o_wbuf;
			uint32	n_outbitcnt, n_outbitbuf, o_outbitcnt, o_outbitbuf;
 
#ifdef CHANGE_BRIGHTNESS
			dc_reset = 1;
#endif
 
#define PUSH_BIT_IO \
			o_owbuf = owbuf; o_wbuf = wbuf; \
			o_outbitcnt = outbitcnt; o_outbitbuf = outbitbuf; \
			owbuf = wbuf = n_owbuf; \
			outbitcnt = BITS_IN_BUF; outbitbuf = 0;
 
#define POP_BIT_IO \
			n_wbuf = wbuf; \
			n_outbitcnt = outbitcnt; n_outbitbuf = outbitbuf; \
			owbuf = o_owbuf; wbuf = o_wbuf; \
			outbitcnt = o_outbitcnt; outbitbuf = o_outbitbuf;
 
			PUSH_BIT_IO
 
			if (picture_structure == FRAME_PICTURE)
				switch (macroblock_modes & MOTION_TYPE_MASK)
				{
					case MC_FRAME: MOTION_CALL (motion_fr_frame, macroblock_modes); break;
					case MC_FIELD: MOTION_CALL (motion_fr_field, macroblock_modes); break;
					case MC_DMV: MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); break;
				}
			else
				switch (macroblock_modes & MOTION_TYPE_MASK)
				{
					case MC_FIELD: MOTION_CALL (motion_fi_field, macroblock_modes); break;
					case MC_16X8: MOTION_CALL (motion_fi_16x8, macroblock_modes); break;
					case MC_DMV: MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); break;
				}
 
			POP_BIT_IO
 
			// end saving data
 
#ifdef STAT
			if (picture_coding_type == P_TYPE) cnt_p_ni++;
			else if (picture_coding_type == B_TYPE) cnt_b_ni++;
#endif
			new_quantizer_scale = getNewQuant(quantizer_scale, 0);
 
			if (macroblock_modes & MACROBLOCK_PATTERN)
			{
				int coded_block_pattern = get_coded_block_pattern ();
 
				mb_sav_lev = 0xFFFF;
				curTable = quant_tables[quant_equ[quantizer_scale]][quant_equ[new_quantizer_scale]];
				if (!curTable)
				{
					/*DEBF("Inv. curTable: qs: %i nqs: %i qe_qs: %i qe_nqs: %i\n", 
							quantizer_scale, new_quantizer_scale,
							quant_equ[quantizer_scale], quant_equ[new_quantizer_scale]);*/
					curTable = quant_table_id;
				}
 
				if (coded_block_pattern & 0x20) { slice_non_intra_DCT(0); if (isNotEmpty(block[0])) new_coded_block_pattern |= 0x20; }
				if (coded_block_pattern & 0x10) { slice_non_intra_DCT(1); if (isNotEmpty(block[1])) new_coded_block_pattern |= 0x10; }
				if (coded_block_pattern & 0x08) { slice_non_intra_DCT(2); if (isNotEmpty(block[2])) new_coded_block_pattern |= 0x08; }
				if (coded_block_pattern & 0x04) { slice_non_intra_DCT(3); if (isNotEmpty(block[3])) new_coded_block_pattern |= 0x04; }
				if (coded_block_pattern & 0x02) { slice_non_intra_DCT(4); if (isNotEmpty(block[4])) new_coded_block_pattern |= 0x02; }
				if (coded_block_pattern & 0x01) { slice_non_intra_DCT(5); if (isNotEmpty(block[5])) new_coded_block_pattern |= 0x01; }
#ifdef P_FRAME_NON_INTRA_DROP
				if (picture_coding_type == P_TYPE) new_quantizer_scale = quantizer_scale;
#endif
				if (!new_coded_block_pattern)
				{
					macroblock_modes &= 0xFFFFFFED; // remove MACROBLOCK_PATTERN and MACROBLOCK_QUANT flag
					if (	(picture_coding_type == P_TYPE)
						&& !(macroblock_modes & MACROBLOCK_MOTION_FORWARD))
					{
						assert(n_wbuf == n_owbuf);
						assert(n_outbitcnt == BITS_IN_BUF);
 
						if ((h_offset == 0) || (h_offset == horizontal_size_value - 16))  // can't skip last mb
						{
							// we can't transmit mv (0,0) since PMV could be different than 0 for last block
							// so we transmit the single smallest coeff. instead unrequantised
							// anyway this is likely to take no more bit than transmiting a null mv....
 
							assert((mb_sav_lev) && (mb_sav_lev != 0xFFFF));
 
							new_coded_block_pattern = 1 << (5 - mb_sav_c);
							macroblock_modes |= MACROBLOCK_PATTERN;
							new_quantizer_scale = quantizer_scale;
							block[mb_sav_c][0].run = mb_sav_run; block[mb_sav_c][0].level = mb_sav_lev;
							block[mb_sav_c][1].run = 0; block[mb_sav_c][1].level = 0;
						}
						else
						{
							mb_skip += mb_add;
							goto skip_mb;
						}
					}
				}
			}
 
			if (last_coded_scale == new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT
			else if (macroblock_modes & MACROBLOCK_PATTERN) macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT
			assert( (macroblock_modes & MACROBLOCK_PATTERN) || !(macroblock_modes & MACROBLOCK_QUANT) );
 
			putaddrinc(mb_add + mb_skip); mb_skip = 0;
			putmbdata(macroblock_modes);
			if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser(new_quantizer_scale);
 
			// put saved motion data...
			for (batb = 0; batb < (n_wbuf - n_owbuf); batb++) putbits(n_owbuf[batb], 8);
			putbits(n_outbitbuf, BITS_IN_BUF - n_outbitcnt);
			// end saved motion data...
 
			if (macroblock_modes & MACROBLOCK_PATTERN)
			{
				putcbp(new_coded_block_pattern);
 
				if (new_coded_block_pattern & 0x20) putnonintrablk(block[0]);
				if (new_coded_block_pattern & 0x10) putnonintrablk(block[1]);
				if (new_coded_block_pattern & 0x08) putnonintrablk(block[2]);
				if (new_coded_block_pattern & 0x04) putnonintrablk(block[3]);
				if (new_coded_block_pattern & 0x02) putnonintrablk(block[4]);
				if (new_coded_block_pattern & 0x01) putnonintrablk(block[5]);
			}
		}
 
skip_mb:
 
		NEXT_MACROBLOCK;
 
		mba_inc = 0;
		while (1)
		{
			if (bit_buf >= 0x10000000)
			{
				mba = MBA_5 + (UBITS (bit_buf, 5) - 2);
				break;
			}
			else if (bit_buf >= 0x03000000)
			{
				mba = MBA_11 + (UBITS (bit_buf, 11) - 24);
				break;
			}
			else
				switch (UBITS (bit_buf, 11))
				{
					case 8:		/* macroblock_escape */
						mba_inc += 33;
						DUMPBITS (bit_buf, bits, 11);
						continue;
					default:	/* end of slice, or error */
						//LOGF("hoffset: %i, hsv: %i, curo: %i\n", h_offset, horizontal_size_value, (int)outbytecnt + (wbuf - owbuf));
						if (h_offset != 0)
							sliceError++;
						return;
				}
		}
		DUMPBITS (bit_buf, bits, mba->len); //PPP
 
		mba_inc += mba->mba;
		mb_add = mba_inc + 1;
 
#ifdef CHANGE_BRIGHTNESS
		if (mba_inc) dc_reset = 1;
#endif
 
		if (mba_inc) do { NEXT_MACROBLOCK; } while (--mba_inc);
    }
 
}
 
/////---- end ext mpeg code
 
#ifdef CHANGE_BRIGHTNESS
	#ifdef USE_FD
		#define USAGE \
			fprintf(stderr,\
				"\nUsage is :\n"\
				"\t%s [ignored_recompression_factor] [ignored_quality_factor] inputM2Vsize brightness_delta input.m2v output.m2v\n\n", argv[0]);\
			return -1;
	#else
		#define USAGE \
			fprintf(stderr,\
				"\nUsage is :\n"\
				"\t%s [ignored_recompression_factor] [ignored_quality_factor] inputM2Vsize brightness_delta\n\n", argv[0]);\
			return -1;
	#endif
#else
	#ifdef USE_FD
		#define USAGE \
			fprintf(stderr,\
				"\nUsage is :\n"\
				"\t%s recompression_factor [ignored_quality_factor] inputM2Vsize input.m2v output.m2v\n\n", argv[0]);\
			return -1;
	#else
		#define USAGE \
			fprintf(stderr,\
				"\nUsage is :\n"\
				"\t%s recompression_factor [ignored_quality_factor] inputM2Vsize\n\n", argv[0]);\
			return -1;
	#endif
#endif
 
int quantisers[42] = 
{
	1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
	34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 72, 80,
	88, 96, 104, 112
};
 
int main (int argc, const char * argv[])
{
	uint8 ID, found;
	int64 greedyFactor, greedyFactor2;
	int i;
 
#ifdef DEMO // gopCount set to 0
	gopCount = 0;
#endif
 
#ifdef LOG_RATE_CONTROL
	{
		int suffix = 0;
		char logFileName[256];
		do
		{
			sprintf(logFileName, "Logfile_%03i.txt", suffix);
			LOG_FILE = fopen(logFileName, "r");
			if (LOG_FILE) { fclose(LOG_FILE); suffix++; }
		} while(LOG_FILE != 0);
		LOG_FILE = fopen(logFileName, "w");
	}
#endif
 
#ifdef STAT
	ori_i = ori_p = ori_b = 0;
	new_i = new_p = new_b = 0;
	cnt_i = cnt_p = cnt_b = 0;
	cnt_p_i = cnt_p_ni = 0;
	cnt_b_i = cnt_b_ni = 0;
#endif
 
#ifdef USE_FD
	if (argc < 3) { USAGE }
	ifd = fopen(argv[argc - 2], "rb");
	ofd = fopen(argv[argc - 1], "wb");
	if (!ifd)
	{
		LOGF("Bad input path! (%s)\n", argv[argc - 2]);
		return 2;
	}
	if (!ofd)
	{
		LOGF("Bad output path! (%s)\n", argv[argc - 1]);
		return 2;
	}
	argc -= 2;
#endif
 
	rbuf = cbuf = orbuf = malloc(BUF_SIZE);
	wbuf = owbuf = malloc(BUF_SIZE);
	inbytecnt = outbytecnt = 0;
	eof = 0;
 
	validPicHeader = 0;
	validSeqHeader = 0;
	validExtHeader = 0;
 
	// argument parsing
#ifdef CHANGE_BRIGHTNESS
	if (argc < 5) { USAGE }
	delta_bright = atoi(argv[4]);
#else
	if (argc < 4) { USAGE }
#endif
	fact_x = atof(argv[1]);
	sscanf(argv[3], "%lld", &orim2vsize);
	greedyFactor = orim2vsize / 100;
	greedyFactor2 = orim2vsize / 50;
 
	if (fact_x <= 1.0)
	{
		unsigned char buf[4096];
 
		while(1)
		{		
			int i = read(0, buf, 4096);
			if (i > 0) write(1, buf, i);
			else return 0;
		}
	}
	else if (fact_x > 900.0) fact_x = 900.0;
 
	// factor and stresses setting
	if (fact_x <= 1.0)
	{
		i_factor = i_factors[0];
		p_factor = p_factors[0];
		b_factor = b_factors[0];
		i_min_stress = i_min_stresses[0];
		p_min_stress = p_min_stresses[0];
		b_min_stress = b_min_stresses[0];
	}
	else if (fact_x >= 5.0)
	{
		i_factor = i_factors[2];
		p_factor = p_factors[2];
		b_factor = b_factors[2];
		i_min_stress = i_min_stresses[2];
		p_min_stress = p_min_stresses[2];
		b_min_stress = b_min_stresses[2];
	}
	else if (fact_x <= 3.0) // 1.0 .. 3.0
	{
		double inter = (fact_x - 1.0)/(3.0 - 1.0);
		i_factor = i_factors[0] + inter * (i_factors[1] - i_factors[0]);
		p_factor = p_factors[0] + inter * (p_factors[1] - p_factors[0]);
		b_factor = b_factors[0] + inter * (b_factors[1] - b_factors[0]);
		i_min_stress = i_min_stresses[0] + inter * (i_min_stresses[1] - i_min_stresses[0]);
		p_min_stress = p_min_stresses[0] + inter * (p_min_stresses[1] - p_min_stresses[0]);
		b_min_stress = b_min_stresses[0] + inter * (b_min_stresses[1] - b_min_stresses[0]);
	}
	else // 3.0 .. 5.0
	{
		double inter = (fact_x - 3.0)/(5.0 - 3.0);
		i_factor = i_factors[1] + inter * (i_factors[2] - i_factors[1]);
		p_factor = p_factors[1] + inter * (p_factors[2] - p_factors[1]);
		b_factor = b_factors[1] + inter * (b_factors[2] - b_factors[1]);
		i_min_stress = i_min_stresses[1] + inter * (i_min_stresses[2] - i_min_stresses[1]);
		p_min_stress = p_min_stresses[1] + inter * (p_min_stresses[2] - p_min_stresses[1]);
		b_min_stress = b_min_stresses[1] + inter * (b_min_stresses[2] - b_min_stresses[1]);
	}
 
	/*LOGF(   "i_factor: %i p_factor: %i b_factor: %i\n"
			"i_min_stress: %.02f p_min_stress: %.02f b_min_stress: %.02f\n",
			i_factor, p_factor, b_factor,
			i_min_stress, p_min_stress, b_min_stress);*/
 
	// fill quant table
	// id table
	for (i = -2048; i <= 2047; i++) quant_table_id[i] = i;
 
	// other tables
	for (i = 0; i < 42; i++)
	{
		int q = quantisers[i];
		int j;
 
		for (j = i + 1; j < 42; j++)
		{
			int nq = quantisers[j];
			int k;
			short *cTab = quant_tables[quant_equ[q]][quant_equ[nq]];
 
			for (k = -2048; k <= 2047; k++)
			{
				int ov = k*q;
				int t = ov / nq;
 
				if (fact_x <= max_alt_table)
				{
					int t2, t3;
					int d, d2, d3;
					int nv, nv2, nv3;
 
					t2 = t + 1;
					t3 = t - 1;
 
					nv = t * nq;
					nv2 = t2 * nq;
					nv3 = t3 * nq;
 
					d = abs(nv - ov);
					d2 = abs(nv2 - ov);
					d3 = abs(nv3 - ov);
 
					if (d2 < d) { d = d2; t = t2; }
					if (d3 < d) t = t3;
				}
 
				if (t > 2047) t = 2047;
				else if (t < -2048) t = -2048;
 
				cTab[k] = t;
			}
		}
	}
 
	LOG("M2VRequantiser by Makira.\n");
#ifdef WIN
	fprintf(stderr, "Using %f as factor, %lld as m2v size.\n", fact_x, orim2vsize);
#else
	LOGF("Using %f as factor, %lld as m2v size.\n", fact_x, orim2vsize);
#endif
	// recoding
	while(1)
	{
		// get next start code prefix
		found = 0;
		while (!found)
		{
#ifndef REMOVE_BYTE_STUFFING
			LOCK(3)
#else
			LOCK(8)
			if		(		(cbuf[7] == 0) && (cbuf[6] == 0) && (cbuf[5] == 0) && (cbuf[4] == 0)
						&&  (cbuf[3] == 0) && (cbuf[2] == 0) && (cbuf[1] == 0) && (cbuf[0] == 0) ) { SEEKR(1) }
			else 
#endif
			if ( (cbuf[0] == 0) && (cbuf[1] == 0) && (cbuf[2] == 1) ) found = 1; // start code !
			else { COPY(1) } // continue search
		}
		COPY(3)
 
		// get start code
		LOCK(1)
		ID = cbuf[0];
		COPY(1)
 
		if (ID == 0x00) // pic header
		{
			LOCK(4)
			picture_coding_type = (cbuf[1] >> 3) & 0x7;
			if (picture_coding_type < 1 || picture_coding_type > 3)
			{
				DEBF("illegal picture_coding_type: %i\n", picture_coding_type);
				validPicHeader = 0;
			}
			else
			{
				validPicHeader = 1;
				cbuf[1] |= 0x7; cbuf[2] = 0xFF; cbuf[3] |= 0xF8; // vbv_delay is now 0xFFFF
			}
 
			validExtHeader = 0;
 
			COPY(4)
		}
		else if (ID == 0xB3) // seq header
		{
			LOCK(8)
			horizontal_size_value = (cbuf[0] << 4) | (cbuf[1] >> 4);
			vertical_size_value = ((cbuf[1] & 0xF) << 8) | cbuf[2];
			if (	horizontal_size_value > 720 || horizontal_size_value < 352
				||  vertical_size_value > 576 || vertical_size_value < 480
				|| (horizontal_size_value & 0xF) || (vertical_size_value & 0xF))
			{
				DEBF("illegal size, hori: %i verti: %i\n", horizontal_size_value, vertical_size_value);
				validSeqHeader = 0;
			}
			else
				validSeqHeader = 1;
 
			validPicHeader = 0;
			validExtHeader = 0;
 
			COPY(8)
		}
		else if (ID == 0xB5) // extension
		{
			LOCK(1)
			if ((cbuf[0] >> 4) == 0x8) // pic coding ext
			{
				LOCK(5)
 
				f_code[0][0] = (cbuf[0] & 0xF) - 1;
				f_code[0][1] = (cbuf[1] >> 4) - 1;
				f_code[1][0] = (cbuf[1] & 0xF) - 1;
				f_code[1][1] = (cbuf[2] >> 4) - 1;
 
				intra_dc_precision = (cbuf[2] >> 2) & 0x3;
				picture_structure = cbuf[2] & 0x3;
				frame_pred_frame_dct = (cbuf[3] >> 6) & 0x1;
				concealment_motion_vectors = (cbuf[3] >> 5) & 0x1;
				q_scale_type = (cbuf[3] >> 4) & 0x1;
				intra_vlc_format = (cbuf[3] >> 3) & 0x1;
				alternate_scan = (cbuf[3] >> 2) & 0x1;
 
				if (	(f_code[0][0] > 8 && f_code[0][0] < 14)
					||  (f_code[0][1] > 8 && f_code[0][1] < 14)
					||  (f_code[1][0] > 8 && f_code[1][0] < 14)
					||  (f_code[1][1] > 8 && f_code[1][1] < 14)
					||  picture_structure == 0)
				{
					DEBF("illegal ext, f_code[0][0]: %i f_code[0][1]: %i f_code[1][0]: %i f_code[1][1]: %i picture_structure:%i\n",
							f_code[0][0], f_code[0][1], f_code[1][0], f_code[1][1], picture_structure);
					validExtHeader = 0;
				}
				else
					validExtHeader = 1;
				COPY(5)
			}
			else
			{
				COPY(1)
			}
		}
		else if (ID == 0xB8) // gop header
		{
			LOCK(4)
			COPY(4)
 
#ifdef DEMO // gopCount increment
			gopCount++;
#endif
		}
		else if ((ID >= 0x01) && (ID <= 0xAF) && validPicHeader && validSeqHeader && validExtHeader) // slice
		{
			uint8 *outTemp = wbuf, *inTemp = cbuf;
			int64 threshold;
 
			bytediff = (outbytecnt + (wbuf - owbuf)) - ((inbytecnt - (rbuf - cbuf)) / fact_x);
 
 
			if (inbytecnt < greedyFactor2) threshold = inbytecnt >> 1;
			else if (orim2vsize - inbytecnt < greedyFactor2) threshold = (orim2vsize - inbytecnt) >> 1;
			else threshold = greedyFactor;
 
			if (threshold < 1024) threshold = 1024;
 
			stress_factor = (float)(bytediff + threshold) / (float)(threshold << 1);
			if (stress_factor > 1.0f)		stress_factor = 1.0f;
			else if (stress_factor < 0.0f)	stress_factor = 0.0f;
 
 
#ifdef LOG_RATE_CONTROL
			/*fprintf(LOG_FILE, "%f%%: Requested: %f  Current: %f  Delta: %lld   Threshold: %f  Stress: %f\n", 
				(float)(100.0f*inbytecnt)/orim2vsize,		//	percent
				(float)fact_x,								//	requested
				(float)(inbytecnt - (rbuf - cbuf))/(float)(outbytecnt + (wbuf - owbuf)), //	current
				(long long)bytediff,						//	delta
				(float)threshold, 							//	threshold
				stress_factor								//	Stress
			);*/
			fprintf(LOG_FILE, "inb: %.0f inb_c: %.0f oub: %.0f oub_c: %.0f cur: %.3f dif: %.0f thr: %.0f str: %.03f\n",
				(float)inbytecnt,
				(float)(inbytecnt - (rbuf - cbuf)),
				(float)outbytecnt, 
				(float)(outbytecnt + (wbuf - owbuf)),
				(float)(inbytecnt - (rbuf - cbuf))/(float)(outbytecnt + (wbuf - owbuf)),
				(float)bytediff,
				(float)threshold,
				(float)stress_factor );
#endif
 
 
#ifndef CHANGE_BRIGHTNESS
			if (	((picture_coding_type == I_TYPE) && ( stress_factor > i_min_stress))
				||  ((picture_coding_type == P_TYPE) && ( stress_factor > p_min_stress))
				||  ((picture_coding_type == B_TYPE) && ( stress_factor > b_min_stress))
#ifdef DEMO // force processing
				||	((gopCount & 0x7F) < 10)
#endif
				)
#endif
			{
 
				// lock all the slice if less than 1 meg in buffer
				if (rbuf - cbuf < 1*1024*1024)
				{
					// try to read more data
					if (!eof)
					{ 
						mloka2 = MIN_READ; 
						while (mloka2) 
						{
							assert(rbuf + mloka2 < orbuf + BUF_SIZE); 
#ifdef USE_FD
							mloka1 = fread(rbuf, 1, mloka2, ifd);
#else
							mloka1 = read(0, rbuf, mloka2);
#endif							
							if (mloka1 <= 0) { eof = 1; break; } 
							inbytecnt += mloka1; 
							rbuf += mloka1; 
							mloka2 -= mloka1; 
						}
					}
					// lock slice manually
					if (rbuf - cbuf < 1*1024*1024)
					{
						uint8 *nsc = cbuf;
						int fsc = 0, toLock;
						while (!fsc)
						{
							toLock = nsc - cbuf + 3;
							LOCK(toLock)
 
							if ( (nsc[0] == 0) && (nsc[1] == 0) && (nsc[2] == 1) ) fsc = 1; // start code !
							else nsc++; // continue search
						}
					}
				}
 
 
				// init error
				sliceError = 0;
 
				// init bit buffer
				inbitbuf = 0; inbitcnt = 0;
				outbitbuf = 0; outbitcnt = BITS_IN_BUF;
 
				// get 32 bits
				Refill_bits();
				Refill_bits();
				Refill_bits();
				Refill_bits();
 
				// begin bit level recoding
				mpeg2_slice(ID);
				flush_read_buffer();
				flush_write_buffer();
				// end bit level recoding
 
#ifndef CHANGE_BRIGHTNESS
				if ((wbuf - outTemp > cbuf - inTemp) || (sliceError > MAX_ERRORS)) // yes that might happen, rarely
				{
#ifndef NDEBUG
					if (sliceError > MAX_ERRORS)
					{
						DEBF("sliceError (%i) > MAX_ERRORS (%i)\n", sliceError, MAX_ERRORS);
					}
#endif
 
					// in this case, we'll just use the original slice !
					memcpy(outTemp, inTemp, cbuf - inTemp);
					wbuf = outTemp + (cbuf - inTemp);
 
					// adjust outbytecnt
					outbytecnt -= (wbuf - outTemp) - (cbuf - inTemp);
				}
#endif
 
#ifdef STAT
	#ifdef LOG_RATE_CONTROL
				if (picture_coding_type == I_TYPE)
					fprintf(LOG_FILE, "-I-\n");
	#endif
				switch(picture_coding_type)
				{
					case I_TYPE:
						ori_i += cbuf - inTemp;
						new_i += (wbuf - outTemp > cbuf - inTemp) ? (cbuf - inTemp) : (wbuf - outTemp);
						cnt_i ++;
						break;
 
					case P_TYPE:
						ori_p += cbuf - inTemp;
						new_p += (wbuf - outTemp > cbuf - inTemp) ? (cbuf - inTemp) : (wbuf - outTemp);
						cnt_p ++;
						break;
 
					case B_TYPE:
						ori_b += cbuf - inTemp;
						new_b += (wbuf - outTemp > cbuf - inTemp) ? (cbuf - inTemp) : (wbuf - outTemp);
						cnt_b ++;
						break;
 
					default:
						assert(0);
						break;
				}
#endif
			}
		}
 
#ifndef NDEBUG
		if ((ID >= 0x01) && (ID <= 0xAF) && (!validPicHeader || !validSeqHeader || !validExtHeader))
		{
			if (!validPicHeader) DEBF("missing pic header (%02X)\n", ID);
			if (!validSeqHeader) DEBF("missing seq header (%02X)\n", ID);
			if (!validExtHeader) DEBF("missing ext header (%02X)\n", ID);
		}
#endif
		if (rbuf - orbuf > MAX_READ) { MOV_READ }
		if (wbuf - owbuf > MIN_WRITE) { WRITE }
	}
 
#ifdef LOG_RATE_CONTROL
	fclose(LOG_FILE);
#endif
	// keeps gcc happy
	return 0;
}
 
 
Parsed using GeSHi 1.0.8.6

Karsten Römke (k Ponkt roemke at gmx in de), Rechtliches, Datenschutz, etc.
Rein private Seite, lediglich eine Spielerei
Last modified: 2010-05-13
Created: 2010-05-13
Reason: –
Home sweet home