diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2004-10-30 02:16:27 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2004-10-30 02:16:27 +0000 |
commit | 28869757739254cd7c289a2f4c3c72a0790188d3 (patch) | |
tree | eded5b5640f2c3ae54b788d9c0a371cd54b96637 | |
parent | 672a19aac24f94d4a55394099596a84add67c39b (diff) | |
download | ffmpeg-28869757739254cd7c289a2f4c3c72a0790188d3.tar.gz |
CABAC -> range coder
Originally committed as revision 3655 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/snow.c | 191 |
1 files changed, 104 insertions, 87 deletions
diff --git a/libavcodec/snow.c b/libavcodec/snow.c index eaeb98cfc3..eeb84a0fcf 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -19,7 +19,9 @@ #include "avcodec.h" #include "common.h" #include "dsputil.h" -#include "cabac.h" + +#include "rangecoder.h" +#define MID_STATE 128 #include "mpegvideo.h" @@ -392,7 +394,7 @@ typedef struct SnowContext{ // 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; @@ -443,7 +445,7 @@ static inline int mirror(int v, int m){ 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){ @@ -451,82 +453,82 @@ static inline void put_symbol(CABACContext *c, uint8_t *state, int v, int is_sig 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; @@ -534,33 +536,33 @@ static inline void put_symbol2(CABACContext *c, uint8_t *state, int v, int log2) 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; @@ -1371,7 +1373,7 @@ static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTEL 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++]; @@ -1387,7 +1389,7 @@ static void encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTEL 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); } } } @@ -1460,7 +1462,7 @@ static inline void decode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTE 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); @@ -1482,7 +1484,7 @@ static inline void decode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTE 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{ @@ -1522,12 +1524,12 @@ static void reset_contexts(SnowContext *s){ 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){ @@ -1541,10 +1543,12 @@ 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 @@ -1630,8 +1634,9 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ 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; @@ -1761,16 +1766,20 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ // 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); @@ -1786,16 +1795,20 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ // 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); @@ -1813,7 +1826,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ } 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); @@ -1825,18 +1838,18 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ } 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; @@ -1866,7 +1879,7 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ 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]; @@ -1876,7 +1889,7 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ 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); @@ -2371,22 +2384,24 @@ static void correlate(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int 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++){ @@ -2406,9 +2421,11 @@ static void encode_header(SnowContext *s){ 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){ @@ -2417,15 +2434,15 @@ static int decode_header(SnowContext *s){ 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++){ @@ -2666,14 +2683,14 @@ static int frame_start(SnowContext *s){ 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; @@ -2759,8 +2776,8 @@ redo_frame: 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); @@ -2831,7 +2848,7 @@ STOP_TIMER("pred-conv")} emms_c(); - return put_cabac_terminate(c, 1); + return ff_rac_terminate(c); } static void common_end(SnowContext *s){ @@ -2877,7 +2894,7 @@ static int decode_init(AVCodecContext *avctx) 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; @@ -2887,8 +2904,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 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); @@ -2956,8 +2973,8 @@ else *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; } @@ -3032,7 +3049,7 @@ int main(){ 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++){ @@ -3040,10 +3057,10 @@ START_TIMER 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++){ |