From 0d382a262c0638d0f572fc37193ccc5ed3dc895f Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 17 Feb 2010 00:32:19 +0000 Subject: Added old abandoned version of k9copy git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k9copy@1091546 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- k9vamps/k9requant.cpp | 2481 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2481 insertions(+) create mode 100644 k9vamps/k9requant.cpp (limited to 'k9vamps/k9requant.cpp') diff --git a/k9vamps/k9requant.cpp b/k9vamps/k9requant.cpp new file mode 100644 index 0000000..009f76c --- /dev/null +++ b/k9vamps/k9requant.cpp @@ -0,0 +1,2481 @@ +// +// C++ Implementation: k9requant +// +// Description: +// +// +// Author: Jean-Michel PETIT , (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 +#include +#include +#include +#include + +#ifndef USE_FD +#include +#include +#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( register int x, register int y ) +{ return x < y ? y : x; } + +int k9requant::intmin( register int x, register 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< (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)) + { + QMutexLocker locker( &mutw ); + //mutw.lock(); + rqt_wcnt = wbuf - owbuf; + condw.wakeAll(); + //mutw.unlock(); + } + //mutr.lock(); + QMutexLocker 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; + +} + + + -- cgit v1.2.1