else
{
int carry = out & 0x100;
- if( cb->p + cb->i_bytes_outstanding + 1 >= cb->p_end )
+ int bytes_outstanding = cb->i_bytes_outstanding;
+ if( cb->p + bytes_outstanding + 1 >= cb->p_end )
return;
if( carry )
{
// are in bytes_outstanding and thus not written yet.
cb->p[-1]++;
}
- while( cb->i_bytes_outstanding > 0 )
+ while( bytes_outstanding > 0 )
{
- *(cb->p++) = carry ? 0 : 0xff;
- cb->i_bytes_outstanding--;
+ *(cb->p++) = (carry >> 8) - 1;
+ bytes_outstanding--;
}
*(cb->p++) = out;
+ cb->i_bytes_outstanding = 0;
}
}
}
void x264_cabac_encode_bypass( x264_cabac_t *cb, int b )
{
cb->i_low <<= 1;
- cb->i_low += (((int32_t)b<<31)>>31) & cb->i_range;
+ cb->i_low += -b & cb->i_range;
cb->i_queue += 1;
x264_cabac_putbyte( cb );
}
-void x264_cabac_encode_terminal( x264_cabac_t *cb, int b )
+void x264_cabac_encode_terminal( x264_cabac_t *cb )
{
cb->i_range -= 2;
- if( b )
- {
- cb->i_low += cb->i_range;
- cb->i_range = 2<<7;
- cb->i_low <<= 7;
- cb->i_queue += 7;
- x264_cabac_putbyte( cb );
- }
- else
- {
- x264_cabac_encode_renorm( cb );
- }
+ x264_cabac_encode_renorm( cb );
}
-void x264_cabac_encode_flush( x264_cabac_t *cb )
+void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb )
{
- cb->i_low |= 0x80;
- cb->i_low <<= 10;
- cb->i_queue += 10;
+ cb->i_low += cb->i_range - 2;
+ cb->i_low |= 1;
+ cb->i_low <<= 9;
+ cb->i_queue += 9;
+ x264_cabac_putbyte( cb );
x264_cabac_putbyte( cb );
+ cb->i_low <<= 8 - cb->i_queue;
+ cb->i_low |= (0x35a4e4f5 >> (h->i_frame & 31) & 1) << 10;
+ cb->i_queue = 8;
x264_cabac_putbyte( cb );
- cb->i_queue = 0;
if( cb->p + cb->i_bytes_outstanding + 1 >= cb->p_end )
return; //FIXME throw an error instead of silently truncating the frame
void x264_cabac_encode_init ( x264_cabac_t *cb, uint8_t *p_data, uint8_t *p_end );
void x264_cabac_encode_decision( x264_cabac_t *cb, int i_ctx_idx, int b );
void x264_cabac_encode_bypass( x264_cabac_t *cb, int b );
-void x264_cabac_encode_terminal( x264_cabac_t *cb, int b );
-void x264_cabac_encode_flush( x264_cabac_t *cb );
+void x264_cabac_encode_terminal( x264_cabac_t *cb );
+void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb );
/* internal only. these don't write the bitstream, just calculate bit cost: */
void x264_cabac_size_decision( x264_cabac_t *cb, int i_ctx, int b );
else if( i_mb_type == I_PCM )
{
x264_cabac_encode_decision( cb, ctx0, 1 );
- x264_cabac_encode_terminal( cb, 1 );
- x264_cabac_encode_flush( cb );
+ x264_cabac_encode_flush( h, cb );
}
else
{
int i_pred = x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode];
x264_cabac_encode_decision( cb, ctx0, 1 );
- x264_cabac_encode_terminal( cb, 0 );
+ x264_cabac_encode_terminal( cb );
x264_cabac_encode_decision( cb, ctx1, ( h->mb.i_cbp_luma == 0 ? 0 : 1 ));
if( h->mb.i_cbp_chroma == 0 )
if( h->param.b_cabac )
{
if( mb_xy > h->sh.i_first_mb && !(h->sh.b_mbaff && (i_mb_y&1)) )
- x264_cabac_encode_terminal( &h->cabac, 0 );
+ x264_cabac_encode_terminal( &h->cabac );
if( IS_SKIP( h->mb.i_type ) )
x264_cabac_mb_skip( h, 1 );
if( h->param.b_cabac )
{
- /* end of slice */
- x264_cabac_encode_terminal( &h->cabac, 1 );
- }
- else if( i_skip > 0 )
- {
- bs_write_ue( &h->out.bs, i_skip ); /* last skip run */
- }
-
- if( h->param.b_cabac )
- {
- x264_cabac_encode_flush( &h->cabac );
+ x264_cabac_encode_flush( h, &h->cabac );
h->out.bs.p = h->cabac.p;
}
else
{
+ if( i_skip > 0 )
+ bs_write_ue( &h->out.bs, i_skip ); /* last skip run */
/* rbsp_slice_trailing_bits */
bs_rbsp_trailing( &h->out.bs );
}
/* CABAC: not exactly the same. x264_cabac_size_decision() keeps track of
* fractional bits, but only finite precision. */
#define x264_cabac_encode_decision(c,x,v) x264_cabac_size_decision(c,x,v)
-#define x264_cabac_encode_terminal(c,v) x264_cabac_size_decision(c,276,v)
+#define x264_cabac_encode_terminal(c) x264_cabac_size_decision(c,276,0)
#define x264_cabac_encode_bypass(c,v) ((c)->f8_bits_encoded += 256)
-#define x264_cabac_encode_flush(c)
+#define x264_cabac_encode_flush(h,c)
#define x264_macroblock_write_cabac x264_macroblock_size_cabac
#define x264_cabac_mb_skip x264_cabac_mb_size_skip_unused
#include "cabac.c"