diff --git a/libavcodec/snow.c b/libavcodec/snow.c index ae6608bf31..9e92eecab0 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -439,6 +439,7 @@ typedef struct SnowContext{ int always_reset; int version; int spatial_decomposition_type; + int last_spatial_decomposition_type; int temporal_decomposition_type; int spatial_decomposition_count; int temporal_decomposition_count; @@ -452,15 +453,19 @@ typedef struct SnowContext{ int chroma_v_shift; int spatial_scalability; int qlog; + int last_qlog; int lambda; int lambda2; int pass1_rc; int mv_scale; + int last_mv_scale; int qbias; + int last_qbias; #define QBIAS_SHIFT 3 int b_width; int b_height; int block_max_depth; + int last_block_max_depth; Plane plane[MAX_PLANES]; BlockNode *block; #define ME_CACHE_SIZE 1024 @@ -1849,7 +1854,7 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli return; } -static void reset_contexts(SnowContext *s){ +static void reset_contexts(SnowContext *s){ //FIXME better initial contexts int plane_index, level, orientation; for(plane_index=0; plane_index<3; plane_index++){ @@ -3603,8 +3608,14 @@ static void encode_header(SnowContext *s){ memset(kstate, MID_STATE, sizeof(kstate)); put_rac(&s->c, kstate, s->keyframe); - if(s->keyframe || s->always_reset) + if(s->keyframe || s->always_reset){ reset_contexts(s); + s->last_spatial_decomposition_type= + s->last_qlog= + s->last_qbias= + s->last_mv_scale= + s->last_block_max_depth= 0; + } if(s->keyframe){ put_symbol(&s->c, s->header_state, s->version, 0); put_rac(&s->c, s->header_state, s->always_reset); @@ -3627,11 +3638,17 @@ static void encode_header(SnowContext *s){ } } } - put_symbol(&s->c, s->header_state, s->spatial_decomposition_type, 0); - put_symbol(&s->c, s->header_state, s->qlog, 1); - put_symbol(&s->c, s->header_state, s->mv_scale, 0); - put_symbol(&s->c, s->header_state, s->qbias, 1); - put_symbol(&s->c, s->header_state, s->block_max_depth, 0); + put_symbol(&s->c, s->header_state, s->spatial_decomposition_type - s->last_spatial_decomposition_type, 1); + put_symbol(&s->c, s->header_state, s->qlog - s->last_qlog , 1); + put_symbol(&s->c, s->header_state, s->mv_scale - s->last_mv_scale, 1); + put_symbol(&s->c, s->header_state, s->qbias - s->last_qbias , 1); + put_symbol(&s->c, s->header_state, s->block_max_depth - s->last_block_max_depth, 1); + + s->last_spatial_decomposition_type= s->spatial_decomposition_type; + s->last_qlog = s->qlog; + s->last_qbias = s->qbias; + s->last_mv_scale = s->mv_scale; + s->last_block_max_depth = s->block_max_depth; } static int decode_header(SnowContext *s){ @@ -3641,8 +3658,14 @@ static int decode_header(SnowContext *s){ memset(kstate, MID_STATE, sizeof(kstate)); s->keyframe= get_rac(&s->c, kstate); - if(s->keyframe || s->always_reset) + if(s->keyframe || s->always_reset){ reset_contexts(s); + s->spatial_decomposition_type= + s->qlog= + s->qbias= + s->mv_scale= + s->block_max_depth= 0; + } if(s->keyframe){ s->version= get_symbol(&s->c, s->header_state, 0); if(s->version>0){ @@ -3673,16 +3696,16 @@ static int decode_header(SnowContext *s){ } } - s->spatial_decomposition_type= get_symbol(&s->c, s->header_state, 0); + s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1); if(s->spatial_decomposition_type > 2){ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type); return -1; } - s->qlog= get_symbol(&s->c, s->header_state, 1); - s->mv_scale= get_symbol(&s->c, s->header_state, 0); - s->qbias= get_symbol(&s->c, s->header_state, 1); - s->block_max_depth= get_symbol(&s->c, s->header_state, 0); + s->qlog += get_symbol(&s->c, s->header_state, 1); + s->mv_scale += get_symbol(&s->c, s->header_state, 1); + s->qbias += get_symbol(&s->c, s->header_state, 1); + s->block_max_depth+= get_symbol(&s->c, s->header_state, 1); if(s->block_max_depth > 1 || s->block_max_depth < 0){ av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth); s->block_max_depth= 0; @@ -4170,7 +4193,6 @@ redo_frame: pict->pict_type= FF_I_TYPE; s->keyframe=1; s->current_picture.key_frame=1; - reset_contexts(s); goto redo_frame; } diff --git a/tests/ffmpeg.regression.ref b/tests/ffmpeg.regression.ref index fb5dee736c..d68c1345e7 100644 --- a/tests/ffmpeg.regression.ref +++ b/tests/ffmpeg.regression.ref @@ -141,12 +141,12 @@ f8f51fa737add17f7fecaefa118b57ed *./data/a-ffv1.avi 2654678 ./data/a-ffv1.avi 799d3db687f6cdd7a837ec156efc171f *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 -b12ff53580cd8a9ce92ab7a0649e99f9 *./data/a-snow.avi -155948 ./data/a-snow.avi +ed13d6d458ada3973046d469dd4314b5 *./data/a-snow.avi +155842 ./data/a-snow.avi b3feb1bf17bb4e720da1f1e8b4da4c03 *./data/out.yuv stddev: 23.19 PSNR:20.81 bytes:7602176 -265c4e0c45b2313817fa4d86dccbe6ba *./data/a-snow53.avi -3519574 ./data/a-snow53.avi +ba999e86070aa971376e7f317a022c37 *./data/a-snow53.avi +3519486 ./data/a-snow53.avi 799d3db687f6cdd7a837ec156efc171f *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 2fcbcdc63816e1321bf4b6b5380338d2 *./data/a-dv.dv diff --git a/tests/rotozoom.regression.ref b/tests/rotozoom.regression.ref index 58c3fed698..c65bdab944 100644 --- a/tests/rotozoom.regression.ref +++ b/tests/rotozoom.regression.ref @@ -141,12 +141,12 @@ d72b0960e162d4998b9acbabb07e99ab *./data/a-ffv1.avi 3525804 ./data/a-ffv1.avi dde5895817ad9d219f79a52d0bdfb001 *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 -4b306a67e21771eba4c61b1cf0f56141 *./data/a-snow.avi -68526 ./data/a-snow.avi +2158b42147fd7a32fc3099148df0700d *./data/a-snow.avi +68432 ./data/a-snow.avi d2914543504345fad6e5593f66f072bc *./data/out.yuv stddev: 10.93 PSNR:27.34 bytes:7602176 -892221ef4c1debf694a481a5e23e1136 *./data/a-snow53.avi -2722066 ./data/a-snow53.avi +3d0da6aeec9b80c6ee0ff4b747bdd0f0 *./data/a-snow53.avi +2721980 ./data/a-snow53.avi dde5895817ad9d219f79a52d0bdfb001 *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 af9f474238c9c68cb32e389659ee25ab *./data/a-dv.dv