You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2482 lines
58 KiB
2482 lines
58 KiB
//
|
|
// C++ Implementation: k9requant
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2006
|
|
//
|
|
// Copyright: See COPYING file that comes with this distribution
|
|
//
|
|
//
|
|
#include "k9requant.h"
|
|
#include "getvlc.h"
|
|
#include "putvlc.h"
|
|
#include "ac.h"
|
|
// 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 THREAD
|
|
// #define LOG_RATE_CONTROL // some stats
|
|
// #define 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
|
|
// #define USE_GLOBAL_REGISTER // assign registers to bit buffers
|
|
#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 = 10.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.70, 0.40, 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.0;
|
|
|
|
// 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
|
|
|
|
// 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
|
|
|
|
#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
|
|
|
|
#ifndef THREAD
|
|
#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
|
|
#endif
|
|
|
|
|
|
|
|
/*#define MOV_READ \
|
|
mloka1 = rbuf - cbuf; if (mloka1) memmove(orbuf, cbuf, mloka1);\
|
|
cbuf = rbuf = orbuf; rbuf += mloka1;
|
|
*/
|
|
|
|
#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 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)
|
|
|
|
#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
|
|
|
|
#define UPDATE_VAL \
|
|
val = curTable[val];
|
|
|
|
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 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
|
|
};
|
|
|
|
|
|
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
|
|
};
|
|
|
|
|
|
k9requant::k9requant()
|
|
{
|
|
|
|
cbuf=rbuf=orbuf=wbuf=NULL;
|
|
quant_table_id = &quant_table_id_data[2048];
|
|
rqt_run=false;
|
|
initvar();
|
|
}
|
|
void k9requant::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);
|
|
}
|
|
|
|
void k9requant::Refill_bits(void)
|
|
{
|
|
assert((rbuf - cbuf) >= 1);
|
|
inbitbuf |= cbuf[0] << (24 - inbitcnt);
|
|
inbitcnt += 8;
|
|
SEEKR(1)
|
|
}
|
|
|
|
void k9requant::Flush_Bits(uint n)
|
|
{
|
|
assert(inbitcnt >= n);
|
|
|
|
inbitbuf <<= n;
|
|
inbitcnt -= n;
|
|
|
|
assert( (!n) || ((n>0) && !(inbitbuf & 0x1)) );
|
|
|
|
while (unlikely(inbitcnt < 24)) Refill_bits();
|
|
}
|
|
|
|
uint k9requant::Show_Bits(uint n)
|
|
{
|
|
return ((unsigned int)inbitbuf) >> (32 - n);
|
|
}
|
|
|
|
uint k9requant::Get_Bits(uint n)
|
|
{
|
|
uint Val = Show_Bits(n);
|
|
Flush_Bits(n);
|
|
return Val;
|
|
}
|
|
|
|
uint k9requant::Copy_Bits(uint n)
|
|
{
|
|
uint Val = Get_Bits(n);
|
|
putbits(Val, n);
|
|
return Val;
|
|
}
|
|
|
|
void k9requant::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;
|
|
}
|
|
|
|
void k9requant::flush_write_buffer()
|
|
{
|
|
if (outbitcnt != 8) putbits(0, outbitcnt);
|
|
}
|
|
|
|
/////---- begin ext mpeg code
|
|
int k9requant::scale_quant(double quant )
|
|
{
|
|
int iquant;
|
|
#ifdef DEMO
|
|
if ((gopCount & 0x7F) < 10) // gop is ~ 0.5 sec, so 5 sec every ~minute (127 * 0.5 = 63.5 sec)
|
|
{
|
|
if (q_scale_type) return 112;
|
|
else return 62;
|
|
}
|
|
#endif
|
|
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;
|
|
}
|
|
|
|
int k9requant::increment_quant(int quant)
|
|
{
|
|
#ifdef DEMO
|
|
if ((gopCount & 0x7F) < 10)
|
|
{
|
|
if (q_scale_type) return 112;
|
|
else return 62;
|
|
}
|
|
#endif
|
|
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;
|
|
}
|
|
|
|
int k9requant::intmax( int x, int y )
|
|
{ return x < y ? y : x; }
|
|
|
|
int k9requant::intmin( int x, int y )
|
|
{ return x < y ? x : y; }
|
|
|
|
|
|
int k9requant::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
|
|
}
|
|
|
|
int k9requant::isNotEmpty(RunLevel *blk)
|
|
{
|
|
return (blk->level);
|
|
}
|
|
|
|
|
|
// return != 0 if error
|
|
int k9requant::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
|
|
int k9requant::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 k9requant::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);
|
|
}
|
|
|
|
void k9requant::putcbp(int cbp)
|
|
{
|
|
assert(cbp > 0 && cbp < 64);
|
|
putbits(cbptable[cbp].code,cbptable[cbp].len);
|
|
}
|
|
|
|
void k9requant::putmbtype(int mb_type)
|
|
{
|
|
putbits(mbtypetab[picture_coding_type-1][mb_type].code,
|
|
mbtypetab[picture_coding_type-1][mb_type].len);
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
|
|
void k9requant::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;
|
|
}
|
|
}
|
|
|
|
|
|
void k9requant::get_dmv ()
|
|
{
|
|
const DMVtab * tab;
|
|
tab = DMV_2 + UBITS (bit_buf, 2);
|
|
COPYBITS (bit_buf, bits, tab->len);
|
|
return;
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
}
|
|
|
|
|
|
void k9requant::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 */
|
|
}
|
|
|
|
void k9requant::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 */
|
|
}
|
|
|
|
int k9requant::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;
|
|
}
|
|
|
|
|
|
int k9requant::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
|
|
if ((gopCount & 0x7F) < 10) blk = oblk;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
blk->level = 0;
|
|
|
|
return i;
|
|
}
|
|
|
|
#ifdef P_FRAME_NON_INTRA_DROP
|
|
int k9requant::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
|
|
if ((gopCount & 0x7F) < 10) blk = oblk;
|
|
#endif
|
|
#endif
|
|
|
|
blk->level = 0;
|
|
|
|
return i;
|
|
}
|
|
#endif
|
|
|
|
#ifdef CHANGE_BRIGHTNESS
|
|
void k9requant::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
|
|
void k9requant::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 ();
|
|
}
|
|
|
|
void k9requant::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
|
|
}
|
|
|
|
void k9requant::motion_fr_frame ( uint f_code[2] )
|
|
{
|
|
get_motion_delta (f_code[0]);
|
|
get_motion_delta (f_code[1]);
|
|
}
|
|
|
|
void k9requant::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]);
|
|
}
|
|
|
|
void k9requant::motion_fr_dmv ( uint f_code[2] )
|
|
{
|
|
get_motion_delta (f_code[0]);
|
|
get_dmv ();
|
|
|
|
get_motion_delta (f_code[1]);
|
|
get_dmv ();
|
|
}
|
|
|
|
void k9requant::motion_fr_conceal ( )
|
|
{
|
|
get_motion_delta (f_code[0][0]);
|
|
get_motion_delta (f_code[0][1]);
|
|
|
|
COPYBITS (bit_buf, bits, 1);
|
|
}
|
|
|
|
void k9requant::motion_fi_field ( uint f_code[2] )
|
|
{
|
|
COPYBITS (bit_buf, bits, 1);
|
|
|
|
get_motion_delta (f_code[0]);
|
|
get_motion_delta (f_code[1]);
|
|
}
|
|
|
|
void k9requant::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]);
|
|
}
|
|
|
|
void k9requant::motion_fi_dmv ( uint f_code[2] )
|
|
{
|
|
get_motion_delta (f_code[0]);
|
|
get_dmv ();
|
|
|
|
get_motion_delta (f_code[1]);
|
|
get_dmv ();
|
|
}
|
|
|
|
void k9requant::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);
|
|
}
|
|
|
|
|
|
void k9requant::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);
|
|
}
|
|
}
|
|
|
|
void k9requant::put_quantiser(int quantiser)
|
|
{
|
|
putbits(q_scale_type ? map_non_linear_mquant[quantiser] : quantiser >> 1, 5);
|
|
last_coded_scale = quantiser;
|
|
}
|
|
|
|
void k9requant::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);
|
|
}
|
|
|
|
int k9requant::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 k9requant::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);
|
|
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
|
|
|
|
void k9requant::run ()
|
|
{
|
|
uint8 ID, found;
|
|
int64 greedyFactor, greedyFactor2;
|
|
int i;
|
|
|
|
#ifdef DEMO
|
|
gopCount = 0;
|
|
#endif
|
|
|
|
#ifdef LOG_RATE_CONTROL
|
|
LOG_FILE = fopen("Logfile.txt", "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
|
|
|
|
#ifndef THREAD
|
|
rbuf = cbuf = orbuf = malloc(BUF_SIZE);
|
|
wbuf = owbuf = malloc(BUF_SIZE);
|
|
inbytecnt = outbytecnt = 0;
|
|
eof = 0;
|
|
#endif
|
|
|
|
validPicHeader = 0;
|
|
validSeqHeader = 0;
|
|
validExtHeader = 0;
|
|
|
|
#ifndef THREAD
|
|
// 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);
|
|
#endif
|
|
|
|
#ifdef THREAD
|
|
orim2vsize=rqt_visize;
|
|
fact_x = rqt_fact;
|
|
#endif
|
|
|
|
greedyFactor = orim2vsize / 100;
|
|
greedyFactor2 = orim2vsize / 50;
|
|
|
|
#ifndef THREAD
|
|
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;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
if (fact_x > 10.0) fact_x = 10.0;
|
|
|
|
// factor and stresses setting
|
|
initRequant();
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef THREAD
|
|
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
|
|
#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++;
|
|
#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
|
|
|| ((gopCount & 0x7F) < 10)
|
|
#endif
|
|
)
|
|
#endif
|
|
{
|
|
// 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 !
|
|
tc_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
|
|
rqt_run=false;
|
|
// keeps gcc happy
|
|
return ;
|
|
}
|
|
|
|
void k9requant::initvar()
|
|
{
|
|
cbuf = NULL;
|
|
rbuf = NULL;
|
|
wbuf = NULL;
|
|
orbuf = NULL;
|
|
owbuf = NULL;
|
|
inbitcnt = outbitcnt = 0;
|
|
inbitbuf = outbitbuf = 0;
|
|
inbytecnt = outbytecnt = 0;
|
|
fact_x = 0;
|
|
mloka1 = mloka2 = eof = 0;
|
|
orim2vsize = 0;
|
|
bytediff = 0;
|
|
stress_factor = 0;
|
|
i_factor = 0;
|
|
p_factor = 0;
|
|
b_factor = 0;
|
|
i_min_stress = 0;
|
|
p_min_stress = 0;
|
|
b_min_stress = 0;
|
|
quant_table_id = &quant_table_id_data[2048];
|
|
horizontal_size_value = 0;
|
|
vertical_size_value = 0;
|
|
|
|
picture_coding_type = 0;
|
|
|
|
memset( f_code,0 , sizeof(f_code));
|
|
intra_dc_precision = 0;
|
|
picture_structure = 0;
|
|
frame_pred_frame_dct = 0;
|
|
concealment_motion_vectors = 0;
|
|
q_scale_type = 0;
|
|
intra_vlc_format = 0;
|
|
alternate_scan = 0;
|
|
|
|
validPicHeader = 0;
|
|
validSeqHeader = 0;
|
|
validExtHeader = 0;
|
|
sliceError = 0;
|
|
|
|
quantizer_scale = 0;
|
|
new_quantizer_scale = 0;
|
|
last_coded_scale = 0;
|
|
h_offset = v_offset = 0;
|
|
mb_skip = mb_add = 0;
|
|
mb_out = 0;
|
|
|
|
mb_sav_run = mb_sav_lev = mb_sav_c = 0;
|
|
curTable = NULL;
|
|
memset( block, 0, sizeof(block));
|
|
}
|
|
|
|
|
|
|
|
void k9requant::initRequant() {
|
|
int i;
|
|
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 >= 10.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 .. 10.0
|
|
{
|
|
double inter = (fact_x - 3.0)/(10.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);*/
|
|
|
|
|
|
|
|
}
|
|
|
|
bool k9requant::lock( int64 x) {
|
|
if (unlikely ((x) > (rbuf - cbuf)))
|
|
{
|
|
if (likely (wbuf))
|
|
{
|
|
TQMutexLocker locker( &mutw );
|
|
//mutw.lock();
|
|
rqt_wcnt = wbuf - owbuf;
|
|
condw.wakeAll();
|
|
//mutw.unlock();
|
|
}
|
|
//mutr.lock();
|
|
TQMutexLocker locker( &mutr );
|
|
while (!rqt_rcnt)
|
|
{
|
|
condr.wait( &mutr);
|
|
if (rqt_stop==true) {
|
|
//mutr.unlock();
|
|
return false;
|
|
}
|
|
}
|
|
cbuf = rqt_rptr; //src buffer
|
|
rbuf =orbuf = cbuf;
|
|
rbuf += rqt_rcnt + 3; // end of src buffer
|
|
rqt_rcnt = 0;
|
|
owbuf = rqt_wptr; // dest buffer
|
|
inbytecnt = rqt_inbytes;
|
|
outbytecnt = rqt_outbytes;
|
|
orim2vsize = rqt_visize;
|
|
//mutr.unlock();
|
|
wbuf = owbuf;
|
|
if ( fact_x < rqt_fact) {
|
|
fact_x=rqt_fact;
|
|
initRequant();
|
|
}
|
|
fact_x=rqt_fact;
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|