From 730460c00c3d132dfe573ee03013f0c77362a20f Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Wed, 12 Nov 2003 18:13:31 +0000 Subject: [PATCH] * all: big clean up (no more global variables). --- modules/stream_out/transrate/getvlc.h | 8 +- modules/stream_out/transrate/transrate.c | 2770 +++++++++++----------- 2 files changed, 1390 insertions(+), 1388 deletions(-) diff --git a/modules/stream_out/transrate/getvlc.h b/modules/stream_out/transrate/getvlc.h index bcf82c00df..9941f0af67 100644 --- a/modules/stream_out/transrate/getvlc.h +++ b/modules/stream_out/transrate/getvlc.h @@ -20,15 +20,11 @@ #define BOTTOM_FIELD 2 #define FRAME_PICTURE 3 -/* remove num valid bits from bit_buf */ -#define DUMPBITS(bit_buf,bits,num) Flush_Bits(num) -#define COPYBITS(bit_buf,bits,num) Copy_Bits(num) - /* take num bits from the high part of bit_buf and zero extend them */ -#define UBITS(bit_buf,num) (((uint32_t)(inbitbuf)) >> (32 - (num))) +#define UBITS(bit_buf,num) (((uint32_t)(bs->i_bit_in_cache)) >> (32 - (num))) /* take num bits from the high part of bit_buf and sign extend them */ -#define SBITS(bit_buf,num) (((int32_t)(inbitbuf)) >> (32 - (num))) +#define SBITS(bit_buf,num) (((int32_t)(bs->i_bit_in_cache)) >> (32 - (num))) typedef struct { uint8_t modes; diff --git a/modules/stream_out/transrate/transrate.c b/modules/stream_out/transrate/transrate.c index f44419d266..9a59c65d8e 100644 --- a/modules/stream_out/transrate/transrate.c +++ b/modules/stream_out/transrate/transrate.c @@ -6,9 +6,10 @@ * Copyright (C) 2003 Antoine Missout * Copyright (C) 2000-2003 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman - * $Id: transrate.c,v 1.1 2003/11/07 21:30:52 massiot Exp $ + * $Id: transrate.c,v 1.2 2003/11/12 18:13:31 fenrir Exp $ * * Authors: Christophe Massiot + * Laurent Aimar * Antoine Missout * Michel Lespinasse * Aaron Holtzman @@ -33,18 +34,13 @@ *****************************************************************************/ #include #include -#include #define NDEBUG 1 #include -#include #include -#include #include -#include #include -#include -#include +#include /***************************************************************************** * Exported prototypes @@ -56,8 +52,6 @@ static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * ); static int Del ( sout_stream_t *, sout_stream_id_t * ); static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_t * ); -static int transrate_video_new ( sout_stream_t *, sout_stream_id_t * ); -static void transrate_video_close ( sout_stream_t *, sout_stream_id_t * ); static int transrate_video_process( sout_stream_t *, sout_stream_id_t *, sout_buffer_t *, sout_buffer_t ** ); /***************************************************************************** @@ -140,6 +134,70 @@ static void Close( vlc_object_t * p_this ) free( p_sys ); } + + +/***************************************************************************** + * sout_stream_id_t: + *****************************************************************************/ + +typedef struct +{ + uint8_t run; + short level; +} RunLevel; + +typedef struct +{ + uint8_t *p_c; + uint8_t *p_r; + uint8_t *p_w; + uint8_t *p_ow; + uint8_t *p_rw; + + int i_bit_in; + int i_bit_out; + uint32_t i_bit_in_cache; + uint32_t i_bit_out_cache; + + uint32_t i_byte_in; + uint32_t i_byte_out; +} bs_transrate_t; + +typedef struct +{ + bs_transrate_t bs; + + /* MPEG2 state */ + + // seq header + unsigned int horizontal_size_value; + unsigned int vertical_size_value; + + // pic header + unsigned int picture_coding_type; + + // pic code ext + unsigned int f_code[2][2]; + /* unsigned int intra_dc_precision; */ + unsigned int picture_structure; + unsigned int frame_pred_frame_dct; + unsigned int concealment_motion_vectors; + unsigned int q_scale_type; + unsigned int intra_vlc_format; + /* unsigned int alternate_scan; */ + + // slice or mb + // quantizer_scale_code + unsigned int quantizer_scale; + unsigned int new_quantizer_scale; + unsigned int last_coded_scale; + int h_offset, v_offset; + + // mb + double quant_corr, fact_x; +} transrate_t; + + struct sout_stream_id_t { void *id; @@ -149,6 +207,8 @@ struct sout_stream_id_t sout_buffer_t *p_next_gop; mtime_t i_next_gop_duration; size_t i_next_gop_size; + + transrate_t tr; }; @@ -167,13 +227,14 @@ static sout_stream_id_t * Add( sout_stream_t *p_stream, sout_format_t *p_fmt ) "creating video transrating for fcc=`%4.4s'", (char*)&p_fmt->i_fourcc ); - /* build decoder -> filter -> encoder */ - if( transrate_video_new( p_stream, id ) ) - { - msg_Err( p_stream, "cannot create video chain" ); - free( id ); - return NULL; - } + id->p_current_buffer = NULL; + id->p_next_gop = NULL; + id->i_next_gop_duration = 0; + id->i_next_gop_size = 0; + memset( &id->tr, 0, sizeof( transrate_t ) ); + id->tr.bs.i_byte_in = id->tr.bs.i_byte_out = 0; + id->tr.quant_corr = 0.0; + id->tr.fact_x = 1.0; /* open output stream */ id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt ); @@ -199,12 +260,10 @@ static int Del ( sout_stream_t *p_stream, sout_stream_id_t *id ) { sout_stream_sys_t *p_sys = p_stream->p_sys; - if( id->b_transrate ) + if( id->id ) { - transrate_video_close( p_stream, id ); + p_sys->p_out->pf_del( p_sys->p_out, id->id ); } - - if( id->id ) p_sys->p_out->pf_del( p_sys->p_out, id->id ); free( id ); return VLC_SUCCESS; @@ -243,12 +302,6 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, // toggles: // #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 */ - /* This is awful magic --Meuuh */ //#define REACT_DELAY (1024.0*128.0) #define REACT_DELAY (1024.0*4.0) @@ -256,12 +309,12 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, // notes: // // - intra block: -// - the quantiser is increment by one step +// - 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 +// - 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 @@ -273,9 +326,13 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, // - drop a few coefficients but always keep the first one // useful constants -#define I_TYPE 1 -#define P_TYPE 2 -#define B_TYPE 3 +enum +{ + I_TYPE = 1, + P_TYPE = 2, + B_TYPE = 3 +}; + // gcc #ifdef HAVE_BUILTIN_EXPECT @@ -286,363 +343,266 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, #define unlikely(x) (x) #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, *rwbuf; -static int inbitcnt, outbitcnt; -static uint32 inbitbuf, outbitbuf; -static uint32 inbytecnt, outbytecnt; - - static struct sout_stream_sys_t * p_sys; -// 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; - - // slice or mb - // quantizer_scale_code - static uint quantizer_scale; - static uint new_quantizer_scale; - static uint last_coded_scale; - static int h_offset, v_offset; - - // mb - static double quant_corr, fact_x; - - // 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 - #define LOG(msg) fprintf (stderr, msg) #define LOGF(format, args...) fprintf (stderr, format, args) -#define WRITE \ - do { } while(0); - -#define LOCK(x) \ - do { } while(0); +static inline void bs_write( bs_transrate_t *s, unsigned int val, int n) +{ + assert(n < 32); + assert(!(val & (0xffffffffU << n))); -#define COPY(x)\ - assert(x > 0); \ - memcpy(wbuf, cbuf, x);\ - cbuf += x; \ - wbuf += x; + while (unlikely(n >= s->i_bit_out)) + { + s->p_w[0] = (s->i_bit_out_cache << s->i_bit_out ) | (val >> (n - s->i_bit_out)); + s->p_w++; + n -= s->i_bit_out; + s->i_bit_out_cache = 0; + val &= ~(0xffffffffU << n); + s->i_bit_out = BITS_IN_BUF; + } -#define SEEKR(x)\ - cbuf += x; - -#define SEEKW(x)\ - wbuf += x; + if (likely(n)) + { + s->i_bit_out_cache = (s->i_bit_out_cache << n) | val; + s->i_bit_out -= n; + } -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); + assert(s->i_bit_out > 0); + assert(s->i_bit_out <= BITS_IN_BUF); } -static inline void Refill_bits(void) +static inline void bs_refill( bs_transrate_t *s ) { - assert((rbuf - cbuf) >= 1); - inbitbuf |= cbuf[0] << (24 - inbitcnt); - inbitcnt += 8; - SEEKR(1) + assert((s->p_r - s->p_c) >= 1); + s->i_bit_in_cache |= s->p_c[0] << (24 - s->i_bit_in); + s->i_bit_in += 8; + s->p_c++; } -static inline void Flush_Bits(uint n) +static inline void bs_flush( bs_transrate_t *s, unsigned int n ) { - assert(inbitcnt >= n); + assert(s->i_bit_in >= n); - inbitbuf <<= n; - inbitcnt -= n; + s->i_bit_in_cache <<= n; + s->i_bit_in -= n; - assert( (!n) || ((n>0) && !(inbitbuf & 0x1)) ); + assert( (!n) || ((n>0) && !(s->i_bit_in_cache & 0x1)) ); - while (unlikely(inbitcnt < 24)) Refill_bits(); + while (unlikely(s->i_bit_in < 24)) bs_refill( s ); } -static inline uint Show_Bits(uint n) +static inline unsigned int bs_read( bs_transrate_t *s, unsigned int n) { - return ((unsigned int)inbitbuf) >> (32 - n); + unsigned int Val = ((unsigned int)s->i_bit_in_cache) >> (32 - n); + bs_flush( s, n ); + return Val; } -static inline uint Get_Bits(uint n) +static inline unsigned int bs_copy( bs_transrate_t *s, unsigned int n) { - uint Val = Show_Bits(n); - Flush_Bits(n); - return Val; + unsigned int Val = bs_read( s, n); + bs_write(s, Val, n); + return Val; } -static inline uint Copy_Bits(uint n) +static inline void bs_flush_read( bs_transrate_t *s ) { - uint Val = Get_Bits(n); - putbits(Val, n); - return Val; -} - -static inline void flush_read_buffer() -{ - int i = inbitcnt & 0x7; - if (i) - { - //uint val = Show_Bits(i); - //putbits(val, i); - assert(((unsigned int)inbitbuf) >> (32 - i) == 0); - inbitbuf <<= i; - inbitcnt -= i; - } - SEEKR(-1 * (inbitcnt >> 3)); - inbitcnt = 0; + int i = s->i_bit_in & 0x7; + if( i ) + { + assert(((unsigned int)bs->i_bit_in_cache) >> (32 - i) == 0); + s->i_bit_in_cache <<= i; + s->i_bit_in -= i; + } + s->p_c += -1 * (s->i_bit_in >> 3); + s->i_bit_in = 0; } - - -static inline void flush_write_buffer() +static inline void bs_flush_write( bs_transrate_t *s ) { - if (outbitcnt != 8) putbits(0, outbitcnt); + if( s->i_bit_out != 8 ) bs_write(s, 0, s->i_bit_out); } /////---- begin ext mpeg code -const uint8 non_linear_mquant_table[32] = +const uint8_t 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 + 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] = +const uint8_t 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 + 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 ) +static int scale_quant( unsigned int q_scale_type, 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; + 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) +static int increment_quant( transrate_t *tr, int quant ) { - if (q_scale_type) - { - assert(quant >= 1 && quant <= 112); - 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)); - quant += 2; - if (quant_corr < -60.0f) quant += 2; - if (quant > 62) quant = 62; - } - return quant; + if( tr->q_scale_type) + { + assert(quant >= 1 && quant <= 112); + quant = map_non_linear_mquant[quant] + 1; + if( tr->quant_corr < -60.0f) quant++; + if( quant > 31) quant = 31; + quant = non_linear_mquant_table[quant]; + } + else + { + assert(!(quant & 1)); + quant += 2; + if( tr->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; } - +{ + return x < y ? y : x; +} static inline int intmin( register int x, register int y ) -{ return x < y ? x : y; } +{ + return x < y ? x : y; +} -static int getNewQuant(int curQuant) +static int getNewQuant( transrate_t *tr, int curQuant) { - double calc_quant, quant_to_use; - int mquant = 0; - - quant_corr = (((inbytecnt - (rbuf - 4 - cbuf)) / fact_x) - (outbytecnt + (wbuf - owbuf))) / REACT_DELAY; - calc_quant = curQuant * fact_x; - 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\n", - (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; + bs_transrate_t *bs = &tr->bs; + + double calc_quant, quant_to_use; + int mquant = 0; + + tr->quant_corr = (((bs->i_byte_in - (bs->p_r - 4 - bs->p_c)) / tr->fact_x) - (bs->i_byte_out + (bs->p_w - bs->p_ow))) / REACT_DELAY; + calc_quant = curQuant * tr->fact_x; + quant_to_use = calc_quant - tr->quant_corr; + + switch (tr->picture_coding_type ) + { + case I_TYPE: + case P_TYPE: + mquant = increment_quant( tr, curQuant); + break; + + case B_TYPE: + mquant = intmax(scale_quant( tr->q_scale_type, quant_to_use), increment_quant( tr, curQuant)); + break; + + default: + assert(0); + break; + } + + /* + LOGF("type: %s orig_quant: %3i calc_quant: %7.1f quant_corr: %7.1f using_quant: %3i\n", + (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); + return (blk->level); } #include "putvlc.h" -void putAC(int run, int signed_level, int vlcformat) +static void putAC( bs_transrate_t *bs, 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)); - - 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); - } -} + int level, len; + const VLCtable *ptab = NULL; + level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */ -static inline void putACfirst(int run, int val) -{ - if (run==0 && (val==1 || val==-1)) putbits(2|(val<0),2); - else putAC(run,val,0); -} + assert(!(run<0 || run>63 || level==0 || level>2047)); -void putnonintrablk(RunLevel *blk) -{ - assert(blk->level); - - putACfirst(blk->run, blk->level); - blk++; - - while(blk->level) - { - putAC(blk->run, blk->level, 0); - blk++; - } - - putbits(2,2); + 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 */ + { + bs_write( bs, ptab->code, len); + bs_write( bs, signed_level<0, 1); /* sign */ + } + else + { + bs_write( bs, 1l, 6); /* Escape */ + bs_write( bs, run, 6); /* 6 bit code for run */ + bs_write( bs, ((unsigned int)signed_level) & 0xFFF, 12); + } } -static inline void putcbp(int cbp) + +static inline void putACfirst( bs_transrate_t *bs, int run, int val) { - putbits(cbptable[cbp].code,cbptable[cbp].len); + if (run==0 && (val==1 || val==-1)) bs_write( bs, 2|(val<0),2); + else putAC( bs, run,val,0); } -void putmbtype(int mb_type) +static void putnonintrablk( bs_transrate_t *bs, RunLevel *blk) { - putbits(mbtypetab[picture_coding_type-1][mb_type].code, - mbtypetab[picture_coding_type-1][mb_type].len); + assert(blk->level); + + putACfirst( bs, blk->run, blk->level); + blk++; + + while(blk->level) + { + putAC( bs, blk->run, blk->level, 0); + blk++; + } + + bs_write( bs, 2,2); } -#include #include "getvlc.h" -static int non_linear_quantizer_scale [] = +static const int non_linear_quantizer_scale [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, @@ -650,1222 +610,1263 @@ static int non_linear_quantizer_scale [] = 56, 64, 72, 80, 88, 96, 104, 112 }; -static inline int get_macroblock_modes () +static inline int get_macroblock_modes( transrate_t *tr ) { + bs_transrate_t *bs = &tr->bs; + 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; + switch( tr->picture_coding_type) + { + case I_TYPE: + + tab = MB_I + UBITS (bs->i_bit_in_cache, 1); + bs_flush( bs, tab->len ); + macroblock_modes = tab->modes; + + if ((! ( tr->frame_pred_frame_dct)) && ( tr->picture_structure == FRAME_PICTURE)) + { + macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED; + bs_flush( bs, 1 ); + } + + return macroblock_modes; + + case P_TYPE: + + tab = MB_P + UBITS (bs->i_bit_in_cache, 5); + bs_flush( bs, tab->len ); + macroblock_modes = tab->modes; + + if (tr->picture_structure != FRAME_PICTURE) + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + { + macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE; + bs_flush( bs, 2 ); + } + return macroblock_modes; + } + else if (tr->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 (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE; + bs_flush( bs, 2 ); + } + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED; + bs_flush( bs, 1 ); + } + return macroblock_modes; + } + + case B_TYPE: + + tab = MB_B + UBITS (bs->i_bit_in_cache, 6); + bs_flush( bs, tab->len ); + macroblock_modes = tab->modes; + + if( tr->picture_structure != FRAME_PICTURE) + { + if (! (macroblock_modes & MACROBLOCK_INTRA)) + { + macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE; + bs_flush( bs, 2 ); + } + return macroblock_modes; + } + else if (tr->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 (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE; + bs_flush( bs, 2 ); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + intra: + macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED; + bs_flush( bs, 1 ); + } + return macroblock_modes; + } + + default: + return 0; } } -static inline int get_quantizer_scale () +static inline int get_quantizer_scale( transrate_t *tr ) { + bs_transrate_t *bs = &tr->bs; + int quantizer_scale_code; - quantizer_scale_code = UBITS (bit_buf, 5); - DUMPBITS (bit_buf, bits, 5); - - if (q_scale_type) return non_linear_quantizer_scale[quantizer_scale_code]; - else return quantizer_scale_code << 1; + quantizer_scale_code = UBITS (bs->i_bit_in_cache, 5); + bs_flush( bs, 5 ); + + if( tr->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) +static inline int get_motion_delta( bs_transrate_t *bs, 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; + if (bs->i_bit_in_cache & 0x80000000) + { + bs_copy( bs, 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 if (bs->i_bit_in_cache >= 0x0c000000) + { + + tab = MV_4 + UBITS (bs->i_bit_in_cache, 4); + delta = (tab->delta << f_code) + 1; + bs_copy( bs, tab->len); + + sign = SBITS (bs->i_bit_in_cache, 1); + bs_copy( bs, 1 ); + + if (f_code) delta += UBITS (bs->i_bit_in_cache, f_code); + bs_copy( bs, 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; + else + { + + tab = MV_10 + UBITS (bs->i_bit_in_cache, 10); + delta = (tab->delta << f_code) + 1; + bs_copy( bs, tab->len); + + sign = SBITS (bs->i_bit_in_cache, 1); + bs_copy( bs, 1); + + if (f_code) + { + delta += UBITS (bs->i_bit_in_cache, f_code); + bs_copy( bs, f_code); + } + + return (delta ^ sign) - sign; } } -static inline int get_dmv () +static inline int get_dmv( bs_transrate_t *bs ) { const DMVtab * tab; - tab = DMV_2 + UBITS (bit_buf, 2); - COPYBITS (bit_buf, bits, tab->len); + tab = DMV_2 + UBITS (bs->i_bit_in_cache, 2); + bs_copy( bs, tab->len); return tab->dmv; } -static inline int get_coded_block_pattern () +static inline int get_coded_block_pattern( bs_transrate_t *bs ) { -#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; + if (bs->i_bit_in_cache >= 0x20000000) + { + tab = CBP_7 + (UBITS (bs->i_bit_in_cache, 7) - 16); + bs_flush( bs, tab->len ); + return tab->cbp; } - else - { - tab = CBP_9 + UBITS (bit_buf, 9); - DUMPBITS (bit_buf, bits, tab->len); - return tab->cbp; + else + { + tab = CBP_9 + UBITS (bs->i_bit_in_cache, 9); + bs_flush( bs, tab->len ); + return tab->cbp; } } -static inline int get_luma_dc_dct_diff () +static inline int get_luma_dc_dct_diff( bs_transrate_t *bs ) { -#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; - } + if (bs->i_bit_in_cache < 0xf8000000) + { + tab = DC_lum_5 + UBITS (bs->i_bit_in_cache, 5); + size = tab->size; + if (size) + { + bs_copy( bs, tab->len); + //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size); + dc_diff = UBITS (bs->i_bit_in_cache, size); + if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); + bs_copy( bs, size); + return dc_diff; + } + else + { + bs_copy( bs, 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; + else + { + tab = DC_long + (UBITS (bs->i_bit_in_cache, 9) - 0x1e0); + size = tab->size; + bs_copy( bs, tab->len); + //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size); + dc_diff = UBITS (bs->i_bit_in_cache, size); + if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); + bs_copy( bs, size); + return dc_diff; } } -static inline int get_chroma_dc_dct_diff () +static inline int get_chroma_dc_dct_diff( bs_transrate_t *bs ) { -#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; - } + if (bs->i_bit_in_cache < 0xf8000000) + { + tab = DC_chrom_5 + UBITS (bs->i_bit_in_cache, 5); + size = tab->size; + if (size) + { + bs_copy( bs, tab->len); + //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size); + dc_diff = UBITS (bs->i_bit_in_cache, size); + if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); + bs_copy( bs, size); + return dc_diff; + } else + { + bs_copy( bs, 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; + else + { + tab = DC_long + (UBITS (bs->i_bit_in_cache, 10) - 0x3e0); + size = tab->size; + bs_copy( bs, tab->len + 1); + //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size); + dc_diff = UBITS (bs->i_bit_in_cache, size); + if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); + bs_copy( bs, size); + return dc_diff; } } -static void get_intra_block_B14 () +static void get_intra_block_B14( bs_transrate_t *bs, const int i_qscale, const int i_qscale_new ) { -#define bit_buf (inbitbuf) - int q = quantizer_scale, nq = new_quantizer_scale, tst; + int tst; int i, li; int val; const DCTtab * tab; - + /* Basic sanity check --Meuuh */ - if ( q == 0 ) + if( i_qscale == 0 ) + { return; + } - tst = (nq / q) + ((nq % q) ? 1 : 0); + tst = i_qscale_new/i_qscale + ((i_qscale_new%i_qscale) ? 1 : 0); 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); - putAC(i - li - 1, (val * q) / nq, 0); - 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) - { - putAC(i - li - 1, (val * q) / nq, 0); - 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 */ + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x28000000) + { + tab = DCT_B14AC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5); + + i += tab->run; + if (i >= 64) break; /* end of block */ + + normal_code: + bs_flush( bs, tab->len ); + val = tab->level; + if (val >= tst) + { + val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1); + putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 0); + li = i; + } + + bs_flush( bs, 1 ); + continue; + } + else if (bs->i_bit_in_cache >= 0x04000000) + { + tab = DCT_B14_8 + (UBITS (bs->i_bit_in_cache, 8) - 4); + + i += tab->run; + if (i < 64) goto normal_code; + + /* escape code */ + i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64; + if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ + + bs_flush( bs, 12 ); + val = SBITS (bs->i_bit_in_cache, 12); + if (abs(val) >= tst) + { + putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 0); + li = i; + } + + bs_flush( bs, 12 ); + + continue; + } + else if (bs->i_bit_in_cache >= 0x02000000) + { + tab = DCT_B14_10 + (UBITS (bs->i_bit_in_cache, 10) - 8); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00800000) + { + tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00200000) + { + tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else + { + tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16); + bs_flush( bs, 16); + i += tab->run; + if (i < 64) goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + bs_copy( bs, 2); /* end of block code */ } -static void get_intra_block_B15 () +static void get_intra_block_B15( bs_transrate_t *bs, const int i_qscale, int const i_qscale_new ) { -#define bit_buf (inbitbuf) - int q = quantizer_scale, nq = new_quantizer_scale, tst; + int tst; int i, li; int val; const DCTtab * tab; - + /* Basic sanity check --Meuuh */ - if ( q == 0 ) + if( i_qscale == 0 ) + { return; + } - tst = (nq / q) + ((nq % q) ? 1 : 0); + tst = i_qscale_new/i_qscale + ((i_qscale_new%i_qscale) ? 1 : 0); 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); - putAC(i - li - 1, (val * q) / nq, 1); - 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) - { - putAC(i - li - 1, (val * q) / nq, 1); - 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 */ + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x04000000) + { + tab = DCT_B15_8 + (UBITS (bs->i_bit_in_cache, 8) - 4); + + i += tab->run; + if (i < 64) + { + normal_code: + bs_flush( bs, tab->len ); + + val = tab->level; + if (val >= tst) + { + val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1); + putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 1); + li = i; + } + + bs_flush( bs, 1 ); + continue; + } + else + { + i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64; + + if (i >= 64) break; /* illegal, check against buffer overflow */ + + bs_flush( bs, 12 ); + val = SBITS (bs->i_bit_in_cache, 12); + if (abs(val) >= tst) + { + putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 1); + li = i; + } + + bs_flush( bs, 12 ); + continue; + } + } + else if (bs->i_bit_in_cache >= 0x02000000) + { + tab = DCT_B15_10 + (UBITS (bs->i_bit_in_cache, 10) - 8); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00800000) + { + tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00200000) + { + tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else + { + tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16); + bs_flush( bs, 16 ); + i += tab->run; + if (i < 64) goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + + bs_copy( bs, 4); /* end of block code */ } -static int get_non_intra_block_drop (RunLevel *blk) +static int get_non_intra_block_drop( transrate_t *tr, RunLevel *blk) { -#define bit_buf (inbitbuf) + bs_transrate_t *bs = &tr->bs; int i, li; int val; const DCTtab * tab; - RunLevel *sblk = blk + 1; + RunLevel *sblk = blk + 1; li = i = -1; - if (bit_buf >= 0x28000000) - { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; + if (bs->i_bit_in_cache >= 0x28000000) + { + tab = DCT_B14DC_5 + (UBITS (bs->i_bit_in_cache, 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; - + else goto entry_2; + + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x28000000) + { + tab = DCT_B14AC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5); + + entry_1: + i += tab->run; + if (i >= 64) break; /* end of block */ + + normal_code: + + bs_flush( bs, tab->len ); + val = tab->level; + val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1); /* if (bitstream_get (1)) val = -val; */ + + blk->level = val; + blk->run = i - li - 1; + li = i; + blk++; + + bs_flush( bs, 1 ); + continue; + } + + entry_2: + + if (bs->i_bit_in_cache >= 0x04000000) + { + tab = DCT_B14_8 + (UBITS (bs->i_bit_in_cache, 8) - 4); + + i += tab->run; + if (i < 64) goto normal_code; + + /* escape code */ + + i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64; + + if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ + + bs_flush( bs, 12 ); + val = SBITS (bs->i_bit_in_cache, 12); + + blk->level = val; + blk->run = i - li - 1; + li = i; + blk++; + + bs_flush( bs, 12 ); + continue; + } + else if (bs->i_bit_in_cache >= 0x02000000) + { + tab = DCT_B14_10 + (UBITS (bs->i_bit_in_cache, 10) - 8); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00800000) + { + tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00200000) + { + tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else + { + tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16); + bs_flush( bs, 16 ); + i += tab->run; + if (i < 64) goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + bs_flush( bs, 2 ); /* dump end of block code */ + + // remove last coeff + if (blk != sblk) + { + blk--; + // remove more coeffs if very late + if ((tr->quant_corr < -60.0f) && (blk != sblk)) + { + blk--; + if ((tr->quant_corr < -80.0f) && (blk != sblk)) + { + blk--; + if ((tr->quant_corr < -100.0f) && (blk != sblk)) + { + blk--; + if ((tr->quant_corr < -120.0f) && (blk != sblk)) + blk--; + } + } + } + } + + blk->level = 0; + return i; } -static int get_non_intra_block_rq (RunLevel *blk) +static int get_non_intra_block_rq( bs_transrate_t *bs, RunLevel *blk, const int i_qscale, const int i_qscale_new ) { -#define bit_buf (inbitbuf) - int q = quantizer_scale, nq = new_quantizer_scale, tst; + int tst; int i, li; int val; const DCTtab * tab; /* Basic sanity check --Meuuh */ - if ( q == 0 ) + if( i_qscale == 0 ) + { return 0; + } - tst = (nq / q) + ((nq % q) ? 1 : 0); + tst = i_qscale_new/i_qscale + ((i_qscale_new%i_qscale) ? 1 : 0); li = i = -1; - if (bit_buf >= 0x28000000) - { - tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); - goto entry_1; + if (bs->i_bit_in_cache >= 0x28000000) + { + tab = DCT_B14DC_5 + (UBITS (bs->i_bit_in_cache, 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\n", 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; + else goto entry_2; - return i; -} + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x28000000) + { + tab = DCT_B14AC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5); -static inline void slice_intra_DCT (const int cc) -{ - if (cc == 0) get_luma_dc_dct_diff (); - else get_chroma_dc_dct_diff (); + entry_1: + i += tab->run; + if (i >= 64) + break; /* end of block */ - if (intra_vlc_format) get_intra_block_B15 (); - else get_intra_block_B14 (); -} + normal_code: -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]); -} + bs_flush( bs, tab->len ); + val = tab->level; + if (val >= tst) + { + val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1); + blk->level = (val * i_qscale) / i_qscale_new; + blk->run = i - li - 1; + li = i; + blk++; + } -static void motion_fr_frame ( uint f_code[2] ) -{ - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); -} + //if ( ((val) && (tab->level < tst)) || ((!val) && (tab->level >= tst)) ) + // LOGF("level: %i val: %i tst : %i q: %i nq : %i\n", tab->level, val, tst, q, nq); -static void motion_fr_field ( uint f_code[2] ) -{ - COPYBITS (bit_buf, bits, 1); + bs_flush( bs, 1 ); + continue; + } - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); + entry_2: + if (bs->i_bit_in_cache >= 0x04000000) + { + tab = DCT_B14_8 + (UBITS (bs->i_bit_in_cache, 8) - 4); - COPYBITS (bit_buf, bits, 1); + i += tab->run; + if (i < 64) goto normal_code; - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); -} + /* escape code */ -static void motion_fr_dmv ( uint f_code[2] ) -{ - get_motion_delta (f_code[0]); - get_dmv (); + i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64; + + if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ + + bs_flush( bs, 12 ); + val = SBITS (bs->i_bit_in_cache, 12); + if (abs(val) >= tst) + { + blk->level = (val * i_qscale) / i_qscale_new; + blk->run = i - li - 1; + li = i; + blk++; + } + + bs_flush( bs, 12 ); + continue; + } + else if (bs->i_bit_in_cache >= 0x02000000) + { + tab = DCT_B14_10 + (UBITS (bs->i_bit_in_cache, 10) - 8); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00800000) + { + tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else if (bs->i_bit_in_cache >= 0x00200000) + { + tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16); + i += tab->run; + if (i < 64) goto normal_code; + } + else + { + tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16); + bs_flush( bs, 16 ); - get_motion_delta (f_code[1]); - get_dmv (); + i += tab->run; + if (i < 64) goto normal_code; + } + break; /* illegal, check needed to avoid buffer overflow */ + } + bs_flush( bs, 2 ); /* dump end of block code */ + + blk->level = 0; + + return i; } -/* like motion_frame, but parsing without actual motion compensation */ -static void motion_fr_conceal ( ) +static void motion_fr_frame( bs_transrate_t *bs, unsigned int f_code[2] ) { - get_motion_delta (f_code[0][0]); - get_motion_delta (f_code[0][1]); - - COPYBITS (bit_buf, bits, 1); /* remove marker_bit */ + get_motion_delta( bs, f_code[0] ); + get_motion_delta( bs, f_code[1] ); } -static void motion_fi_field ( uint f_code[2] ) +static void motion_fr_field( bs_transrate_t *bs, unsigned int f_code[2] ) { - COPYBITS (bit_buf, bits, 1); + bs_copy( bs, 1); + + get_motion_delta( bs, f_code[0]); + get_motion_delta( bs, f_code[1]); + + bs_copy( bs, 1); - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); + get_motion_delta( bs, f_code[0]); + get_motion_delta( bs, f_code[1]); } -static void motion_fi_16x8 ( uint f_code[2] ) +static void motion_fr_dmv( bs_transrate_t *bs, unsigned int f_code[2] ) { - COPYBITS (bit_buf, bits, 1); + get_motion_delta( bs, f_code[0]); + get_dmv( bs ); - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); + get_motion_delta( bs, f_code[1]); + get_dmv( bs ); +} - COPYBITS (bit_buf, bits, 1); +static void motion_fi_field( bs_transrate_t *bs, unsigned int f_code[2] ) +{ + bs_copy( bs, 1); - get_motion_delta (f_code[0]); - get_motion_delta (f_code[1]); + get_motion_delta( bs, f_code[0]); + get_motion_delta( bs, f_code[1]); } -static void motion_fi_dmv ( uint f_code[2] ) +static void motion_fi_16x8( bs_transrate_t *bs, unsigned int f_code[2] ) { - get_motion_delta (f_code[0]); - get_dmv (); + bs_copy( bs, 1); + + get_motion_delta( bs, f_code[0]); + get_motion_delta( bs, f_code[1]); + + bs_copy( bs, 1); - get_motion_delta (f_code[1]); - get_dmv (); + get_motion_delta( bs, f_code[0]); + get_motion_delta( bs, f_code[1]); } -static void motion_fi_conceal () +static void motion_fi_dmv( bs_transrate_t *bs, unsigned int f_code[2] ) { - COPYBITS (bit_buf, bits, 1); /* remove field_select */ + get_motion_delta( bs, f_code[0]); + get_dmv( bs ); - get_motion_delta (f_code[0][0]); - get_motion_delta (f_code[0][1]); - - COPYBITS (bit_buf, bits, 1); /* remove marker_bit */ + get_motion_delta( bs, f_code[1]); + get_dmv( bs ); } -#define MOTION_CALL(routine,direction) \ -do { \ - if ((direction) & MACROBLOCK_MOTION_FORWARD) \ - routine (f_code[0]); \ - if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ - routine (f_code[1]); \ + +#define MOTION_CALL(routine,direction) \ +do { \ + if ((direction) & MACROBLOCK_MOTION_FORWARD) \ + routine( bs, tr->f_code[0]); \ + if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ + routine( bs, tr->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; \ - } \ +#define NEXT_MACROBLOCK \ +do { \ + tr->h_offset += 16; \ + if( tr->h_offset == tr->horizontal_size_value) \ + { \ + tr->v_offset += 16; \ + if (tr->v_offset > (tr->vertical_size_value - 16)) return; \ + tr->h_offset = 0; \ + } \ } while (0) -void putmbdata(int macroblock_modes) +static void putmbdata( transrate_t *tr, 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; - } - } + bs_transrate_t *bs = &tr->bs; + + bs_write( bs, + mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].code, + mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].len); + switch ( tr->picture_coding_type) + { + case I_TYPE: + if ((! (tr->frame_pred_frame_dct)) && (tr->picture_structure == FRAME_PICTURE)) + bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + break; + + case P_TYPE: + if (tr->picture_structure != FRAME_PICTURE) + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + break; + } + else if (tr->frame_pred_frame_dct) break; + else + { + if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) + bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + break; + } + + case B_TYPE: + if (tr->picture_structure != FRAME_PICTURE) + { + if (! (macroblock_modes & MACROBLOCK_INTRA)) + bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + break; + } + else if (tr->frame_pred_frame_dct) break; + else + { + if (macroblock_modes & MACROBLOCK_INTRA) goto intra; + bs_write( bs, (macroblock_modes & MOTION_TYPE_MASK) / MOTION_TYPE_BASE, 2); + if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) + { + intra: + bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1); + } + break; + } + } } -static inline void put_quantiser(int quantiser) +static inline void put_quantiser( transrate_t *tr ) { - putbits(q_scale_type ? map_non_linear_mquant[quantiser] : quantiser >> 1, 5); - last_coded_scale = quantiser; + bs_transrate_t *bs = &tr->bs; + + bs_write( bs, tr->q_scale_type ? map_non_linear_mquant[tr->new_quantizer_scale] : tr->new_quantizer_scale >> 1, 5); + tr->last_coded_scale = tr->new_quantizer_scale; } -static int slice_init (int code) +static int slice_init( transrate_t *tr, int code) { -#define bit_buf (inbitbuf) - + bs_transrate_t *bs = &tr->bs; int offset; const MBAtab * mba; - v_offset = (code - 1) * 16; + tr->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\n", code, - (picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), - quantizer_scale, new_quantizer_scale);*/ + tr->quantizer_scale = get_quantizer_scale( tr ); + if ( tr->picture_coding_type == P_TYPE) + { + tr->new_quantizer_scale = tr->quantizer_scale; + } + else + { + tr->new_quantizer_scale = getNewQuant(tr, tr->quantizer_scale); + } + put_quantiser( tr ); + + /*LOGF("************************\nstart of slice %i in %s picture. ori quant: %i new quant: %i\n", 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); + while (bs->i_bit_in_cache & 0x80000000) + { + bs_flush( bs, 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; - } + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x08000000) + { + mba = MBA_5 + (UBITS (bs->i_bit_in_cache, 6) - 2); + break; + } + else if (bs->i_bit_in_cache >= 0x01800000) + { + mba = MBA_11 + (UBITS (bs->i_bit_in_cache, 12) - 24); + break; + } + else if( UBITS (bs->i_bit_in_cache, 12 ) == 8 ) + { + /* macroblock_escape */ + offset += 33; + bs_copy( bs, 11); + } + else + { + return -1; + } } - COPYBITS (bit_buf, bits, mba->len + 1); - h_offset = (offset + mba->mba) << 4; + bs_copy( bs, mba->len + 1); + tr->h_offset = (offset + mba->mba) << 4; - while (h_offset - (int)horizontal_size_value >= 0) - { - h_offset -= horizontal_size_value; - v_offset += 16; + while( tr->h_offset - (int)tr->horizontal_size_value >= 0) + { + tr->h_offset -= tr->horizontal_size_value; + tr->v_offset += 16; } - if (v_offset > (vertical_size_value - 16)) return 1; - + if( tr->v_offset > tr->vertical_size_value - 16 ) + { + return -1; + } return 0; - } -void mpeg2_slice ( const int code ) +static void mpeg2_slice( transrate_t *tr, 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) - { - //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 - - 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("\n\to: %i c: %i n: %i\n", 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); + bs_transrate_t *bs = &tr->bs; + + if( slice_init( tr, code ) ) + { + return; } + for( ;; ) + { + int macroblock_modes; + int mba_inc; + const MBAtab * mba; + + macroblock_modes = get_macroblock_modes( tr ); + if (macroblock_modes & MACROBLOCK_QUANT) tr->quantizer_scale = get_quantizer_scale( tr ); + + //LOGF("blk %i : ", h_offset >> 4); + + if (macroblock_modes & MACROBLOCK_INTRA) + { + //LOG("intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); + + tr->new_quantizer_scale = increment_quant( tr, tr->quantizer_scale); + if (tr->last_coded_scale == tr->new_quantizer_scale) macroblock_modes &= 0xFFFFFFEF; // remove MACROBLOCK_QUANT + else macroblock_modes |= MACROBLOCK_QUANT; //add MACROBLOCK_QUANT + putmbdata( tr, macroblock_modes); + if (macroblock_modes & MACROBLOCK_QUANT) put_quantiser( tr ); + + //if (macroblock_modes & MACROBLOCK_QUANT) LOGF("put new quant: %i ", new_quantizer_scale); + + if (tr->concealment_motion_vectors) + { + if (tr->picture_structure != FRAME_PICTURE) + { + bs_copy( bs, 1); /* remove field_select */ + } + /* like motion_frame, but parsing without actual motion compensation */ + get_motion_delta( bs, tr->f_code[0][0]); + get_motion_delta( bs, tr->f_code[0][1]); + + bs_copy( bs, 1); /* remove marker_bit */ + } + + if( tr->intra_vlc_format ) + { + /* Luma */ + get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + /* Chroma */ + get_chroma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_chroma_dc_dct_diff( bs ); get_intra_block_B15( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + } + else + { + /* Luma */ + get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_luma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + /* Chroma */ + get_chroma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + get_chroma_dc_dct_diff( bs ); get_intra_block_B14( bs, tr->quantizer_scale, tr->new_quantizer_scale ); + } + } + else + { + RunLevel block[6][65]; // terminated by level = 0, so we need 64+1 + int new_coded_block_pattern = 0; + + // begin saving data + int batb; + uint8_t p_n_ow[32], *p_n_w, + *p_o_ow = bs->p_ow, *p_o_w = bs->p_w; + uint32_t i_n_bit_out, i_n_bit_out_cache, + i_o_bit_out = bs->i_bit_out, i_o_bit_out_cache = bs->i_bit_out_cache; + + bs->i_bit_out_cache = 0; bs->i_bit_out = BITS_IN_BUF; + bs->p_ow = bs->p_w = p_n_ow; + + if (tr->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(bs->p_w - bs->p_ow < 32); + + p_n_w = bs->p_w; + i_n_bit_out = bs->i_bit_out; + i_n_bit_out_cache = bs->i_bit_out_cache; + assert(bs->p_ow == p_n_ow); + + bs->i_bit_out = i_o_bit_out ; + bs->i_bit_out_cache = i_o_bit_out_cache; + bs->p_ow = p_o_ow; + bs->p_w = p_o_w; + // end saving data + + if ( tr->picture_coding_type == P_TYPE) tr->new_quantizer_scale = tr->quantizer_scale; + else tr->new_quantizer_scale = getNewQuant( tr, tr->quantizer_scale); + + //LOG("non intra "); if (macroblock_modes & MACROBLOCK_QUANT) LOGF("got new quant: %i ", quantizer_scale); + + if (macroblock_modes & MACROBLOCK_PATTERN) + { + const int cbp = get_coded_block_pattern( bs ); + + if( tr->picture_coding_type == P_TYPE ) + { + if( cbp&0x20 ) get_non_intra_block_drop( tr, block[0] ); + if( cbp&0x10 ) get_non_intra_block_drop( tr, block[1] ); + if( cbp&0x08 ) get_non_intra_block_drop( tr, block[2] ); + if( cbp&0x04 ) get_non_intra_block_drop( tr, block[3] ); + if( cbp&0x02 ) get_non_intra_block_drop( tr, block[4] ); + if( cbp&0x01 ) get_non_intra_block_drop( tr, block[5] ); + + new_coded_block_pattern = cbp; + } + else + { + if( cbp&0x20 ) + { + get_non_intra_block_rq( bs, block[0], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[0] ) ) new_coded_block_pattern |= 0x20; + } + if( cbp&0x10 ) + { + get_non_intra_block_rq( bs, block[1], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[1] ) ) new_coded_block_pattern |= 0x10; + } + if( cbp&0x08 ) + { + get_non_intra_block_rq( bs, block[2], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[2] ) ) new_coded_block_pattern |= 0x08; + } + if( cbp&0x04 ) + { + get_non_intra_block_rq( bs, block[3], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[3] ) ) new_coded_block_pattern |= 0x04; + } + if( cbp&0x02 ) + { + get_non_intra_block_rq( bs, block[4], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[4] ) ) new_coded_block_pattern |= 0x02; + } + if( cbp&0x01 ) + { + get_non_intra_block_rq( bs, block[5], tr->quantizer_scale, tr->new_quantizer_scale ); + if( isNotEmpty( block[5] ) ) new_coded_block_pattern |= 0x01; + } + if( !new_coded_block_pattern) macroblock_modes &= 0xFFFFFFED; // remove MACROBLOCK_PATTERN and MACROBLOCK_QUANT flag + } + } + + if (tr->last_coded_scale == tr->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( tr, macroblock_modes); + if( macroblock_modes & MACROBLOCK_QUANT ) + { + put_quantiser( tr ); + } + + // put saved motion data... + for (batb = 0; batb < (p_n_w - p_n_ow); batb++) + { + bs_write( bs, p_n_ow[batb], 8 ); + } + bs_write( bs, i_n_bit_out_cache, BITS_IN_BUF - i_n_bit_out); + // end saved motion data... + + if (macroblock_modes & MACROBLOCK_PATTERN) + { + /* Write CBP */ + bs_write( bs, cbptable[new_coded_block_pattern].code,cbptable[new_coded_block_pattern].len); + + if (new_coded_block_pattern & 0x20) putnonintrablk( bs, block[0]); + if (new_coded_block_pattern & 0x10) putnonintrablk( bs, block[1]); + if (new_coded_block_pattern & 0x08) putnonintrablk( bs, block[2]); + if (new_coded_block_pattern & 0x04) putnonintrablk( bs, block[3]); + if (new_coded_block_pattern & 0x02) putnonintrablk( bs, block[4]); + if (new_coded_block_pattern & 0x01) putnonintrablk( bs, block[5]); + } + } + + //LOGF("\n\to: %i c: %i n: %i\n", quantizer_scale, last_coded_scale, new_quantizer_scale); + + NEXT_MACROBLOCK; + + mba_inc = 0; + for( ;; ) + { + if (bs->i_bit_in_cache >= 0x10000000) + { + mba = MBA_5 + (UBITS (bs->i_bit_in_cache, 5) - 2); + break; + } + else if (bs->i_bit_in_cache >= 0x03000000) + { + mba = MBA_11 + (UBITS (bs->i_bit_in_cache, 11) - 24); + break; + } + else if( UBITS (bs->i_bit_in_cache, 11 ) == 8 ) + { + /* macroblock_escape */ + mba_inc += 33; + bs_copy( bs, 11); + } + else + { + /* EOS or error */ + return; + } + } + bs_copy( bs, mba->len); + mba_inc += mba->mba; + + while( mba_inc-- ) + { + NEXT_MACROBLOCK; + } + } } /////---- end ext mpeg code -static int do_next_start_code(void) +static int do_next_start_code( transrate_t *tr ) { - uint8 ID; + bs_transrate_t *bs = &tr->bs; + uint8_t ID; // get start code - LOCK(1) - ID = cbuf[0]; - COPY(1) + ID = bs->p_c[0]; + + /* Copy one byte */ + *bs->p_w++ = *bs->p_c++; if (ID == 0x00) // pic header { - LOCK(4) - picture_coding_type = (cbuf[1] >> 3) & 0x7; - cbuf[1] |= 0x7; cbuf[2] = 0xFF; cbuf[3] |= 0xF8; // vbv_delay is now 0xFFFF - COPY(4) + tr->picture_coding_type = (bs->p_c[1] >> 3) & 0x7; + bs->p_c[1] |= 0x7; bs->p_c[2] = 0xFF; bs->p_c[3] |= 0xF8; // vbv_delay is now 0xFFFF + + memcpy(bs->p_w, bs->p_c, 4); + bs->p_c += 4; + bs->p_w += 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 || !vertical_size_value) + tr->horizontal_size_value = (bs->p_c[0] << 4) | (bs->p_c[1] >> 4); + tr->vertical_size_value = ((bs->p_c[1] & 0xF) << 8) | bs->p_c[2]; + if(!tr->horizontal_size_value || !tr->vertical_size_value ) + { return -1; - COPY(8) + } + + memcpy(bs->p_w, bs->p_c, 8 ); + bs->p_c += 8; + bs->p_w += 8; } else if (ID == 0xB5) // extension { - LOCK(1) - if ((cbuf[0] >> 4) == 0x8) // pic coding ext + if ((bs->p_c[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; - COPY(5) + tr->f_code[0][0] = (bs->p_c[0] & 0xF) - 1; + tr->f_code[0][1] = (bs->p_c[1] >> 4) - 1; + tr->f_code[1][0] = (bs->p_c[1] & 0xF) - 1; + tr->f_code[1][1] = (bs->p_c[2] >> 4) - 1; + + /* tr->intra_dc_precision = (bs->p_c[2] >> 2) & 0x3; */ + tr->picture_structure = bs->p_c[2] & 0x3; + tr->frame_pred_frame_dct = (bs->p_c[3] >> 6) & 0x1; + tr->concealment_motion_vectors = (bs->p_c[3] >> 5) & 0x1; + tr->q_scale_type = (bs->p_c[3] >> 4) & 0x1; + tr->intra_vlc_format = (bs->p_c[3] >> 3) & 0x1; + /* tr->alternate_scan = (bs->p_c[3] >> 2) & 0x1; */ + + + memcpy(bs->p_w, bs->p_c, 5); + bs->p_c += 5; + bs->p_w += 5; } else { - COPY(1) + *bs->p_w++ = *bs->p_c++; } } else if (ID == 0xB8) // gop header { - LOCK(4) - COPY(4) + memcpy(bs->p_w, bs->p_c, 4); + bs->p_c += 4; + bs->p_w += 4; } else if ((ID >= 0x01) && (ID <= 0xAF)) // slice { - uint8 *outTemp = wbuf, *inTemp = cbuf; - - 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; - - if (!horizontal_size_value || !vertical_size_value) - return -1; + uint8_t *outTemp = bs->p_w, *inTemp = bs->p_c; - // lock all the slice - while (!fsc) + if( ( tr->picture_coding_type == B_TYPE && tr->quant_corr < 2.5f ) || // don't recompress if we're in advance! + ( tr->picture_coding_type == P_TYPE && tr->quant_corr < -2.5f ) || + ( tr->picture_coding_type == I_TYPE && tr->quant_corr < -5.0f ) ) + { + if( !tr->horizontal_size_value || !tr->vertical_size_value ) { - toLock = nsc - cbuf + 3; - LOCK(toLock) - - if ( (nsc[0] == 0) && (nsc[1] == 0) && (nsc[2] == 1) ) fsc = 1; // start code ! - else nsc++; // continue search + return -1; } - + // init bit buffer - inbitbuf = 0; inbitcnt = 0; - outbitbuf = 0; outbitcnt = BITS_IN_BUF; - + bs->i_bit_in_cache = 0; bs->i_bit_in = 0; + bs->i_bit_out_cache = 0; bs->i_bit_out = BITS_IN_BUF; + // get 32 bits - Refill_bits(); - Refill_bits(); - Refill_bits(); - Refill_bits(); - + bs_refill( bs ); + bs_refill( bs ); + bs_refill( bs ); + bs_refill( bs ); + // begin bit level recoding - mpeg2_slice(ID); - flush_read_buffer(); - flush_write_buffer(); + mpeg2_slice(tr, ID); + + bs_flush_read( bs ); + bs_flush_write( bs ); // end bit level recoding /* Basic sanity checks --Meuuh */ - if (cbuf > rbuf || wbuf > rwbuf) + if (bs->p_c > bs->p_r || bs->p_w > bs->p_rw) + { return -1; - + } + /*LOGF("type: %s code: %02i in : %6i out : %6i diff : %6i fact: %2.2f\n", (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) // yes that might happen, rarely + ID, bs->p_c - inTemp, bs->p_w - outTemp, (bs->p_w - outTemp) - (bs->p_c - inTemp), (float)(bs->p_c - inTemp) / (float)(bs->p_w - outTemp));*/ + + if (bs->p_w - outTemp > bs->p_c - inTemp) // yes that might happen, rarely { /*LOGF("*** slice bigger than before !! (type: %s code: %i in : %i out : %i diff : %i)\n", (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));*/ - + ID, bs->p_c - inTemp, bs->p_w - outTemp, (bs->p_w - outTemp) - (bs->p_c - inTemp));*/ + // in this case, we'll just use the original slice ! - memcpy(outTemp, inTemp, cbuf - inTemp); - wbuf = outTemp + (cbuf - inTemp); - - // adjust outbytecnt - outbytecnt -= (wbuf - outTemp) - (cbuf - inTemp); + memcpy(outTemp, inTemp, bs->p_c - inTemp); + bs->p_w = outTemp + (bs->p_c - inTemp); + + // adjust bs->i_byte_out + bs->i_byte_out -= (bs->p_w - outTemp) - (bs->p_c - inTemp); } } } @@ -1873,9 +1874,11 @@ static int do_next_start_code(void) } static void process_frame( sout_stream_t *p_stream, - sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out ) + sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out ) { - uint8_t found; + transrate_t *tr = &id->tr; + bs_transrate_t *bs = &tr->bs; + sout_buffer_t *p_out; /* The output buffer can't be bigger than the input buffer. */ @@ -1887,52 +1890,76 @@ static void process_frame( sout_stream_t *p_stream, sout_BufferChain( out, p_out ); - rwbuf = owbuf = wbuf = p_out->p_buffer; - cbuf = rbuf = in->p_buffer; - rbuf += in->i_size + 4; - rwbuf += in->i_size; + bs->p_rw = bs->p_ow = bs->p_w = p_out->p_buffer; + bs->p_c = bs->p_r = in->p_buffer; + bs->p_r += in->i_size + 4; + bs->p_rw += in->i_size; *(in->p_buffer + in->i_size) = 0; *(in->p_buffer + in->i_size + 1) = 0; *(in->p_buffer + in->i_size + 2) = 1; *(in->p_buffer + in->i_size + 3) = 0; - inbytecnt += in->i_size; + bs->i_byte_in += in->i_size; for ( ; ; ) { - // get next start code prefix - found = 0; - while (!found) + uint8_t *p_end = &in->p_buffer[in->i_size]; + + /* Search next start code */ + for( ;; ) { -#ifndef REMOVE_BYTE_STUFFING - 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) } - else -#endif - if ( (cbuf[0] == 0) && (cbuf[1] == 0) && (cbuf[2] == 1) ) found = 1; // start code ! - else { COPY(1) } // continue search + if( bs->p_c < p_end - 3 && bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 1 ) + { + /* Next start code */ + break; + } + else if( bs->p_c < p_end - 6 && + bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 0 && + bs->p_c[3] == 0 && bs->p_c[4] == 0 && bs->p_c[5] == 0 ) + { + /* remove stuffing (looking for 6 0x00 bytes) */ + bs->p_c++; + } + else + { + /* Copy */ + *bs->p_w++ = *bs->p_c++; + } - if (cbuf >= in->p_buffer + in->i_size) + if( bs->p_c >= p_end) + { break; + } } - if (cbuf >= in->p_buffer + in->i_size) + + if( bs->p_c >= p_end ) + { break; - COPY(3) - - if (do_next_start_code() == -1) + } + + /* Copy the start code */ + memcpy(bs->p_w, bs->p_c, 3 ); + bs->p_c += 3; + bs->p_w += 3; + + if (do_next_start_code( tr ) ) + { + /* Error */ break; + } - quant_corr = (((inbytecnt - (rbuf - 4 - cbuf)) / fact_x) - (outbytecnt + (wbuf - owbuf))) / REACT_DELAY; + tr->quant_corr = (((bs->i_byte_in - (bs->p_r - 4 - bs->p_c)) / tr->fact_x) - (bs->i_byte_out + (bs->p_w - bs->p_ow))) / REACT_DELAY; } - outbytecnt += wbuf - owbuf; - p_out->i_size = wbuf - owbuf; + bs->i_byte_out += bs->p_w - bs->p_ow; + p_out->i_size = bs->p_w - bs->p_ow; } static int transrate_video_process( sout_stream_t *p_stream, sout_stream_id_t *id, sout_buffer_t *in, sout_buffer_t **out ) { + transrate_t *tr = &id->tr; + bs_transrate_t *bs = &tr->bs; + *out = NULL; if ( in->i_flags & SOUT_BUFFER_FLAGS_GOP ) @@ -1940,9 +1967,9 @@ static int transrate_video_process( sout_stream_t *p_stream, while ( id->p_current_buffer != NULL ) { sout_buffer_t * p_next = id->p_current_buffer->p_next; - if ( fact_x == 1.0 ) + if ( tr->fact_x == 1.0 ) { - outbytecnt += id->p_current_buffer->i_size; + bs->i_byte_out += id->p_current_buffer->i_size; id->p_current_buffer->p_next = NULL; sout_BufferChain( out, id->p_current_buffer ); } @@ -1953,7 +1980,7 @@ static int transrate_video_process( sout_stream_t *p_stream, } id->p_current_buffer = p_next; } - + if ( id->i_next_gop_duration ) { mtime_t i_bitrate = (mtime_t)id->i_next_gop_size * 8000 @@ -1963,26 +1990,26 @@ static int transrate_video_process( sout_stream_t *p_stream, if (i_old_bitrate) { msg_Dbg(p_stream, "bitrate = %lld -> %lld", i_old_bitrate, - (mtime_t)outbytecnt * 8000 / (i_old_duration / 1000)); + (mtime_t)bs->i_byte_out * 8000 / (i_old_duration / 1000)); } i_old_bitrate = i_bitrate; i_old_duration = id->i_next_gop_duration; - if ( i_bitrate > p_sys->i_vbitrate ) + if ( i_bitrate > p_stream->p_sys->i_vbitrate ) { - fact_x = (double)i_bitrate / p_sys->i_vbitrate; + tr->fact_x = (double)i_bitrate / p_stream->p_sys->i_vbitrate; } else { - fact_x = 1.0; + tr->fact_x = 1.0; } - msg_Dbg(p_stream, "new fact_x = %f", fact_x); + msg_Dbg(p_stream, "new fact_x = %f", tr->fact_x); id->p_current_buffer = id->p_next_gop; id->p_next_gop = NULL; id->i_next_gop_duration = 0; id->i_next_gop_size = 0; - inbytecnt = 0; - outbytecnt = 0; + bs->i_byte_in = 0; + bs->i_byte_out = 0; } } @@ -1994,9 +2021,9 @@ static int transrate_video_process( sout_stream_t *p_stream, if ( id->p_current_buffer != NULL ) { sout_buffer_t * p_next = id->p_current_buffer->p_next; - if ( fact_x == 1.0 ) + if ( tr->fact_x == 1.0 ) { - outbytecnt += id->p_current_buffer->i_size; + bs->i_byte_out += id->p_current_buffer->i_size; id->p_current_buffer->p_next = NULL; sout_BufferChain( out, id->p_current_buffer ); } @@ -2011,24 +2038,3 @@ static int transrate_video_process( sout_stream_t *p_stream, return VLC_SUCCESS; } -static int transrate_video_new( sout_stream_t *p_stream, - sout_stream_id_t *id ) -{ - id->p_current_buffer = NULL; - id->p_next_gop = NULL; - id->i_next_gop_duration = 0; - id->i_next_gop_size = 0; - - p_sys = p_stream->p_sys; - - inbytecnt = outbytecnt = 0; - - quant_corr = 0.0; - fact_x = 1.0; - - return VLC_SUCCESS; -} - -static void transrate_video_close ( sout_stream_t *p_stream, sout_stream_id_t *id ) -{ -} -- 2.39.5