annotate ffmpeg/libavcodec/snow.h @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
yading@10 3 * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net>
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 #ifndef AVCODEC_SNOW_H
yading@10 23 #define AVCODEC_SNOW_H
yading@10 24
yading@10 25 #include "dsputil.h"
yading@10 26 #include "hpeldsp.h"
yading@10 27 #include "snow_dwt.h"
yading@10 28
yading@10 29 #include "rangecoder.h"
yading@10 30 #include "mathops.h"
yading@10 31 #include "mpegvideo.h"
yading@10 32 #include "h264qpel.h"
yading@10 33
yading@10 34 #define MID_STATE 128
yading@10 35
yading@10 36 #define MAX_PLANES 4
yading@10 37 #define QSHIFT 5
yading@10 38 #define QROOT (1<<QSHIFT)
yading@10 39 #define LOSSLESS_QLOG -128
yading@10 40 #define FRAC_BITS 4
yading@10 41 #define MAX_REF_FRAMES 8
yading@10 42
yading@10 43 #define LOG2_OBMC_MAX 8
yading@10 44 #define OBMC_MAX (1<<(LOG2_OBMC_MAX))
yading@10 45 typedef struct BlockNode{
yading@10 46 int16_t mx;
yading@10 47 int16_t my;
yading@10 48 uint8_t ref;
yading@10 49 uint8_t color[3];
yading@10 50 uint8_t type;
yading@10 51 //#define TYPE_SPLIT 1
yading@10 52 #define BLOCK_INTRA 1
yading@10 53 #define BLOCK_OPT 2
yading@10 54 //#define TYPE_NOCOLOR 4
yading@10 55 uint8_t level; //FIXME merge into type?
yading@10 56 }BlockNode;
yading@10 57
yading@10 58 static const BlockNode null_block= { //FIXME add border maybe
yading@10 59 .color= {128,128,128},
yading@10 60 .mx= 0,
yading@10 61 .my= 0,
yading@10 62 .ref= 0,
yading@10 63 .type= 0,
yading@10 64 .level= 0,
yading@10 65 };
yading@10 66
yading@10 67 #define LOG2_MB_SIZE 4
yading@10 68 #define MB_SIZE (1<<LOG2_MB_SIZE)
yading@10 69 #define ENCODER_EXTRA_BITS 4
yading@10 70 #define HTAPS_MAX 8
yading@10 71
yading@10 72 typedef struct x_and_coeff{
yading@10 73 int16_t x;
yading@10 74 uint16_t coeff;
yading@10 75 } x_and_coeff;
yading@10 76
yading@10 77 typedef struct SubBand{
yading@10 78 int level;
yading@10 79 int stride;
yading@10 80 int width;
yading@10 81 int height;
yading@10 82 int qlog; ///< log(qscale)/log[2^(1/6)]
yading@10 83 DWTELEM *buf;
yading@10 84 IDWTELEM *ibuf;
yading@10 85 int buf_x_offset;
yading@10 86 int buf_y_offset;
yading@10 87 int stride_line; ///< Stride measured in lines, not pixels.
yading@10 88 x_and_coeff * x_coeff;
yading@10 89 struct SubBand *parent;
yading@10 90 uint8_t state[/*7*2*/ 7 + 512][32];
yading@10 91 }SubBand;
yading@10 92
yading@10 93 typedef struct Plane{
yading@10 94 int width;
yading@10 95 int height;
yading@10 96 SubBand band[MAX_DECOMPOSITIONS][4];
yading@10 97
yading@10 98 int htaps;
yading@10 99 int8_t hcoeff[HTAPS_MAX/2];
yading@10 100 int diag_mc;
yading@10 101 int fast_mc;
yading@10 102
yading@10 103 int last_htaps;
yading@10 104 int8_t last_hcoeff[HTAPS_MAX/2];
yading@10 105 int last_diag_mc;
yading@10 106 }Plane;
yading@10 107
yading@10 108 typedef struct SnowContext{
yading@10 109 AVClass *class;
yading@10 110 AVCodecContext *avctx;
yading@10 111 RangeCoder c;
yading@10 112 DSPContext dsp;
yading@10 113 HpelDSPContext hdsp;
yading@10 114 VideoDSPContext vdsp;
yading@10 115 H264QpelContext h264qpel;
yading@10 116 SnowDWTContext dwt;
yading@10 117 AVFrame new_picture;
yading@10 118 AVFrame input_picture; ///< new_picture with the internal linesizes
yading@10 119 AVFrame current_picture;
yading@10 120 AVFrame last_picture[MAX_REF_FRAMES];
yading@10 121 uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
yading@10 122 AVFrame mconly_picture;
yading@10 123 // uint8_t q_context[16];
yading@10 124 uint8_t header_state[32];
yading@10 125 uint8_t block_state[128 + 32*128];
yading@10 126 int keyframe;
yading@10 127 int always_reset;
yading@10 128 int version;
yading@10 129 int spatial_decomposition_type;
yading@10 130 int last_spatial_decomposition_type;
yading@10 131 int temporal_decomposition_type;
yading@10 132 int spatial_decomposition_count;
yading@10 133 int last_spatial_decomposition_count;
yading@10 134 int temporal_decomposition_count;
yading@10 135 int max_ref_frames;
yading@10 136 int ref_frames;
yading@10 137 int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
yading@10 138 uint32_t *ref_scores[MAX_REF_FRAMES];
yading@10 139 DWTELEM *spatial_dwt_buffer;
yading@10 140 DWTELEM *temp_dwt_buffer;
yading@10 141 IDWTELEM *spatial_idwt_buffer;
yading@10 142 IDWTELEM *temp_idwt_buffer;
yading@10 143 int *run_buffer;
yading@10 144 int colorspace_type;
yading@10 145 int chroma_h_shift;
yading@10 146 int chroma_v_shift;
yading@10 147 int spatial_scalability;
yading@10 148 int qlog;
yading@10 149 int last_qlog;
yading@10 150 int lambda;
yading@10 151 int lambda2;
yading@10 152 int pass1_rc;
yading@10 153 int mv_scale;
yading@10 154 int last_mv_scale;
yading@10 155 int qbias;
yading@10 156 int last_qbias;
yading@10 157 #define QBIAS_SHIFT 3
yading@10 158 int b_width;
yading@10 159 int b_height;
yading@10 160 int block_max_depth;
yading@10 161 int last_block_max_depth;
yading@10 162 Plane plane[MAX_PLANES];
yading@10 163 BlockNode *block;
yading@10 164 #define ME_CACHE_SIZE 1024
yading@10 165 unsigned me_cache[ME_CACHE_SIZE];
yading@10 166 unsigned me_cache_generation;
yading@10 167 slice_buffer sb;
yading@10 168 int memc_only;
yading@10 169 int no_bitstream;
yading@10 170
yading@10 171 MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
yading@10 172
yading@10 173 uint8_t *scratchbuf;
yading@10 174 uint8_t *emu_edge_buffer;
yading@10 175 }SnowContext;
yading@10 176
yading@10 177 /* Tables */
yading@10 178 extern const uint8_t * const ff_obmc_tab[4];
yading@10 179 extern uint8_t ff_qexp[QROOT];
yading@10 180 extern int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
yading@10 181
yading@10 182 /* C bits used by mmx/sse2/altivec */
yading@10 183
yading@10 184 static av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){
yading@10 185 (*i) = (width) - 2;
yading@10 186
yading@10 187 if (width & 1){
yading@10 188 low[(*i)+1] = low[((*i)+1)>>1];
yading@10 189 (*i)--;
yading@10 190 }
yading@10 191 }
yading@10 192
yading@10 193 static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){
yading@10 194 for (; (*i)>=0; (*i)-=2){
yading@10 195 low[(*i)+1] = high[(*i)>>1];
yading@10 196 low[*i] = low[(*i)>>1];
yading@10 197 }
yading@10 198 }
yading@10 199
yading@10 200 static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){
yading@10 201 for(; i<w; i++){
yading@10 202 dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift);
yading@10 203 }
yading@10 204
yading@10 205 if((width^lift_high)&1){
yading@10 206 dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift);
yading@10 207 }
yading@10 208 }
yading@10 209
yading@10 210 static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){
yading@10 211 for(; i<w; i++){
yading@10 212 dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS);
yading@10 213 }
yading@10 214
yading@10 215 if(width&1){
yading@10 216 dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS);
yading@10 217 }
yading@10 218 }
yading@10 219
yading@10 220 /* common code */
yading@10 221
yading@10 222 int ff_snow_common_init(AVCodecContext *avctx);
yading@10 223 int ff_snow_common_init_after_header(AVCodecContext *avctx);
yading@10 224 void ff_snow_common_end(SnowContext *s);
yading@10 225 void ff_snow_release_buffer(AVCodecContext *avctx);
yading@10 226 void ff_snow_reset_contexts(SnowContext *s);
yading@10 227 int ff_snow_alloc_blocks(SnowContext *s);
yading@10 228 int ff_snow_frame_start(SnowContext *s);
yading@10 229 void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
yading@10 230 int sx, int sy, int b_w, int b_h, BlockNode *block,
yading@10 231 int plane_index, int w, int h);
yading@10 232 /* common inline functions */
yading@10 233 //XXX doublecheck all of them should stay inlined
yading@10 234
yading@10 235 static inline void snow_set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
yading@10 236 const int w= s->b_width << s->block_max_depth;
yading@10 237 const int rem_depth= s->block_max_depth - level;
yading@10 238 const int index= (x + y*w) << rem_depth;
yading@10 239 const int block_w= 1<<rem_depth;
yading@10 240 BlockNode block;
yading@10 241 int i,j;
yading@10 242
yading@10 243 block.color[0]= l;
yading@10 244 block.color[1]= cb;
yading@10 245 block.color[2]= cr;
yading@10 246 block.mx= mx;
yading@10 247 block.my= my;
yading@10 248 block.ref= ref;
yading@10 249 block.type= type;
yading@10 250 block.level= level;
yading@10 251
yading@10 252 for(j=0; j<block_w; j++){
yading@10 253 for(i=0; i<block_w; i++){
yading@10 254 s->block[index + i + j*w]= block;
yading@10 255 }
yading@10 256 }
yading@10 257 }
yading@10 258
yading@10 259 static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
yading@10 260 const BlockNode *left, const BlockNode *top, const BlockNode *tr){
yading@10 261 if(s->ref_frames == 1){
yading@10 262 *mx = mid_pred(left->mx, top->mx, tr->mx);
yading@10 263 *my = mid_pred(left->my, top->my, tr->my);
yading@10 264 }else{
yading@10 265 const int *scale = ff_scale_mv_ref[ref];
yading@10 266 *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
yading@10 267 (top ->mx * scale[top ->ref] + 128) >>8,
yading@10 268 (tr ->mx * scale[tr ->ref] + 128) >>8);
yading@10 269 *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
yading@10 270 (top ->my * scale[top ->ref] + 128) >>8,
yading@10 271 (tr ->my * scale[tr ->ref] + 128) >>8);
yading@10 272 }
yading@10 273 }
yading@10 274
yading@10 275 static av_always_inline int same_block(BlockNode *a, BlockNode *b){
yading@10 276 if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
yading@10 277 return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
yading@10 278 }else{
yading@10 279 return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
yading@10 280 }
yading@10 281 }
yading@10 282
yading@10 283 //FIXME name cleanup (b_w, block_w, b_width stuff)
yading@10 284 //XXX should we really inline it?
yading@10 285 static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
yading@10 286 const int b_width = s->b_width << s->block_max_depth;
yading@10 287 const int b_height= s->b_height << s->block_max_depth;
yading@10 288 const int b_stride= b_width;
yading@10 289 BlockNode *lt= &s->block[b_x + b_y*b_stride];
yading@10 290 BlockNode *rt= lt+1;
yading@10 291 BlockNode *lb= lt+b_stride;
yading@10 292 BlockNode *rb= lb+1;
yading@10 293 uint8_t *block[4];
yading@10 294 int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
yading@10 295 uint8_t *tmp = s->scratchbuf;
yading@10 296 uint8_t *ptmp;
yading@10 297 int x,y;
yading@10 298
yading@10 299 if(b_x<0){
yading@10 300 lt= rt;
yading@10 301 lb= rb;
yading@10 302 }else if(b_x + 1 >= b_width){
yading@10 303 rt= lt;
yading@10 304 rb= lb;
yading@10 305 }
yading@10 306 if(b_y<0){
yading@10 307 lt= lb;
yading@10 308 rt= rb;
yading@10 309 }else if(b_y + 1 >= b_height){
yading@10 310 lb= lt;
yading@10 311 rb= rt;
yading@10 312 }
yading@10 313
yading@10 314 if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
yading@10 315 obmc -= src_x;
yading@10 316 b_w += src_x;
yading@10 317 if(!sliced && !offset_dst)
yading@10 318 dst -= src_x;
yading@10 319 src_x=0;
yading@10 320 }else if(src_x + b_w > w){
yading@10 321 b_w = w - src_x;
yading@10 322 }
yading@10 323 if(src_y<0){
yading@10 324 obmc -= src_y*obmc_stride;
yading@10 325 b_h += src_y;
yading@10 326 if(!sliced && !offset_dst)
yading@10 327 dst -= src_y*dst_stride;
yading@10 328 src_y=0;
yading@10 329 }else if(src_y + b_h> h){
yading@10 330 b_h = h - src_y;
yading@10 331 }
yading@10 332
yading@10 333 if(b_w<=0 || b_h<=0) return;
yading@10 334
yading@10 335 av_assert2(src_stride > 2*MB_SIZE + 5);
yading@10 336
yading@10 337 if(!sliced && offset_dst)
yading@10 338 dst += src_x + src_y*dst_stride;
yading@10 339 dst8+= src_x + src_y*src_stride;
yading@10 340 // src += src_x + src_y*src_stride;
yading@10 341
yading@10 342 ptmp= tmp + 3*tmp_step;
yading@10 343 block[0]= ptmp;
yading@10 344 ptmp+=tmp_step;
yading@10 345 ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
yading@10 346
yading@10 347 if(same_block(lt, rt)){
yading@10 348 block[1]= block[0];
yading@10 349 }else{
yading@10 350 block[1]= ptmp;
yading@10 351 ptmp+=tmp_step;
yading@10 352 ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
yading@10 353 }
yading@10 354
yading@10 355 if(same_block(lt, lb)){
yading@10 356 block[2]= block[0];
yading@10 357 }else if(same_block(rt, lb)){
yading@10 358 block[2]= block[1];
yading@10 359 }else{
yading@10 360 block[2]= ptmp;
yading@10 361 ptmp+=tmp_step;
yading@10 362 ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
yading@10 363 }
yading@10 364
yading@10 365 if(same_block(lt, rb) ){
yading@10 366 block[3]= block[0];
yading@10 367 }else if(same_block(rt, rb)){
yading@10 368 block[3]= block[1];
yading@10 369 }else if(same_block(lb, rb)){
yading@10 370 block[3]= block[2];
yading@10 371 }else{
yading@10 372 block[3]= ptmp;
yading@10 373 ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
yading@10 374 }
yading@10 375 if(sliced){
yading@10 376 s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
yading@10 377 }else{
yading@10 378 for(y=0; y<b_h; y++){
yading@10 379 //FIXME ugly misuse of obmc_stride
yading@10 380 const uint8_t *obmc1= obmc + y*obmc_stride;
yading@10 381 const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
yading@10 382 const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
yading@10 383 const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
yading@10 384 for(x=0; x<b_w; x++){
yading@10 385 int v= obmc1[x] * block[3][x + y*src_stride]
yading@10 386 +obmc2[x] * block[2][x + y*src_stride]
yading@10 387 +obmc3[x] * block[1][x + y*src_stride]
yading@10 388 +obmc4[x] * block[0][x + y*src_stride];
yading@10 389
yading@10 390 v <<= 8 - LOG2_OBMC_MAX;
yading@10 391 if(FRAC_BITS != 8){
yading@10 392 v >>= 8 - FRAC_BITS;
yading@10 393 }
yading@10 394 if(add){
yading@10 395 v += dst[x + y*dst_stride];
yading@10 396 v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
yading@10 397 if(v&(~255)) v= ~(v>>31);
yading@10 398 dst8[x + y*src_stride] = v;
yading@10 399 }else{
yading@10 400 dst[x + y*dst_stride] -= v;
yading@10 401 }
yading@10 402 }
yading@10 403 }
yading@10 404 }
yading@10 405 }
yading@10 406
yading@10 407 static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
yading@10 408 Plane *p= &s->plane[plane_index];
yading@10 409 const int mb_w= s->b_width << s->block_max_depth;
yading@10 410 const int mb_h= s->b_height << s->block_max_depth;
yading@10 411 int x, y, mb_x;
yading@10 412 int block_size = MB_SIZE >> s->block_max_depth;
yading@10 413 int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
yading@10 414 int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
yading@10 415 const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
yading@10 416 const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
yading@10 417 int ref_stride= s->current_picture.linesize[plane_index];
yading@10 418 uint8_t *dst8= s->current_picture.data[plane_index];
yading@10 419 int w= p->width;
yading@10 420 int h= p->height;
yading@10 421 av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares
yading@10 422 if(s->keyframe || (s->avctx->debug&512)){
yading@10 423 if(mb_y==mb_h)
yading@10 424 return;
yading@10 425
yading@10 426 if(add){
yading@10 427 for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
yading@10 428 for(x=0; x<w; x++){
yading@10 429 int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
yading@10 430 v >>= FRAC_BITS;
yading@10 431 if(v&(~255)) v= ~(v>>31);
yading@10 432 dst8[x + y*ref_stride]= v;
yading@10 433 }
yading@10 434 }
yading@10 435 }else{
yading@10 436 for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
yading@10 437 for(x=0; x<w; x++){
yading@10 438 buf[x + y*w]-= 128<<FRAC_BITS;
yading@10 439 }
yading@10 440 }
yading@10 441 }
yading@10 442
yading@10 443 return;
yading@10 444 }
yading@10 445
yading@10 446 for(mb_x=0; mb_x<=mb_w; mb_x++){
yading@10 447 add_yblock(s, 0, NULL, buf, dst8, obmc,
yading@10 448 block_w*mb_x - block_w/2,
yading@10 449 block_h*mb_y - block_h/2,
yading@10 450 block_w, block_h,
yading@10 451 w, h,
yading@10 452 w, ref_stride, obmc_stride,
yading@10 453 mb_x - 1, mb_y - 1,
yading@10 454 add, 1, plane_index);
yading@10 455 }
yading@10 456 }
yading@10 457
yading@10 458 static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
yading@10 459 const int mb_h= s->b_height << s->block_max_depth;
yading@10 460 int mb_y;
yading@10 461 for(mb_y=0; mb_y<=mb_h; mb_y++)
yading@10 462 predict_slice(s, buf, plane_index, add, mb_y);
yading@10 463 }
yading@10 464
yading@10 465 static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
yading@10 466 const int w= s->b_width << s->block_max_depth;
yading@10 467 const int rem_depth= s->block_max_depth - level;
yading@10 468 const int index= (x + y*w) << rem_depth;
yading@10 469 const int block_w= 1<<rem_depth;
yading@10 470 const int block_h= 1<<rem_depth; //FIXME "w!=h"
yading@10 471 BlockNode block;
yading@10 472 int i,j;
yading@10 473
yading@10 474 block.color[0]= l;
yading@10 475 block.color[1]= cb;
yading@10 476 block.color[2]= cr;
yading@10 477 block.mx= mx;
yading@10 478 block.my= my;
yading@10 479 block.ref= ref;
yading@10 480 block.type= type;
yading@10 481 block.level= level;
yading@10 482
yading@10 483 for(j=0; j<block_h; j++){
yading@10 484 for(i=0; i<block_w; i++){
yading@10 485 s->block[index + i + j*w]= block;
yading@10 486 }
yading@10 487 }
yading@10 488 }
yading@10 489
yading@10 490 static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
yading@10 491 SnowContext *s = c->avctx->priv_data;
yading@10 492 const int offset[3]= {
yading@10 493 y*c-> stride + x,
yading@10 494 ((y*c->uvstride + x)>>s->chroma_h_shift),
yading@10 495 ((y*c->uvstride + x)>>s->chroma_h_shift),
yading@10 496 };
yading@10 497 int i;
yading@10 498 for(i=0; i<3; i++){
yading@10 499 c->src[0][i]= src [i];
yading@10 500 c->ref[0][i]= ref [i] + offset[i];
yading@10 501 }
yading@10 502 av_assert2(!ref_index);
yading@10 503 }
yading@10 504
yading@10 505
yading@10 506 /* bitstream functions */
yading@10 507
yading@10 508 extern const int8_t ff_quant3bA[256];
yading@10 509
yading@10 510 #define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
yading@10 511
yading@10 512 static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
yading@10 513 int i;
yading@10 514
yading@10 515 if(v){
yading@10 516 const int a= FFABS(v);
yading@10 517 const int e= av_log2(a);
yading@10 518 const int el= FFMIN(e, 10);
yading@10 519 put_rac(c, state+0, 0);
yading@10 520
yading@10 521 for(i=0; i<el; i++){
yading@10 522 put_rac(c, state+1+i, 1); //1..10
yading@10 523 }
yading@10 524 for(; i<e; i++){
yading@10 525 put_rac(c, state+1+9, 1); //1..10
yading@10 526 }
yading@10 527 put_rac(c, state+1+FFMIN(i,9), 0);
yading@10 528
yading@10 529 for(i=e-1; i>=el; i--){
yading@10 530 put_rac(c, state+22+9, (a>>i)&1); //22..31
yading@10 531 }
yading@10 532 for(; i>=0; i--){
yading@10 533 put_rac(c, state+22+i, (a>>i)&1); //22..31
yading@10 534 }
yading@10 535
yading@10 536 if(is_signed)
yading@10 537 put_rac(c, state+11 + el, v < 0); //11..21
yading@10 538 }else{
yading@10 539 put_rac(c, state+0, 1);
yading@10 540 }
yading@10 541 }
yading@10 542
yading@10 543 static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
yading@10 544 if(get_rac(c, state+0))
yading@10 545 return 0;
yading@10 546 else{
yading@10 547 int i, e, a;
yading@10 548 e= 0;
yading@10 549 while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
yading@10 550 e++;
yading@10 551 }
yading@10 552
yading@10 553 a= 1;
yading@10 554 for(i=e-1; i>=0; i--){
yading@10 555 a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
yading@10 556 }
yading@10 557
yading@10 558 e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
yading@10 559 return (a^e)-e;
yading@10 560 }
yading@10 561 }
yading@10 562
yading@10 563 static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
yading@10 564 int i;
yading@10 565 int r= log2>=0 ? 1<<log2 : 1;
yading@10 566
yading@10 567 av_assert2(v>=0);
yading@10 568 av_assert2(log2>=-4);
yading@10 569
yading@10 570 while(v >= r){
yading@10 571 put_rac(c, state+4+log2, 1);
yading@10 572 v -= r;
yading@10 573 log2++;
yading@10 574 if(log2>0) r+=r;
yading@10 575 }
yading@10 576 put_rac(c, state+4+log2, 0);
yading@10 577
yading@10 578 for(i=log2-1; i>=0; i--){
yading@10 579 put_rac(c, state+31-i, (v>>i)&1);
yading@10 580 }
yading@10 581 }
yading@10 582
yading@10 583 static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
yading@10 584 int i;
yading@10 585 int r= log2>=0 ? 1<<log2 : 1;
yading@10 586 int v=0;
yading@10 587
yading@10 588 av_assert2(log2>=-4);
yading@10 589
yading@10 590 while(log2<28 && get_rac(c, state+4+log2)){
yading@10 591 v+= r;
yading@10 592 log2++;
yading@10 593 if(log2>0) r+=r;
yading@10 594 }
yading@10 595
yading@10 596 for(i=log2-1; i>=0; i--){
yading@10 597 v+= get_rac(c, state+31-i)<<i;
yading@10 598 }
yading@10 599
yading@10 600 return v;
yading@10 601 }
yading@10 602
yading@10 603 static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
yading@10 604 const int w= b->width;
yading@10 605 const int h= b->height;
yading@10 606 int x,y;
yading@10 607
yading@10 608 int run, runs;
yading@10 609 x_and_coeff *xc= b->x_coeff;
yading@10 610 x_and_coeff *prev_xc= NULL;
yading@10 611 x_and_coeff *prev2_xc= xc;
yading@10 612 x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
yading@10 613 x_and_coeff *prev_parent_xc= parent_xc;
yading@10 614
yading@10 615 runs= get_symbol2(&s->c, b->state[30], 0);
yading@10 616 if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
yading@10 617 else run= INT_MAX;
yading@10 618
yading@10 619 for(y=0; y<h; y++){
yading@10 620 int v=0;
yading@10 621 int lt=0, t=0, rt=0;
yading@10 622
yading@10 623 if(y && prev_xc->x == 0){
yading@10 624 rt= prev_xc->coeff;
yading@10 625 }
yading@10 626 for(x=0; x<w; x++){
yading@10 627 int p=0;
yading@10 628 const int l= v;
yading@10 629
yading@10 630 lt= t; t= rt;
yading@10 631
yading@10 632 if(y){
yading@10 633 if(prev_xc->x <= x)
yading@10 634 prev_xc++;
yading@10 635 if(prev_xc->x == x + 1)
yading@10 636 rt= prev_xc->coeff;
yading@10 637 else
yading@10 638 rt=0;
yading@10 639 }
yading@10 640 if(parent_xc){
yading@10 641 if(x>>1 > parent_xc->x){
yading@10 642 parent_xc++;
yading@10 643 }
yading@10 644 if(x>>1 == parent_xc->x){
yading@10 645 p= parent_xc->coeff;
yading@10 646 }
yading@10 647 }
yading@10 648 if(/*ll|*/l|lt|t|rt|p){
yading@10 649 int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
yading@10 650
yading@10 651 v=get_rac(&s->c, &b->state[0][context]);
yading@10 652 if(v){
yading@10 653 v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
yading@10 654 v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]);
yading@10 655
yading@10 656 xc->x=x;
yading@10 657 (xc++)->coeff= v;
yading@10 658 }
yading@10 659 }else{
yading@10 660 if(!run){
yading@10 661 if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
yading@10 662 else run= INT_MAX;
yading@10 663 v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
yading@10 664 v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
yading@10 665
yading@10 666 xc->x=x;
yading@10 667 (xc++)->coeff= v;
yading@10 668 }else{
yading@10 669 int max_run;
yading@10 670 run--;
yading@10 671 v=0;
yading@10 672 av_assert2(run >= 0);
yading@10 673 if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
yading@10 674 else max_run= FFMIN(run, w-x-1);
yading@10 675 if(parent_xc)
yading@10 676 max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
yading@10 677 av_assert2(max_run >= 0 && max_run <= run);
yading@10 678
yading@10 679 x+= max_run;
yading@10 680 run-= max_run;
yading@10 681 }
yading@10 682 }
yading@10 683 }
yading@10 684 (xc++)->x= w+1; //end marker
yading@10 685 prev_xc= prev2_xc;
yading@10 686 prev2_xc= xc;
yading@10 687
yading@10 688 if(parent_xc){
yading@10 689 if(y&1){
yading@10 690 while(parent_xc->x != parent->width+1)
yading@10 691 parent_xc++;
yading@10 692 parent_xc++;
yading@10 693 prev_parent_xc= parent_xc;
yading@10 694 }else{
yading@10 695 parent_xc= prev_parent_xc;
yading@10 696 }
yading@10 697 }
yading@10 698 }
yading@10 699
yading@10 700 (xc++)->x= w+1; //end marker
yading@10 701 }
yading@10 702
yading@10 703 #endif /* AVCODEC_SNOW_H */