📄 snow.c
字号:
//#define TYPE_NOCOLOR 4 uint8_t level; //FIXME merge into type?}BlockNode;#define LOG2_MB_SIZE 4#define MB_SIZE (1<<LOG2_MB_SIZE)typedef struct x_and_coeff{ int16_t x; uint16_t coeff;} x_and_coeff;typedef struct SubBand{ int level; int stride; int width; int height; int qlog; ///< log(qscale)/log[2^(1/6)] DWTELEM *buf; int buf_x_offset; int buf_y_offset; int stride_line; ///< Stride measured in lines, not pixels. x_and_coeff * x_coeff; struct SubBand *parent; uint8_t state[/*7*2*/ 7 + 512][32];}SubBand;typedef struct Plane{ int width; int height; SubBand band[MAX_DECOMPOSITIONS][4];}Plane;/** Used to minimize the amount of memory used in order to optimize cache performance. **/typedef struct { DWTELEM * * line; ///< For use by idwt and predict_slices. DWTELEM * * data_stack; ///< Used for internal purposes. int data_stack_top; int line_count; int line_width; int data_count; DWTELEM * base_buffer; ///< Buffer that this structure is caching.} slice_buffer;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; RangeCoder c; DSPContext dsp; AVFrame input_picture; AVFrame current_picture; AVFrame last_picture; AVFrame mconly_picture;// uint8_t q_context[16]; uint8_t header_state[32]; uint8_t block_state[128 + 32*128]; int keyframe; int always_reset; int version; int spatial_decomposition_type; int temporal_decomposition_type; int spatial_decomposition_count; int temporal_decomposition_count; DWTELEM *spatial_dwt_buffer; int colorspace_type; int chroma_h_shift; int chroma_v_shift; int spatial_scalability; int qlog; int lambda; int lambda2; int mv_scale; int qbias;#define QBIAS_SHIFT 3 int b_width; int b_height; int block_max_depth; Plane plane[MAX_PLANES]; BlockNode *block; slice_buffer sb; 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)}SnowContext;typedef struct { DWTELEM *b0; DWTELEM *b1; DWTELEM *b2; DWTELEM *b3; int y;} dwt_compose_t;#define slice_buffer_get_line(slice_buf, line_num) ((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] : slice_buffer_load_line((slice_buf), (line_num)))//#define slice_buffer_get_line(slice_buf, line_num) (slice_buffer_load_line((slice_buf), (line_num)))static void slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, DWTELEM * base_buffer){ int i; buf->base_buffer = base_buffer; buf->line_count = line_count; buf->line_width = line_width; buf->data_count = max_allocated_lines; buf->line = (DWTELEM * *) av_mallocz (sizeof(DWTELEM *) * line_count); buf->data_stack = (DWTELEM * *) av_malloc (sizeof(DWTELEM *) * max_allocated_lines); for (i = 0; i < max_allocated_lines; i++) { buf->data_stack[i] = (DWTELEM *) av_malloc (sizeof(DWTELEM) * line_width); } buf->data_stack_top = max_allocated_lines - 1;}static DWTELEM * slice_buffer_load_line(slice_buffer * buf, int line){ int i; int offset; DWTELEM * buffer; // av_log(NULL, AV_LOG_DEBUG, "Cache hit: %d\n", line); assert(buf->data_stack_top >= 0);// assert(!buf->line[line]); if (buf->line[line]) return buf->line[line]; offset = buf->line_width * line; buffer = buf->data_stack[buf->data_stack_top]; buf->data_stack_top--; buf->line[line] = buffer; // av_log(NULL, AV_LOG_DEBUG, "slice_buffer_load_line: line: %d remaining: %d\n", line, buf->data_stack_top + 1); return buffer;}static void slice_buffer_release(slice_buffer * buf, int line){ int i; int offset; DWTELEM * buffer; assert(line >= 0 && line < buf->line_count); assert(buf->line[line]); offset = buf->line_width * line; buffer = buf->line[line]; buf->data_stack_top++; buf->data_stack[buf->data_stack_top] = buffer; buf->line[line] = NULL; // av_log(NULL, AV_LOG_DEBUG, "slice_buffer_release: line: %d remaining: %d\n", line, buf->data_stack_top + 1);}static void slice_buffer_flush(slice_buffer * buf){ int i; for (i = 0; i < buf->line_count; i++) { if (buf->line[i]) {// av_log(NULL, AV_LOG_DEBUG, "slice_buffer_flush: line: %d \n", i); slice_buffer_release(buf, i); } }}static void slice_buffer_destroy(slice_buffer * buf){ int i; slice_buffer_flush(buf); for (i = buf->data_count - 1; i >= 0; i--) { assert(buf->data_stack[i]); av_free(buf->data_stack[i]); } assert(buf->data_stack); av_free(buf->data_stack); assert(buf->line); av_free(buf->line);}#ifdef __sgi// Avoid a name clash on SGI IRIX#undef qexp#endif#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0static uint8_t qexp[QROOT];static inline int mirror(int v, int m){ if (v<0) return -v; else if(v>m) return 2*m-v; else return v;}static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ int i; if(v){ const int a= ABS(v); const int e= av_log2(a);#if 1 const int el= FFMIN(e, 10); put_rac(c, state+0, 0); for(i=0; i<el; i++){ put_rac(c, state+1+i, 1); //1..10 } for(; i<e; i++){ put_rac(c, state+1+9, 1); //1..10 } put_rac(c, state+1+FFMIN(i,9), 0); for(i=e-1; i>=el; i--){ put_rac(c, state+22+9, (a>>i)&1); //22..31 } for(; i>=0; i--){ put_rac(c, state+22+i, (a>>i)&1); //22..31 } if(is_signed) put_rac(c, state+11 + el, v < 0); //11..21#else put_rac(c, state+0, 0); if(e<=9){ for(i=0; i<e; i++){ put_rac(c, state+1+i, 1); //1..10 } put_rac(c, state+1+i, 0); for(i=e-1; i>=0; i--){ put_rac(c, state+22+i, (a>>i)&1); //22..31 } if(is_signed) put_rac(c, state+11 + e, v < 0); //11..21 }else{ for(i=0; i<e; i++){ put_rac(c, state+1+FFMIN(i,9), 1); //1..10 } put_rac(c, state+1+FFMIN(i,9), 0); for(i=e-1; i>=0; i--){ put_rac(c, state+22+FFMIN(i,9), (a>>i)&1); //22..31 } if(is_signed) put_rac(c, state+11 + FFMIN(e,10), v < 0); //11..21 }#endif }else{ put_rac(c, state+0, 1); }}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_rac(c, state+1 + FFMIN(e,9))){ //1..10 e++; } a= 1; for(i=e-1; i>=0; i--){ a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31 } if(is_signed && get_rac(c, state+11 + FFMIN(e,10))) //11..21 return -a; else return a; }}static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){ int i; int r= log2>=0 ? 1<<log2 : 1; assert(v>=0); assert(log2>=-4); while(v >= r){ put_rac(c, state+4+log2, 1); v -= r; log2++; if(log2>0) r+=r; } put_rac(c, state+4+log2, 0); for(i=log2-1; i>=0; i--){ put_rac(c, state+31-i, (v>>i)&1); }}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_rac(c, state+4+log2)){ v+= r; log2++; if(log2>0) r+=r; } for(i=log2-1; i>=0; i--){ v+= get_rac(c, state+31-i)<<i; } return v;}static always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); int i;#define LIFT(src, ref, inv) ((src) + ((inv) ? - (ref) : + (ref))) if(mirror_left){ dst[0] = LIFT(src[0], ((mul*2*ref[0]+add)>>shift), inverse); dst += dst_step; src += src_step; } for(i=0; i<w; i++){ dst[i*dst_step] = LIFT(src[i*src_step], ((mul*(ref[i*ref_step] + ref[(i+1)*ref_step])+add)>>shift), inverse); } if(mirror_right){ dst[w*dst_step] = LIFT(src[w*src_step], ((mul*2*ref[w*ref_step]+add)>>shift), inverse); }}static always_inline void lift5(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); int i; if(mirror_left){ int r= 3*2*ref[0]; r += r>>4; r += r>>8; dst[0] = LIFT(src[0], ((r+add)>>shift), inverse); dst += dst_step; src += src_step; } for(i=0; i<w; i++){ int r= 3*(ref[i*ref_step] + ref[(i+1)*ref_step]); r += r>>4; r += r>>8; dst[i*dst_step] = LIFT(src[i*src_step], ((r+add)>>shift), inverse); } if(mirror_right){ int r= 3*2*ref[w*ref_step]; r += r>>4; r += r>>8; dst[w*dst_step] = LIFT(src[w*src_step], ((r+add)>>shift), inverse); }}static always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref, int dst_step, int src_step, int ref_step, int width, int mul, int add, int shift, int highpass, int inverse){ const int mirror_left= !highpass; const int mirror_right= (width&1) ^ highpass; const int w= (width>>1) - 1 + (highpass & width); int i; assert(shift == 4);#define LIFTS(src, ref, inv) ((inv) ? (src) - (((ref) - 4*(src))>>shift): (16*4*(src) + 4*(ref) + 8 + (5<<27))/(5*16) - (1<<23)) if(mirror_left){ dst[0] = LIFTS(src[0], mul*2*ref[0]+add, inverse); dst += dst_step; src += src_step;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -