uint8_t *src_plane= s->input_picture.data[0]; int src_stride= s->input_picture.linesize[0]; int x,y;
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){    SnowContext *s = avctx->priv_data;    CABACContext * const c= &s->c;    AVFrame *pict = data;    const int width= s->avctx->width;    const int height= s->avctx->height;    int used_count= 0;    int log2_threshold, level, orientation, plane_index, i;    ff_init_cabac_encoder(c, buf, buf_size);    ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);        s->input_picture = *pict;    memset(s->header_state, 0, sizeof(s->header_state));    s->keyframe=avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;    pict->pict_type= s->keyframe ? FF_I_TYPE : FF_P_TYPE;        if(pict->quality){        s->qlog= rint(QROOT*log(pict->quality / (float)FF_QP2LAMBDA)/log(2));        //<64 >60        s->qlog += 61;    }else{        s->qlog= LOSSLESS_QLOG;    }    frame_start(s);    if(pict->pict_type == P_TYPE){        int block_width = (width +15)>>4;        int block_height= (height+15)>>4;        int stride= s->current_picture.linesize[0];        uint8_t *src_plane= s->input_picture.data[0];        int src_stride= s->input_picture.linesize[0];        int x,y;                assert(s->current_picture.data[0]);        assert(s->last_picture.data[0]);             s->m.avctx= s->avctx;        s->m.current_picture.data[0]= s->current_picture.data[0];        s->m.   last_picture.data[0]= s->   last_picture.data[0];        s->m.    new_picture.data[0]= s->  input_picture.data[0];        s->m.current_picture_ptr= &s->m.current_picture;        s->m.   last_picture_ptr= &s->m.   last_picture;        s->m.linesize=        s->m.   last_picture.linesize[0]=        s->m.    new_picture.linesize[0]=        s->m.current_picture.linesize[0]= stride;        s->m.uvlinesize= s->current_picture.linesize[1];        s->m.width = width;        s->m.height= height;        s->m.mb_width = block_width;        s->m.mb_height= block_height;        s->m.mb_stride=   s->m.mb_width+1;        s->m.b8_stride= 2*s->m.mb_width+1;        s->m.f_code=1;        s->m.pict_type= pict->pict_type;        s->m.me_method= s->avctx->me_method;        s->m.me.scene_change_score=0;        s->m.flags= s->avctx->flags;        s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;        s->m.out_format= FMT_H263;        s->m.unrestricted_mv= 1;        s->lambda = s->m.lambda= pict->quality * 3/2; //FIXME bug somewhere else        s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);        s->lambda2= s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;        s->m.dsp= s->dsp; //move        ff_init_me(&s->m);    }    redo_frame:            s->qbias= pict->pict_type == P_TYPE ? 2 : 0;    encode_header(s);    encode_blocks(s);          for(plane_index=0; plane_index<3; plane_index++){        Plane *p= &s->plane[plane_index];        int w= p->width;        int h= p->height;        int x, y;        int bits= put_bits_count(&s->c.pb);        //FIXME optimize     if(pict->data[plane_index]) //FIXME gray hack        for(y=0; y<h; y++){            for(x=0; x<w; x++){                s->spatial_dwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<8;            }        }        predict_plane(s, s->spatial_dwt_buffer, plane_index, 0);                if(   plane_index==0            && pict->pict_type == P_TYPE            && s->m.me.scene_change_score > s->avctx->scenechange_threshold){            ff_init_cabac_encoder(c, buf, buf_size);            ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);            pict->pict_type= FF_I_TYPE;            s->keyframe=1;            reset_contexts(s);            goto redo_frame;        }                if(s->qlog == LOSSLESS_QLOG){            for(y=0; y<h; y++){                for(x=0; x<w; x++){                    s->spatial_dwt_buffer[y*w + x]= (s->spatial_dwt_buffer[y*w + x] + 127)>>8;                }            }        }         ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);        for(level=0; level<s->spatial_decomposition_count; level++){            for(orientation=level ? 1 : 0; orientation<4; orientation++){                SubBand *b= &p->band[level][orientation];                                quantize(s, b, b->buf, b->stride, s->qbias);                if(orientation==0)                    decorrelate(s, b, b->buf, b->stride, pict->pict_type == P_TYPE, 0);                encode_subband(s, b, b->buf, b->parent ? b->parent->buf : NULL, b->stride, orientation);                assert(b->parent==NULL || b->parent->stride == b->stride*2);                if(orientation==0)                    correlate(s, b, b->buf, b->stride, 1, 0);            }        }//        av_log(NULL, AV_LOG_DEBUG, "plane:%d bits:%d\n", plane_index, put_bits_count(&s->c.pb) - bits);        for(level=0; level<s->spatial_decomposition_count; level++){            for(orientation=level ? 1 : 0; orientation<4; orientation++){                SubBand *b= &p->band[level][orientation];                dequantize(s, b, b->buf, b->stride);            }        }        ff_spatial_idwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);        if(s->qlog == LOSSLESS_QLOG){            for(y=0; y<h; y++){                for(x=0; x<w; x++){                    s->spatial_dwt_buffer[y*w + x]<<=8;                }            }        }        predict_plane(s, s->spatial_dwt_buffer, plane_index, 1);        //FIXME optimize        for(y=0; y<h; y++){            for(x=0; x<w; x++){                int v= (s->spatial_dwt_buffer[y*w + x]+128)>>8;                if(v&(~255)) v= ~(v>>31);                s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]= v;            }        }        if(s->avctx->flags&CODEC_FLAG_PSNR){            int64_t error= 0;                if(pict->data[plane_index]) //FIXME gray hack            for(y=0; y<h; y++){                for(x=0; x<w; x++){                    int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];                    error += d*d;                }            }            s->avctx->error[plane_index] += error;            s->avctx->error[3] += error;        }    }    if(s->last_picture.data[0])        avctx->release_buffer(avctx, &s->last_picture);    emms_c();        return put_cabac_terminate(c, 1);}