📄 snow.c
字号:
b2[i] += (W_BM*(b1[i] + b3[i])+W_BO)>>W_BS;
#else
b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS;
#endif
b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS;
}
}
static void spatial_compose97i_buffered_init(dwt_compose_t *cs, slice_buffer * sb, int height, int stride_line){
cs->b0 = slice_buffer_get_line(sb, mirror(-3-1, height-1) * stride_line);
cs->b1 = slice_buffer_get_line(sb, mirror(-3 , height-1) * stride_line);
cs->b2 = slice_buffer_get_line(sb, mirror(-3+1, height-1) * stride_line);
cs->b3 = slice_buffer_get_line(sb, mirror(-3+2, height-1) * stride_line);
cs->y = -3;
}
static void spatial_compose97i_init(dwt_compose_t *cs, DWTELEM *buffer, int height, int stride){
cs->b0 = buffer + mirror(-3-1, height-1)*stride;
cs->b1 = buffer + mirror(-3 , height-1)*stride;
cs->b2 = buffer + mirror(-3+1, height-1)*stride;
cs->b3 = buffer + mirror(-3+2, height-1)*stride;
cs->y = -3;
}
static void spatial_compose97i_dy_buffered(DSPContext *dsp, dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line){
int y = cs->y;
DWTELEM *b0= cs->b0;
DWTELEM *b1= cs->b1;
DWTELEM *b2= cs->b2;
DWTELEM *b3= cs->b3;
DWTELEM *b4= slice_buffer_get_line(sb, mirror(y + 3, height - 1) * stride_line);
DWTELEM *b5= slice_buffer_get_line(sb, mirror(y + 4, height - 1) * stride_line);
if(y>0 && y+4<height){
dsp->vertical_compose97i(b0, b1, b2, b3, b4, b5, width);
}else{
if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
}
if(y-1<(unsigned)height) dsp->horizontal_compose97i(b0, width);
if(y+0<(unsigned)height) dsp->horizontal_compose97i(b1, width);
cs->b0=b2;
cs->b1=b3;
cs->b2=b4;
cs->b3=b5;
cs->y += 2;
}
static void spatial_compose97i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){
int y = cs->y;
DWTELEM *b0= cs->b0;
DWTELEM *b1= cs->b1;
DWTELEM *b2= cs->b2;
DWTELEM *b3= cs->b3;
DWTELEM *b4= buffer + mirror(y+3, height-1)*stride;
DWTELEM *b5= buffer + mirror(y+4, height-1)*stride;
if(y+3<(unsigned)height) vertical_compose97iL1(b3, b4, b5, width);
if(y+2<(unsigned)height) vertical_compose97iH1(b2, b3, b4, width);
if(y+1<(unsigned)height) vertical_compose97iL0(b1, b2, b3, width);
if(y+0<(unsigned)height) vertical_compose97iH0(b0, b1, b2, width);
if(y-1<(unsigned)height) ff_snow_horizontal_compose97i(b0, width);
if(y+0<(unsigned)height) ff_snow_horizontal_compose97i(b1, width);
cs->b0=b2;
cs->b1=b3;
cs->b2=b4;
cs->b3=b5;
cs->y += 2;
}
static void spatial_compose97i(DWTELEM *buffer, int width, int height, int stride){
dwt_compose_t cs;
spatial_compose97i_init(&cs, buffer, height, stride);
while(cs.y <= height)
spatial_compose97i_dy(&cs, buffer, width, height, stride);
}
static void ff_spatial_idwt_buffered_init(dwt_compose_t *cs, slice_buffer * sb, int width, int height, int stride_line, int type, int decomposition_count){
int level;
for(level=decomposition_count-1; level>=0; level--){
switch(type){
case DWT_97: spatial_compose97i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
case DWT_53: spatial_compose53i_buffered_init(cs+level, sb, height>>level, stride_line<<level); break;
/* not slicified yet */
case DWT_X: /*spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;*/
av_log(NULL, AV_LOG_ERROR, "spatial_composeX neither buffered nor slicified yet.\n"); break;
}
}
}
static void ff_spatial_idwt_init(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
int level;
for(level=decomposition_count-1; level>=0; level--){
switch(type){
case DWT_97: spatial_compose97i_init(cs+level, buffer, height>>level, stride<<level); break;
case DWT_53: spatial_compose53i_init(cs+level, buffer, height>>level, stride<<level); break;
/* not slicified yet */
case DWT_X: spatial_composeX(buffer, width>>level, height>>level, stride<<level); break;
}
}
}
static void ff_spatial_idwt_slice(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count, int y){
const int support = type==1 ? 3 : 5;
int level;
if(type==2) return;
for(level=decomposition_count-1; level>=0; level--){
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
switch(type){
case DWT_97: spatial_compose97i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
break;
case DWT_53: spatial_compose53i_dy(cs+level, buffer, width>>level, height>>level, stride<<level);
break;
case DWT_X: break;
}
}
}
}
static void ff_spatial_idwt_buffered_slice(DSPContext *dsp, dwt_compose_t *cs, slice_buffer * slice_buf, int width, int height, int stride_line, int type, int decomposition_count, int y){
const int support = type==1 ? 3 : 5;
int level;
if(type==2) return;
for(level=decomposition_count-1; level>=0; level--){
while(cs[level].y <= FFMIN((y>>level)+support, height>>level)){
switch(type){
case DWT_97: spatial_compose97i_dy_buffered(dsp, cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
break;
case DWT_53: spatial_compose53i_dy_buffered(cs+level, slice_buf, width>>level, height>>level, stride_line<<level);
break;
case DWT_X: break;
}
}
}
}
static void ff_spatial_idwt(DWTELEM *buffer, int width, int height, int stride, int type, int decomposition_count){
if(type==2){
int level;
for(level=decomposition_count-1; level>=0; level--)
spatial_composeX (buffer, width>>level, height>>level, stride<<level);
}else{
dwt_compose_t cs[MAX_DECOMPOSITIONS];
int y;
ff_spatial_idwt_init(cs, buffer, width, height, stride, type, decomposition_count);
for(y=0; y<height; y+=4)
ff_spatial_idwt_slice(cs, buffer, width, height, stride, type, decomposition_count, y);
}
}
static int encode_subband_c0run(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){
const int w= b->width;
const int h= b->height;
int x, y;
if(1){
int run=0;
int runs[w*h];
int run_index=0;
int max_index;
for(y=0; y<h; y++){
for(x=0; x<w; x++){
int v, p=0;
int 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(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(!(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 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(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(l|lt|t|rt|p){
int context= av_log2(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(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);
}
}
}
}
return 0;
}
static int encode_subband(SnowContext *s, SubBand *b, DWTELEM *src, DWTELEM *parent, int stride, int orientation){
return encode_subband_c0run(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(l|lt|t|rt|p){
int context= av_log2(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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -