Commit 730460c0 authored by Laurent Aimar's avatar Laurent Aimar

* all: big clean up (no more global variables).

parent c7bc1acb
...@@ -20,15 +20,11 @@ ...@@ -20,15 +20,11 @@
#define BOTTOM_FIELD 2 #define BOTTOM_FIELD 2
#define FRAME_PICTURE 3 #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 */ /* 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 */ /* 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 { typedef struct {
uint8_t modes; uint8_t modes;
......
...@@ -6,9 +6,10 @@ ...@@ -6,9 +6,10 @@
* Copyright (C) 2003 Antoine Missout * Copyright (C) 2003 Antoine Missout
* Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
* $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 <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Laurent Aimar <fenrir@via.ecp.fr>
* Antoine Missout * Antoine Missout
* Michel Lespinasse <walken@zoy.org> * Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
...@@ -33,18 +34,13 @@ ...@@ -33,18 +34,13 @@
*****************************************************************************/ *****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#define NDEBUG 1 #define NDEBUG 1
#include <assert.h> #include <assert.h>
#include <unistd.h>
#include <math.h> #include <math.h>
#include <fcntl.h>
#include <vlc/vlc.h> #include <vlc/vlc.h>
#include <vlc/input.h>
#include <vlc/sout.h> #include <vlc/sout.h>
#include <vlc/vout.h> #include <vlc/input.h>
#include <vlc/decoder.h>
/***************************************************************************** /*****************************************************************************
* Exported prototypes * Exported prototypes
...@@ -56,8 +52,6 @@ static sout_stream_id_t *Add ( sout_stream_t *, sout_format_t * ); ...@@ -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 Del ( sout_stream_t *, sout_stream_id_t * );
static int Send( sout_stream_t *, sout_stream_id_t *, sout_buffer_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 ** ); 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 ) ...@@ -140,6 +134,70 @@ static void Close( vlc_object_t * p_this )
free( p_sys ); 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 struct sout_stream_id_t
{ {
void *id; void *id;
...@@ -149,6 +207,8 @@ struct sout_stream_id_t ...@@ -149,6 +207,8 @@ struct sout_stream_id_t
sout_buffer_t *p_next_gop; sout_buffer_t *p_next_gop;
mtime_t i_next_gop_duration; mtime_t i_next_gop_duration;
size_t i_next_gop_size; 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 ) ...@@ -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'", "creating video transrating for fcc=`%4.4s'",
(char*)&p_fmt->i_fourcc ); (char*)&p_fmt->i_fourcc );
/* build decoder -> filter -> encoder */ id->p_current_buffer = NULL;
if( transrate_video_new( p_stream, id ) ) id->p_next_gop = NULL;
{ id->i_next_gop_duration = 0;
msg_Err( p_stream, "cannot create video chain" ); id->i_next_gop_size = 0;
free( id ); memset( &id->tr, 0, sizeof( transrate_t ) );
return NULL; 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 */ /* open output stream */
id->id = p_sys->p_out->pf_add( p_sys->p_out, p_fmt ); 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 ) ...@@ -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; 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 ); free( id );
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -243,12 +302,6 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -243,12 +302,6 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
// toggles: // toggles:
// #define NDEBUG // turns off asserts // #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 */ /* This is awful magic --Meuuh */
//#define REACT_DELAY (1024.0*128.0) //#define REACT_DELAY (1024.0*128.0)
#define REACT_DELAY (1024.0*4.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, ...@@ -256,12 +309,12 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
// notes: // notes:
// //
// - intra block: // - intra block:
// - the quantiser is increment by one step // - the quantiser is increment by one step
// //
// - non intra block: // - non intra block:
// - in P_FRAME we keep the original quantiser but drop the last coefficient // - in P_FRAME we keep the original quantiser but drop the last coefficient
// if there is more than one // if there is more than one
// - in B_FRAME we multiply the quantiser by a factor // - in B_FRAME we multiply the quantiser by a factor
// //
// - I_FRAME is recoded when we're 5.0 * REACT_DELAY late // - I_FRAME is recoded when we're 5.0 * REACT_DELAY late
// - P_FRAME is recoded when we're 2.5 * 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, ...@@ -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 // - drop a few coefficients but always keep the first one
// useful constants // useful constants
#define I_TYPE 1 enum
#define P_TYPE 2 {
#define B_TYPE 3 I_TYPE = 1,
P_TYPE = 2,
B_TYPE = 3
};
// gcc // gcc
#ifdef HAVE_BUILTIN_EXPECT #ifdef HAVE_BUILTIN_EXPECT
...@@ -286,363 +343,266 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id, ...@@ -286,363 +343,266 @@ static int Send( sout_stream_t *p_stream, sout_stream_id_t *id,
#define unlikely(x) (x) #define unlikely(x) (x)
#endif #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) #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 LOG(msg) fprintf (stderr, msg)
#define LOGF(format, args...) fprintf (stderr, format, args) #define LOGF(format, args...) fprintf (stderr, format, args)
#define WRITE \ static inline void bs_write( bs_transrate_t *s, unsigned int val, int n)
do { } while(0); {
assert(n < 32);
#define LOCK(x) \ assert(!(val & (0xffffffffU << n)));
do { } while(0);
#define COPY(x)\ while (unlikely(n >= s->i_bit_out))
assert(x > 0); \ {
memcpy(wbuf, cbuf, x);\ s->p_w[0] = (s->i_bit_out_cache << s->i_bit_out ) | (val >> (n - s->i_bit_out));
cbuf += x; \ s->p_w++;
wbuf += x; n -= s->i_bit_out;
s->i_bit_out_cache = 0;
val &= ~(0xffffffffU << n);
s->i_bit_out = BITS_IN_BUF;
}
#define SEEKR(x)\ if (likely(n))
cbuf += x; {
s->i_bit_out_cache = (s->i_bit_out_cache << n) | val;
#define SEEKW(x)\ s->i_bit_out -= n;
wbuf += x; }
static inline void putbits(uint val, int n) assert(s->i_bit_out > 0);
{ assert(s->i_bit_out <= BITS_IN_BUF);
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) static inline void bs_refill( bs_transrate_t *s )
{ {
assert((rbuf - cbuf) >= 1); assert((s->p_r - s->p_c) >= 1);
inbitbuf |= cbuf[0] << (24 - inbitcnt); s->i_bit_in_cache |= s->p_c[0] << (24 - s->i_bit_in);
inbitcnt += 8; s->i_bit_in += 8;
SEEKR(1) 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; s->i_bit_in_cache <<= n;
inbitcnt -= 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); unsigned int Val = bs_read( s, n);
Flush_Bits(n); bs_write(s, Val, n);
return Val; return Val;
} }
static inline uint Copy_Bits(uint n) static inline void bs_flush_read( bs_transrate_t *s )
{ {
uint Val = Get_Bits(n); int i = s->i_bit_in & 0x7;
putbits(Val, n); if( i )
return Val; {
} assert(((unsigned int)bs->i_bit_in_cache) >> (32 - i) == 0);
s->i_bit_in_cache <<= i;
static inline void flush_read_buffer() s->i_bit_in -= i;
{ }
int i = inbitcnt & 0x7; s->p_c += -1 * (s->i_bit_in >> 3);
if (i) s->i_bit_in = 0;
{
//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;
} }
static inline void bs_flush_write( bs_transrate_t *s )
static inline void flush_write_buffer()
{ {
if (outbitcnt != 8) putbits(0, outbitcnt); if( s->i_bit_out != 8 ) bs_write(s, 0, s->i_bit_out);
} }
/////---- begin ext mpeg code /////---- 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, 0, 1, 2, 3, 4, 5, 6, 7,
8,10,12,14,16,18,20,22, 8,10,12,14,16,18,20,22,
24,28,32,36,40,44,48,52, 24,28,32,36,40,44,48,52,
56,64,72,80,88,96,104,112 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, 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, 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, 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, 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 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; int iquant;
if (q_scale_type) if (q_scale_type)
{ {
iquant = (int) floor(quant+0.5); iquant = (int) floor(quant+0.5);
/* clip mquant to legal (linear) range */ /* clip mquant to legal (linear) range */
if (iquant<1) iquant = 1; if (iquant<1) iquant = 1;
if (iquant>112) iquant = 112; if (iquant>112) iquant = 112;
iquant = non_linear_mquant_table[map_non_linear_mquant[iquant]]; iquant = non_linear_mquant_table[map_non_linear_mquant[iquant]];
} }
else else
{ {
/* clip mquant to legal (linear) range */ /* clip mquant to legal (linear) range */
iquant = (int)floor(quant+0.5); iquant = (int)floor(quant+0.5);
if (iquant<2) iquant = 2; if (iquant<2) iquant = 2;
if (iquant>62) iquant = 62; if (iquant>62) iquant = 62;
iquant = (iquant/2)*2; // Must be *even* iquant = (iquant/2)*2; // Must be *even*
} }
return iquant; return iquant;
} }
static int increment_quant(int quant) static int increment_quant( transrate_t *tr, int quant )
{ {
if (q_scale_type) if( tr->q_scale_type)
{ {
assert(quant >= 1 && quant <= 112); assert(quant >= 1 && quant <= 112);
quant = map_non_linear_mquant[quant] + 1; quant = map_non_linear_mquant[quant] + 1;
if (quant_corr < -60.0f) quant++; if( tr->quant_corr < -60.0f) quant++;
if (quant > 31) quant = 31; if( quant > 31) quant = 31;
quant = non_linear_mquant_table[quant]; quant = non_linear_mquant_table[quant];
} }
else else
{ {
assert(!(quant & 1)); assert(!(quant & 1));
quant += 2; quant += 2;
if (quant_corr < -60.0f) quant += 2; if( tr->quant_corr < -60.0f) quant += 2;
if (quant > 62) quant = 62; if (quant > 62) quant = 62;
} }
return quant; return quant;
} }
static inline int intmax( register int x, register int y ) 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 ) 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; bs_transrate_t *bs = &tr->bs;
int mquant = 0;
double calc_quant, quant_to_use;
quant_corr = (((inbytecnt - (rbuf - 4 - cbuf)) / fact_x) - (outbytecnt + (wbuf - owbuf))) / REACT_DELAY; int mquant = 0;
calc_quant = curQuant * fact_x;
quant_to_use = calc_quant - quant_corr; 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;
switch (picture_coding_type) quant_to_use = calc_quant - tr->quant_corr;
{
case I_TYPE: switch (tr->picture_coding_type )
case P_TYPE: {
mquant = increment_quant(curQuant); case I_TYPE:
break; case P_TYPE:
mquant = increment_quant( tr, curQuant);
case B_TYPE: break;
mquant = intmax(scale_quant(quant_to_use), increment_quant(curQuant));
break; case B_TYPE:
mquant = intmax(scale_quant( tr->q_scale_type, quant_to_use), increment_quant( tr, curQuant));
default: break;
assert(0);
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); 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; assert(mquant >= curQuant);
return mquant;
} }
static inline int isNotEmpty(RunLevel *blk) static inline int isNotEmpty(RunLevel *blk)
{ {
return (blk->level); return (blk->level);
} }
#include "putvlc.h" #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; int level, len;
const VLCtable *ptab = NULL; 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);
}
}
level = (signed_level<0) ? -signed_level : signed_level; /* abs(signed_level) */
static inline void putACfirst(int run, int val) assert(!(run<0 || run>63 || level==0 || level>2047));
{
if (run==0 && (val==1 || val==-1)) putbits(2|(val<0),2);
else putAC(run,val,0);
}
void putnonintrablk(RunLevel *blk) len = 0;
{
assert(blk->level); if (run<2 && level<41)
{
putACfirst(blk->run, blk->level); if (vlcformat) ptab = &dct_code_tab1a[run][level-1];
blk++; else ptab = &dct_code_tab1[run][level-1];
len = ptab->len;
while(blk->level) }
{ else if (run<32 && level<6)
putAC(blk->run, blk->level, 0); {
blk++; if (vlcformat) ptab = &dct_code_tab2a[run-2][level-1];
} else ptab = &dct_code_tab2[run-2][level-1];
len = ptab->len;
putbits(2,2); }
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, assert(blk->level);
mbtypetab[picture_coding_type-1][mb_type].len);
putACfirst( bs, blk->run, blk->level);
blk++;
while(blk->level)
{
putAC( bs, blk->run, blk->level, 0);
blk++;
}
bs_write( bs, 2,2);
} }
#include <inttypes.h>
#include "getvlc.h" #include "getvlc.h"
static int non_linear_quantizer_scale [] = static const int non_linear_quantizer_scale [] =
{ {
0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 14, 16, 18, 20, 22, 8, 10, 12, 14, 16, 18, 20, 22,
...@@ -650,1222 +610,1263 @@ static int non_linear_quantizer_scale [] = ...@@ -650,1222 +610,1263 @@ static int non_linear_quantizer_scale [] =
56, 64, 72, 80, 88, 96, 104, 112 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; int macroblock_modes;
const MBtab * tab; const MBtab * tab;
switch (picture_coding_type) switch( tr->picture_coding_type)
{ {
case I_TYPE: case I_TYPE:
tab = MB_I + UBITS (bit_buf, 1); tab = MB_I + UBITS (bs->i_bit_in_cache, 1);
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
macroblock_modes = tab->modes; macroblock_modes = tab->modes;
if ((! (frame_pred_frame_dct)) && (picture_structure == FRAME_PICTURE)) if ((! ( tr->frame_pred_frame_dct)) && ( tr->picture_structure == FRAME_PICTURE))
{ {
macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
} }
return macroblock_modes; return macroblock_modes;
case P_TYPE: case P_TYPE:
tab = MB_P + UBITS (bit_buf, 5); tab = MB_P + UBITS (bs->i_bit_in_cache, 5);
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
macroblock_modes = tab->modes; macroblock_modes = tab->modes;
if (picture_structure != FRAME_PICTURE) if (tr->picture_structure != FRAME_PICTURE)
{ {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
{ {
macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;
DUMPBITS (bit_buf, bits, 2); bs_flush( bs, 2 );
} }
return macroblock_modes; return macroblock_modes;
} }
else if (frame_pred_frame_dct) else if (tr->frame_pred_frame_dct)
{ {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
macroblock_modes |= MC_FRAME; macroblock_modes |= MC_FRAME;
return macroblock_modes; return macroblock_modes;
} }
else else
{ {
if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
{ {
macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;
DUMPBITS (bit_buf, bits, 2); bs_flush( bs, 2 );
} }
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
{ {
macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
} }
return macroblock_modes; return macroblock_modes;
} }
case B_TYPE: case B_TYPE:
tab = MB_B + UBITS (bit_buf, 6); tab = MB_B + UBITS (bs->i_bit_in_cache, 6);
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
macroblock_modes = tab->modes; macroblock_modes = tab->modes;
if (picture_structure != FRAME_PICTURE) if( tr->picture_structure != FRAME_PICTURE)
{ {
if (! (macroblock_modes & MACROBLOCK_INTRA)) if (! (macroblock_modes & MACROBLOCK_INTRA))
{ {
macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;
DUMPBITS (bit_buf, bits, 2); bs_flush( bs, 2 );
} }
return macroblock_modes; return macroblock_modes;
} }
else if (frame_pred_frame_dct) else if (tr->frame_pred_frame_dct)
{ {
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
macroblock_modes |= MC_FRAME; macroblock_modes |= MC_FRAME;
return macroblock_modes; return macroblock_modes;
} }
else else
{ {
if (macroblock_modes & MACROBLOCK_INTRA) goto intra; if (macroblock_modes & MACROBLOCK_INTRA) goto intra;
macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;
DUMPBITS (bit_buf, bits, 2); bs_flush( bs, 2 );
if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))
{ {
intra: intra:
macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
} }
return macroblock_modes; return macroblock_modes;
} }
default: default:
return 0; 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; int quantizer_scale_code;
quantizer_scale_code = UBITS (bit_buf, 5); quantizer_scale_code = UBITS (bs->i_bit_in_cache, 5);
DUMPBITS (bit_buf, bits, 5); bs_flush( bs, 5 );
if (q_scale_type) return non_linear_quantizer_scale[quantizer_scale_code]; if( tr->q_scale_type )
else return quantizer_scale_code << 1; 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 delta;
int sign; int sign;
const MVtab * tab; const MVtab * tab;
if (bit_buf & 0x80000000) if (bs->i_bit_in_cache & 0x80000000)
{ {
COPYBITS (bit_buf, bits, 1); bs_copy( bs, 1 );
return 0; return 0;
} }
else if (bit_buf >= 0x0c000000) else if (bs->i_bit_in_cache >= 0x0c000000)
{ {
tab = MV_4 + UBITS (bit_buf, 4); tab = MV_4 + UBITS (bs->i_bit_in_cache, 4);
delta = (tab->delta << f_code) + 1; delta = (tab->delta << f_code) + 1;
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
sign = SBITS (bit_buf, 1); sign = SBITS (bs->i_bit_in_cache, 1);
COPYBITS (bit_buf, bits, 1); bs_copy( bs, 1 );
if (f_code) delta += UBITS (bit_buf, f_code); if (f_code) delta += UBITS (bs->i_bit_in_cache, f_code);
COPYBITS (bit_buf, bits, f_code); bs_copy( bs, f_code);
return (delta ^ sign) - sign; return (delta ^ sign) - sign;
} }
else else
{ {
tab = MV_10 + UBITS (bit_buf, 10); tab = MV_10 + UBITS (bs->i_bit_in_cache, 10);
delta = (tab->delta << f_code) + 1; delta = (tab->delta << f_code) + 1;
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
sign = SBITS (bit_buf, 1); sign = SBITS (bs->i_bit_in_cache, 1);
COPYBITS (bit_buf, bits, 1); bs_copy( bs, 1);
if (f_code) if (f_code)
{ {
delta += UBITS (bit_buf, f_code); delta += UBITS (bs->i_bit_in_cache, f_code);
COPYBITS (bit_buf, bits, f_code); bs_copy( bs, f_code);
} }
return (delta ^ sign) - sign; return (delta ^ sign) - sign;
} }
} }
static inline int get_dmv () static inline int get_dmv( bs_transrate_t *bs )
{ {
const DMVtab * tab; const DMVtab * tab;
tab = DMV_2 + UBITS (bit_buf, 2); tab = DMV_2 + UBITS (bs->i_bit_in_cache, 2);
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
return tab->dmv; 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; const CBPtab * tab;
if (bit_buf >= 0x20000000) if (bs->i_bit_in_cache >= 0x20000000)
{ {
tab = CBP_7 + (UBITS (bit_buf, 7) - 16); tab = CBP_7 + (UBITS (bs->i_bit_in_cache, 7) - 16);
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
return tab->cbp; return tab->cbp;
} }
else else
{ {
tab = CBP_9 + UBITS (bit_buf, 9); tab = CBP_9 + UBITS (bs->i_bit_in_cache, 9);
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
return tab->cbp; 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; const DCtab * tab;
int size; int size;
int dc_diff; int dc_diff;
if (bit_buf < 0xf8000000) if (bs->i_bit_in_cache < 0xf8000000)
{ {
tab = DC_lum_5 + UBITS (bit_buf, 5); tab = DC_lum_5 + UBITS (bs->i_bit_in_cache, 5);
size = tab->size; size = tab->size;
if (size) if (size)
{ {
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);
dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); dc_diff = UBITS (bs->i_bit_in_cache, size);
COPYBITS (bit_buf, bits, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
return dc_diff; bs_copy( bs, size);
} return dc_diff;
else }
{ else
COPYBITS (bit_buf, bits, 3); {
return 0; bs_copy( bs, 3);
} return 0;
}
} }
else else
{ {
tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); tab = DC_long + (UBITS (bs->i_bit_in_cache, 9) - 0x1e0);
size = tab->size; size = tab->size;
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);
dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); dc_diff = UBITS (bs->i_bit_in_cache, size);
COPYBITS (bit_buf, bits, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
return dc_diff; 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; const DCtab * tab;
int size; int size;
int dc_diff; int dc_diff;
if (bit_buf < 0xf8000000) if (bs->i_bit_in_cache < 0xf8000000)
{ {
tab = DC_chrom_5 + UBITS (bit_buf, 5); tab = DC_chrom_5 + UBITS (bs->i_bit_in_cache, 5);
size = tab->size; size = tab->size;
if (size) if (size)
{ {
COPYBITS (bit_buf, bits, tab->len); bs_copy( bs, tab->len);
//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);
dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); dc_diff = UBITS (bs->i_bit_in_cache, size);
COPYBITS (bit_buf, bits, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
return dc_diff; bs_copy( bs, size);
} else return dc_diff;
{ } else
COPYBITS (bit_buf, bits, 2); {
return 0; bs_copy( bs, 2);
} return 0;
}
} }
else else
{ {
tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); tab = DC_long + (UBITS (bs->i_bit_in_cache, 10) - 0x3e0);
size = tab->size; size = tab->size;
COPYBITS (bit_buf, bits, tab->len + 1); bs_copy( bs, tab->len + 1);
//dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);
dc_diff = UBITS (bit_buf, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size); dc_diff = UBITS (bs->i_bit_in_cache, size);
COPYBITS (bit_buf, bits, size); if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);
return dc_diff; 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 tst;
int q = quantizer_scale, nq = new_quantizer_scale, tst;
int i, li; int i, li;
int val; int val;
const DCTtab * tab; const DCTtab * tab;
/* Basic sanity check --Meuuh */ /* Basic sanity check --Meuuh */
if ( q == 0 ) if( i_qscale == 0 )
{
return; return;
}
tst = (nq / q) + ((nq % q) ? 1 : 0); tst = i_qscale_new/i_qscale + ((i_qscale_new%i_qscale) ? 1 : 0);
li = i = 0; li = i = 0;
while (1) for( ;; )
{ {
if (bit_buf >= 0x28000000) if (bs->i_bit_in_cache >= 0x28000000)
{ {
tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); tab = DCT_B14AC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5);
i += tab->run; i += tab->run;
if (i >= 64) break; /* end of block */ if (i >= 64) break; /* end of block */
normal_code: normal_code:
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
val = tab->level; val = tab->level;
if (val >= tst) if (val >= tst)
{ {
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1);
putAC(i - li - 1, (val * q) / nq, 0); putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 0);
li = i; li = i;
} }
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
continue;
continue; }
} else if (bs->i_bit_in_cache >= 0x04000000)
else if (bit_buf >= 0x04000000) {
{ tab = DCT_B14_8 + (UBITS (bs->i_bit_in_cache, 8) - 4);
tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code;
/* escape code */
/* escape code */ i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64;
i += (UBITS (bit_buf, 12) & 0x3F) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12); val = SBITS (bs->i_bit_in_cache, 12);
val = SBITS (bit_buf, 12); if (abs(val) >= tst)
if (abs(val) >= tst) {
{ putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 0);
putAC(i - li - 1, (val * q) / nq, 0); li = i;
li = i; }
}
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12);
continue;
continue; }
} else if (bs->i_bit_in_cache >= 0x02000000)
else if (bit_buf >= 0x02000000) {
{ tab = DCT_B14_10 + (UBITS (bs->i_bit_in_cache, 10) - 8);
tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code; }
} else if (bs->i_bit_in_cache >= 0x00800000)
else if (bit_buf >= 0x00800000) {
{ tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16);
tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code; }
} else if (bs->i_bit_in_cache >= 0x00200000)
else if (bit_buf >= 0x00200000) {
{ tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16);
tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code; }
} else
else {
{ tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16);
tab = DCT_16 + UBITS (bit_buf, 16); bs_flush( bs, 16);
DUMPBITS (bit_buf, bits, 16); i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code; }
} break; /* illegal, check needed to avoid buffer overflow */
break; /* illegal, check needed to avoid buffer overflow */ }
}
bs_copy( bs, 2); /* end of block code */
COPYBITS (bit_buf, bits, 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 tst;
int q = quantizer_scale, nq = new_quantizer_scale, tst;
int i, li; int i, li;
int val; int val;
const DCTtab * tab; const DCTtab * tab;
/* Basic sanity check --Meuuh */ /* Basic sanity check --Meuuh */
if ( q == 0 ) if( i_qscale == 0 )
{
return; return;
}
tst = (nq / q) + ((nq % q) ? 1 : 0); tst = i_qscale_new/i_qscale + ((i_qscale_new%i_qscale) ? 1 : 0);
li = i = 0; li = i = 0;
while (1) for( ;; )
{ {
if (bit_buf >= 0x04000000) if (bs->i_bit_in_cache >= 0x04000000)
{ {
tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); tab = DCT_B15_8 + (UBITS (bs->i_bit_in_cache, 8) - 4);
i += tab->run; i += tab->run;
if (i < 64) if (i < 64)
{ {
normal_code: normal_code:
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
val = tab->level; val = tab->level;
if (val >= tst) if (val >= tst)
{ {
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); val = (val ^ SBITS (bs->i_bit_in_cache, 1)) - SBITS (bs->i_bit_in_cache, 1);
putAC(i - li - 1, (val * q) / nq, 1); putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 1);
li = i; li = i;
} }
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
continue;
continue; }
} else
else {
{ i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64;
i += (UBITS (bit_buf, 12) & 0x3F) - 64;
if (i >= 64) break; /* illegal, check against buffer overflow */
if (i >= 64) break; /* illegal, check against buffer overflow */
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12); val = SBITS (bs->i_bit_in_cache, 12);
val = SBITS (bit_buf, 12); if (abs(val) >= tst)
if (abs(val) >= tst) {
{ putAC( bs, i - li - 1, (val * i_qscale) / i_qscale_new, 1);
putAC(i - li - 1, (val * q) / nq, 1); li = i;
li = i; }
}
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12); continue;
}
continue; }
} else if (bs->i_bit_in_cache >= 0x02000000)
} {
else if (bit_buf >= 0x02000000) tab = DCT_B15_10 + (UBITS (bs->i_bit_in_cache, 10) - 8);
{ i += tab->run;
tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else if (bs->i_bit_in_cache >= 0x00800000)
} {
else if (bit_buf >= 0x00800000) tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16);
{ i += tab->run;
tab = DCT_13 + (UBITS (bit_buf, 13) - 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else if (bs->i_bit_in_cache >= 0x00200000)
} {
else if (bit_buf >= 0x00200000) tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16);
{ i += tab->run;
tab = DCT_15 + (UBITS (bit_buf, 15) - 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else
} {
else tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16);
{ bs_flush( bs, 16 );
tab = DCT_16 + UBITS (bit_buf, 16); i += tab->run;
DUMPBITS (bit_buf, bits, 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; break; /* illegal, check needed to avoid buffer overflow */
} }
break; /* illegal, check needed to avoid buffer overflow */
} bs_copy( bs, 4); /* end of block code */
COPYBITS (bit_buf, bits, 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 i, li;
int val; int val;
const DCTtab * tab; const DCTtab * tab;
RunLevel *sblk = blk + 1; RunLevel *sblk = blk + 1;
li = i = -1; li = i = -1;
if (bit_buf >= 0x28000000) if (bs->i_bit_in_cache >= 0x28000000)
{ {
tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); tab = DCT_B14DC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5);
goto entry_1; goto entry_1;
} }
else goto entry_2; else goto entry_2;
while (1) for( ;; )
{ {
if (bit_buf >= 0x28000000) if (bs->i_bit_in_cache >= 0x28000000)
{ {
tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); tab = DCT_B14AC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5);
entry_1: entry_1:
i += tab->run; i += tab->run;
if (i >= 64) break; /* end of block */ if (i >= 64) break; /* end of block */
normal_code: normal_code:
DUMPBITS (bit_buf, bits, tab->len); bs_flush( bs, tab->len );
val = tab->level; val = tab->level;
val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); /* if (bitstream_get (1)) val = -val; */ 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->level = val;
blk->run = i - li - 1; blk->run = i - li - 1;
li = i; li = i;
blk++; blk++;
DUMPBITS (bit_buf, bits, 1); bs_flush( bs, 1 );
continue;
continue; }
}
entry_2:
entry_2:
if (bs->i_bit_in_cache >= 0x04000000)
if (bit_buf >= 0x04000000) {
{ tab = DCT_B14_8 + (UBITS (bs->i_bit_in_cache, 8) - 4);
tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4);
i += tab->run;
i += tab->run; if (i < 64) goto normal_code;
if (i < 64) goto normal_code;
/* escape code */
/* escape code */
i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64;
i += (UBITS (bit_buf, 12) & 0x3F) - 64;
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12); val = SBITS (bs->i_bit_in_cache, 12);
val = SBITS (bit_buf, 12);
blk->level = val;
blk->level = val; blk->run = i - li - 1;
blk->run = i - li - 1; li = i;
li = i; blk++;
blk++;
bs_flush( bs, 12 );
DUMPBITS (bit_buf, bits, 12); continue;
}
continue; else if (bs->i_bit_in_cache >= 0x02000000)
} {
else if (bit_buf >= 0x02000000) tab = DCT_B14_10 + (UBITS (bs->i_bit_in_cache, 10) - 8);
{ i += tab->run;
tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else if (bs->i_bit_in_cache >= 0x00800000)
} {
else if (bit_buf >= 0x00800000) tab = DCT_13 + (UBITS (bs->i_bit_in_cache, 13) - 16);
{ i += tab->run;
tab = DCT_13 + (UBITS (bit_buf, 13) - 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else if (bs->i_bit_in_cache >= 0x00200000)
} {
else if (bit_buf >= 0x00200000) tab = DCT_15 + (UBITS (bs->i_bit_in_cache, 15) - 16);
{ i += tab->run;
tab = DCT_15 + (UBITS (bit_buf, 15) - 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; else
} {
else tab = DCT_16 + UBITS (bs->i_bit_in_cache, 16);
{ bs_flush( bs, 16 );
tab = DCT_16 + UBITS (bit_buf, 16); i += tab->run;
DUMPBITS (bit_buf, bits, 16); if (i < 64) goto normal_code;
i += tab->run; }
if (i < 64) goto normal_code; break; /* illegal, check needed to avoid buffer overflow */
} }
break; /* illegal, check needed to avoid buffer overflow */ bs_flush( bs, 2 ); /* dump end of block code */
}
DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ // remove last coeff
if (blk != sblk)
// remove last coeff {
if (blk != sblk) blk--;
{ // remove more coeffs if very late
blk--; if ((tr->quant_corr < -60.0f) && (blk != sblk))
// remove more coeffs if very late {
if ((quant_corr < -60.0f) && (blk != sblk)) blk--;
{ if ((tr->quant_corr < -80.0f) && (blk != sblk))
blk--; {
if ((quant_corr < -80.0f) && (blk != sblk)) blk--;
{ if ((tr->quant_corr < -100.0f) && (blk != sblk))
blk--; {
if ((quant_corr < -100.0f) && (blk != sblk)) blk--;
{ if ((tr->quant_corr < -120.0f) && (blk != sblk))
blk--; blk--;
if ((quant_corr < -120.0f) && (blk != sblk)) }
blk--; }
} }
} }
}
} blk->level = 0;
blk->level = 0;
return i; 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 tst;
int q = quantizer_scale, nq = new_quantizer_scale, tst;
int i, li; int i, li;
int val; int val;
const DCTtab * tab; const DCTtab * tab;
/* Basic sanity check --Meuuh */ /* Basic sanity check --Meuuh */
if ( q == 0 ) if( i_qscale == 0 )
{
return 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; li = i = -1;
if (bit_buf >= 0x28000000) if (bs->i_bit_in_cache >= 0x28000000)
{ {
tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); tab = DCT_B14DC_5 + (UBITS (bs->i_bit_in_cache, 5) - 5);
goto entry_1; goto entry_1;
} }
else goto entry_2; 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;
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) entry_1:
{ i += tab->run;
if (cc == 0) get_luma_dc_dct_diff (); if (i >= 64)
else get_chroma_dc_dct_diff (); break; /* end of block */
if (intra_vlc_format) get_intra_block_B15 (); normal_code:
else get_intra_block_B14 ();
}
static inline void slice_non_intra_DCT (int cur_block) bs_flush( bs, tab->len );
{ val = tab->level;
if (picture_coding_type == P_TYPE) get_non_intra_block_drop(block[cur_block]); if (val >= tst)
else get_non_intra_block_rq(block[cur_block]); {
} 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] ) //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);
get_motion_delta (f_code[0]);
get_motion_delta (f_code[1]);
}
static void motion_fr_field ( uint f_code[2] ) bs_flush( bs, 1 );
{ continue;
COPYBITS (bit_buf, bits, 1); }
get_motion_delta (f_code[0]); entry_2:
get_motion_delta (f_code[1]); 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]); /* escape code */
get_motion_delta (f_code[1]);
}
static void motion_fr_dmv ( uint f_code[2] ) i += (UBITS (bs->i_bit_in_cache, 12) & 0x3F) - 64;
{
get_motion_delta (f_code[0]); if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */
get_dmv ();
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]); i += tab->run;
get_dmv (); 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_frame( bs_transrate_t *bs, unsigned int f_code[2] )
static void motion_fr_conceal ( )
{ {
get_motion_delta (f_code[0][0]); get_motion_delta( bs, f_code[0] );
get_motion_delta (f_code[0][1]); get_motion_delta( bs, f_code[1] );
COPYBITS (bit_buf, bits, 1); /* remove marker_bit */
} }
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( bs, f_code[0]);
get_motion_delta (f_code[1]); 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( bs, f_code[1]);
get_motion_delta (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( bs, f_code[0]);
get_motion_delta (f_code[1]); 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]); bs_copy( bs, 1);
get_dmv ();
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_motion_delta( bs, f_code[0]);
get_dmv (); 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( bs, f_code[1]);
get_motion_delta (f_code[0][1]); get_dmv( bs );
COPYBITS (bit_buf, bits, 1); /* remove marker_bit */
} }
#define MOTION_CALL(routine,direction) \
do { \ #define MOTION_CALL(routine,direction) \
if ((direction) & MACROBLOCK_MOTION_FORWARD) \ do { \
routine (f_code[0]); \ if ((direction) & MACROBLOCK_MOTION_FORWARD) \
if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ routine( bs, tr->f_code[0]); \
routine (f_code[1]); \ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
routine( bs, tr->f_code[1]); \
} while (0) } while (0)
#define NEXT_MACROBLOCK \ #define NEXT_MACROBLOCK \
do { \ do { \
h_offset += 16; \ tr->h_offset += 16; \
if (h_offset == horizontal_size_value) \ if( tr->h_offset == tr->horizontal_size_value) \
{ \ { \
v_offset += 16; \ tr->v_offset += 16; \
if (v_offset > (vertical_size_value - 16)) return; \ if (tr->v_offset > (tr->vertical_size_value - 16)) return; \
h_offset = 0; \ tr->h_offset = 0; \
} \ } \
} while (0) } while (0)
void putmbdata(int macroblock_modes) static void putmbdata( transrate_t *tr, int macroblock_modes )
{ {
putmbtype(macroblock_modes & 0x1F); bs_transrate_t *bs = &tr->bs;
switch (picture_coding_type) bs_write( bs,
{ mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].code,
case I_TYPE: mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].len);
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;
}
}
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); bs_transrate_t *bs = &tr->bs;
last_coded_scale = quantiser;
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; int offset;
const MBAtab * mba; const MBAtab * mba;
v_offset = (code - 1) * 16; tr->v_offset = (code - 1) * 16;
quantizer_scale = get_quantizer_scale (); tr->quantizer_scale = get_quantizer_scale( tr );
if (picture_coding_type == P_TYPE) new_quantizer_scale = quantizer_scale; if ( tr->picture_coding_type == P_TYPE)
else new_quantizer_scale = getNewQuant(quantizer_scale); {
put_quantiser(new_quantizer_scale); tr->new_quantizer_scale = tr->quantizer_scale;
}
/*LOGF("************************\nstart of slice %i in %s picture. ori quant: %i new quant: %i\n", code, else
(picture_coding_type == I_TYPE ? "I_TYPE" : (picture_coding_type == P_TYPE ? "P_TYPE" : "B_TYPE")), {
quantizer_scale, new_quantizer_scale);*/ 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 */ /* ignore intra_slice and all the extra data */
while (bit_buf & 0x80000000) while (bs->i_bit_in_cache & 0x80000000)
{ {
DUMPBITS (bit_buf, bits, 9); bs_flush( bs, 9 );
} }
/* decode initial macroblock address increment */ /* decode initial macroblock address increment */
offset = 0; offset = 0;
while (1) for( ;; )
{ {
if (bit_buf >= 0x08000000) if (bs->i_bit_in_cache >= 0x08000000)
{ {
mba = MBA_5 + (UBITS (bit_buf, 6) - 2); mba = MBA_5 + (UBITS (bs->i_bit_in_cache, 6) - 2);
break; break;
} }
else if (bit_buf >= 0x01800000) else if (bs->i_bit_in_cache >= 0x01800000)
{ {
mba = MBA_11 + (UBITS (bit_buf, 12) - 24); mba = MBA_11 + (UBITS (bs->i_bit_in_cache, 12) - 24);
break; break;
} }
else switch (UBITS (bit_buf, 12)) else if( UBITS (bs->i_bit_in_cache, 12 ) == 8 )
{ {
case 8: /* macroblock_escape */ /* macroblock_escape */
offset += 33; offset += 33;
COPYBITS (bit_buf, bits, 11); bs_copy( bs, 11);
continue; }
default: /* error */ else
return 1; {
} return -1;
}
} }
COPYBITS (bit_buf, bits, mba->len + 1); bs_copy( bs, mba->len + 1);
h_offset = (offset + mba->mba) << 4; tr->h_offset = (offset + mba->mba) << 4;
while (h_offset - (int)horizontal_size_value >= 0) while( tr->h_offset - (int)tr->horizontal_size_value >= 0)
{ {
h_offset -= horizontal_size_value; tr->h_offset -= tr->horizontal_size_value;
v_offset += 16; 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; return 0;
} }
void mpeg2_slice ( const int code ) static void mpeg2_slice( transrate_t *tr, const int code )
{ {
#define bit_buf (inbitbuf) bs_transrate_t *bs = &tr->bs;
if (slice_init (code)) return; if( slice_init( tr, code ) )
{
while (1) return;
{
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);
} }
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 /////---- 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 // get start code
LOCK(1) ID = bs->p_c[0];
ID = cbuf[0];
COPY(1) /* Copy one byte */
*bs->p_w++ = *bs->p_c++;
if (ID == 0x00) // pic header if (ID == 0x00) // pic header
{ {
LOCK(4) tr->picture_coding_type = (bs->p_c[1] >> 3) & 0x7;
picture_coding_type = (cbuf[1] >> 3) & 0x7; bs->p_c[1] |= 0x7; bs->p_c[2] = 0xFF; bs->p_c[3] |= 0xF8; // vbv_delay is now 0xFFFF
cbuf[1] |= 0x7; cbuf[2] = 0xFF; cbuf[3] |= 0xF8; // vbv_delay is now 0xFFFF
COPY(4) memcpy(bs->p_w, bs->p_c, 4);
bs->p_c += 4;
bs->p_w += 4;
} }
else if (ID == 0xB3) // seq header else if (ID == 0xB3) // seq header
{ {
LOCK(8) tr->horizontal_size_value = (bs->p_c[0] << 4) | (bs->p_c[1] >> 4);
horizontal_size_value = (cbuf[0] << 4) | (cbuf[1] >> 4); tr->vertical_size_value = ((bs->p_c[1] & 0xF) << 8) | bs->p_c[2];
vertical_size_value = ((cbuf[1] & 0xF) << 8) | cbuf[2]; if(!tr->horizontal_size_value || !tr->vertical_size_value )
if (!horizontal_size_value || !vertical_size_value) {
return -1; 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 else if (ID == 0xB5) // extension
{ {
LOCK(1) if ((bs->p_c[0] >> 4) == 0x8) // pic coding ext
if ((cbuf[0] >> 4) == 0x8) // pic coding ext
{ {
LOCK(5) tr->f_code[0][0] = (bs->p_c[0] & 0xF) - 1;
tr->f_code[0][1] = (bs->p_c[1] >> 4) - 1;
f_code[0][0] = (cbuf[0] & 0xF) - 1; tr->f_code[1][0] = (bs->p_c[1] & 0xF) - 1;
f_code[0][1] = (cbuf[1] >> 4) - 1; tr->f_code[1][1] = (bs->p_c[2] >> 4) - 1;
f_code[1][0] = (cbuf[1] & 0xF) - 1;
f_code[1][1] = (cbuf[2] >> 4) - 1; /* tr->intra_dc_precision = (bs->p_c[2] >> 2) & 0x3; */
tr->picture_structure = bs->p_c[2] & 0x3;
intra_dc_precision = (cbuf[2] >> 2) & 0x3; tr->frame_pred_frame_dct = (bs->p_c[3] >> 6) & 0x1;
picture_structure = cbuf[2] & 0x3; tr->concealment_motion_vectors = (bs->p_c[3] >> 5) & 0x1;
frame_pred_frame_dct = (cbuf[3] >> 6) & 0x1; tr->q_scale_type = (bs->p_c[3] >> 4) & 0x1;
concealment_motion_vectors = (cbuf[3] >> 5) & 0x1; tr->intra_vlc_format = (bs->p_c[3] >> 3) & 0x1;
q_scale_type = (cbuf[3] >> 4) & 0x1; /* tr->alternate_scan = (bs->p_c[3] >> 2) & 0x1; */
intra_vlc_format = (cbuf[3] >> 3) & 0x1;
alternate_scan = (cbuf[3] >> 2) & 0x1;
COPY(5) memcpy(bs->p_w, bs->p_c, 5);
bs->p_c += 5;
bs->p_w += 5;
} }
else else
{ {
COPY(1) *bs->p_w++ = *bs->p_c++;
} }
} }
else if (ID == 0xB8) // gop header else if (ID == 0xB8) // gop header
{ {
LOCK(4) memcpy(bs->p_w, bs->p_c, 4);
COPY(4) bs->p_c += 4;
bs->p_w += 4;
} }
else if ((ID >= 0x01) && (ID <= 0xAF)) // slice else if ((ID >= 0x01) && (ID <= 0xAF)) // slice
{ {
uint8 *outTemp = wbuf, *inTemp = cbuf; uint8_t *outTemp = bs->p_w, *inTemp = bs->p_c;
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;
// lock all the slice if( ( tr->picture_coding_type == B_TYPE && tr->quant_corr < 2.5f ) || // don't recompress if we're in advance!
while (!fsc) ( 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; return -1;
LOCK(toLock)
if ( (nsc[0] == 0) && (nsc[1] == 0) && (nsc[2] == 1) ) fsc = 1; // start code !
else nsc++; // continue search
} }
// init bit buffer // init bit buffer
inbitbuf = 0; inbitcnt = 0; bs->i_bit_in_cache = 0; bs->i_bit_in = 0;
outbitbuf = 0; outbitcnt = BITS_IN_BUF; bs->i_bit_out_cache = 0; bs->i_bit_out = BITS_IN_BUF;
// get 32 bits // get 32 bits
Refill_bits(); bs_refill( bs );
Refill_bits(); bs_refill( bs );
Refill_bits(); bs_refill( bs );
Refill_bits(); bs_refill( bs );
// begin bit level recoding // begin bit level recoding
mpeg2_slice(ID); mpeg2_slice(tr, ID);
flush_read_buffer();
flush_write_buffer(); bs_flush_read( bs );
bs_flush_write( bs );
// end bit level recoding // end bit level recoding
/* Basic sanity checks --Meuuh */ /* Basic sanity checks --Meuuh */
if (cbuf > rbuf || wbuf > rwbuf) if (bs->p_c > bs->p_r || bs->p_w > bs->p_rw)
{
return -1; return -1;
}
/*LOGF("type: %s code: %02i in : %6i out : %6i diff : %6i fact: %2.2f\n", /*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")), (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));*/ 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 (wbuf - outTemp > cbuf - inTemp) // yes that might happen, rarely 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", /*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")), (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 ! // in this case, we'll just use the original slice !
memcpy(outTemp, inTemp, cbuf - inTemp); memcpy(outTemp, inTemp, bs->p_c - inTemp);
wbuf = outTemp + (cbuf - inTemp); bs->p_w = outTemp + (bs->p_c - inTemp);
// adjust outbytecnt // adjust bs->i_byte_out
outbytecnt -= (wbuf - outTemp) - (cbuf - inTemp); bs->i_byte_out -= (bs->p_w - outTemp) - (bs->p_c - inTemp);
} }
} }
} }
...@@ -1873,9 +1874,11 @@ static int do_next_start_code(void) ...@@ -1873,9 +1874,11 @@ static int do_next_start_code(void)
} }
static void process_frame( sout_stream_t *p_stream, 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; sout_buffer_t *p_out;
/* The output buffer can't be bigger than the input buffer. */ /* The output buffer can't be bigger than the input buffer. */
...@@ -1887,52 +1890,76 @@ static void process_frame( sout_stream_t *p_stream, ...@@ -1887,52 +1890,76 @@ static void process_frame( sout_stream_t *p_stream,
sout_BufferChain( out, p_out ); sout_BufferChain( out, p_out );
rwbuf = owbuf = wbuf = p_out->p_buffer; bs->p_rw = bs->p_ow = bs->p_w = p_out->p_buffer;
cbuf = rbuf = in->p_buffer; bs->p_c = bs->p_r = in->p_buffer;
rbuf += in->i_size + 4; bs->p_r += in->i_size + 4;
rwbuf += in->i_size; bs->p_rw += in->i_size;
*(in->p_buffer + in->i_size) = 0; *(in->p_buffer + in->i_size) = 0;
*(in->p_buffer + in->i_size + 1) = 0; *(in->p_buffer + in->i_size + 1) = 0;
*(in->p_buffer + in->i_size + 2) = 1; *(in->p_buffer + in->i_size + 2) = 1;
*(in->p_buffer + in->i_size + 3) = 0; *(in->p_buffer + in->i_size + 3) = 0;
inbytecnt += in->i_size; bs->i_byte_in += in->i_size;
for ( ; ; ) for ( ; ; )
{ {
// get next start code prefix uint8_t *p_end = &in->p_buffer[in->i_size];
found = 0;
while (!found) /* Search next start code */
for( ;; )
{ {
#ifndef REMOVE_BYTE_STUFFING if( bs->p_c < p_end - 3 && bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 1 )
LOCK(3) {
#else /* Next start code */
LOCK(6) break;
if ( (cbuf[0] == 0) && (cbuf[1] == 0) && (cbuf[2] == 0) && (cbuf[3] == 0) && (cbuf[4] == 0) && (cbuf[5] == 0) ) { SEEKR(1) } }
else else if( bs->p_c < p_end - 6 &&
#endif bs->p_c[0] == 0 && bs->p_c[1] == 0 && bs->p_c[2] == 0 &&
if ( (cbuf[0] == 0) && (cbuf[1] == 0) && (cbuf[2] == 1) ) found = 1; // start code ! bs->p_c[3] == 0 && bs->p_c[4] == 0 && bs->p_c[5] == 0 )
else { COPY(1) } // continue search {
/* 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; break;
}
} }
if (cbuf >= in->p_buffer + in->i_size)
if( bs->p_c >= p_end )
{
break; 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; 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; bs->i_byte_out += bs->p_w - bs->p_ow;
p_out->i_size = wbuf - owbuf; p_out->i_size = bs->p_w - bs->p_ow;
} }
static int transrate_video_process( sout_stream_t *p_stream, static int transrate_video_process( 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 )
{ {
transrate_t *tr = &id->tr;
bs_transrate_t *bs = &tr->bs;
*out = NULL; *out = NULL;
if ( in->i_flags & SOUT_BUFFER_FLAGS_GOP ) if ( in->i_flags & SOUT_BUFFER_FLAGS_GOP )
...@@ -1940,9 +1967,9 @@ static int transrate_video_process( sout_stream_t *p_stream, ...@@ -1940,9 +1967,9 @@ static int transrate_video_process( sout_stream_t *p_stream,
while ( id->p_current_buffer != NULL ) while ( id->p_current_buffer != NULL )
{ {
sout_buffer_t * p_next = id->p_current_buffer->p_next; 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; id->p_current_buffer->p_next = NULL;
sout_BufferChain( out, id->p_current_buffer ); sout_BufferChain( out, id->p_current_buffer );
} }
...@@ -1953,7 +1980,7 @@ static int transrate_video_process( sout_stream_t *p_stream, ...@@ -1953,7 +1980,7 @@ static int transrate_video_process( sout_stream_t *p_stream,
} }
id->p_current_buffer = p_next; id->p_current_buffer = p_next;
} }
if ( id->i_next_gop_duration ) if ( id->i_next_gop_duration )
{ {
mtime_t i_bitrate = (mtime_t)id->i_next_gop_size * 8000 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, ...@@ -1963,26 +1990,26 @@ static int transrate_video_process( sout_stream_t *p_stream,
if (i_old_bitrate) if (i_old_bitrate)
{ {
msg_Dbg(p_stream, "bitrate = %lld -> %lld", 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_bitrate = i_bitrate;
i_old_duration = id->i_next_gop_duration; 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 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_current_buffer = id->p_next_gop;
id->p_next_gop = NULL; id->p_next_gop = NULL;
id->i_next_gop_duration = 0; id->i_next_gop_duration = 0;
id->i_next_gop_size = 0; id->i_next_gop_size = 0;
inbytecnt = 0; bs->i_byte_in = 0;
outbytecnt = 0; bs->i_byte_out = 0;
} }
} }
...@@ -1994,9 +2021,9 @@ static int transrate_video_process( sout_stream_t *p_stream, ...@@ -1994,9 +2021,9 @@ static int transrate_video_process( sout_stream_t *p_stream,
if ( id->p_current_buffer != NULL ) if ( id->p_current_buffer != NULL )
{ {
sout_buffer_t * p_next = id->p_current_buffer->p_next; 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; id->p_current_buffer->p_next = NULL;
sout_BufferChain( out, id->p_current_buffer ); sout_BufferChain( out, id->p_current_buffer );
} }
...@@ -2011,24 +2038,3 @@ static int transrate_video_process( sout_stream_t *p_stream, ...@@ -2011,24 +2038,3 @@ static int transrate_video_process( sout_stream_t *p_stream,
return VLC_SUCCESS; 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 )
{
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment