diff options
Diffstat (limited to 'debian/transcode/transcode-1.1.7/import/tcrequant.c')
| -rw-r--r-- | debian/transcode/transcode-1.1.7/import/tcrequant.c | 2003 |
1 files changed, 2003 insertions, 0 deletions
diff --git a/debian/transcode/transcode-1.1.7/import/tcrequant.c b/debian/transcode/transcode-1.1.7/import/tcrequant.c new file mode 100644 index 00000000..f2e5e2d1 --- /dev/null +++ b/debian/transcode/transcode-1.1.7/import/tcrequant.c @@ -0,0 +1,2003 @@ +// Adapted into transcode by Tilmann Bitterberg +// 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 STAT // print stats on exit +#define NDEBUG // turns off asserts +#define REMOVE_BYTE_STUFFING // removes 0x 00 00 00 00 00 00 used in cbr streams (look for 6 0x00 and remove 1 0x00) + /* 4 0x00 might be legit, for exemple: + 00 00 01 b5 14 82 00 01 00 00 00 00 01 b8 .. .. + these two: -- -- are part of the seq. header ext. + AFAIK 5 0x00 should never happen except for byte stuffing but to be safe look for 6 */ +// #define USE_FD // use 2 lasts args for input/output paths + +#define REACT_DELAY (1024.0*128.0) +#define MAX_ERRORS 0 + +// notes: +// +// - intra block: +// - the quantiser is increment by one step +// +// - non intra block: +// - in P_FRAME we keep the original quantiser but drop the last coefficient +// if there is more than one +// - in B_FRAME we multiply the quantiser by a factor +// +// - I_FRAME is recoded when we're 5.0 * REACT_DELAY late +// - P_FRAME is recoded when we're 2.5 * REACT_DELAY late +// - B_FRAME are always recoded + +// if we're getting *very* late (60 * REACT_DELAY) +// +// - intra blocks quantiser is incremented two step +// - drop a few coefficients but always keep the first one + + +// includes +#include "transcode.h" + +#include <assert.h> +#include <math.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 + +int verbose = TC_QUIET; +#define EXE "tcrequant" + +#ifndef PACKAGE +# define PACKAGE "transcode" +#endif + +#ifndef VERSION +# define VERSION "1.0.0" +#endif + + +// user defined types +//typedef unsigned int uint; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long long uint64; + +typedef char int8; +typedef short int16; +typedef int int32; +typedef long long int64; + +typedef signed int sint; +typedef signed char sint8; +typedef signed short sint16; +typedef signed int sint32; +typedef signed long long sint64; + +#define BITS_IN_BUF (8) + +// global variables +static uint8 *cbuf, *rbuf, *wbuf, *orbuf, *owbuf; +static int inbitcnt, outbitcnt; +static uint32 inbitbuf, outbitbuf; +static uint64 inbytecnt, outbytecnt; +static float fact_x; +static int mloka1; + +static int ifd, ofd; + +#ifdef STAT +static uint64 ori_i, ori_p, ori_b; +static uint64 new_i, new_p, new_b; +static uint64 cnt_i, cnt_p, cnt_b; +static uint64 cnt_p_i, cnt_p_ni; +static uint64 cnt_b_i, cnt_b_ni; +#endif + +// mpeg2 state + // seq header + static uint horizontal_size_value; + static uint vertical_size_value; + + // pic header + static uint picture_coding_type; + + // pic code ext + static uint f_code[2][2]; + static uint intra_dc_precision; + static uint picture_structure; + static uint frame_pred_frame_dct; + static uint concealment_motion_vectors; + static uint q_scale_type; + static uint intra_vlc_format; + static uint alternate_scan; + + // error + static int validPicHeader; + static int validSeqHeader; + static int validExtHeader; + static int sliceError; + + // slice or mb + static uint quantizer_scale; + static uint new_quantizer_scale; + static uint last_coded_scale; + static int h_offset, v_offset; + + // rate + static double quant_corr; + + // block data + typedef struct + { + uint8 run; + short level; + } RunLevel; + + static RunLevel block[6][65]; // terminated by level = 0, so we need 64+1 +// end mpeg2 state + +#ifndef NDEBUG + #define DEB(msg) tc_log_msg(EXE, "%s:%d " msg, __FILE__, __LINE__) + #define DEBF(format, args...) tc_log_msg(EXE, "%s:%d " format, __FILE__, __LINE__, args) +#else + #define DEB(msg) + #define DEBF(format, args...) +#endif + +#define LOG(msg) do { if (verbose > 1) tc_log_msg(EXE, msg); } while (0) +#define LOGF(format, args...) do { if (verbose > 1) tc_log_msg(EXE, format, args); } while (0) + +#define BUF_SIZE (16*1024*1024) +#define MIN_READ (1*1024*1024) +#define MIN_WRITE (1*1024*1024) + + #define WRITE \ + mloka1 = wbuf - owbuf; \ + write(ofd, owbuf, mloka1); \ + outbytecnt += mloka1; \ + wbuf = owbuf; \ + mloka1 = rbuf - cbuf; if (mloka1) memmove(orbuf, cbuf, mloka1);\ + cbuf = rbuf = orbuf; rbuf += mloka1; + + #define LOCK(x) \ + while (unlikely(x > (rbuf-cbuf))) \ + { \ + assert(rbuf + MIN_READ < orbuf + BUF_SIZE); \ + mloka1 = read(ifd, rbuf, MIN_READ); \ + if (mloka1 <= 0) { RETURN } \ + inbytecnt += mloka1; \ + rbuf += mloka1; \ + } + + +#ifdef STAT + + #define RETURN \ + assert(rbuf >= cbuf);\ + mloka1 = rbuf - cbuf;\ + if (mloka1) { COPY(mloka1); }\ + WRITE \ + free(orbuf); \ + free(owbuf); \ + \ + LOG("Stats:");\ + \ + LOGF("Wanted fact_x: %.1f", fact_x);\ + \ + if (cnt_i) LOGF("cnt_i: %.0f ori_i: %.0f new_i: %.0f fact_i: %.1f", (float)cnt_i, (float)ori_i, (float)new_i, (float)ori_i/(float)new_i); \ + else LOGF("cnt_i: %.0f", (float)cnt_i);\ + \ + if (cnt_p) LOGF("cnt_p: %.0f ori_p: %.0f new_p: %.0f fact_p: %.1f cnt_p_i: %.0f cnt_p_ni: %.0f propor: %.1f i", \ + (float)cnt_p, (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 LOGF("cnt_p: %.0f", (float)cnt_p); \ + \ + if (cnt_b) LOGF("cnt_b: %.0f ori_b: %.0f new_b: %.0f fact_b: %.1f cnt_b_i: %.0f cnt_b_ni: %.0f propor: %.1f i\n", \ + (float)cnt_b, (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 LOGF("cnt_b: %.0f", (float)cnt_b); \ + \ + LOGF("Final fact_x: %.1f", (float)inbytecnt/(float)outbytecnt);\ + exit(0); + +#else + + #define RETURN \ + assert(rbuf >= cbuf);\ + mloka1 = rbuf - cbuf;\ + if (mloka1) { COPY(mloka1); }\ + WRITE \ + free(orbuf); \ + free(owbuf); \ + exit(0); + +#endif + +#define COPY(x)\ + assert(x > 0); \ + assert(wbuf + x < owbuf + BUF_SIZE); \ + assert(cbuf + x < orbuf + BUF_SIZE); \ + assert(cbuf + x >= orbuf); \ + assert(wbuf + x >= orbuf); \ + ac_memcpy(wbuf, cbuf, x);\ + cbuf += x; \ + wbuf += x; + +#define SEEKR(x)\ + cbuf += x; \ + assert (cbuf <= rbuf); \ + assert (cbuf < orbuf + BUF_SIZE); \ + assert (cbuf >= orbuf); + +#define SEEKW(x)\ + wbuf += x; \ + assert (wbuf < owbuf + BUF_SIZE); \ + assert (wbuf >= owbuf); + +static inline void putbits(uint val, int n) +{ + assert(n < 32); + assert(!(val & (0xffffffffU << n))); + + while (unlikely(n >= outbitcnt)) + { + wbuf[0] = (outbitbuf << outbitcnt ) | (val >> (n - outbitcnt)); + SEEKW(1); + n -= outbitcnt; + outbitbuf = 0; + val &= ~(0xffffffffU << n); + outbitcnt = BITS_IN_BUF; + } + + if (likely(n)) + { + outbitbuf = (outbitbuf << n) | val; + outbitcnt -= n; + } + + assert(outbitcnt > 0); + assert(outbitcnt <= BITS_IN_BUF); +} + +static inline void Refill_bits(void) +{ + assert((rbuf - cbuf) >= 1); + inbitbuf |= cbuf[0] << (24 - inbitcnt); + inbitcnt += 8; + SEEKR(1) +} + +static inline void Flush_Bits(uint n) +{ + assert(inbitcnt >= n); + + inbitbuf <<= n; + inbitcnt -= n; + + assert( (!n) || ((n>0) && !(inbitbuf & 0x1)) ); + + while (unlikely(inbitcnt < 24)) Refill_bits(); +} + +static inline uint Show_Bits(uint n) +{ + return ((unsigned int)inbitbuf) >> (32 - n); +} + +static inline uint Get_Bits(uint n) +{ + uint Val = Show_Bits(n); + Flush_Bits(n); + return Val; +} + +static inline uint Copy_Bits(uint n) +{ + uint Val = Get_Bits(n); + putbits(Val, n); + return Val; +} + +static inline void flush_read_buffer(void) +{ + int i = inbitcnt & 0x7; + if (i) + { + if (inbitbuf >> (32 - i)) + { + DEBF("illegal inbitbuf: 0x%08X, %i, 0x%02X, %i", inbitbuf, inbitcnt, (inbitbuf >> (32 - i)), i); + sliceError++; + } + + inbitbuf <<= i; + inbitcnt -= i; + } + SEEKR(-1 * (inbitcnt >> 3)); + inbitcnt = 0; +} + +static inline void flush_write_buffer(void) +{ + if (outbitcnt != 8) putbits(0, outbitcnt); +} + +/////---- begin ext mpeg code + +const uint8 non_linear_mquant_table[32] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, + 8,10,12,14,16,18,20,22, + 24,28,32,36,40,44,48,52, + 56,64,72,80,88,96,104,112 +}; +const uint8 map_non_linear_mquant[113] = +{ + 0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16, + 16,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,22,22, + 22,22,23,23,23,23,24,24,24,24,24,24,24,25,25,25,25,25,25,25,26,26, + 26,26,26,26,26,26,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,29, + 29,29,29,29,29,29,29,29,29,30,30,30,30,30,30,30,31,31,31,31,31 +}; + +static int scale_quant(double quant ) +{ + int iquant; + if (q_scale_type) + { + iquant = (int) floor(quant+0.5); + + /* clip mquant to legal (linear) range */ + if (iquant<1) iquant = 1; + if (iquant>112) iquant = 112; + + iquant = non_linear_mquant_table[map_non_linear_mquant[iquant]]; + } + else + { + /* clip mquant to legal (linear) range */ + iquant = (int)floor(quant+0.5); + if (iquant<2) iquant = 2; + if (iquant>62) iquant = 62; + iquant = (iquant/2)*2; // Must be *even* + } + return iquant; +} + +static int increment_quant(int quant) +{ + if (q_scale_type) + { + //assert(quant >= 1 && quant <= 112); + if (quant < 1 || quant > 112) + { + DEBF("illegal quant: %d", quant); + if (quant > 112) quant = 112; + else if (quant < 1) quant = 1; + DEBF("illegal quant changed to : %d", quant); + sliceError++; + } + quant = map_non_linear_mquant[quant] + 1; + if (quant_corr < -60.0f) quant++; + if (quant > 31) quant = 31; + quant = non_linear_mquant_table[quant]; + } + else + { + // assert(!(quant & 1)); + if ((quant & 1) || (quant < 2) || (quant > 62)) + { + DEBF("illegal quant: %d", quant); + if (quant & 1) quant--; + if (quant > 62) quant = 62; + else if (quant < 2) quant = 2; + DEBF("illegal quant changed to : %d", quant); + sliceError++; + } + quant += 2; + if (quant_corr < -60.0f) quant += 2; + if (quant > 62) quant = 62; + } + return quant; +} + +static inline int intmax( register int x, register int y ) +{ return x < y ? y : x; } + +static inline int intmin( register int x, register int y ) +{ return x < y ? x : y; } + + +static int getNewQuant(int curQuant) +{ + double calc_quant, quant_to_use; + int mquant = 0; + + calc_quant = curQuant * fact_x; + quant_corr = (((inbytecnt - (rbuf - cbuf)) / fact_x) - (outbytecnt + (wbuf - owbuf))) / REACT_DELAY; + quant_to_use = calc_quant - quant_corr; + + switch (picture_coding_type) + { + case I_TYPE: + case P_TYPE: + mquant = increment_quant(curQuant); + break; + + case B_TYPE: + mquant = intmax(scale_quant(quant_to_use), increment_quant(curQuant)); + break; + + default: + assert(0); + break; + } + + /* + LOGF("type: %s orig_quant: %3i calc_quant: %7.1f quant_corr: %7.1f using_quant: %3i", + (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), + (int)curQuant, (float)calc_quant, (float)quant_corr, (int)mquant); + */ + + assert(mquant >= curQuant); + + return mquant; +} + +static inline int isNotEmpty(RunLevel *blk) +{ + return (blk->level); +} + +#include "putvlc.h" + +// return != 0 if error +static int putAC(int run, int signed_level, int vlcformat) +{ + int level, len; + const VLCtable *ptab = NULL; + + level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */ + + // assert(!(run<0 || run>63 || level==0 || level>2047)); + if(run<0 || run>63) + { + DEBF("illegal run: %d", run); + sliceError++; + return 1; + } + if(level==0 || level>2047) + { + DEBF("illegal level: %d", level); + sliceError++; + return 1; + } + + len = 0; + + if (run<2 && level<41) + { + if (vlcformat) ptab = &dct_code_tab1a[run][level-1]; + else ptab = &dct_code_tab1[run][level-1]; + len = ptab->len; + } + else if (run<32 && level<6) + { + if (vlcformat) ptab = &dct_code_tab2a[run-2][level-1]; + else ptab = &dct_code_tab2[run-2][level-1]; + len = ptab->len; + } + + if (len) /* a VLC code exists */ + { + putbits(ptab->code, len); + putbits(signed_level<0, 1); /* sign */ + } + else + { + putbits(1l, 6); /* Escape */ + putbits(run, 6); /* 6 bit code for run */ + putbits(((uint)signed_level) & 0xFFF, 12); + } + + return 0; +} + +// return != 0 if error +static inline int putACfirst(int run, int val) +{ + if (run==0 && (val==1 || val==-1)) + { + putbits(2|(val<0),2); + return 0; + } + else return putAC(run,val,0); +} + +static void putnonintrablk(RunLevel *blk) +{ + assert(blk->level); + + if (putACfirst(blk->run, blk->level)) return; + blk++; + + while(blk->level) + { + if (putAC(blk->run, blk->level, 0)) return; + blk++; + } + + putbits(2,2); +} + +static inline void putcbp(int cbp) +{ + putbits(cbptable[cbp].code,cbptable[cbp].len); +} + +static void putmbtype(int mb_type) +{ + putbits(mbtypetab[picture_coding_type-1][mb_type].code, + mbtypetab[picture_coding_type-1][mb_type].len); +} + +#include <stdint.h> +#include "getvlc.h" + +static int non_linear_quantizer_scale [] = +{ + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 10, 12, 14, 16, 18, 20, 22, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 64, 72, 80, 88, 96, 104, 112 +}; + +static inline int get_macroblock_modes(void) +{ + int macroblock_modes; + const MBtab * tab; + + switch (picture_coding_type) + { + case I_TYPE: + + tab = MB_I + UBITS (bit_buf, 1); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if ((! (frame_pred_frame_dct)) && (picture_structure == FRAME_PICTURE)) + { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + + return macroblock_modes; + + case P_TYPE: + + tab = MB_P + UBITS (bit_buf, 5); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture_structure != FRAME_PICTURE) + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } + else if (frame_pred_frame_dct) + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } + else + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + case B_TYPE: + + tab = MB_B + UBITS (bit_buf, 6); + DUMPBITS (bit_buf, bits, tab->len); + macroblock_modes = tab->modes; + + if (picture_structure != FRAME_PICTURE) + { + if (! (macroblock_modes & MACROBLOCK_INTRA)) + { + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + } + return macroblock_modes; + } + else if (frame_pred_frame_dct) + { + /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ + macroblock_modes |= MC_FRAME; + return macroblock_modes; + } + else + { + if (macroblock_modes & MACROBLOCK_INTRA) goto intra; + macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; + DUMPBITS (bit_buf, bits, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + intra: + macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; + DUMPBITS (bit_buf, bits, 1); + } + return macroblock_modes; + } + + default: + return 0; + } + +} + +static inline int get_quantizer_scale(void) +{ + 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", quantizer_scale_code); + sliceError++; + quantizer_scale_code++; + } + + if (q_scale_type) return non_linear_quantizer_scale[quantizer_scale_code]; + else return quantizer_scale_code << 1; +} + +static inline int get_motion_delta (const int f_code) +{ +#define bit_buf (inbitbuf) + + int delta; + int sign; + const MVtab * tab; + + if (bit_buf & 0x80000000) + { + COPYBITS (bit_buf, bits, 1); + return 0; + } + else if (bit_buf >= 0x0c000000) + { + + tab = MV_4 + UBITS (bit_buf, 4); + delta = (tab->delta << f_code) + 1; + COPYBITS (bit_buf, bits, tab->len); + + sign = SBITS (bit_buf, 1); + COPYBITS (bit_buf, bits, 1); + + if (f_code) delta += UBITS (bit_buf, f_code); + COPYBITS (bit_buf, bits, f_code); + + return (delta ^ sign) - sign; + } + else + { + + tab = MV_10 + UBITS (bit_buf, 10); + delta = (tab->delta << f_code) + 1; + COPYBITS (bit_buf, bits, tab->len); + + sign = SBITS (bit_buf, 1); + COPYBITS (bit_buf, bits, 1); + + if (f_code) + { + delta += UBITS (bit_buf, f_code); + COPYBITS (bit_buf, bits, f_code); + } + + return (delta ^ sign) - sign; + } +} + + +static inline int get_dmv(void) +{ + const DMVtab * tab; + + tab = DMV_2 + UBITS (bit_buf, 2); + COPYBITS (bit_buf, bits, tab->len); + return tab->dmv; +} + +static inline int get_coded_block_pattern(void) +{ +#define bit_buf (inbitbuf) + const CBPtab * tab; + + if (bit_buf >= 0x20000000) + { + tab = CBP_7 + (UBITS (bit_buf, 7) - 16); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + } + else + { + tab = CBP_9 + UBITS (bit_buf, 9); + DUMPBITS (bit_buf, bits, tab->len); + return tab->cbp; + } +} + +static inline int get_luma_dc_dct_diff(void) +{ +#define bit_buf (inbitbuf) + 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) + { + 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, 3); + return 0; + } + } + else + { + tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); + size = tab->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; + } +} + +static inline int get_chroma_dc_dct_diff(void) +{ +#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; + } +} + +static void get_intra_block_B14(void) +{ +#define bit_buf (inbitbuf) + int q = quantizer_scale, nq = new_quantizer_scale, tst = (nq / q) + ((nq % q) ? 1 : 0); + 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; + if (val >= tst) + { + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + if (putAC(i - li - 1, (val * q) / nq, 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) break; /* illegal, check needed to avoid buffer overflow */ + + DUMPBITS (bit_buf, bits, 12); + val = SBITS (bit_buf, 12); + if (abs(val) >= tst) + { + if (putAC(i - li - 1, (val * q) / nq, 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; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + COPYBITS (bit_buf, bits, 2); /* end of block code */ +} + +static void get_intra_block_B15(void) +{ +#define bit_buf (inbitbuf) + int q = quantizer_scale, nq = new_quantizer_scale, tst = (nq / q) + ((nq % q) ? 1 : 0); + 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; + if (val >= tst) + { + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + if (putAC(i - li - 1, (val * q) / nq, 1)) break; + li = i; + } + + DUMPBITS (bit_buf, bits, 1); + + continue; + } + else + { + i += (UBITS (bit_buf, 12) & 0x3F) - 64; + + if (i >= 64) break; /* illegal, check against buffer overflow */ + + DUMPBITS (bit_buf, bits, 12); + val = SBITS (bit_buf, 12); + if (abs(val) >= tst) + { + if (putAC(i - li - 1, (val * q) / nq, 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; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + COPYBITS (bit_buf, bits, 4); /* end of block code */ +} + + +static int get_non_intra_block_drop (RunLevel *blk) +{ +#define bit_buf (inbitbuf) + + int i, li; + int val; + const DCTtab * tab; + RunLevel *sblk = blk + 1; + + 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); /* if (bitstream_get (1)) val = -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) break; /* illegal, check needed to avoid buffer overflow */ + + DUMPBITS (bit_buf, bits, 12); + val = SBITS (bit_buf, 12); + + 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; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + + // remove last coeff + if (blk != sblk) + { + blk--; + // remove more coeffs if very late + if ((quant_corr < -60.0f) && (blk != sblk)) + { + blk--; + if ((quant_corr < -80.0f) && (blk != sblk)) + { + blk--; + if ((quant_corr < -100.0f) && (blk != sblk)) + { + blk--; + if ((quant_corr < -120.0f) && (blk != sblk)) + blk--; + } + } + } + } + + blk->level = 0; + + return i; +} + +static int get_non_intra_block_rq (RunLevel *blk) +{ +#define bit_buf (inbitbuf) + int q = quantizer_scale, 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; + if (val >= tst) + { + val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); + blk->level = (val * q) / nq; + blk->run = i - li - 1; + li = i; + blk++; + } + + //if ( ((val) && (tab->level < tst)) || ((!val) && (tab->level >= tst)) ) + // LOGF("level: %i val: %i tst : %i q: %i nq : %i", tab->level, val, tst, q, nq); + + 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) break; /* illegal, check needed to avoid buffer overflow */ + + DUMPBITS (bit_buf, bits, 12); + val = SBITS (bit_buf, 12); + if (abs(val) >= tst) + { + blk->level = (val * q) / nq; + 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; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ + + blk->level = 0; + + return i; +} + +static inline void slice_intra_DCT (const int cc) +{ + if (cc == 0) get_luma_dc_dct_diff (); + else get_chroma_dc_dct_diff (); + + if (intra_vlc_format) get_intra_block_B15 (); + else get_intra_block_B14 (); +} + +static inline void slice_non_intra_DCT (int cur_block) +{ + if (picture_coding_type == P_TYPE) get_non_intra_block_drop(block[cur_block]); + else get_non_intra_block_rq(block[cur_block]); +} + +static void motion_fr_frame(uint f_code[2]) +{ + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); +} + +static void motion_fr_field(uint f_code[2]) +{ + COPYBITS (bit_buf, bits, 1); + + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); + + COPYBITS (bit_buf, bits, 1); + + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); +} + +static void motion_fr_dmv(uint f_code[2]) +{ + get_motion_delta (f_code[0]); + get_dmv (); + + get_motion_delta (f_code[1]); + get_dmv (); +} + +/* like motion_frame, but parsing without actual motion compensation */ +static void motion_fr_conceal(void) +{ + get_motion_delta (f_code[0][0]); + get_motion_delta (f_code[0][1]); + + COPYBITS (bit_buf, bits, 1); /* remove marker_bit */ +} + +static void motion_fi_field(uint f_code[2]) +{ + COPYBITS (bit_buf, bits, 1); + + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); +} + +static void motion_fi_16x8(uint f_code[2]) +{ + COPYBITS (bit_buf, bits, 1); + + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); + + COPYBITS (bit_buf, bits, 1); + + get_motion_delta (f_code[0]); + get_motion_delta (f_code[1]); +} + +static void motion_fi_dmv(uint f_code[2]) +{ + get_motion_delta (f_code[0]); + get_dmv (); + + get_motion_delta (f_code[1]); + get_dmv (); +} + +static void motion_fi_conceal(void) +{ + COPYBITS (bit_buf, bits, 1); /* remove field_select */ + + get_motion_delta (f_code[0][0]); + get_motion_delta (f_code[0][1]); + + COPYBITS (bit_buf, bits, 1); /* remove marker_bit */ +} + +#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) + +static void putmbdata(int macroblock_modes) +{ + putmbtype(macroblock_modes & 0x1F); + + switch (picture_coding_type) + { + case I_TYPE: + if ((! (frame_pred_frame_dct)) && (picture_structure == FRAME_PICTURE)) + putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + break; + + case P_TYPE: + if (picture_structure != FRAME_PICTURE) + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + break; + } + else if (frame_pred_frame_dct) break; + else + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + break; + } + + case B_TYPE: + if (picture_structure != FRAME_PICTURE) + { + if (! (macroblock_modes & MACROBLOCK_INTRA)) + putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + break; + } + else if (frame_pred_frame_dct) break; + else + { + if (macroblock_modes & MACROBLOCK_INTRA) goto intra; + putbits((macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + intra: + putbits(macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + } + break; + } + } + +} + +static inline void put_quantiser(int quantiser) +{ + putbits(q_scale_type ? map_non_linear_mquant[quantiser] : quantiser >> 1, 5); + last_coded_scale = quantiser; +} + +static inline int slice_init (int code) +{ +#define bit_buf (inbitbuf) + + int offset; + const MBAtab * mba; + + v_offset = (code - 1) * 16; + + quantizer_scale = get_quantizer_scale (); + if (picture_coding_type == P_TYPE) new_quantizer_scale = quantizer_scale; + else new_quantizer_scale = getNewQuant(quantizer_scale); + put_quantiser(new_quantizer_scale); + + /*LOGF("************************\nstart of slice %i in %s picture. ori quant: %i new quant: %i", code, + (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), + quantizer_scale, 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; + COPYBITS (bit_buf, bits, 11); + continue; + default: /* error */ + return 1; + } + } + + COPYBITS (bit_buf, bits, mba->len + 1); + 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; + +} + +static void mpeg2_slice(const int code) +{ +#define bit_buf (inbitbuf) + + 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 (); + + //LOGF("blk %i : ", h_offset >> 4); + + 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 + + //LOG("intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); + + new_quantizer_scale = increment_quant(quantizer_scale); + if (last_coded_scale == new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT + else macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT + putmbdata(macroblock_modes); + if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser(new_quantizer_scale); + + //if (macroblock_modes & MACROBLOCK_QUANT) LOGF("put new quant: %i ", new_quantizer_scale); + + if (concealment_motion_vectors) + { + if (picture_structure == FRAME_PICTURE) motion_fr_conceal (); + else motion_fi_conceal (); + } + + 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 = owbuf, *o_wbuf = wbuf; + uint32 n_outbitcnt, n_outbitbuf, + o_outbitcnt = outbitcnt, o_outbitbuf = outbitbuf; + + outbitbuf = 0; outbitcnt = BITS_IN_BUF; + owbuf = wbuf = n_owbuf; + + 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; + } + + assert(wbuf - owbuf < 32); + + n_wbuf = wbuf; + n_outbitcnt = outbitcnt; + n_outbitbuf = outbitbuf; + assert(owbuf == n_owbuf); + + outbitcnt = o_outbitcnt; + outbitbuf = o_outbitbuf; + owbuf = o_owbuf; + wbuf = o_wbuf; + // 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 + + if (picture_coding_type == P_TYPE) new_quantizer_scale = quantizer_scale; + else new_quantizer_scale = getNewQuant(quantizer_scale); + + //LOG("non intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); + + if (macroblock_modes & MACROBLOCK_PATTERN) + { + int coded_block_pattern = get_coded_block_pattern (); + + if (coded_block_pattern & 0x20) slice_non_intra_DCT(0); + if (coded_block_pattern & 0x10) slice_non_intra_DCT(1); + if (coded_block_pattern & 0x08) slice_non_intra_DCT(2); + if (coded_block_pattern & 0x04) slice_non_intra_DCT(3); + if (coded_block_pattern & 0x02) slice_non_intra_DCT(4); + if (coded_block_pattern & 0x01) slice_non_intra_DCT(5); + + if (picture_coding_type == B_TYPE) + { + if (coded_block_pattern & 0x20) if (isNotEmpty(block[0])) new_coded_block_pattern |= 0x20; + if (coded_block_pattern & 0x10) if (isNotEmpty(block[1])) new_coded_block_pattern |= 0x10; + if (coded_block_pattern & 0x08) if (isNotEmpty(block[2])) new_coded_block_pattern |= 0x08; + if (coded_block_pattern & 0x04) if (isNotEmpty(block[3])) new_coded_block_pattern |= 0x04; + if (coded_block_pattern & 0x02) if (isNotEmpty(block[4])) new_coded_block_pattern |= 0x02; + if (coded_block_pattern & 0x01) if (isNotEmpty(block[5])) new_coded_block_pattern |= 0x01; + if (!new_coded_block_pattern) macroblock_modes &= 0xFFFFFFED; // remove MACROBLOCK_PATTERN and MACROBLOCK_QUANT flag + } + else new_coded_block_pattern = coded_block_pattern; + } + + 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) ); + + putmbdata(macroblock_modes); + if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser(new_quantizer_scale); + + //if (macroblock_modes & MACROBLOCK_PATTERN) LOG("coded "); + //if (macroblock_modes & MACROBLOCK_QUANT) LOGF("put new quant: %i ", 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]); + } + } + + //LOGF("o: %i c: %i n: %i", quantizer_scale, last_coded_scale, new_quantizer_scale); + + 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; + COPYBITS (bit_buf, bits, 11); + continue; + default: /* end of slice, or error */ + return; + } + } + COPYBITS (bit_buf, bits, mba->len); + mba_inc += mba->mba; + + if (mba_inc) do { NEXT_MACROBLOCK; } while (--mba_inc); + } + +} + +/////---- end ext mpeg code + +void version(void) +{ + /* print id string to stderr */ + fprintf(stderr, "%s (%s v%s) (C) 2001-2003 Antoine Missout\n", + EXE, PACKAGE, VERSION); +} + +static void usage(int status) +{ + version(); + + fprintf(stderr,"\nUsage: %s [options]\n", EXE); + fprintf(stderr," -i name input file name [stdin]\n"); + fprintf(stderr," -o file output file name [stdout]\n"); + fprintf(stderr," -d mode verbosity mode\n"); + fprintf(stderr," -f factor requantize factor [1.5]\n"); + fprintf(stderr," -b N remove byte stuffing [1]\n"); + fprintf(stderr," -v print version\n"); + + exit(status); + +} + + +int main (int argc, char *argv[]) +{ + uint8 ID, found; + int ch; + char *ifile=NULL, *ofile=NULL; + int byte_stuff; + +#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 + + // default + fact_x = 1.25; + byte_stuff = 1; + + libtc_init(&argc, &argv); + + while ((ch = getopt(argc, argv, "b:d:i:o:f:v?h")) != -1) { + + switch (ch) { + + case 'i': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + ifile = optarg; + break; + + case 'o': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + ofile = optarg; + break; + + case 'f': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + fact_x = atof(optarg); break; + + case 'd': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + verbose = atoi(optarg); + break; + + case 'b': + + if(optarg[0]=='-') usage(EXIT_FAILURE); + byte_stuff = atoi(optarg); + break; + + case 'v': + version(); + exit(0); + break; + + case 'h': + case '?': + default: + usage(EXIT_SUCCESS); + break; + } + } // while + + + if (ifile) { + if ( (ifd = open(ifile, O_RDONLY, 0)) < 0) { + tc_log_warn(EXE, "Cannot open input file: %s", strerror(errno)); + } + } else { + ifd = STDIN_FILENO; + } + + if (ofile) { + if ( (ofd = open(ofile, O_WRONLY | O_CREAT | O_TRUNC, 0644))<0) { + tc_log_warn(EXE, "Cannot open output file: %s", strerror(errno)); + } + } else { + ofd = STDOUT_FILENO; + } + + rbuf = cbuf = orbuf = tc_malloc(BUF_SIZE); + wbuf = owbuf = tc_malloc(BUF_SIZE); + if (!orbuf || !owbuf) { + tc_log_error(EXE, "malloc() failed at %s:%d", __FILE__, __LINE__); + exit (1); + } + inbytecnt = outbytecnt = 0; + + validPicHeader = 0; + validSeqHeader = 0; + validExtHeader = 0; + + if (fact_x < 1.0) fact_x = 1.0; + else if (fact_x > 900.0) fact_x = 900.0; + byte_stuff = !!byte_stuff; + + LOG("MPEG2 Requantiser by Makira."); + LOGF("Using %f as factor.", fact_x); + + // recoding + while(1) + { + // get next start code prefix + found = 0; + while (!found) + { + if (!byte_stuff) { + LOCK(3) + } else { + LOCK(6) + if ( (cbuf[0] == 0) && (cbuf[1] == 0) && (cbuf[2] == 0) && (cbuf[3] == 0) && (cbuf[4] == 0) && (cbuf[5] == 0) ) { SEEKR(1) } + } + 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", picture_coding_type); + validPicHeader = 0; + } + else + { + validPicHeader = 1; + cbuf[1] |= 0x7; cbuf[2] = 0xFF; cbuf[3] |= 0xF8; // vbv_delay is now 0xFFFF + } + 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", horizontal_size_value, vertical_size_value); + validSeqHeader = 0; + } + else + validSeqHeader = 1; + 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", + 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) + } + else if ((ID >= 0x01) && (ID <= 0xAF) && validPicHeader && validSeqHeader && validExtHeader) // slice + { + uint8 *outTemp = wbuf, *inTemp = cbuf; + + quant_corr = (((inbytecnt - (rbuf - cbuf)) / fact_x) - (outbytecnt + (wbuf - owbuf))) / REACT_DELAY; + + if ( ((picture_coding_type == B_TYPE) && (quant_corr < 2.5f)) // don't recompress if we're in advance! + || ((picture_coding_type == P_TYPE) && (quant_corr < -2.5f)) + || ((picture_coding_type == I_TYPE) && (quant_corr < -5.0f)) + ) + { + uint8 *nsc = cbuf; + int fsc = 0, toLock; + + // lock all the slice + while (!fsc) + { + toLock = nsc - cbuf + 3; + LOCK(toLock) + + if ( (nsc[0] == 0) && (nsc[1] == 0) && (nsc[2] == 1) ) fsc = 1; // start code ! + else nsc++; // continue search + } + + // init error + sliceError = 0; + + // init bit buffer + inbitbuf = 0; inbitcnt = 0; + outbitbuf = 0; outbitcnt = BITS_IN_BUF; + + // get 32 bits + Refill_bits(); + Refill_bits(); + Refill_bits(); + Refill_bits(); + + // begin bit level recoding + mpeg2_slice(ID); + flush_read_buffer(); + flush_write_buffer(); + // end bit level recoding + + /*LOGF("type: %s code: %02i in : %6i out : %6i diff : %6i fact: %2.2f", + (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), + ID, cbuf - inTemp, wbuf - outTemp, (wbuf - outTemp) - (cbuf - inTemp), (float)(cbuf - inTemp) / (float)(wbuf - outTemp));*/ + + 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)", sliceError, MAX_ERRORS); + } +#endif + + /*LOGF("*** slice bigger than before !! (type: %s code: %i in : %i out : %i diff : %i)", + (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), + ID, cbuf - inTemp, wbuf - outTemp, (wbuf - outTemp) - (cbuf - inTemp));*/ + + // in this case, we'll just use the original slice ! + ac_memcpy(outTemp, inTemp, cbuf - inTemp); + wbuf = outTemp + (cbuf - inTemp); + + // adjust outbytecnt + outbytecnt -= (wbuf - outTemp) - (cbuf - inTemp); + } + +#ifdef STAT + 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)", ID); + if (!validSeqHeader) DEBF("missing seq header (%02X)", ID); + if (!validExtHeader) DEBF("missing ext header (%02X)", ID); + } +#endif + + if (wbuf - owbuf > MIN_WRITE) { WRITE } + } + + // keeps gcc happy + return 0; +} + +#include "libtc/static_xio.h" |
