📄 snow.c
字号:
};//linear *64static const uint8_t obmc4[16]={ 16, 48, 48, 16, 48,144,144, 48, 48,144,144, 48, 16, 48, 48, 16,//error:0.000000};static const uint8_t * const obmc_tab[4]={ obmc32, obmc16, obmc8, obmc4};static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];typedef struct BlockNode{ int16_t mx; int16_t my; uint8_t ref; uint8_t color[3]; uint8_t type;//#define TYPE_SPLIT 1#define BLOCK_INTRA 1#define BLOCK_OPT 2//#define TYPE_NOCOLOR 4 uint8_t level; //FIXME merge into type?}BlockNode;#ifdef __CW32__static const BlockNode null_block= { //FIXME add border maybe 0, 0, 0, {128,128,128}, 0, 0,};#elsestatic const BlockNode null_block= { //FIXME add border maybe .color= {128,128,128}, .mx= 0, .my= 0, .ref= 0, .type= 0, .level= 0,};#endif#define LOG2_MB_SIZE 4#define MB_SIZE (1<<LOG2_MB_SIZE)#define ENCODER_EXTRA_BITS 4#define HTAPS_MAX 8typedef 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; IDWTELEM *ibuf; 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]; int htaps; int8_t hcoeff[HTAPS_MAX/2]; int diag_mc; int fast_mc; int last_htaps; int8_t last_hcoeff[HTAPS_MAX/2]; int last_diag_mc;}Plane;typedef struct SnowContext{// 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) AVCodecContext *avctx; RangeCoder c; DSPContext dsp; AVFrame new_picture; AVFrame input_picture; ///< new_picture with the internal linesizes AVFrame current_picture; AVFrame last_picture[MAX_REF_FRAMES]; uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4]; 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 last_spatial_decomposition_type; int temporal_decomposition_type; int spatial_decomposition_count; int last_spatial_decomposition_count; int temporal_decomposition_count; int max_ref_frames; int ref_frames; int16_t (*ref_mvs[MAX_REF_FRAMES])[2]; uint32_t *ref_scores[MAX_REF_FRAMES]; DWTELEM *spatial_dwt_buffer; IDWTELEM *spatial_idwt_buffer; int colorspace_type; int chroma_h_shift; 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 int me_cache[ME_CACHE_SIZE]; int me_cache_generation; slice_buffer sb; 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)}SnowContext;typedef struct { IDWTELEM *b0; IDWTELEM *b1; IDWTELEM *b2; IDWTELEM *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 iterative_me(SnowContext *s);static void slice_buffer_init(slice_buffer * buf, int line_count, int max_allocated_lines, int line_width, IDWTELEM * 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 = av_mallocz (sizeof(IDWTELEM *) * line_count); buf->data_stack = av_malloc (sizeof(IDWTELEM *) * max_allocated_lines); for(i = 0; i < max_allocated_lines; i++){ buf->data_stack[i] = av_malloc (sizeof(IDWTELEM) * line_width); } buf->data_stack_top = max_allocated_lines - 1;}static IDWTELEM * slice_buffer_load_line(slice_buffer * buf, int line){ int offset; IDWTELEM * buffer; 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; return buffer;}static void slice_buffer_release(slice_buffer * buf, int line){ int offset; IDWTELEM * 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;}static void slice_buffer_flush(slice_buffer * buf){ int i; for(i = 0; i < buf->line_count; i++){ if (buf->line[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--){ av_freep(&buf->data_stack[i]); } av_freep(&buf->data_stack); av_freep(&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){ while((unsigned)v > (unsigned)m){ v=-v; if(v<0) v+= 2*m; } return v;}static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){ int i; if(v){ const int a= FFABS(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 /* 1 */ }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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -