📄 snow.c
字号:
/*if(x > 1){ if(orientation==1) ll= src[y + (x-2)*stride]; else ll= src[x - 2 + y*stride]; }*/ } if(parent){ int px= x>>1; int py= y>>1; if(px<b->parent->width && py<b->parent->height) p= parent[px + py*2*stride]; } if(!(/*ll|*/l|lt|t|rt|p)){ if(v){ runs[run_index++]= run; run=0; }else{ run++; } } } } max_index= run_index; runs[run_index++]= run; run_index=0; run= runs[run_index++]; put_symbol2(&s->c, b->state[30], max_index, 0); if(run_index <= max_index) put_symbol2(&s->c, b->state[1], run, 3); for(y=0; y<h; y++){ if(s->c.bytestream_end - s->c.bytestream < w*40){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } for(x=0; x<w; x++){ int v, p=0; int /*ll=0, */l=0, lt=0, t=0, rt=0; v= src[x + y*stride]; if(y){ t= src[x + (y-1)*stride]; if(x){ lt= src[x - 1 + (y-1)*stride]; } if(x + 1 < w){ rt= src[x + 1 + (y-1)*stride]; } } if(x){ l= src[x - 1 + y*stride]; /*if(x > 1){ if(orientation==1) ll= src[y + (x-2)*stride]; else ll= src[x - 2 + y*stride]; }*/ } if(parent){ int px= x>>1; int py= y>>1; if(px<b->parent->width && py<b->parent->height) p= parent[px + py*2*stride]; } if(/*ll|*/l|lt|t|rt|p){ int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); put_rac(&s->c, &b->state[0][context], !!v); }else{ if(!run){ run= runs[run_index++]; if(run_index <= max_index) put_symbol2(&s->c, b->state[1], run, 3); assert(v); }else{ run--; assert(!v); } } if(v){ int context= av_log2(/*FFABS(ll) + */3*FFABS(l) + FFABS(lt) + 2*FFABS(t) + FFABS(rt) + FFABS(p)); int l2= 2*FFABS(l) + (l<0); int t2= 2*FFABS(t) + (t<0); put_symbol2(&s->c, b->state[context + 2], FFABS(v)-1, context-4); put_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l2&0xFF] + 3*quant3bA[t2&0xFF]], v<0); } } }#ifdef __CW32__ av_free(runs);#endif } return 0;}static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){// encode_subband_qtree(s, b, src, parent, stride, orientation);// encode_subband_z0run(s, b, src, parent, stride, orientation); return encode_subband_c0run(s, b, src, parent, stride, orientation);// encode_subband_dzr(s, b, src, parent, stride, orientation);}static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){ const int w= b->width; const int h= b->height; int x,y; if(1){ int run, runs; x_and_coeff *xc= b->x_coeff; x_and_coeff *prev_xc= NULL; x_and_coeff *prev2_xc= xc; x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL; x_and_coeff *prev_parent_xc= parent_xc; runs= get_symbol2(&s->c, b->state[30], 0); if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); else run= INT_MAX; for(y=0; y<h; y++){ int v=0; int lt=0, t=0, rt=0; if(y && prev_xc->x == 0){ rt= prev_xc->coeff; } for(x=0; x<w; x++){ int p=0; const int l= v; lt= t; t= rt; if(y){ if(prev_xc->x <= x) prev_xc++; if(prev_xc->x == x + 1) rt= prev_xc->coeff; else rt=0; } if(parent_xc){ if(x>>1 > parent_xc->x){ parent_xc++; } if(x>>1 == parent_xc->x){ p= parent_xc->coeff; } } if(/*ll|*/l|lt|t|rt|p){ int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1)); v=get_rac(&s->c, &b->state[0][context]); if(v){ v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + quant3bA[l&0xFF] + 3*quant3bA[t&0xFF]]); xc->x=x; (xc++)->coeff= v; } }else{ if(!run){ if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3); else run= INT_MAX; v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]); xc->x=x; (xc++)->coeff= v; }else{ int max_run; run--; v=0; if(y) max_run= FFMIN(run, prev_xc->x - x - 2); else max_run= FFMIN(run, w-x-1); if(parent_xc) max_run= FFMIN(max_run, 2*parent_xc->x - x - 1); x+= max_run; run-= max_run; } } } (xc++)->x= w+1; //end marker prev_xc= prev2_xc; prev2_xc= xc; if(parent_xc){ if(y&1){ while(parent_xc->x != parent->width+1) parent_xc++; parent_xc++; prev_parent_xc= parent_xc; }else{ parent_xc= prev_parent_xc; } } } (xc++)->x= w+1; //end marker }}static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){ const int w= b->width; int y; const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16); int qmul= qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT); int qadd= (s->qbias*qmul)>>QBIAS_SHIFT; int new_index = 0; if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){ qadd= 0; qmul= 1<<QEXPSHIFT; } /* If we are on the second or later slice, restore our index. */ if (start_y != 0) new_index = save_state[0]; for(y=start_y; y<h; y++){ int x = 0; int v; IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset; memset(line, 0, b->width*sizeof(IDWTELEM)); v = b->x_coeff[new_index].coeff; x = b->x_coeff[new_index++].x; while(x < w){ register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT; register int u= -(v&1); line[x] = (t^u) - u; v = b->x_coeff[new_index].coeff; x = b->x_coeff[new_index++].x; } } /* Save our variables for the next slice. */ save_state[0] = new_index; return;}static void reset_contexts(SnowContext *s){ //FIXME better initial contexts int plane_index, level, orientation; for(plane_index=0; plane_index<3; plane_index++){ for(level=0; level<MAX_DECOMPOSITIONS; level++){ for(orientation=level ? 1:0; orientation<4; orientation++){ memset(s->plane[plane_index].band[level][orientation].state, MID_STATE, sizeof(s->plane[plane_index].band[level][orientation].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){ int w= -((-s->avctx->width )>>LOG2_MB_SIZE); int h= -((-s->avctx->height)>>LOG2_MB_SIZE); s->b_width = w; s->b_height= h; s->block= av_mallocz(w * h * sizeof(BlockNode) << (s->block_max_depth*2)); return 0;}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->bytestream= bytestream; d->bytestream_start= bytestream_start;}//near copy & paste from dsputil, FIXMEstatic int pix_sum(uint8_t * pix, int line_size, int w){ int s, i, j; s = 0; for (i = 0; i < w; i++) { for (j = 0; j < w; j++) { s += pix[0]; pix ++; } pix += line_size - w; } return s;}//near copy & paste from dsputil, FIXMEstatic int pix_norm1(uint8_t * pix, int line_size, int w){ int s, i, j; uint32_t *sq = ff_squareTbl + 256; s = 0; for (i = 0; i < w; i++) { for (j = 0; j < w; j ++) { s += sq[pix[0]]; pix ++; } pix += line_size - w; } return s;}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){ const int w= s->b_width << s->block_max_depth; const int rem_depth= s->block_max_depth - level; const int index= (x + y*w) << rem_depth; const int block_w= 1<<rem_depth; BlockNode block; int i,j; block.color[0]= l; block.color[1]= cb; block.color[2]= cr; block.mx= mx; block.my= my; block.ref= ref; block.type= type; block.level= level; for(j=0; j<block_w; j++){ for(i=0; i<block_w; i++){ s->block[index + i + j*w]= block; } }}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){#ifdef __CW32__ int offset[3];#else const int offset[3]= { y*c-> stride + x, ((y*c->uvstride + x)>>1), ((y*c->uvstride + x)>>1), };#endif int i;#ifdef __CW32__ offset[0] = y*c-> stride + x; offset[1] = ((y*c->uvstride + x)>>1); offset[2] = ((y*c->uvstride + x)>>1);#endif for(i=0; i<3; i++){ c->src[0][i]= src [i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -