#include "avcodec.h"
#include "common.h"
#include "dsputil.h"
-#include "cabac.h"
+
+#include "rangecoder.h"
+#define MID_STATE 128
#include "mpegvideo.h"
// MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to make the motion estimation eventually independant of MpegEncContext, so this will be removed then (FIXME/XXX)
AVCodecContext *avctx;
- CABACContext c;
+ RangeCoder c;
DSPContext dsp;
AVFrame input_picture;
AVFrame current_picture;
else return v;
}
-static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_signed){
+static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
int i;
if(v){
const int e= av_log2(a);
#if 1
const int el= FFMIN(e, 10);
- put_cabac(c, state+0, 0);
+ put_rac(c, state+0, 0);
for(i=0; i<el; i++){
- put_cabac(c, state+1+i, 1); //1..10
+ put_rac(c, state+1+i, 1); //1..10
}
for(; i<e; i++){
- put_cabac(c, state+1+9, 1); //1..10
+ put_rac(c, state+1+9, 1); //1..10
}
- put_cabac(c, state+1+FFMIN(i,9), 0);
+ put_rac(c, state+1+FFMIN(i,9), 0);
for(i=e-1; i>=el; i--){
- put_cabac(c, state+22+9, (a>>i)&1); //22..31
+ put_rac(c, state+22+9, (a>>i)&1); //22..31
}
for(; i>=0; i--){
- put_cabac(c, state+22+i, (a>>i)&1); //22..31
+ put_rac(c, state+22+i, (a>>i)&1); //22..31
}
if(is_signed)
- put_cabac(c, state+11 + el, v < 0); //11..21
+ put_rac(c, state+11 + el, v < 0); //11..21
#else
- put_cabac(c, state+0, 0);
+ put_rac(c, state+0, 0);
if(e<=9){
for(i=0; i<e; i++){
- put_cabac(c, state+1+i, 1); //1..10
+ put_rac(c, state+1+i, 1); //1..10
}
- put_cabac(c, state+1+i, 0);
+ put_rac(c, state+1+i, 0);
for(i=e-1; i>=0; i--){
- put_cabac(c, state+22+i, (a>>i)&1); //22..31
+ put_rac(c, state+22+i, (a>>i)&1); //22..31
}
if(is_signed)
- put_cabac(c, state+11 + e, v < 0); //11..21
+ put_rac(c, state+11 + e, v < 0); //11..21
}else{
for(i=0; i<e; i++){
- put_cabac(c, state+1+FFMIN(i,9), 1); //1..10
+ put_rac(c, state+1+FFMIN(i,9), 1); //1..10
}
- put_cabac(c, state+1+FFMIN(i,9), 0);
+ put_rac(c, state+1+FFMIN(i,9), 0);
for(i=e-1; i>=0; i--){
- put_cabac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
+ put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31
}
if(is_signed)
- put_cabac(c, state+11 + FFMIN(e,10), v < 0); //11..21
+ put_rac(c, state+11 + FFMIN(e,10), v < 0); //11..21
}
#endif
}else{
- put_cabac(c, state+0, 1);
+ put_rac(c, state+0, 1);
}
}
-static inline int get_symbol(CABACContext *c, uint8_t *state, int is_signed){
- if(get_cabac(c, state+0))
+static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
+ if(get_rac(c, state+0))
return 0;
else{
int i, e, a;
e= 0;
- while(get_cabac(c, state+1 + FFMIN(e,9))){ //1..10
+ while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
e++;
}
a= 1;
for(i=e-1; i>=0; i--){
- a += a + get_cabac(c, state+22 + FFMIN(i,9)); //22..31
+ a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
}
- if(is_signed && get_cabac(c, state+11 + FFMIN(e,10))) //11..21
+ if(is_signed && get_rac(c, state+11 + FFMIN(e,10))) //11..21
return -a;
else
return a;
}
}
-static inline void put_symbol2(CABACContext *c, uint8_t *state, int v, int log2){
+static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
int i;
int r= log2>=0 ? 1<<log2 : 1;
assert(log2>=-4);
while(v >= r){
- put_cabac(c, state+4+log2, 1);
+ put_rac(c, state+4+log2, 1);
v -= r;
log2++;
if(log2>0) r+=r;
}
- put_cabac(c, state+4+log2, 0);
+ put_rac(c, state+4+log2, 0);
for(i=log2-1; i>=0; i--){
- put_cabac(c, state+31-i, (v>>i)&1);
+ put_rac(c, state+31-i, (v>>i)&1);
}
}
-static inline int get_symbol2(CABACContext *c, uint8_t *state, int log2){
+static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
int i;
int r= log2>=0 ? 1<<log2 : 1;
int v=0;
assert(log2>=-4);
- while(get_cabac(c, state+4+log2)){
+ while(get_rac(c, state+4+log2)){
v+= r;
log2++;
if(log2>0) r+=r;
}
for(i=log2-1; i>=0; i--){
- v+= get_cabac(c, state+31-i)<<i;
+ v+= get_rac(c, state+31-i)<<i;
}
return v;
if(/*ll|*/l|lt|t|rt|p){
int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));
- put_cabac(&s->c, &b->state[0][context], !!v);
+ put_rac(&s->c, &b->state[0][context], !!v);
}else{
if(!run){
run= runs[run_index++];
int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));
put_symbol2(&s->c, b->state[context + 2], ABS(v)-1, context-4);
- put_cabac(&s->c, &b->state[0][16 + 1 + 3 + quant3b[l&0xFF] + 3*quant3b[t&0xFF]], v<0);
+ put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3b[l&0xFF] + 3*quant3b[t&0xFF]], v<0);
}
}
}
if(/*ll|*/l|lt|t|rt|p){
int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));
- v=get_cabac(&s->c, &b->state[0][context]);
+ v=get_rac(&s->c, &b->state[0][context]);
}else{
if(!run){
run= get_symbol2(&s->c, b->state[1], 3);
if(v){
int context= av_log2(/*ABS(ll) + */3*ABS(l) + ABS(lt) + 2*ABS(t) + ABS(rt) + ABS(p));
v= get_symbol2(&s->c, b->state[context + 2], context-4) + 1;
- if(get_cabac(&s->c, &b->state[0][16 + 1 + 3 + quant3b[l&0xFF] + 3*quant3b[t&0xFF]])){
+ if(get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3b[l&0xFF] + 3*quant3b[t&0xFF]])){
src[x + y*stride]=-(( v*qmul + qadd)>>(QEXPSHIFT));
v= -v;
}else{
for(plane_index=0; plane_index<3; plane_index++){
for(level=0; level<s->spatial_decomposition_count; level++){
for(orientation=level ? 1:0; orientation<4; orientation++){
- memset(s->plane[plane_index].band[level][orientation].state, 0, sizeof(s->plane[plane_index].band[level][orientation].state));
+ memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].state));
}
}
}
- memset(s->header_state, 0, sizeof(s->header_state));
- memset(s->block_state, 0, sizeof(s->block_state));
+ memset(s->header_state, MID_STATE, sizeof(s->header_state));
+ memset(s->block_state, MID_STATE, sizeof(s->block_state));
}
static int alloc_blocks(SnowContext *s){
return 0;
}
-static inline void copy_cabac_state(CABACContext *d, CABACContext *s){
- PutBitContext bak= d->pb;
+static inline void copy_rac_state(RangeCoder *d, RangeCoder *s){
+ uint8_t *bytestream= d->bytestream;
+ uint8_t *bytestream_start= d->bytestream_start;
*d= *s;
- d->pb= bak;
+ d->bytestream= bytestream;
+ d->bytestream_start= bytestream_start;
}
//near copy & paste from dsputil, FIXME
uint8_t i_buffer[1024];
uint8_t p_state[sizeof(s->block_state)];
uint8_t i_state[sizeof(s->block_state)];
- CABACContext pc, ic;
- PutBitContext pbbak= s->c.pb;
+ RangeCoder pc, ic;
+ uint8_t *pbbak= s->c.bytestream;
+ uint8_t *pbbak_start= s->c.bytestream_start;
int score, score2, iscore, i_len, p_len, block_s, sum;
const int w= s->b_width << s->block_max_depth;
const int h= s->b_height << s->block_max_depth;
// subpel search
pc= s->c;
- init_put_bits(&pc.pb, p_buffer, sizeof(p_buffer));
+ pc.bytestream_start=
+ pc.bytestream= p_buffer; //FIXME end/start? and at the other stoo
memcpy(p_state, s->block_state, sizeof(s->block_state));
if(level!=s->block_max_depth)
- put_cabac(&pc, &p_state[4 + s_context], 1);
- put_cabac(&pc, &p_state[1 + left->type + top->type], 0);
+ put_rac(&pc, &p_state[4 + s_context], 1);
+ put_rac(&pc, &p_state[1 + left->type + top->type], 0);
put_symbol(&pc, &p_state[128 + 32*mx_context], mx - pmx, 1);
put_symbol(&pc, &p_state[128 + 32*my_context], my - pmy, 1);
- p_len= put_bits_count(&pc.pb);
- score += (s->lambda2*(p_len + pc.outstanding_count - s->c.outstanding_count))>>FF_LAMBDA_SHIFT;
+ p_len= pc.bytestream - pc.bytestream_start;
+ score += (s->lambda2*(p_len*8
+ + (pc.outstanding_count - s->c.outstanding_count)*8
+ + (-av_log2(pc.range) + av_log2(s->c.range))
+ ))>>FF_LAMBDA_SHIFT;
block_s= block_w*block_w;
sum = pix_sum(¤t_mb[0][0], stride, block_w);
// iscore += pix_norm1(¤t_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
ic= s->c;
- init_put_bits(&ic.pb, i_buffer, sizeof(i_buffer));
+ ic.bytestream_start=
+ ic.bytestream= i_buffer; //FIXME end/start? and at the other stoo
memcpy(i_state, s->block_state, sizeof(s->block_state));
if(level!=s->block_max_depth)
- put_cabac(&ic, &i_state[4 + s_context], 1);
- put_cabac(&ic, &i_state[1 + left->type + top->type], 1);
+ put_rac(&ic, &i_state[4 + s_context], 1);
+ put_rac(&ic, &i_state[1 + left->type + top->type], 1);
put_symbol(&ic, &i_state[32], l-pl , 1);
put_symbol(&ic, &i_state[64], cb-pcb, 1);
put_symbol(&ic, &i_state[96], cr-pcr, 1);
- i_len= put_bits_count(&ic.pb);
- iscore += (s->lambda2*(i_len + ic.outstanding_count - s->c.outstanding_count))>>FF_LAMBDA_SHIFT;
+ i_len= ic.bytestream - ic.bytestream_start;
+ iscore += (s->lambda2*(i_len*8
+ + (ic.outstanding_count - s->c.outstanding_count)*8
+ + (-av_log2(ic.range) + av_log2(s->c.range))
+ ))>>FF_LAMBDA_SHIFT;
// assert(score==256*256*256*64-1);
assert(iscore < 255*255*256 + s->lambda2*10);
}
if(level!=s->block_max_depth){
- put_cabac(&s->c, &s->block_state[4 + s_context], 0);
+ put_rac(&s->c, &s->block_state[4 + s_context], 0);
score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);
score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);
score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);
}
if(iscore < score){
- flush_put_bits(&ic.pb);
- ff_copy_bits(&pbbak, i_buffer, i_len);
+ memcpy(pbbak, i_buffer, i_len);
s->c= ic;
- s->c.pb= pbbak;
+ s->c.bytestream_start= pbbak_start;
+ s->c.bytestream= pbbak + i_len;
set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, BLOCK_INTRA);
memcpy(s->block_state, i_state, sizeof(s->block_state));
return iscore;
}else{
- flush_put_bits(&pc.pb);
- ff_copy_bits(&pbbak, p_buffer, p_len);
+ memcpy(pbbak, p_buffer, p_len);
s->c= pc;
- s->c.pb= pbbak;
+ s->c.bytestream_start= pbbak_start;
+ s->c.bytestream= pbbak + p_len;
set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, 0);
memcpy(s->block_state, p_state, sizeof(s->block_state));
return score;
return;
}
- if(level==s->block_max_depth || get_cabac(&s->c, &s->block_state[4 + s_context])){
+ if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
int type;
int l = left->color[0];
int cb= left->color[1];
int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 0*av_log2(2*ABS(tr->mx - top->mx));
int my_context= av_log2(2*ABS(left->my - top->my)) + 0*av_log2(2*ABS(tr->my - top->my));
- type= get_cabac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
+ type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
if(type){
l += get_symbol(&s->c, &s->block_state[32], 1);
static void encode_header(SnowContext *s){
int plane_index, level, orientation;
- uint8_t kstate[32]={0};
+ uint8_t kstate[32];
+
+ memset(kstate, MID_STATE, sizeof(kstate));
- put_cabac(&s->c, kstate, s->keyframe);
+ put_rac(&s->c, kstate, s->keyframe);
if(s->keyframe || s->always_reset)
reset_contexts(s);
if(s->keyframe){
put_symbol(&s->c, s->header_state, s->version, 0);
- put_cabac(&s->c, s->header_state, s->always_reset);
+ put_rac(&s->c, s->header_state, s->always_reset);
put_symbol(&s->c, s->header_state, s->temporal_decomposition_type, 0);
put_symbol(&s->c, s->header_state, s->temporal_decomposition_count, 0);
put_symbol(&s->c, s->header_state, s->spatial_decomposition_count, 0);
put_symbol(&s->c, s->header_state, s->colorspace_type, 0);
put_symbol(&s->c, s->header_state, s->chroma_h_shift, 0);
put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0);
- put_cabac(&s->c, s->header_state, s->spatial_scalability);
-// put_cabac(&s->c, s->header_state, s->rate_scalability);
+ put_rac(&s->c, s->header_state, s->spatial_scalability);
+// put_rac(&s->c, s->header_state, s->rate_scalability);
for(plane_index=0; plane_index<2; plane_index++){
for(level=0; level<s->spatial_decomposition_count; level++){
static int decode_header(SnowContext *s){
int plane_index, level, orientation;
- uint8_t kstate[32]={0};
+ uint8_t kstate[32];
+
+ memset(kstate, MID_STATE, sizeof(kstate));
- s->keyframe= get_cabac(&s->c, kstate);
+ s->keyframe= get_rac(&s->c, kstate);
if(s->keyframe || s->always_reset)
reset_contexts(s);
if(s->keyframe){
av_log(s->avctx, AV_LOG_ERROR, "version %d not supported", s->version);
return -1;
}
- s->always_reset= get_cabac(&s->c, s->header_state);
+ s->always_reset= get_rac(&s->c, s->header_state);
s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
s->spatial_decomposition_count= get_symbol(&s->c, s->header_state, 0);
s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
- s->spatial_scalability= get_cabac(&s->c, s->header_state);
-// s->rate_scalability= get_cabac(&s->c, s->header_state);
+ s->spatial_scalability= get_rac(&s->c, s->header_state);
+// s->rate_scalability= get_rac(&s->c, s->header_state);
for(plane_index=0; plane_index<3; plane_index++){
for(level=0; level<s->spatial_decomposition_count; level++){
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
SnowContext *s = avctx->priv_data;
- CABACContext * const c= &s->c;
+ RangeCoder * const c= &s->c;
AVFrame *pict = data;
const int width= s->avctx->width;
const int height= s->avctx->height;
int level, orientation, plane_index;
- ff_init_cabac_encoder(c, buf, buf_size);
- ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
+ ff_init_range_encoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
s->input_picture = *pict;
if( plane_index==0
&& pict->pict_type == P_TYPE
&& s->m.me.scene_change_score > s->avctx->scenechange_threshold){
- ff_init_cabac_encoder(c, buf, buf_size);
- ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
+ ff_init_range_encoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
pict->pict_type= FF_I_TYPE;
s->keyframe=1;
reset_contexts(s);
emms_c();
- return put_cabac_terminate(c, 1);
+ return ff_rac_terminate(c);
}
static void common_end(SnowContext *s){
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
SnowContext *s = avctx->priv_data;
- CABACContext * const c= &s->c;
+ RangeCoder * const c= &s->c;
int bytes_read;
AVFrame *picture = data;
int level, orientation, plane_index;
if (buf_size == 0)
return 0;
- ff_init_cabac_decoder(c, buf, buf_size);
- ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
+ ff_init_range_decoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
s->current_picture.pict_type= FF_I_TYPE; //FIXME I vs. P
decode_header(s);
*data_size = sizeof(AVFrame);
- bytes_read= get_cabac_terminate(c);
- if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n");
+ bytes_read= c->bytestream - c->bytestream_start;
+ if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
return bytes_read;
}
printf("testing AC coder\n");
memset(s.header_state, 0, sizeof(s.header_state));
- ff_init_cabac_encoder(&s.c, buffer[0], 256*256);
+ ff_init_range_encoder(&s.c, buffer[0], 256*256);
ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
for(i=-256; i<256; i++){
put_symbol(&s.c, s.header_state, i*i*i/3*ABS(i), 1);
STOP_TIMER("put_symbol")
}
- put_cabac_terminate(&s.c, 1);
+ ff_rac_terminate(&s.c);
memset(s.header_state, 0, sizeof(s.header_state));
- ff_init_cabac_decoder(&s.c, buffer[0], 256*256);
+ ff_init_range_decoder(&s.c, buffer[0], 256*256);
ff_init_cabac_states(&s.c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);
for(i=-256; i<256; i++){