/*
 * The simplest mpeg encoder (well, it was the simplest!)
 * Copyright (c) 2000,2001 Fabrice Bellard
 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
 *
 * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file libavcodec/mpegvideo_enc.c
 * The simplest mpeg encoder (well, it was the simplest!).
 */

#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "mpegvideo_common.h"
#include "mjpegenc.h"
#include "msmpeg4.h"
#include "h263.h"
#include "faandct.h"
#include "aandcttab.h"
#include <limits.h>

//#undef NDEBUG
//#include <assert.h>

static int encode_picture(MpegEncContext *s, int picture_number);
static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale);
static int sse_mb(MpegEncContext *s);

/* enable all paranoid tests for rounding, overflows, etc... */
//#define PARANOID

//#define DEBUG

static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
static uint8_t default_fcode_tab[MAX_MV*2+1];

void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],
                           const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra)
{
    int qscale;
    int shift=0;

    for(qscale=qmin; qscale<=qmax; qscale++){
        int i;
        if (dsp->fdct == ff_jpeg_fdct_islow
#ifdef FAAN_POSTSCALE
            || dsp->fdct == ff_faandct
#endif
            ) {
            for(i=0;i<64;i++) {
                const int j= dsp->idct_permutation[i];
                /* 16 <= qscale * quant_matrix[i] <= 7905 */
                /* 19952             <= ff_aanscales[i] * qscale * quant_matrix[i]               <= 249205026 */
                /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1 << 36) / 249205026 */
                /* 3444240           >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */

                qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /
                                (qscale * quant_matrix[j]));
            }
        } else if (dsp->fdct == fdct_ifast
#ifndef FAAN_POSTSCALE
                   || dsp->fdct == ff_faandct
#endif
                   ) {
            for(i=0;i<64;i++) {
                const int j= dsp->idct_permutation[i];
                /* 16 <= qscale * quant_matrix[i] <= 7905 */
                /* 19952             <= ff_aanscales[i] * qscale * quant_matrix[i]               <= 249205026 */
                /* (1 << 36) / 19952 >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */
                /* 3444240           >= (1 << 36) / (ff_aanscales[i] * qscale * quant_matrix[i]) >= 275 */

                qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /
                                (ff_aanscales[i] * qscale * quant_matrix[j]));
            }
        } else {
            for(i=0;i<64;i++) {
                const int j= dsp->idct_permutation[i];
                /* We can safely suppose that 16 <= quant_matrix[i] <= 255
                   So 16           <= qscale * quant_matrix[i]             <= 7905
                   so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
                   so 32768        >= (1<<19) / (qscale * quant_matrix[i]) >= 67
                */
                qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j]));
//                qmat  [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);
                qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);

                if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;
                qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);
            }
        }

        for(i=intra; i<64; i++){
            int64_t max= 8191;
            if (dsp->fdct == fdct_ifast
#ifndef FAAN_POSTSCALE
                   || dsp->fdct == ff_faandct
#endif
                   ) {
                max = (8191LL*ff_aanscales[i]) >> 14;
            }
            while(((max * qmat[qscale][i]) >> shift) > INT_MAX){
                shift++;
            }
        }
    }
    if(shift){
        av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift);
    }
}

static inline void update_qscale(MpegEncContext *s){
    s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);
    s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax);

    s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;
}

void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix){
    int i;

    if(matrix){
        put_bits(pb, 1, 1);
        for(i=0;i<64;i++) {
            put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]);
        }
    }else
        put_bits(pb, 1, 0);
}

static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){
    int i;

    dst->pict_type              = src->pict_type;
    dst->quality                = src->quality;
    dst->coded_picture_number   = src->coded_picture_number;
    dst->display_picture_number = src->display_picture_number;
//    dst->reference              = src->reference;
    dst->pts                    = src->pts;
    dst->interlaced_frame       = src->interlaced_frame;
    dst->top_field_first        = src->top_field_first;

    if(s->avctx->me_threshold){
        if(!src->motion_val[0])
            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n");
        if(!src->mb_type)
            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n");
        if(!src->ref_index[0])
            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n");
        if(src->motion_subsample_log2 != dst->motion_subsample_log2)
            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n",
            src->motion_subsample_log2, dst->motion_subsample_log2);

        memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0]));

        for(i=0; i<2; i++){
            int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1;
            int height= ((16*s->mb_height)>>src->motion_subsample_log2);

            if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){
                memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t));
            }
            if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){
                memcpy(dst->ref_index[i], src->ref_index[i], s->b8_stride*2*s->mb_height*sizeof(int8_t));
            }
        }
    }
}

static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){
#define COPY(a) dst->a= src->a
    COPY(pict_type);
    COPY(current_picture);
    COPY(f_code);
    COPY(b_code);
    COPY(qscale);
    COPY(lambda);
    COPY(lambda2);
    COPY(picture_in_gop_number);
    COPY(gop_picture_number);
    COPY(frame_pred_frame_dct); //FIXME don't set in encode_header
    COPY(progressive_frame); //FIXME don't set in encode_header
    COPY(partitioned_frame); //FIXME don't set in encode_header
#undef COPY
}

/**
 * sets the given MpegEncContext to defaults for encoding.
 * the changed fields will not depend upon the prior state of the MpegEncContext.
 */
static void MPV_encode_defaults(MpegEncContext *s){
    int i;
    MPV_common_defaults(s);

    for(i=-16; i<16; i++){
        default_fcode_tab[i + MAX_MV]= 1;
    }
    s->me.mv_penalty= default_mv_penalty;
    s->fcode_tab= default_fcode_tab;
}

/* init video encoder */
av_cold int MPV_encode_init(AVCodecContext *avctx)
{
    MpegEncContext *s = avctx->priv_data;
    int i;
    int chroma_h_shift, chroma_v_shift;

    MPV_encode_defaults(s);

    switch (avctx->codec_id) {
    case CODEC_ID_MPEG2VIDEO:
        if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){
            av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");
            return -1;
        }
        break;
    case CODEC_ID_LJPEG:
    case CODEC_ID_MJPEG:
        if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && avctx->pix_fmt != PIX_FMT_RGB32 &&
           ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){
            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");
            return -1;
        }
        break;
    default:
        if(avctx->pix_fmt != PIX_FMT_YUV420P){
            av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");
            return -1;
        }
    }

    switch (avctx->pix_fmt) {
    case PIX_FMT_YUVJ422P:
    case PIX_FMT_YUV422P:
        s->chroma_format = CHROMA_422;
        break;
    case PIX_FMT_YUVJ420P:
    case PIX_FMT_YUV420P:
    default:
        s->chroma_format = CHROMA_420;
        break;
    }

    s->bit_rate = avctx->bit_rate;
    s->width = avctx->width;
    s->height = avctx->height;
    if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){
        av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n");
        avctx->gop_size=600;
    }
    s->gop_size = avctx->gop_size;
    s->avctx = avctx;
    s->flags= avctx->flags;
    s->flags2= avctx->flags2;
    s->max_b_frames= avctx->max_b_frames;
    s->codec_id= avctx->codec->id;
    s->luma_elim_threshold  = avctx->luma_elim_threshold;
    s->chroma_elim_threshold= avctx->chroma_elim_threshold;
    s->strict_std_compliance= avctx->strict_std_compliance;
    s->data_partitioning= avctx->flags & CODEC_FLAG_PART;
    s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;
    s->mpeg_quant= avctx->mpeg_quant;
    s->rtp_mode= !!avctx->rtp_payload_size;
    s->intra_dc_precision= avctx->intra_dc_precision;
    s->user_specified_pts = AV_NOPTS_VALUE;

    if (s->gop_size <= 1) {
        s->intra_only = 1;
        s->gop_size = 12;
    } else {
        s->intra_only = 0;
    }

    s->me_method = avctx->me_method;

    /* Fixed QSCALE */
    s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);

    s->adaptive_quant= (   s->avctx->lumi_masking
                        || s->avctx->dark_masking
                        || s->avctx->temporal_cplx_masking
                        || s->avctx->spatial_cplx_masking
                        || s->avctx->p_masking
                        || s->avctx->border_masking
                        || (s->flags&CODEC_FLAG_QP_RD))
                       && !s->fixed_qscale;

    s->obmc= !!(s->flags & CODEC_FLAG_OBMC);
    s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER);
    s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN);
    s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);
    s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);

    if(avctx->rc_max_rate && !avctx->rc_buffer_size){
        av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n");
        return -1;
    }

    if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){
        av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");
    }

    if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){
        av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n");
        return -1;
    }

    if(avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate){
        av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n");
        return -1;
    }

    if(avctx->rc_max_rate && avctx->rc_max_rate == avctx->bit_rate && avctx->rc_max_rate != avctx->rc_min_rate){
        av_log(avctx, AV_LOG_INFO, "impossible bitrate constraints, this will fail\n");
    }

    if(avctx->rc_buffer_size && avctx->bit_rate*av_q2d(avctx->time_base) > avctx->rc_buffer_size){
        av_log(avctx, AV_LOG_ERROR, "VBV buffer too small for bitrate\n");
        return -1;
    }

    if(avctx->bit_rate*av_q2d(avctx->time_base) > avctx->bit_rate_tolerance){
        av_log(avctx, AV_LOG_ERROR, "bitrate tolerance too small for bitrate\n");
        return -1;
    }

    if(   s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate
       && (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO)
       && 90000LL * (avctx->rc_buffer_size-1) > s->avctx->rc_max_rate*0xFFFFLL){

        av_log(avctx, AV_LOG_INFO, "Warning vbv_delay will be set to 0xFFFF (=VBR) as the specified vbv buffer is too large for the given bitrate!\n");
    }

    if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4
       && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P && s->codec_id != CODEC_ID_FLV1){
        av_log(avctx, AV_LOG_ERROR, "4MV not supported by codec\n");
        return -1;
    }

    if(s->obmc && s->avctx->mb_decision != FF_MB_DECISION_SIMPLE){
        av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with simple mb decision\n");
        return -1;
    }

    if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){
        av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n");
        return -1;
    }

    if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){
        av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n");
        return -1;
    }

    if(s->data_partitioning && s->codec_id != CODEC_ID_MPEG4){
        av_log(avctx, AV_LOG_ERROR, "data partitioning not supported by codec\n");
        return -1;
    }

    if(s->max_b_frames && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO){
        av_log(avctx, AV_LOG_ERROR, "b frames not supported by codec\n");
        return -1;
    }

    if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN))
       && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_MPEG2VIDEO){
        av_log(avctx, AV_LOG_ERROR, "interlacing not supported by codec\n");
        return -1;
    }

    if(s->mpeg_quant && s->codec_id != CODEC_ID_MPEG4){ //FIXME mpeg2 uses that too
        av_log(avctx, AV_LOG_ERROR, "mpeg2 style quantization not supported by codec\n");
        return -1;
    }

    if((s->flags & CODEC_FLAG_CBP_RD) && !avctx->trellis){
        av_log(avctx, AV_LOG_ERROR, "CBP RD needs trellis quant\n");
        return -1;
    }

    if((s->flags & CODEC_FLAG_QP_RD) && s->avctx->mb_decision != FF_MB_DECISION_RD){
        av_log(avctx, AV_LOG_ERROR, "QP RD needs mbd=2\n");
        return -1;
    }

    if(s->avctx->scenechange_threshold < 1000000000 && (s->flags & CODEC_FLAG_CLOSED_GOP)){
        av_log(avctx, AV_LOG_ERROR, "closed gop with scene change detection are not supported yet, set threshold to 1000000000\n");
        return -1;
    }

    if((s->flags2 & CODEC_FLAG2_INTRA_VLC) && s->codec_id != CODEC_ID_MPEG2VIDEO){
        av_log(avctx, AV_LOG_ERROR, "intra vlc table not supported by codec\n");
        return -1;
    }

    if(s->flags & CODEC_FLAG_LOW_DELAY){
        if (s->codec_id != CODEC_ID_MPEG2VIDEO){
            av_log(avctx, AV_LOG_ERROR, "low delay forcing is only available for mpeg2\n");
            return -1;
        }
        if (s->max_b_frames != 0){
            av_log(avctx, AV_LOG_ERROR, "b frames cannot be used with low delay\n");
            return -1;
        }
    }

    if(s->q_scale_type == 1){
        if(s->codec_id != CODEC_ID_MPEG2VIDEO){
            av_log(avctx, AV_LOG_ERROR, "non linear quant is only available for mpeg2\n");
            return -1;
        }
        if(avctx->qmax > 12){
            av_log(avctx, AV_LOG_ERROR, "non linear quant only supports qmax <= 12 currently\n");
            return -1;
        }
    }

    if(s->avctx->thread_count > 1 && s->codec_id != CODEC_ID_MPEG4
       && s->codec_id != CODEC_ID_MPEG1VIDEO && s->codec_id != CODEC_ID_MPEG2VIDEO
       && (s->codec_id != CODEC_ID_H263P || !(s->flags & CODEC_FLAG_H263P_SLICE_STRUCT))){
        av_log(avctx, AV_LOG_ERROR, "multi threaded encoding not supported by codec\n");
        return -1;
    }

    if(s->avctx->thread_count > 1)
        s->rtp_mode= 1;

    if(!avctx->time_base.den || !avctx->time_base.num){
        av_log(avctx, AV_LOG_ERROR, "framerate not set\n");
        return -1;
    }

    i= (INT_MAX/2+128)>>8;
    if(avctx->me_threshold >= i){
        av_log(avctx, AV_LOG_ERROR, "me_threshold too large, max is %d\n", i - 1);
        return -1;
    }
    if(avctx->mb_threshold >= i){
        av_log(avctx, AV_LOG_ERROR, "mb_threshold too large, max is %d\n", i - 1);
        return -1;
    }

    if(avctx->b_frame_strategy && (avctx->flags&CODEC_FLAG_PASS2)){
        av_log(avctx, AV_LOG_INFO, "notice: b_frame_strategy only affects the first pass\n");
        avctx->b_frame_strategy = 0;
    }

    i= av_gcd(avctx->time_base.den, avctx->time_base.num);
    if(i > 1){
        av_log(avctx, AV_LOG_INFO, "removing common factors from framerate\n");
        avctx->time_base.den /= i;
        avctx->time_base.num /= i;
//        return -1;
    }

    if(s->codec_id==CODEC_ID_MJPEG){
        s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x
        s->inter_quant_bias= 0;
    }else if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO){
        s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x
        s->inter_quant_bias= 0;
    }else{
        s->intra_quant_bias=0;
        s->inter_quant_bias=-(1<<(QUANT_BIAS_SHIFT-2)); //(a - x/4)/x
    }

    if(avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
        s->intra_quant_bias= avctx->intra_quant_bias;
    if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)
        s->inter_quant_bias= avctx->inter_quant_bias;

    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);

    if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){
        av_log(avctx, AV_LOG_ERROR, "timebase not supported by mpeg 4 standard\n");
        return -1;
    }
    s->time_increment_bits = av_log2(s->avctx->time_base.den - 1) + 1;

    switch(avctx->codec->id) {
    case CODEC_ID_MPEG1VIDEO:
        s->out_format = FMT_MPEG1;
        s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);
        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
        break;
    case CODEC_ID_MPEG2VIDEO:
        s->out_format = FMT_MPEG1;
        s->low_delay= !!(s->flags & CODEC_FLAG_LOW_DELAY);
        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
        s->rtp_mode= 1;
        break;
    case CODEC_ID_LJPEG:
    case CODEC_ID_MJPEG:
        s->out_format = FMT_MJPEG;
        s->intra_only = 1; /* force intra only for jpeg */
        s->mjpeg_vsample[0] = 2;
        s->mjpeg_vsample[1] = 2>>chroma_v_shift;
        s->mjpeg_vsample[2] = 2>>chroma_v_shift;
        s->mjpeg_hsample[0] = 2;
        s->mjpeg_hsample[1] = 2>>chroma_h_shift;
        s->mjpeg_hsample[2] = 2>>chroma_h_shift;
        if (!(CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER)
            || ff_mjpeg_encode_init(s) < 0)
            return -1;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_H261:
        if (!CONFIG_H261_ENCODER)  return -1;
        if (ff_h261_get_picture_format(s->width, s->height) < 0) {
            av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for the H.261 codec.\nValid sizes are 176x144, 352x288\n", s->width, s->height);
            return -1;
        }
        s->out_format = FMT_H261;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_H263:
        if (!CONFIG_H263_ENCODER)  return -1;
        if (h263_get_picture_format(s->width, s->height) == 7) {
            av_log(avctx, AV_LOG_INFO, "The specified picture size of %dx%d is not valid for the H.263 codec.\nValid sizes are 128x96, 176x144, 352x288, 704x576, and 1408x1152. Try H.263+.\n", s->width, s->height);
            return -1;
        }
        s->out_format = FMT_H263;
        s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_H263P:
        s->out_format = FMT_H263;
        s->h263_plus = 1;
        /* Fx */
        s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0;
        s->h263_aic= (avctx->flags & CODEC_FLAG_AC_PRED) ? 1:0;
        s->modified_quant= s->h263_aic;
        s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0;
        s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0;
        s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0;
        s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus;
        s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0;

        /* /Fx */
        /* These are just to be sure */
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_FLV1:
        s->out_format = FMT_H263;
        s->h263_flv = 2; /* format = 1; 11-bit codes */
        s->unrestricted_mv = 1;
        s->rtp_mode=0; /* don't allow GOB */
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_RV10:
        s->out_format = FMT_H263;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_RV20:
        s->out_format = FMT_H263;
        avctx->delay=0;
        s->low_delay=1;
        s->modified_quant=1;
        s->h263_aic=1;
        s->h263_plus=1;
        s->loop_filter=1;
        s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus;
        break;
    case CODEC_ID_MPEG4:
        s->out_format = FMT_H263;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->low_delay= s->max_b_frames ? 0 : 1;
        avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1);
        break;
    case CODEC_ID_MSMPEG4V1:
        s->out_format = FMT_H263;
        s->h263_msmpeg4 = 1;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->msmpeg4_version= 1;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_MSMPEG4V2:
        s->out_format = FMT_H263;
        s->h263_msmpeg4 = 1;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->msmpeg4_version= 2;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_MSMPEG4V3:
        s->out_format = FMT_H263;
        s->h263_msmpeg4 = 1;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->msmpeg4_version= 3;
        s->flipflop_rounding=1;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_WMV1:
        s->out_format = FMT_H263;
        s->h263_msmpeg4 = 1;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->msmpeg4_version= 4;
        s->flipflop_rounding=1;
        avctx->delay=0;
        s->low_delay=1;
        break;
    case CODEC_ID_WMV2:
        s->out_format = FMT_H263;
        s->h263_msmpeg4 = 1;
        s->h263_pred = 1;
        s->unrestricted_mv = 1;
        s->msmpeg4_version= 5;
        s->flipflop_rounding=1;
        avctx->delay=0;
        s->low_delay=1;
        break;
    default:
        return -1;
    }

    avctx->has_b_frames= !s->low_delay;

    s->encoding = 1;

    /* init */
    if (MPV_common_init(s) < 0)
        return -1;

    if(!s->dct_quantize)
        s->dct_quantize = dct_quantize_c;
    if(!s->denoise_dct)
        s->denoise_dct = denoise_dct_c;
    s->fast_dct_quantize = s->dct_quantize;
    if(avctx->trellis)
        s->dct_quantize = dct_quantize_trellis_c;

    if((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
        s->chroma_qscale_table= ff_h263_chroma_qscale_table;
    s->progressive_frame=
    s->progressive_sequence= !(avctx->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN));
    s->quant_precision=5;

    ff_set_cmp(&s->dsp, s->dsp.ildct_cmp, s->avctx->ildct_cmp);
    ff_set_cmp(&s->dsp, s->dsp.frame_skip_cmp, s->avctx->frame_skip_cmp);

    if (CONFIG_H261_ENCODER && s->out_format == FMT_H261)
        ff_h261_encode_init(s);
    if (CONFIG_ANY_H263_ENCODER && s->out_format == FMT_H263)
        h263_encode_init(s);
    if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version)
        ff_msmpeg4_encode_init(s);
    if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
        && s->out_format == FMT_MPEG1)
        ff_mpeg1_encode_init(s);

    /* init q matrix */
    for(i=0;i<64;i++) {
        int j= s->dsp.idct_permutation[i];
        if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->mpeg_quant){
            s->intra_matrix[j] = ff_mpeg4_default_intra_matrix[i];
            s->inter_matrix[j] = ff_mpeg4_default_non_intra_matrix[i];
        }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
            s->intra_matrix[j] =
            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
        }else
        { /* mpeg1/2 */
            s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i];
            s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i];
        }
        if(s->avctx->intra_matrix)
            s->intra_matrix[j] = s->avctx->intra_matrix[i];
        if(s->avctx->inter_matrix)
            s->inter_matrix[j] = s->avctx->inter_matrix[i];
    }

    /* precompute matrix */
    /* for mjpeg, we do include qscale in the matrix */
    if (s->out_format != FMT_MJPEG) {
        ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,
                       s->intra_matrix, s->intra_quant_bias, avctx->qmin, 31, 1);
        ff_convert_matrix(&s->dsp, s->q_inter_matrix, s->q_inter_matrix16,
                       s->inter_matrix, s->inter_quant_bias, avctx->qmin, 31, 0);
    }

    if(ff_rate_control_init(s) < 0)
        return -1;

    return 0;
}

av_cold int MPV_encode_end(AVCodecContext *avctx)
{
    MpegEncContext *s = avctx->priv_data;

    ff_rate_control_uninit(s);

    MPV_common_end(s);
    if ((CONFIG_MJPEG_ENCODER || CONFIG_LJPEG_ENCODER) && s->out_format == FMT_MJPEG)
        ff_mjpeg_encode_close(s);

    av_freep(&avctx->extradata);

    return 0;
}

static int get_sae(uint8_t *src, int ref, int stride){
    int x,y;
    int acc=0;

    for(y=0; y<16; y++){
        for(x=0; x<16; x++){
            acc+= FFABS(src[x+y*stride] - ref);
        }
    }

    return acc;
}

static int get_intra_count(MpegEncContext *s, uint8_t *src, uint8_t *ref, int stride){
    int x, y, w, h;
    int acc=0;

    w= s->width &~15;
    h= s->height&~15;

    for(y=0; y<h; y+=16){
        for(x=0; x<w; x+=16){
            int offset= x + y*stride;
            int sad = s->dsp.sad[0](NULL, src + offset, ref + offset, stride, 16);
            int mean= (s->dsp.pix_sum(src + offset, stride) + 128)>>8;
            int sae = get_sae(src + offset, mean, stride);

            acc+= sae + 500 < sad;
        }
    }
    return acc;
}


static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg){
    AVFrame *pic=NULL;
    int64_t pts;
    int i;
    const int encoding_delay= s->max_b_frames;
    int direct=1;

    if(pic_arg){
        pts= pic_arg->pts;
        pic_arg->display_picture_number= s->input_picture_number++;

        if(pts != AV_NOPTS_VALUE){
            if(s->user_specified_pts != AV_NOPTS_VALUE){
                int64_t time= pts;
                int64_t last= s->user_specified_pts;

                if(time <= last){
                    av_log(s->avctx, AV_LOG_ERROR, "Error, Invalid timestamp=%"PRId64", last=%"PRId64"\n", pts, s->user_specified_pts);
                    return -1;
                }
            }
            s->user_specified_pts= pts;
        }else{
            if(s->user_specified_pts != AV_NOPTS_VALUE){
                s->user_specified_pts=
                pts= s->user_specified_pts + 1;
                av_log(s->avctx, AV_LOG_INFO, "Warning: AVFrame.pts=? trying to guess (%"PRId64")\n", pts);
            }else{
                pts= pic_arg->display_picture_number;
            }
        }
    }

  if(pic_arg){
    if(encoding_delay && !(s->flags&CODEC_FLAG_INPUT_PRESERVED)) direct=0;
    if(pic_arg->linesize[0] != s->linesize) direct=0;
    if(pic_arg->linesize[1] != s->uvlinesize) direct=0;
    if(pic_arg->linesize[2] != s->uvlinesize) direct=0;

//    av_log(AV_LOG_DEBUG, "%d %d %d %d\n",pic_arg->linesize[0], pic_arg->linesize[1], s->linesize, s->uvlinesize);

    if(direct){
        i= ff_find_unused_picture(s, 1);

        pic= (AVFrame*)&s->picture[i];
        pic->reference= 3;

        for(i=0; i<4; i++){
            pic->data[i]= pic_arg->data[i];
            pic->linesize[i]= pic_arg->linesize[i];
        }
        alloc_picture(s, (Picture*)pic, 1);
    }else{
        i= ff_find_unused_picture(s, 0);

        pic= (AVFrame*)&s->picture[i];
        pic->reference= 3;

        alloc_picture(s, (Picture*)pic, 0);

        if(   pic->data[0] + INPLACE_OFFSET == pic_arg->data[0]
           && pic->data[1] + INPLACE_OFFSET == pic_arg->data[1]
           && pic->data[2] + INPLACE_OFFSET == pic_arg->data[2]){
       // empty
        }else{
            int h_chroma_shift, v_chroma_shift;
            avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift);

            for(i=0; i<3; i++){
                int src_stride= pic_arg->linesize[i];
                int dst_stride= i ? s->uvlinesize : s->linesize;
                int h_shift= i ? h_chroma_shift : 0;
                int v_shift= i ? v_chroma_shift : 0;
                int w= s->width >>h_shift;
                int h= s->height>>v_shift;
                uint8_t *src= pic_arg->data[i];
                uint8_t *dst= pic->data[i];

                if(!s->avctx->rc_buffer_size)
                    dst +=INPLACE_OFFSET;

                if(src_stride==dst_stride)
                    memcpy(dst, src, src_stride*h);
                else{
                    while(h--){
                        memcpy(dst, src, w);
                        dst += dst_stride;
                        src += src_stride;
                    }
                }
            }
        }
    }
    copy_picture_attributes(s, pic, pic_arg);
    pic->pts= pts; //we set this here to avoid modifiying pic_arg
  }

    /* shift buffer entries */
    for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++)
        s->input_picture[i-1]= s->input_picture[i];

    s->input_picture[encoding_delay]= (Picture*)pic;

    return 0;
}

static int skip_check(MpegEncContext *s, Picture *p, Picture *ref){
    int x, y, plane;
    int score=0;
    int64_t score64=0;

    for(plane=0; plane<3; plane++){
        const int stride= p->linesize[plane];
        const int bw= plane ? 1 : 2;
        for(y=0; y<s->mb_height*bw; y++){
            for(x=0; x<s->mb_width*bw; x++){
                int off= p->type == FF_BUFFER_TYPE_SHARED ? 0: 16;
                int v= s->dsp.frame_skip_cmp[1](s, p->data[plane] + 8*(x + y*stride)+off, ref->data[plane] + 8*(x + y*stride), stride, 8);

                switch(s->avctx->frame_skip_exp){
                    case 0: score= FFMAX(score, v); break;
                    case 1: score+= FFABS(v);break;
                    case 2: score+= v*v;break;
                    case 3: score64+= FFABS(v*v*(int64_t)v);break;
                    case 4: score64+= v*v*(int64_t)(v*v);break;
                }
            }
        }
    }

    if(score) score64= score;

    if(score64 < s->avctx->frame_skip_threshold)
        return 1;
    if(score64 < ((s->avctx->frame_skip_factor * (int64_t)s->lambda)>>8))
        return 1;
    return 0;
}

static int estimate_best_b_count(MpegEncContext *s){
    AVCodec *codec= avcodec_find_encoder(s->avctx->codec_id);
    AVCodecContext *c= avcodec_alloc_context();
    AVFrame input[FF_MAX_B_FRAMES+2];
    const int scale= s->avctx->brd_scale;
    int i, j, out_size, p_lambda, b_lambda, lambda2;
    int outbuf_size= s->width * s->height; //FIXME
    uint8_t *outbuf= av_malloc(outbuf_size);
    int64_t best_rd= INT64_MAX;
    int best_b_count= -1;

    assert(scale>=0 && scale <=3);

//    emms_c();
    p_lambda= s->last_lambda_for[FF_P_TYPE]; //s->next_picture_ptr->quality;
    b_lambda= s->last_lambda_for[FF_B_TYPE]; //p_lambda *FFABS(s->avctx->b_quant_factor) + s->avctx->b_quant_offset;
    if(!b_lambda) b_lambda= p_lambda; //FIXME we should do this somewhere else
    lambda2= (b_lambda*b_lambda + (1<<FF_LAMBDA_SHIFT)/2 ) >> FF_LAMBDA_SHIFT;

    c->width = s->width >> scale;
    c->height= s->height>> scale;
    c->flags= CODEC_FLAG_QSCALE | CODEC_FLAG_PSNR | CODEC_FLAG_INPUT_PRESERVED /*| CODEC_FLAG_EMU_EDGE*/;
    c->flags|= s->avctx->flags & CODEC_FLAG_QPEL;
    c->mb_decision= s->avctx->mb_decision;
    c->me_cmp= s->avctx->me_cmp;
    c->mb_cmp= s->avctx->mb_cmp;
    c->me_sub_cmp= s->avctx->me_sub_cmp;
    c->pix_fmt = PIX_FMT_YUV420P;
    c->time_base= s->avctx->time_base;
    c->max_b_frames= s->max_b_frames;

    if (avcodec_open(c, codec) < 0)
        return -1;

    for(i=0; i<s->max_b_frames+2; i++){
        int ysize= c->width*c->height;
        int csize= (c->width/2)*(c->height/2);
        Picture pre_input, *pre_input_ptr= i ? s->input_picture[i-1] : s->next_picture_ptr;

        avcodec_get_frame_defaults(&input[i]);
        input[i].data[0]= av_malloc(ysize + 2*csize);
        input[i].data[1]= input[i].data[0] + ysize;
        input[i].data[2]= input[i].data[1] + csize;
        input[i].linesize[0]= c->width;
        input[i].linesize[1]=
        input[i].linesize[2]= c->width/2;

        if(pre_input_ptr && (!i || s->input_picture[i-1])) {
            pre_input= *pre_input_ptr;

            if(pre_input.type != FF_BUFFER_TYPE_SHARED && i) {
                pre_input.data[0]+=INPLACE_OFFSET;
                pre_input.data[1]+=INPLACE_OFFSET;
                pre_input.data[2]+=INPLACE_OFFSET;
            }

            s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], pre_input.data[0], pre_input.linesize[0], c->width, c->height);
            s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], pre_input.data[1], pre_input.linesize[1], c->width>>1, c->height>>1);
            s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], pre_input.data[2], pre_input.linesize[2], c->width>>1, c->height>>1);
        }
    }

    for(j=0; j<s->max_b_frames+1; j++){
        int64_t rd=0;

        if(!s->input_picture[j])
            break;

        c->error[0]= c->error[1]= c->error[2]= 0;

        input[0].pict_type= FF_I_TYPE;
        input[0].quality= 1 * FF_QP2LAMBDA;
        out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[0]);
//        rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT;

        for(i=0; i<s->max_b_frames+1; i++){
            int is_p= i % (j+1) == j || i==s->max_b_frames;

            input[i+1].pict_type= is_p ? FF_P_TYPE : FF_B_TYPE;
            input[i+1].quality= is_p ? p_lambda : b_lambda;
            out_size = avcodec_encode_video(c, outbuf, outbuf_size, &input[i+1]);
            rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
        }

        /* get the delayed frames */
        while(out_size){
            out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
            rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3);
        }

        rd += c->error[0] + c->error[1] + c->error[2];

        if(rd < best_rd){
            best_rd= rd;
            best_b_count= j;
        }
    }

    av_freep(&outbuf);
    avcodec_close(c);
    av_freep(&c);

    for(i=0; i<s->max_b_frames+2; i++){
        av_freep(&input[i].data[0]);
    }

    return best_b_count;
}

static void select_input_picture(MpegEncContext *s){
    int i;

    for(i=1; i<MAX_PICTURE_COUNT; i++)
        s->reordered_input_picture[i-1]= s->reordered_input_picture[i];
    s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL;

    /* set next picture type & ordering */
    if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){
        if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture_ptr==NULL || s->intra_only){
            s->reordered_input_picture[0]= s->input_picture[0];
            s->reordered_input_picture[0]->pict_type= FF_I_TYPE;
            s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++;
        }else{
            int b_frames;

            if(s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor){
                if(s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)){
                //FIXME check that te gop check above is +-1 correct
//av_log(NULL, AV_LOG_DEBUG, "skip %p %"PRId64"\n", s->input_picture[0]->data[0], s->input_picture[0]->pts);

                    if(s->input_picture[0]->type == FF_BUFFER_TYPE_SHARED){
                        for(i=0; i<4; i++)
                            s->input_picture[0]->data[i]= NULL;
                        s->input_picture[0]->type= 0;
                    }else{
                        assert(   s->input_picture[0]->type==FF_BUFFER_TYPE_USER
                               || s->input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL);

                        s->avctx->release_buffer(s->avctx, (AVFrame*)s->input_picture[0]);
                    }

                    emms_c();
                    ff_vbv_update(s, 0);

                    goto no_output_pic;
                }
            }

            if(s->flags&CODEC_FLAG_PASS2){
                for(i=0; i<s->max_b_frames+1; i++){
                    int pict_num= s->input_picture[0]->display_picture_number + i;

                    if(pict_num >= s->rc_context.num_entries)
                        break;
                    if(!s->input_picture[i]){
                        s->rc_context.entry[pict_num-1].new_pict_type = FF_P_TYPE;
                        break;
                    }

                    s->input_picture[i]->pict_type=
                        s->rc_context.entry[pict_num].new_pict_type;
                }
            }

            if(s->avctx->b_frame_strategy==0){
                b_frames= s->max_b_frames;
                while(b_frames && !s->input_picture[b_frames]) b_frames--;
            }else if(s->avctx->b_frame_strategy==1){
                for(i=1; i<s->max_b_frames+1; i++){
                    if(s->input_picture[i] && s->input_picture[i]->b_frame_score==0){
                        s->input_picture[i]->b_frame_score=
                            get_intra_count(s, s->input_picture[i  ]->data[0],
                                               s->input_picture[i-1]->data[0], s->linesize) + 1;
                    }
                }
                for(i=0; i<s->max_b_frames+1; i++){
                    if(s->input_picture[i]==NULL || s->input_picture[i]->b_frame_score - 1 > s->mb_num/s->avctx->b_sensitivity) break;
                }

                b_frames= FFMAX(0, i-1);

                /* reset scores */
                for(i=0; i<b_frames+1; i++){
                    s->input_picture[i]->b_frame_score=0;
                }
            }else if(s->avctx->b_frame_strategy==2){
                b_frames= estimate_best_b_count(s);
            }else{
                av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n");
                b_frames=0;
            }

            emms_c();
//static int b_count=0;
//b_count+= b_frames;
//av_log(s->avctx, AV_LOG_DEBUG, "b_frames: %d\n", b_count);

            for(i= b_frames - 1; i>=0; i--){
                int type= s->input_picture[i]->pict_type;
                if(type && type != FF_B_TYPE)
                    b_frames= i;
            }
            if(s->input_picture[b_frames]->pict_type == FF_B_TYPE && b_frames == s->max_b_frames){
                av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n");
            }

            if(s->picture_in_gop_number + b_frames >= s->gop_size){
              if((s->flags2 & CODEC_FLAG2_STRICT_GOP) && s->gop_size > s->picture_in_gop_number){
                    b_frames= s->gop_size - s->picture_in_gop_number - 1;
              }else{
                if(s->flags & CODEC_FLAG_CLOSED_GOP)
                    b_frames=0;
                s->input_picture[b_frames]->pict_type= FF_I_TYPE;
              }
            }

            if(   (s->flags & CODEC_FLAG_CLOSED_GOP)
               && b_frames
               && s->input_picture[b_frames]->pict_type== FF_I_TYPE)
                b_frames--;

            s->reordered_input_picture[0]= s->input_picture[b_frames];
            if(s->reordered_input_picture[0]->pict_type != FF_I_TYPE)
                s->reordered_input_picture[0]->pict_type= FF_P_TYPE;
            s->reordered_input_picture[0]->coded_picture_number= s->coded_picture_number++;
            for(i=0; i<b_frames; i++){
                s->reordered_input_picture[i+1]= s->input_picture[i];
                s->reordered_input_picture[i+1]->pict_type= FF_B_TYPE;
                s->reordered_input_picture[i+1]->coded_picture_number= s->coded_picture_number++;
            }
        }
    }
no_output_pic:
    if(s->reordered_input_picture[0]){
        s->reordered_input_picture[0]->reference= s->reordered_input_picture[0]->pict_type!=FF_B_TYPE ? 3 : 0;

        ff_copy_picture(&s->new_picture, s->reordered_input_picture[0]);

        if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_SHARED || s->avctx->rc_buffer_size){
            // input is a shared pix, so we can't modifiy it -> alloc a new one & ensure that the shared one is reuseable

            int i= ff_find_unused_picture(s, 0);
            Picture *pic= &s->picture[i];

            pic->reference              = s->reordered_input_picture[0]->reference;
            alloc_picture(s, pic, 0);

            /* mark us unused / free shared pic */
            if(s->reordered_input_picture[0]->type == FF_BUFFER_TYPE_INTERNAL)
                s->avctx->release_buffer(s->avctx, (AVFrame*)s->reordered_input_picture[0]);
            for(i=0; i<4; i++)
                s->reordered_input_picture[0]->data[i]= NULL;
            s->reordered_input_picture[0]->type= 0;

            copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]);

            s->current_picture_ptr= pic;
        }else{
            // input is not a shared pix -> reuse buffer for current_pix

            assert(   s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_USER
                   || s->reordered_input_picture[0]->type==FF_BUFFER_TYPE_INTERNAL);

            s->current_picture_ptr= s->reordered_input_picture[0];
            for(i=0; i<4; i++){
                s->new_picture.data[i]+= INPLACE_OFFSET;
            }
        }
        ff_copy_picture(&s->current_picture, s->current_picture_ptr);

        s->picture_number= s->new_picture.display_picture_number;
//printf("dpn:%d\n", s->picture_number);
    }else{
       memset(&s->new_picture, 0, sizeof(Picture));
    }
}

int MPV_encode_picture(AVCodecContext *avctx,
                       unsigned char *buf, int buf_size, void *data)
{
    MpegEncContext *s = avctx->priv_data;
    AVFrame *pic_arg = data;
    int i, stuffing_count;

    for(i=0; i<avctx->thread_count; i++){
        int start_y= s->thread_context[i]->start_mb_y;
        int   end_y= s->thread_context[i]->  end_mb_y;
        int h= s->mb_height;
        uint8_t *start= buf + (size_t)(((int64_t) buf_size)*start_y/h);
        uint8_t *end  = buf + (size_t)(((int64_t) buf_size)*  end_y/h);

        init_put_bits(&s->thread_context[i]->pb, start, end - start);
    }

    s->picture_in_gop_number++;

    if(load_input_picture(s, pic_arg) < 0)
        return -1;

    select_input_picture(s);

    /* output? */
    if(s->new_picture.data[0]){
        s->pict_type= s->new_picture.pict_type;
//emms_c();
//printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale);
        MPV_frame_start(s, avctx);
vbv_retry:
        if (encode_picture(s, s->picture_number) < 0)
            return -1;

        avctx->real_pict_num  = s->picture_number;
        avctx->header_bits = s->header_bits;
        avctx->mv_bits     = s->mv_bits;
        avctx->misc_bits   = s->misc_bits;
        avctx->i_tex_bits  = s->i_tex_bits;
        avctx->p_tex_bits  = s->p_tex_bits;
        avctx->i_count     = s->i_count;
        avctx->p_count     = s->mb_num - s->i_count - s->skip_count; //FIXME f/b_count in avctx
        avctx->skip_count  = s->skip_count;

        MPV_frame_end(s);

        if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)
            ff_mjpeg_encode_picture_trailer(s);

        if(avctx->rc_buffer_size){
            RateControlContext *rcc= &s->rc_context;
            int max_size= rcc->buffer_index * avctx->rc_max_available_vbv_use;

            if(put_bits_count(&s->pb) > max_size && s->lambda < s->avctx->lmax){
                s->next_lambda= FFMAX(s->lambda+1, s->lambda*(s->qscale+1) / s->qscale);
                if(s->adaptive_quant){
                    int i;
                    for(i=0; i<s->mb_height*s->mb_stride; i++)
                        s->lambda_table[i]= FFMAX(s->lambda_table[i]+1, s->lambda_table[i]*(s->qscale+1) / s->qscale);
                }
                s->mb_skipped = 0;        //done in MPV_frame_start()
                if(s->pict_type==FF_P_TYPE){ //done in encode_picture() so we must undo it
                    if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4)
                        s->no_rounding ^= 1;
                }
                if(s->pict_type!=FF_B_TYPE){
                    s->time_base= s->last_time_base;
                    s->last_non_b_time= s->time - s->pp_time;
                }
//                av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda);
                for(i=0; i<avctx->thread_count; i++){
                    PutBitContext *pb= &s->thread_context[i]->pb;
                    init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);
                }
                goto vbv_retry;
            }

            assert(s->avctx->rc_max_rate);
        }

        if(s->flags&CODEC_FLAG_PASS1)
            ff_write_pass1_stats(s);

        for(i=0; i<4; i++){
            s->current_picture_ptr->error[i]= s->current_picture.error[i];
            avctx->error[i] += s->current_picture_ptr->error[i];
        }

        if(s->flags&CODEC_FLAG_PASS1)
            assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits + avctx->i_tex_bits + avctx->p_tex_bits == put_bits_count(&s->pb));
        flush_put_bits(&s->pb);
        s->frame_bits  = put_bits_count(&s->pb);

        stuffing_count= ff_vbv_update(s, s->frame_bits);
        if(stuffing_count){
            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < stuffing_count + 50){
                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");
                return -1;
            }

            switch(s->codec_id){
            case CODEC_ID_MPEG1VIDEO:
            case CODEC_ID_MPEG2VIDEO:
                while(stuffing_count--){
                    put_bits(&s->pb, 8, 0);
                }
            break;
            case CODEC_ID_MPEG4:
                put_bits(&s->pb, 16, 0);
                put_bits(&s->pb, 16, 0x1C3);
                stuffing_count -= 4;
                while(stuffing_count--){
                    put_bits(&s->pb, 8, 0xFF);
                }
            break;
            default:
                av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");
            }
            flush_put_bits(&s->pb);
            s->frame_bits  = put_bits_count(&s->pb);
        }

        /* update mpeg1/2 vbv_delay for CBR */
        if(s->avctx->rc_max_rate && s->avctx->rc_min_rate == s->avctx->rc_max_rate && s->out_format == FMT_MPEG1
           && 90000LL * (avctx->rc_buffer_size-1) <= s->avctx->rc_max_rate*0xFFFFLL){
            int vbv_delay;

            assert(s->repeat_first_field==0);

            vbv_delay= lrintf(90000 * s->rc_context.buffer_index / s->avctx->rc_max_rate);
            assert(vbv_delay < 0xFFFF);

            s->vbv_delay_ptr[0] &= 0xF8;
            s->vbv_delay_ptr[0] |= vbv_delay>>13;
            s->vbv_delay_ptr[1]  = vbv_delay>>5;
            s->vbv_delay_ptr[2] &= 0x07;
            s->vbv_delay_ptr[2] |= vbv_delay<<3;
        }
        s->total_bits += s->frame_bits;
        avctx->frame_bits  = s->frame_bits;
    }else{
        assert((pbBufPtr(&s->pb) == s->pb.buf));
        s->frame_bits=0;
    }
    assert((s->frame_bits&7)==0);

    return s->frame_bits/8;
}

static inline void dct_single_coeff_elimination(MpegEncContext *s, int n, int threshold)
{
    static const char tab[64]=
        {3,2,2,1,1,1,1,1,
         1,1,1,1,1,1,1,1,
         1,1,1,1,1,1,1,1,
         0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0,
         0,0,0,0,0,0,0,0};
    int score=0;
    int run=0;
    int i;
    DCTELEM *block= s->block[n];
    const int last_index= s->block_last_index[n];
    int skip_dc;

    if(threshold<0){
        skip_dc=0;
        threshold= -threshold;
    }else
        skip_dc=1;

    /* Are all we could set to zero already zero? */
    if(last_index<=skip_dc - 1) return;

    for(i=0; i<=last_index; i++){
        const int j = s->intra_scantable.permutated[i];
        const int level = FFABS(block[j]);
        if(level==1){
            if(skip_dc && i==0) continue;
            score+= tab[run];
            run=0;
        }else if(level>1){
            return;
        }else{
            run++;
        }
    }
    if(score >= threshold) return;
    for(i=skip_dc; i<=last_index; i++){
        const int j = s->intra_scantable.permutated[i];
        block[j]=0;
    }
    if(block[0]) s->block_last_index[n]= 0;
    else         s->block_last_index[n]= -1;
}

static inline void clip_coeffs(MpegEncContext *s, DCTELEM *block, int last_index)
{
    int i;
    const int maxlevel= s->max_qcoeff;
    const int minlevel= s->min_qcoeff;
    int overflow=0;

    if(s->mb_intra){
        i=1; //skip clipping of intra dc
    }else
        i=0;

    for(;i<=last_index; i++){
        const int j= s->intra_scantable.permutated[i];
        int level = block[j];

        if     (level>maxlevel){
            level=maxlevel;
            overflow++;
        }else if(level<minlevel){
            level=minlevel;
            overflow++;
        }

        block[j]= level;
    }

    if(overflow && s->avctx->mb_decision == FF_MB_DECISION_SIMPLE)
        av_log(s->avctx, AV_LOG_INFO, "warning, clipping %d dct coefficients to %d..%d\n", overflow, minlevel, maxlevel);
}

static void get_visual_weight(int16_t *weight, uint8_t *ptr, int stride){
    int x, y;
//FIXME optimize
    for(y=0; y<8; y++){
        for(x=0; x<8; x++){
            int x2, y2;
            int sum=0;
            int sqr=0;
            int count=0;

            for(y2= FFMAX(y-1, 0); y2 < FFMIN(8, y+2); y2++){
                for(x2= FFMAX(x-1, 0); x2 < FFMIN(8, x+2); x2++){
                    int v= ptr[x2 + y2*stride];
                    sum += v;
                    sqr += v*v;
                    count++;
                }
            }
            weight[x + 8*y]= (36*ff_sqrt(count*sqr - sum*sum)) / count;
        }
    }
}

static av_always_inline void encode_mb_internal(MpegEncContext *s, int motion_x, int motion_y, int mb_block_height, int mb_block_count)
{
    int16_t weight[8][64];
    DCTELEM orig[8][64];
    const int mb_x= s->mb_x;
    const int mb_y= s->mb_y;
    int i;
    int skip_dct[8];
    int dct_offset   = s->linesize*8; //default for progressive frames
    uint8_t *ptr_y, *ptr_cb, *ptr_cr;
    int wrap_y, wrap_c;

    for(i=0; i<mb_block_count; i++) skip_dct[i]=s->skipdct;

    if(s->adaptive_quant){
        const int last_qp= s->qscale;
        const int mb_xy= mb_x + mb_y*s->mb_stride;

        s->lambda= s->lambda_table[mb_xy];
        update_qscale(s);

        if(!(s->flags&CODEC_FLAG_QP_RD)){
            s->qscale= s->current_picture_ptr->qscale_table[mb_xy];
            s->dquant= s->qscale - last_qp;

            if(s->out_format==FMT_H263){
                s->dquant= av_clip(s->dquant, -2, 2);

                if(s->codec_id==CODEC_ID_MPEG4){
                    if(!s->mb_intra){
                        if(s->pict_type == FF_B_TYPE){
                            if(s->dquant&1 || s->mv_dir&MV_DIRECT)
                                s->dquant= 0;
                        }
                        if(s->mv_type==MV_TYPE_8X8)
                            s->dquant=0;
                    }
                }
            }
        }
        ff_set_qscale(s, last_qp + s->dquant);
    }else if(s->flags&CODEC_FLAG_QP_RD)
        ff_set_qscale(s, s->qscale + s->dquant);

    wrap_y = s->linesize;
    wrap_c = s->uvlinesize;
    ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16;
    ptr_cb = s->new_picture.data[1] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;
    ptr_cr = s->new_picture.data[2] + (mb_y * mb_block_height * wrap_c) + mb_x * 8;

    if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){
        uint8_t *ebuf= s->edge_emu_buffer + 32;
        ff_emulated_edge_mc(ebuf            , ptr_y , wrap_y,16,16,mb_x*16,mb_y*16, s->width   , s->height);
        ptr_y= ebuf;
        ff_emulated_edge_mc(ebuf+18*wrap_y  , ptr_cb, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
        ptr_cb= ebuf+18*wrap_y;
        ff_emulated_edge_mc(ebuf+18*wrap_y+8, ptr_cr, wrap_c, 8, mb_block_height, mb_x*8, mb_y*8, s->width>>1, s->height>>1);
        ptr_cr= ebuf+18*wrap_y+8;
    }

    if (s->mb_intra) {
        if(s->flags&CODEC_FLAG_INTERLACED_DCT){
            int progressive_score, interlaced_score;

            s->interlaced_dct=0;
            progressive_score= s->dsp.ildct_cmp[4](s, ptr_y           , NULL, wrap_y, 8)
                              +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y*8, NULL, wrap_y, 8) - 400;

            if(progressive_score > 0){
                interlaced_score = s->dsp.ildct_cmp[4](s, ptr_y           , NULL, wrap_y*2, 8)
                                  +s->dsp.ildct_cmp[4](s, ptr_y + wrap_y  , NULL, wrap_y*2, 8);
                if(progressive_score > interlaced_score){
                    s->interlaced_dct=1;

                    dct_offset= wrap_y;
                    wrap_y<<=1;
                    if (s->chroma_format == CHROMA_422)
                        wrap_c<<=1;
                }
            }
        }

        s->dsp.get_pixels(s->block[0], ptr_y                 , wrap_y);
        s->dsp.get_pixels(s->block[1], ptr_y              + 8, wrap_y);
        s->dsp.get_pixels(s->block[2], ptr_y + dct_offset    , wrap_y);
        s->dsp.get_pixels(s->block[3], ptr_y + dct_offset + 8, wrap_y);

        if(s->flags&CODEC_FLAG_GRAY){
            skip_dct[4]= 1;
            skip_dct[5]= 1;
        }else{
            s->dsp.get_pixels(s->block[4], ptr_cb, wrap_c);
            s->dsp.get_pixels(s->block[5], ptr_cr, wrap_c);
            if(!s->chroma_y_shift){ /* 422 */
                s->dsp.get_pixels(s->block[6], ptr_cb + (dct_offset>>1), wrap_c);
                s->dsp.get_pixels(s->block[7], ptr_cr + (dct_offset>>1), wrap_c);
            }
        }
    }else{
        op_pixels_func (*op_pix)[4];
        qpel_mc_func (*op_qpix)[16];
        uint8_t *dest_y, *dest_cb, *dest_cr;

        dest_y  = s->dest[0];
        dest_cb = s->dest[1];
        dest_cr = s->dest[2];

        if ((!s->no_rounding) || s->pict_type==FF_B_TYPE){
            op_pix = s->dsp.put_pixels_tab;
            op_qpix= s->dsp.put_qpel_pixels_tab;
        }else{
            op_pix = s->dsp.put_no_rnd_pixels_tab;
            op_qpix= s->dsp.put_no_rnd_qpel_pixels_tab;
        }

        if (s->mv_dir & MV_DIR_FORWARD) {
            MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix);
            op_pix = s->dsp.avg_pixels_tab;
            op_qpix= s->dsp.avg_qpel_pixels_tab;
        }
        if (s->mv_dir & MV_DIR_BACKWARD) {
            MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix);
        }

        if(s->flags&CODEC_FLAG_INTERLACED_DCT){
            int progressive_score, interlaced_score;

            s->interlaced_dct=0;
            progressive_score= s->dsp.ildct_cmp[0](s, dest_y           , ptr_y           , wrap_y, 8)
                              +s->dsp.ildct_cmp[0](s, dest_y + wrap_y*8, ptr_y + wrap_y*8, wrap_y, 8) - 400;

            if(s->avctx->ildct_cmp == FF_CMP_VSSE) progressive_score -= 400;

            if(progressive_score>0){
                interlaced_score = s->dsp.ildct_cmp[0](s, dest_y           , ptr_y           , wrap_y*2, 8)
                                  +s->dsp.ildct_cmp[0](s, dest_y + wrap_y  , ptr_y + wrap_y  , wrap_y*2, 8);

                if(progressive_score > interlaced_score){
                    s->interlaced_dct=1;

                    dct_offset= wrap_y;
                    wrap_y<<=1;
                    if (s->chroma_format == CHROMA_422)
                        wrap_c<<=1;
                }
            }
        }

        s->dsp.diff_pixels(s->block[0], ptr_y                 , dest_y                 , wrap_y);
        s->dsp.diff_pixels(s->block[1], ptr_y              + 8, dest_y              + 8, wrap_y);
        s->dsp.diff_pixels(s->block[2], ptr_y + dct_offset    , dest_y + dct_offset    , wrap_y);
        s->dsp.diff_pixels(s->block[3], ptr_y + dct_offset + 8, dest_y + dct_offset + 8, wrap_y);

        if(s->flags&CODEC_FLAG_GRAY){
            skip_dct[4]= 1;
            skip_dct[5]= 1;
        }else{
            s->dsp.diff_pixels(s->block[4], ptr_cb, dest_cb, wrap_c);
            s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c);
            if(!s->chroma_y_shift){ /* 422 */
                s->dsp.diff_pixels(s->block[6], ptr_cb + (dct_offset>>1), dest_cb + (dct_offset>>1), wrap_c);
                s->dsp.diff_pixels(s->block[7], ptr_cr + (dct_offset>>1), dest_cr + (dct_offset>>1), wrap_c);
            }
        }
        /* pre quantization */
        if(s->current_picture.mc_mb_var[s->mb_stride*mb_y+ mb_x]<2*s->qscale*s->qscale){
            //FIXME optimize
            if(s->dsp.sad[1](NULL, ptr_y               , dest_y               , wrap_y, 8) < 20*s->qscale) skip_dct[0]= 1;
            if(s->dsp.sad[1](NULL, ptr_y            + 8, dest_y            + 8, wrap_y, 8) < 20*s->qscale) skip_dct[1]= 1;
            if(s->dsp.sad[1](NULL, ptr_y +dct_offset   , dest_y +dct_offset   , wrap_y, 8) < 20*s->qscale) skip_dct[2]= 1;
            if(s->dsp.sad[1](NULL, ptr_y +dct_offset+ 8, dest_y +dct_offset+ 8, wrap_y, 8) < 20*s->qscale) skip_dct[3]= 1;
            if(s->dsp.sad[1](NULL, ptr_cb              , dest_cb              , wrap_c, 8) < 20*s->qscale) skip_dct[4]= 1;
            if(s->dsp.sad[1](NULL, ptr_cr              , dest_cr              , wrap_c, 8) < 20*s->qscale) skip_dct[5]= 1;
            if(!s->chroma_y_shift){ /* 422 */
                if(s->dsp.sad[1](NULL, ptr_cb +(dct_offset>>1), dest_cb +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[6]= 1;
                if(s->dsp.sad[1](NULL, ptr_cr +(dct_offset>>1), dest_cr +(dct_offset>>1), wrap_c, 8) < 20*s->qscale) skip_dct[7]= 1;
            }
        }
    }

    if(s->avctx->quantizer_noise_shaping){
        if(!skip_dct[0]) get_visual_weight(weight[0], ptr_y                 , wrap_y);
        if(!skip_dct[1]) get_visual_weight(weight[1], ptr_y              + 8, wrap_y);
        if(!skip_dct[2]) get_visual_weight(weight[2], ptr_y + dct_offset    , wrap_y);
        if(!skip_dct[3]) get_visual_weight(weight[3], ptr_y + dct_offset + 8, wrap_y);
        if(!skip_dct[4]) get_visual_weight(weight[4], ptr_cb                , wrap_c);
        if(!skip_dct[5]) get_visual_weight(weight[5], ptr_cr                , wrap_c);
        if(!s->chroma_y_shift){ /* 422 */
            if(!skip_dct[6]) get_visual_weight(weight[6], ptr_cb + (dct_offset>>1), wrap_c);
            if(!skip_dct[7]) get_visual_weight(weight[7], ptr_cr + (dct_offset>>1), wrap_c);
        }
        memcpy(orig[0], s->block[0], sizeof(DCTELEM)*64*mb_block_count);
    }

    /* DCT & quantize */
    assert(s->out_format!=FMT_MJPEG || s->qscale==8);
    {
        for(i=0;i<mb_block_count;i++) {
            if(!skip_dct[i]){
                int overflow;
                s->block_last_index[i] = s->dct_quantize(s, s->block[i], i, s->qscale, &overflow);
            // FIXME we could decide to change to quantizer instead of clipping
            // JS: I don't think that would be a good idea it could lower quality instead
            //     of improve it. Just INTRADC clipping deserves changes in quantizer
                if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]);
            }else
                s->block_last_index[i]= -1;
        }
        if(s->avctx->quantizer_noise_shaping){
            for(i=0;i<mb_block_count;i++) {
                if(!skip_dct[i]){
                    s->block_last_index[i] = dct_quantize_refine(s, s->block[i], weight[i], orig[i], i, s->qscale);
                }
            }
        }

        if(s->luma_elim_threshold && !s->mb_intra)
            for(i=0; i<4; i++)
                dct_single_coeff_elimination(s, i, s->luma_elim_threshold);
        if(s->chroma_elim_threshold && !s->mb_intra)
            for(i=4; i<mb_block_count; i++)
                dct_single_coeff_elimination(s, i, s->chroma_elim_threshold);

        if(s->flags & CODEC_FLAG_CBP_RD){
            for(i=0;i<mb_block_count;i++) {
                if(s->block_last_index[i] == -1)
                    s->coded_score[i]= INT_MAX/256;
            }
        }
    }

    if((s->flags&CODEC_FLAG_GRAY) && s->mb_intra){
        s->block_last_index[4]=
        s->block_last_index[5]= 0;
        s->block[4][0]=
        s->block[5][0]= (1024 + s->c_dc_scale/2)/ s->c_dc_scale;
    }

    //non c quantize code returns incorrect block_last_index FIXME
    if(s->alternate_scan && s->dct_quantize != dct_quantize_c){
        for(i=0; i<mb_block_count; i++){
            int j;
            if(s->block_last_index[i]>0){
                for(j=63; j>0; j--){
                    if(s->block[i][ s->intra_scantable.permutated[j] ]) break;
                }
                s->block_last_index[i]= j;
            }
        }
    }

    /* huffman encode */
    switch(s->codec_id){ //FIXME funct ptr could be slightly faster
    case CODEC_ID_MPEG1VIDEO:
    case CODEC_ID_MPEG2VIDEO:
        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
            mpeg1_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_MPEG4:
        if (CONFIG_MPEG4_ENCODER)
            mpeg4_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_MSMPEG4V2:
    case CODEC_ID_MSMPEG4V3:
    case CODEC_ID_WMV1:
        if (CONFIG_MSMPEG4_ENCODER)
            msmpeg4_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_WMV2:
        if (CONFIG_WMV2_ENCODER)
            ff_wmv2_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_H261:
        if (CONFIG_H261_ENCODER)
            ff_h261_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_H263:
    case CODEC_ID_H263P:
    case CODEC_ID_FLV1:
    case CODEC_ID_RV10:
    case CODEC_ID_RV20:
        if (CONFIG_H263_ENCODER || CONFIG_H263P_ENCODER ||
            CONFIG_FLV_ENCODER  || CONFIG_RV10_ENCODER  || CONFIG_RV20_ENCODER)
            h263_encode_mb(s, s->block, motion_x, motion_y);
        break;
    case CODEC_ID_MJPEG:
        if (CONFIG_MJPEG_ENCODER)
            ff_mjpeg_encode_mb(s, s->block);
        break;
    default:
        assert(0);
    }
}

static av_always_inline void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
{
    if (s->chroma_format == CHROMA_420) encode_mb_internal(s, motion_x, motion_y,  8, 6);
    else                                encode_mb_internal(s, motion_x, motion_y, 16, 8);
}

static inline void copy_context_before_encode(MpegEncContext *d, MpegEncContext *s, int type){
    int i;

    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?

    /* mpeg1 */
    d->mb_skip_run= s->mb_skip_run;
    for(i=0; i<3; i++)
        d->last_dc[i]= s->last_dc[i];

    /* statistics */
    d->mv_bits= s->mv_bits;
    d->i_tex_bits= s->i_tex_bits;
    d->p_tex_bits= s->p_tex_bits;
    d->i_count= s->i_count;
    d->f_count= s->f_count;
    d->b_count= s->b_count;
    d->skip_count= s->skip_count;
    d->misc_bits= s->misc_bits;
    d->last_bits= 0;

    d->mb_skipped= 0;
    d->qscale= s->qscale;
    d->dquant= s->dquant;

    d->esc3_level_length= s->esc3_level_length;
}

static inline void copy_context_after_encode(MpegEncContext *d, MpegEncContext *s, int type){
    int i;

    memcpy(d->mv, s->mv, 2*4*2*sizeof(int));
    memcpy(d->last_mv, s->last_mv, 2*2*2*sizeof(int)); //FIXME is memcpy faster then a loop?

    /* mpeg1 */
    d->mb_skip_run= s->mb_skip_run;
    for(i=0; i<3; i++)
        d->last_dc[i]= s->last_dc[i];

    /* statistics */
    d->mv_bits= s->mv_bits;
    d->i_tex_bits= s->i_tex_bits;
    d->p_tex_bits= s->p_tex_bits;
    d->i_count= s->i_count;
    d->f_count= s->f_count;
    d->b_count= s->b_count;
    d->skip_count= s->skip_count;
    d->misc_bits= s->misc_bits;

    d->mb_intra= s->mb_intra;
    d->mb_skipped= s->mb_skipped;
    d->mv_type= s->mv_type;
    d->mv_dir= s->mv_dir;
    d->pb= s->pb;
    if(s->data_partitioning){
        d->pb2= s->pb2;
        d->tex_pb= s->tex_pb;
    }
    d->block= s->block;
    for(i=0; i<8; i++)
        d->block_last_index[i]= s->block_last_index[i];
    d->interlaced_dct= s->interlaced_dct;
    d->qscale= s->qscale;

    d->esc3_level_length= s->esc3_level_length;
}

static inline void encode_mb_hq(MpegEncContext *s, MpegEncContext *backup, MpegEncContext *best, int type,
                           PutBitContext pb[2], PutBitContext pb2[2], PutBitContext tex_pb[2],
                           int *dmin, int *next_block, int motion_x, int motion_y)
{
    int score;
    uint8_t *dest_backup[3];

    copy_context_before_encode(s, backup, type);

    s->block= s->blocks[*next_block];
    s->pb= pb[*next_block];
    if(s->data_partitioning){
        s->pb2   = pb2   [*next_block];
        s->tex_pb= tex_pb[*next_block];
    }

    if(*next_block){
        memcpy(dest_backup, s->dest, sizeof(s->dest));
        s->dest[0] = s->rd_scratchpad;
        s->dest[1] = s->rd_scratchpad + 16*s->linesize;
        s->dest[2] = s->rd_scratchpad + 16*s->linesize + 8;
        assert(s->linesize >= 32); //FIXME
    }

    encode_mb(s, motion_x, motion_y);

    score= put_bits_count(&s->pb);
    if(s->data_partitioning){
        score+= put_bits_count(&s->pb2);
        score+= put_bits_count(&s->tex_pb);
    }

    if(s->avctx->mb_decision == FF_MB_DECISION_RD){
        MPV_decode_mb(s, s->block);

        score *= s->lambda2;
        score += sse_mb(s) << FF_LAMBDA_SHIFT;
    }

    if(*next_block){
        memcpy(s->dest, dest_backup, sizeof(s->dest));
    }

    if(score<*dmin){
        *dmin= score;
        *next_block^=1;

        copy_context_after_encode(best, s, type);
    }
}

static int sse(MpegEncContext *s, uint8_t *src1, uint8_t *src2, int w, int h, int stride){
    uint32_t *sq = ff_squareTbl + 256;
    int acc=0;
    int x,y;

    if(w==16 && h==16)
        return s->dsp.sse[0](NULL, src1, src2, stride, 16);
    else if(w==8 && h==8)
        return s->dsp.sse[1](NULL, src1, src2, stride, 8);

    for(y=0; y<h; y++){
        for(x=0; x<w; x++){
            acc+= sq[src1[x + y*stride] - src2[x + y*stride]];
        }
    }

    assert(acc>=0);

    return acc;
}

static int sse_mb(MpegEncContext *s){
    int w= 16;
    int h= 16;

    if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
    if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;

    if(w==16 && h==16)
      if(s->avctx->mb_cmp == FF_CMP_NSSE){
        return  s->dsp.nsse[0](s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
               +s->dsp.nsse[1](s, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
               +s->dsp.nsse[1](s, s->new_picture.data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
      }else{
        return  s->dsp.sse[0](NULL, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], s->linesize, 16)
               +s->dsp.sse[1](NULL, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[1], s->uvlinesize, 8)
               +s->dsp.sse[1](NULL, s->new_picture.data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[2], s->uvlinesize, 8);
      }
    else
        return  sse(s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16, s->dest[0], w, h, s->linesize)
               +sse(s, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[1], w>>1, h>>1, s->uvlinesize)
               +sse(s, s->new_picture.data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,s->dest[2], w>>1, h>>1, s->uvlinesize);
}

static int pre_estimate_motion_thread(AVCodecContext *c, void *arg){
    MpegEncContext *s= *(void**)arg;


    s->me.pre_pass=1;
    s->me.dia_size= s->avctx->pre_dia_size;
    s->first_slice_line=1;
    for(s->mb_y= s->end_mb_y-1; s->mb_y >= s->start_mb_y; s->mb_y--) {
        for(s->mb_x=s->mb_width-1; s->mb_x >=0 ;s->mb_x--) {
            ff_pre_estimate_p_frame_motion(s, s->mb_x, s->mb_y);
        }
        s->first_slice_line=0;
    }

    s->me.pre_pass=0;

    return 0;
}

static int estimate_motion_thread(AVCodecContext *c, void *arg){
    MpegEncContext *s= *(void**)arg;

    ff_check_alignment();

    s->me.dia_size= s->avctx->dia_size;
    s->first_slice_line=1;
    for(s->mb_y= s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) {
        s->mb_x=0; //for block init below
        ff_init_block_index(s);
        for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) {
            s->block_index[0]+=2;
            s->block_index[1]+=2;
            s->block_index[2]+=2;
            s->block_index[3]+=2;

            /* compute motion vector & mb_type and store in context */
            if(s->pict_type==FF_B_TYPE)
                ff_estimate_b_frame_motion(s, s->mb_x, s->mb_y);
            else
                ff_estimate_p_frame_motion(s, s->mb_x, s->mb_y);
        }
        s->first_slice_line=0;
    }
    return 0;
}

static int mb_var_thread(AVCodecContext *c, void *arg){
    MpegEncContext *s= *(void**)arg;
    int mb_x, mb_y;

    ff_check_alignment();

    for(mb_y=s->start_mb_y; mb_y < s->end_mb_y; mb_y++) {
        for(mb_x=0; mb_x < s->mb_width; mb_x++) {
            int xx = mb_x * 16;
            int yy = mb_y * 16;
            uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx;
            int varc;
            int sum = s->dsp.pix_sum(pix, s->linesize);

            varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8;

            s->current_picture.mb_var [s->mb_stride * mb_y + mb_x] = varc;
            s->current_picture.mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;
            s->me.mb_var_sum_temp    += varc;
        }
    }
    return 0;
}

static void write_slice_end(MpegEncContext *s){
    if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4){
        if(s->partitioned_frame){
            ff_mpeg4_merge_partitions(s);
        }

        ff_mpeg4_stuffing(&s->pb);
    }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){
        ff_mjpeg_encode_stuffing(&s->pb);
    }

    align_put_bits(&s->pb);
    flush_put_bits(&s->pb);

    if((s->flags&CODEC_FLAG_PASS1) && !s->partitioned_frame)
        s->misc_bits+= get_bits_diff(s);
}

static int encode_thread(AVCodecContext *c, void *arg){
    MpegEncContext *s= *(void**)arg;
    int mb_x, mb_y, pdif = 0;
    int chr_h= 16>>s->chroma_y_shift;
    int i, j;
    MpegEncContext best_s, backup_s;
    uint8_t bit_buf[2][MAX_MB_BYTES];
    uint8_t bit_buf2[2][MAX_MB_BYTES];
    uint8_t bit_buf_tex[2][MAX_MB_BYTES];
    PutBitContext pb[2], pb2[2], tex_pb[2];
//printf("%d->%d\n", s->resync_mb_y, s->end_mb_y);

    ff_check_alignment();

    for(i=0; i<2; i++){
        init_put_bits(&pb    [i], bit_buf    [i], MAX_MB_BYTES);
        init_put_bits(&pb2   [i], bit_buf2   [i], MAX_MB_BYTES);
        init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES);
    }

    s->last_bits= put_bits_count(&s->pb);
    s->mv_bits=0;
    s->misc_bits=0;
    s->i_tex_bits=0;
    s->p_tex_bits=0;
    s->i_count=0;
    s->f_count=0;
    s->b_count=0;
    s->skip_count=0;

    for(i=0; i<3; i++){
        /* init last dc values */
        /* note: quant matrix value (8) is implied here */
        s->last_dc[i] = 128 << s->intra_dc_precision;

        s->current_picture.error[i] = 0;
    }
    s->mb_skip_run = 0;
    memset(s->last_mv, 0, sizeof(s->last_mv));

    s->last_mv_dir = 0;

    switch(s->codec_id){
    case CODEC_ID_H263:
    case CODEC_ID_H263P:
    case CODEC_ID_FLV1:
        if (CONFIG_H263_ENCODER || CONFIG_H263P_ENCODER || CONFIG_FLV_ENCODER)
            s->gob_index = ff_h263_get_gob_height(s);
        break;
    case CODEC_ID_MPEG4:
        if(CONFIG_MPEG4_ENCODER && s->partitioned_frame)
            ff_mpeg4_init_partitions(s);
        break;
    }

    s->resync_mb_x=0;
    s->resync_mb_y=0;
    s->first_slice_line = 1;
    s->ptr_lastgob = s->pb.buf;
    for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) {
//    printf("row %d at %X\n", s->mb_y, (int)s);
        s->mb_x=0;
        s->mb_y= mb_y;

        ff_set_qscale(s, s->qscale);
        ff_init_block_index(s);

        for(mb_x=0; mb_x < s->mb_width; mb_x++) {
            int xy= mb_y*s->mb_stride + mb_x; // removed const, H261 needs to adjust this
            int mb_type= s->mb_type[xy];
//            int d;
            int dmin= INT_MAX;
            int dir;

            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
                return -1;
            }
            if(s->data_partitioning){
                if(   s->pb2   .buf_end - s->pb2   .buf - (put_bits_count(&s->    pb2)>>3) < MAX_MB_BYTES
                   || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){
                    av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
                    return -1;
                }
            }

            s->mb_x = mb_x;
            s->mb_y = mb_y;  // moved into loop, can get changed by H.261
            ff_update_block_index(s);

            if(CONFIG_H261_ENCODER && s->codec_id == CODEC_ID_H261){
                ff_h261_reorder_mb_index(s);
                xy= s->mb_y*s->mb_stride + s->mb_x;
                mb_type= s->mb_type[xy];
            }

            /* write gob / video packet header  */
            if(s->rtp_mode){
                int current_packet_size, is_gob_start;

                current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf);

                is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0;

                if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1;

                switch(s->codec_id){
                case CODEC_ID_H263:
                case CODEC_ID_H263P:
                    if(!s->h263_slice_structured)
                        if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0;
                    break;
                case CODEC_ID_MPEG2VIDEO:
                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
                case CODEC_ID_MPEG1VIDEO:
                    if(s->mb_skip_run) is_gob_start=0;
                    break;
                }

                if(is_gob_start){
                    if(s->start_mb_y != mb_y || mb_x!=0){
                        write_slice_end(s);

                        if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){
                            ff_mpeg4_init_partitions(s);
                        }
                    }

                    assert((put_bits_count(&s->pb)&7) == 0);
                    current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob;

                    if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){
                        int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;
                        int d= 100 / s->avctx->error_rate;
                        if(r % d == 0){
                            current_packet_size=0;
#ifndef ALT_BITSTREAM_WRITER
                            s->pb.buf_ptr= s->ptr_lastgob;
#endif
                            assert(pbBufPtr(&s->pb) == s->ptr_lastgob);
                        }
                    }

                    if (s->avctx->rtp_callback){
                        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x;
                        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb);
                    }

                    switch(s->codec_id){
                    case CODEC_ID_MPEG4:
                        if (CONFIG_MPEG4_ENCODER) {
                            ff_mpeg4_encode_video_packet_header(s);
                            ff_mpeg4_clean_buffers(s);
                        }
                    break;
                    case CODEC_ID_MPEG1VIDEO:
                    case CODEC_ID_MPEG2VIDEO:
                        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) {
                            ff_mpeg1_encode_slice_header(s);
                            ff_mpeg1_clean_buffers(s);
                        }
                    break;
                    case CODEC_ID_H263:
                    case CODEC_ID_H263P:
                        if (CONFIG_H263_ENCODER || CONFIG_H263P_ENCODER)
                            h263_encode_gob_header(s, mb_y);
                    break;
                    }

                    if(s->flags&CODEC_FLAG_PASS1){
                        int bits= put_bits_count(&s->pb);
                        s->misc_bits+= bits - s->last_bits;
                        s->last_bits= bits;
                    }

                    s->ptr_lastgob += current_packet_size;
                    s->first_slice_line=1;
                    s->resync_mb_x=mb_x;
                    s->resync_mb_y=mb_y;
                }
            }

            if(  (s->resync_mb_x   == s->mb_x)
               && s->resync_mb_y+1 == s->mb_y){
                s->first_slice_line=0;
            }

            s->mb_skipped=0;
            s->dquant=0; //only for QP_RD

            if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){ // more than 1 MB type possible or CODEC_FLAG_QP_RD
                int next_block=0;
                int pb_bits_count, pb2_bits_count, tex_pb_bits_count;

                copy_context_before_encode(&backup_s, s, -1);
                backup_s.pb= s->pb;
                best_s.data_partitioning= s->data_partitioning;
                best_s.partitioned_frame= s->partitioned_frame;
                if(s->data_partitioning){
                    backup_s.pb2= s->pb2;
                    backup_s.tex_pb= s->tex_pb;
                }

                if(mb_type&CANDIDATE_MB_TYPE_INTER){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->p_mv_table[xy][0];
                    s->mv[0][0][1] = s->p_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTER_I){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = 0;
                    s->mv[0][0][1] = 0;
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTER4V){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_8X8;
                    s->mb_intra= 0;
                    for(i=0; i<4; i++){
                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_FORWARD){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[1][0][0] = s->b_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_back_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BIDIR){
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(dir=0; dir<2; dir++){
                        for(i=0; i<2; i++){
                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                        }
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTRA){
                    s->mv_dir = 0;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 1;
                    s->mv[0][0][0] = 0;
                    s->mv[0][0][1] = 0;
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                    if(s->h263_pred || s->h263_aic){
                        if(best_s.mb_intra)
                            s->mbintra_table[mb_x + mb_y*s->mb_stride]=1;
                        else
                            ff_clean_intra_table_entries(s); //old mode?
                    }
                }

                if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){
                    if(best_s.mv_type==MV_TYPE_16X16){ //FIXME move 4mv after QPRD
                        const int last_qp= backup_s.qscale;
                        int qpi, qp, dc[6];
                        DCTELEM ac[6][16];
                        const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
                        static const int dquant_tab[4]={-1,1,-2,2};

                        assert(backup_s.dquant == 0);

                        //FIXME intra
                        s->mv_dir= best_s.mv_dir;
                        s->mv_type = MV_TYPE_16X16;
                        s->mb_intra= best_s.mb_intra;
                        s->mv[0][0][0] = best_s.mv[0][0][0];
                        s->mv[0][0][1] = best_s.mv[0][0][1];
                        s->mv[1][0][0] = best_s.mv[1][0][0];
                        s->mv[1][0][1] = best_s.mv[1][0][1];

                        qpi = s->pict_type == FF_B_TYPE ? 2 : 0;
                        for(; qpi<4; qpi++){
                            int dquant= dquant_tab[qpi];
                            qp= last_qp + dquant;
                            if(qp < s->avctx->qmin || qp > s->avctx->qmax)
                                continue;
                            backup_s.dquant= dquant;
                            if(s->mb_intra && s->dc_val[0]){
                                for(i=0; i<6; i++){
                                    dc[i]= s->dc_val[0][ s->block_index[i] ];
                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16);
                                }
                            }

                            encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb,
                                         &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]);
                            if(best_s.qscale != qp){
                                if(s->mb_intra && s->dc_val[0]){
                                    for(i=0; i<6; i++){
                                        s->dc_val[0][ s->block_index[i] ]= dc[i];
                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16);
                                    }
                                }
                            }
                        }
                    }
                }
                if(CONFIG_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT){
                    int mx= s->b_direct_mv_table[xy][0];
                    int my= s->b_direct_mv_table[xy][1];

                    backup_s.dquant = 0;
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
                    s->mb_intra= 0;
                    ff_mpeg4_set_direct_mv(s, mx, my);
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,
                                 &dmin, &next_block, mx, my);
                }
                if(CONFIG_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){
                    backup_s.dquant = 0;
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
                    s->mb_intra= 0;
                    ff_mpeg4_set_direct_mv(s, 0, 0);
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){
                    int coded=0;
                    for(i=0; i<6; i++)
                        coded |= s->block_last_index[i];
                    if(coded){
                        int mx,my;
                        memcpy(s->mv, best_s.mv, sizeof(s->mv));
                        if(CONFIG_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){
                            mx=my=0; //FIXME find the one we actually used
                            ff_mpeg4_set_direct_mv(s, mx, my);
                        }else if(best_s.mv_dir&MV_DIR_BACKWARD){
                            mx= s->mv[1][0][0];
                            my= s->mv[1][0][1];
                        }else{
                            mx= s->mv[0][0][0];
                            my= s->mv[0][0][1];
                        }

                        s->mv_dir= best_s.mv_dir;
                        s->mv_type = best_s.mv_type;
                        s->mb_intra= 0;
/*                        s->mv[0][0][0] = best_s.mv[0][0][0];
                        s->mv[0][0][1] = best_s.mv[0][0][1];
                        s->mv[1][0][0] = best_s.mv[1][0][0];
                        s->mv[1][0][1] = best_s.mv[1][0][1];*/
                        backup_s.dquant= 0;
                        s->skipdct=1;
                        encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER /* wrong but unused */, pb, pb2, tex_pb,
                                        &dmin, &next_block, mx, my);
                        s->skipdct=0;
                    }
                }

                s->current_picture.qscale_table[xy]= best_s.qscale;

                copy_context_after_encode(s, &best_s, -1);

                pb_bits_count= put_bits_count(&s->pb);
                flush_put_bits(&s->pb);
                ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);
                s->pb= backup_s.pb;

                if(s->data_partitioning){
                    pb2_bits_count= put_bits_count(&s->pb2);
                    flush_put_bits(&s->pb2);
                    ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);
                    s->pb2= backup_s.pb2;

                    tex_pb_bits_count= put_bits_count(&s->tex_pb);
                    flush_put_bits(&s->tex_pb);
                    ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count);
                    s->tex_pb= backup_s.tex_pb;
                }
                s->last_bits= put_bits_count(&s->pb);

                if (CONFIG_ANY_H263_ENCODER &&
                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)
                    ff_h263_update_motion_val(s);

                if(next_block==0){ //FIXME 16 vs linesize16
                    s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);
                    s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);
                    s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);
                }

                if(s->avctx->mb_decision == FF_MB_DECISION_BITS)
                    MPV_decode_mb(s, s->block);
            } else {
                int motion_x = 0, motion_y = 0;
                s->mv_type=MV_TYPE_16X16;
                // only one MB-Type possible

                switch(mb_type){
                case CANDIDATE_MB_TYPE_INTRA:
                    s->mv_dir = 0;
                    s->mb_intra= 1;
                    motion_x= s->mv[0][0][0] = 0;
                    motion_y= s->mv[0][0][1] = 0;
                    break;
                case CANDIDATE_MB_TYPE_INTER:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0];
                    motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_INTER_I:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_INTER4V:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_8X8;
                    s->mb_intra= 0;
                    for(i=0; i<4; i++){
                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_DIRECT:
                    if (CONFIG_MPEG4_ENCODER) {
                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
                        s->mb_intra= 0;
                        motion_x=s->b_direct_mv_table[xy][0];
                        motion_y=s->b_direct_mv_table[xy][1];
                        ff_mpeg4_set_direct_mv(s, motion_x, motion_y);
                    }
                    break;
                case CANDIDATE_MB_TYPE_DIRECT0:
                    if (CONFIG_MPEG4_ENCODER) {
                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
                        s->mb_intra= 0;
                        ff_mpeg4_set_direct_mv(s, 0, 0);
                    }
                    break;
                case CANDIDATE_MB_TYPE_BIDIR:
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_BACKWARD:
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0];
                    motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_FORWARD:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
                    motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
//                    printf(" %d %d ", motion_x, motion_y);
                    break;
                case CANDIDATE_MB_TYPE_FORWARD_I:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_BACKWARD_I:
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_BIDIR_I:
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(dir=0; dir<2; dir++){
                        for(i=0; i<2; i++){
                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                        }
                    }
                    break;
                default:
                    av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n");
                }

                encode_mb(s, motion_x, motion_y);

                // RAL: Update last macroblock type
                s->last_mv_dir = s->mv_dir;

                if (CONFIG_ANY_H263_ENCODER &&
                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)
                    ff_h263_update_motion_val(s);

                MPV_decode_mb(s, s->block);
            }

            /* clean the MV table in IPS frames for direct mode in B frames */
            if(s->mb_intra /* && I,P,S_TYPE */){
                s->p_mv_table[xy][0]=0;
                s->p_mv_table[xy][1]=0;
            }

            if(s->flags&CODEC_FLAG_PSNR){
                int w= 16;
                int h= 16;

                if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
                if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;

                s->current_picture.error[0] += sse(
                    s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
                    s->dest[0], w, h, s->linesize);
                s->current_picture.error[1] += sse(
                    s, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*chr_h,
                    s->dest[1], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
                s->current_picture.error[2] += sse(
                    s, s->new_picture.data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*chr_h,
                    s->dest[2], w>>1, h>>s->chroma_y_shift, s->uvlinesize);
            }
            if(s->loop_filter){
                if(CONFIG_ANY_H263_ENCODER && s->out_format == FMT_H263)
                    ff_h263_loop_filter(s);
            }
//printf("MB %d %d bits\n", s->mb_x+s->mb_y*s->mb_stride, put_bits_count(&s->pb));
        }
    }

    //not beautiful here but we must write it before flushing so it has to be here
    if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == FF_I_TYPE)
        msmpeg4_encode_ext_header(s);

    write_slice_end(s);

    /* Send the last GOB if RTP */
    if (s->avctx->rtp_callback) {
        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x;
        pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;
        /* Call the RTP callback to send the last GOB */
        emms_c();
        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb);
    }

    return 0;
}

#define MERGE(field) dst->field += src->field; src->field=0
static void merge_context_after_me(MpegEncContext *dst, MpegEncContext *src){
    MERGE(me.scene_change_score);
    MERGE(me.mc_mb_var_sum_temp);
    MERGE(me.mb_var_sum_temp);
}

static void merge_context_after_encode(MpegEncContext *dst, MpegEncContext *src){
    int i;

    MERGE(dct_count[0]); //note, the other dct vars are not part of the context
    MERGE(dct_count[1]);
    MERGE(mv_bits);
    MERGE(i_tex_bits);
    MERGE(p_tex_bits);
    MERGE(i_count);
    MERGE(f_count);
    MERGE(b_count);
    MERGE(skip_count);
    MERGE(misc_bits);
    MERGE(error_count);
    MERGE(padding_bug_score);
    MERGE(current_picture.error[0]);
    MERGE(current_picture.error[1]);
    MERGE(current_picture.error[2]);

    if(dst->avctx->noise_reduction){
        for(i=0; i<64; i++){
            MERGE(dct_error_sum[0][i]);
            MERGE(dct_error_sum[1][i]);
        }
    }

    assert(put_bits_count(&src->pb) % 8 ==0);
    assert(put_bits_count(&dst->pb) % 8 ==0);
    ff_copy_bits(&dst->pb, src->pb.buf, put_bits_count(&src->pb));
    flush_put_bits(&dst->pb);
}

static int estimate_qp(MpegEncContext *s, int dry_run){
    if (s->next_lambda){
        s->current_picture_ptr->quality=
        s->current_picture.quality = s->next_lambda;
        if(!dry_run) s->next_lambda= 0;
    } else if (!s->fixed_qscale) {
        s->current_picture_ptr->quality=
        s->current_picture.quality = ff_rate_estimate_qscale(s, dry_run);
        if (s->current_picture.quality < 0)
            return -1;
    }

    if(s->adaptive_quant){
        switch(s->codec_id){
        case CODEC_ID_MPEG4:
            if (CONFIG_MPEG4_ENCODER)
                ff_clean_mpeg4_qscales(s);
            break;
        case CODEC_ID_H263:
        case CODEC_ID_H263P:
        case CODEC_ID_FLV1:
            if (CONFIG_H263_ENCODER||CONFIG_H263P_ENCODER||CONFIG_FLV_ENCODER)
                ff_clean_h263_qscales(s);
            break;
        }

        s->lambda= s->lambda_table[0];
        //FIXME broken
    }else
        s->lambda= s->current_picture.quality;
//printf("%d %d\n", s->avctx->global_quality, s->current_picture.quality);
    update_qscale(s);
    return 0;
}

/* must be called before writing the header */
static void set_frame_distances(MpegEncContext * s){
    assert(s->current_picture_ptr->pts != AV_NOPTS_VALUE);
    s->time= s->current_picture_ptr->pts*s->avctx->time_base.num;

    if(s->pict_type==FF_B_TYPE){
        s->pb_time= s->pp_time - (s->last_non_b_time - s->time);
        assert(s->pb_time > 0 && s->pb_time < s->pp_time);
    }else{
        s->pp_time= s->time - s->last_non_b_time;
        s->last_non_b_time= s->time;
        assert(s->picture_number==0 || s->pp_time > 0);
    }
}

static int encode_picture(MpegEncContext *s, int picture_number)
{
    int i;
    int bits;

    s->picture_number = picture_number;

    /* Reset the average MB variance */
    s->me.mb_var_sum_temp    =
    s->me.mc_mb_var_sum_temp = 0;

    /* we need to initialize some time vars before we can encode b-frames */
    // RAL: Condition added for MPEG1VIDEO
    if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->h263_msmpeg4))
        set_frame_distances(s);
    if(CONFIG_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4)
        ff_set_mpeg4_time(s);

    s->me.scene_change_score=0;

//    s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME rate distortion

    if(s->pict_type==FF_I_TYPE){
        if(s->msmpeg4_version >= 3) s->no_rounding=1;
        else                        s->no_rounding=0;
    }else if(s->pict_type!=FF_B_TYPE){
        if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4)
            s->no_rounding ^= 1;
    }

    if(s->flags & CODEC_FLAG_PASS2){
        if (estimate_qp(s,1) < 0)
            return -1;
        ff_get_2pass_fcode(s);
    }else if(!(s->flags & CODEC_FLAG_QSCALE)){
        if(s->pict_type==FF_B_TYPE)
            s->lambda= s->last_lambda_for[s->pict_type];
        else
            s->lambda= s->last_lambda_for[s->last_non_b_pict_type];
        update_qscale(s);
    }

    s->mb_intra=0; //for the rate distortion & bit compare functions
    for(i=1; i<s->avctx->thread_count; i++){
        ff_update_duplicate_context(s->thread_context[i], s);
    }

    if(ff_init_me(s)<0)
        return -1;

    /* Estimate motion for every MB */
    if(s->pict_type != FF_I_TYPE){
        s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8;
        s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8;
        if(s->pict_type != FF_B_TYPE && s->avctx->me_threshold==0){
            if((s->avctx->pre_me && s->last_non_b_pict_type==FF_I_TYPE) || s->avctx->pre_me==2){
                s->avctx->execute(s->avctx, pre_estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count, sizeof(void*));
            }
        }

        s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count, sizeof(void*));
    }else /* if(s->pict_type == FF_I_TYPE) */{
        /* I-Frame */
        for(i=0; i<s->mb_stride*s->mb_height; i++)
            s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;

        if(!s->fixed_qscale){
            /* finding spatial complexity for I-frame rate control */
            s->avctx->execute(s->avctx, mb_var_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count, sizeof(void*));
        }
    }
    for(i=1; i<s->avctx->thread_count; i++){
        merge_context_after_me(s, s->thread_context[i]);
    }
    s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp;
    s->current_picture.   mb_var_sum= s->current_picture_ptr->   mb_var_sum= s->me.   mb_var_sum_temp;
    emms_c();

    if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == FF_P_TYPE){
        s->pict_type= FF_I_TYPE;
        for(i=0; i<s->mb_stride*s->mb_height; i++)
            s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
    }

    if(!s->umvplus){
        if(s->pict_type==FF_P_TYPE || s->pict_type==FF_S_TYPE) {
            s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);

            if(s->flags & CODEC_FLAG_INTERLACED_ME){
                int a,b;
                a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select
                b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);
                s->f_code= FFMAX3(s->f_code, a, b);
            }

            ff_fix_long_p_mvs(s);
            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0);
            if(s->flags & CODEC_FLAG_INTERLACED_ME){
                int j;
                for(i=0; i<2; i++){
                    for(j=0; j<2; j++)
                        ff_fix_long_mvs(s, s->p_field_select_table[i], j,
                                        s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0);
                }
            }
        }

        if(s->pict_type==FF_B_TYPE){
            int a, b;

            a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD);
            b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR);
            s->f_code = FFMAX(a, b);

            a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD);
            b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR);
            s->b_code = FFMAX(a, b);

            ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1);
            ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1);
            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1);
            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1);
            if(s->flags & CODEC_FLAG_INTERLACED_ME){
                int dir, j;
                for(dir=0; dir<2; dir++){
                    for(i=0; i<2; i++){
                        for(j=0; j<2; j++){
                            int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I)
                                          : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I);
                            ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j,
                                            s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1);
                        }
                    }
                }
            }
        }
    }

    if (estimate_qp(s, 0) < 0)
        return -1;

    if(s->qscale < 3 && s->max_qcoeff<=128 && s->pict_type==FF_I_TYPE && !(s->flags & CODEC_FLAG_QSCALE))
        s->qscale= 3; //reduce clipping problems

    if (s->out_format == FMT_MJPEG) {
        /* for mjpeg, we do include qscale in the matrix */
        s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];
        for(i=1;i<64;i++){
            int j= s->dsp.idct_permutation[i];

            s->intra_matrix[j] = av_clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3);
        }
        ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,
                       s->intra_matrix, s->intra_quant_bias, 8, 8, 1);
        s->qscale= 8;
    }

    //FIXME var duplication
    s->current_picture_ptr->key_frame=
    s->current_picture.key_frame= s->pict_type == FF_I_TYPE; //FIXME pic_ptr
    s->current_picture_ptr->pict_type=
    s->current_picture.pict_type= s->pict_type;

    if(s->current_picture.key_frame)
        s->picture_in_gop_number=0;

    s->last_bits= put_bits_count(&s->pb);
    switch(s->out_format) {
    case FMT_MJPEG:
        if (CONFIG_MJPEG_ENCODER)
            ff_mjpeg_encode_picture_header(s);
        break;
    case FMT_H261:
        if (CONFIG_H261_ENCODER)
            ff_h261_encode_picture_header(s, picture_number);
        break;
    case FMT_H263:
        if (CONFIG_WMV2_ENCODER && s->codec_id == CODEC_ID_WMV2)
            ff_wmv2_encode_picture_header(s, picture_number);
        else if (CONFIG_MSMPEG4_ENCODER && s->h263_msmpeg4)
            msmpeg4_encode_picture_header(s, picture_number);
        else if (CONFIG_MPEG4_ENCODER && s->h263_pred)
            mpeg4_encode_picture_header(s, picture_number);
        else if (CONFIG_RV10_ENCODER && s->codec_id == CODEC_ID_RV10)
            rv10_encode_picture_header(s, picture_number);
        else if (CONFIG_RV20_ENCODER && s->codec_id == CODEC_ID_RV20)
            rv20_encode_picture_header(s, picture_number);
        else if (CONFIG_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1)
            ff_flv_encode_picture_header(s, picture_number);
        else if (CONFIG_ANY_H263_ENCODER)
            h263_encode_picture_header(s, picture_number);
        break;
    case FMT_MPEG1:
        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER)
            mpeg1_encode_picture_header(s, picture_number);
        break;
    case FMT_H264:
        break;
    default:
        assert(0);
    }
    bits= put_bits_count(&s->pb);
    s->header_bits= bits - s->last_bits;

    for(i=1; i<s->avctx->thread_count; i++){
        update_duplicate_context_after_me(s->thread_context[i], s);
    }
    s->avctx->execute(s->avctx, encode_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count, sizeof(void*));
    for(i=1; i<s->avctx->thread_count; i++){
        merge_context_after_encode(s, s->thread_context[i]);
    }
    emms_c();
    return 0;
}

void  denoise_dct_c(MpegEncContext *s, DCTELEM *block){
    const int intra= s->mb_intra;
    int i;

    s->dct_count[intra]++;

    for(i=0; i<64; i++){
        int level= block[i];

        if(level){
            if(level>0){
                s->dct_error_sum[intra][i] += level;
                level -= s->dct_offset[intra][i];
                if(level<0) level=0;
            }else{
                s->dct_error_sum[intra][i] -= level;
                level += s->dct_offset[intra][i];
                if(level>0) level=0;
            }
            block[i]= level;
        }
    }
}

int dct_quantize_trellis_c(MpegEncContext *s,
                        DCTELEM *block, int n,
                        int qscale, int *overflow){
    const int *qmat;
    const uint8_t *scantable= s->intra_scantable.scantable;
    const uint8_t *perm_scantable= s->intra_scantable.permutated;
    int max=0;
    unsigned int threshold1, threshold2;
    int bias=0;
    int run_tab[65];
    int level_tab[65];
    int score_tab[65];
    int survivor[65];
    int survivor_count;
    int last_run=0;
    int last_level=0;
    int last_score= 0;
    int last_i;
    int coeff[2][64];
    int coeff_count[64];
    int qmul, qadd, start_i, last_non_zero, i, dc;
    const int esc_length= s->ac_esc_length;
    uint8_t * length;
    uint8_t * last_length;
    const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6);

    s->dsp.fdct (block);

    if(s->dct_error_sum)
        s->denoise_dct(s, block);
    qmul= qscale*16;
    qadd= ((qscale-1)|1)*8;

    if (s->mb_intra) {
        int q;
        if (!s->h263_aic) {
            if (n < 4)
                q = s->y_dc_scale;
            else
                q = s->c_dc_scale;
            q = q << 3;
        } else{
            /* For AIC we skip quant/dequant of INTRADC */
            q = 1 << 3;
            qadd=0;
        }

        /* note: block[0] is assumed to be positive */
        block[0] = (block[0] + (q >> 1)) / q;
        start_i = 1;
        last_non_zero = 0;
        qmat = s->q_intra_matrix[qscale];
        if(s->mpeg_quant || s->out_format == FMT_MPEG1)
            bias= 1<<(QMAT_SHIFT-1);
        length     = s->intra_ac_vlc_length;
        last_length= s->intra_ac_vlc_last_length;
    } else {
        start_i = 0;
        last_non_zero = -1;
        qmat = s->q_inter_matrix[qscale];
        length     = s->inter_ac_vlc_length;
        last_length= s->inter_ac_vlc_last_length;
    }
    last_i= start_i;

    threshold1= (1<<QMAT_SHIFT) - bias - 1;
    threshold2= (threshold1<<1);

    for(i=63; i>=start_i; i--) {
        const int j = scantable[i];
        int level = block[j] * qmat[j];

        if(((unsigned)(level+threshold1))>threshold2){
            last_non_zero = i;
            break;
        }
    }

    for(i=start_i; i<=last_non_zero; i++) {
        const int j = scantable[i];
        int level = block[j] * qmat[j];

//        if(   bias+level >= (1<<(QMAT_SHIFT - 3))
//           || bias-level >= (1<<(QMAT_SHIFT - 3))){
        if(((unsigned)(level+threshold1))>threshold2){
            if(level>0){
                level= (bias + level)>>QMAT_SHIFT;
                coeff[0][i]= level;
                coeff[1][i]= level-1;
//                coeff[2][k]= level-2;
            }else{
                level= (bias - level)>>QMAT_SHIFT;
                coeff[0][i]= -level;
                coeff[1][i]= -level+1;
//                coeff[2][k]= -level+2;
            }
            coeff_count[i]= FFMIN(level, 2);
            assert(coeff_count[i]);
            max |=level;
        }else{
            coeff[0][i]= (level>>31)|1;
            coeff_count[i]= 1;
        }
    }

    *overflow= s->max_qcoeff < max; //overflow might have happened

    if(last_non_zero < start_i){
        memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
        return last_non_zero;
    }

    score_tab[start_i]= 0;
    survivor[0]= start_i;
    survivor_count= 1;

    for(i=start_i; i<=last_non_zero; i++){
        int level_index, j, zero_distortion;
        int dct_coeff= FFABS(block[ scantable[i] ]);
        int best_score=256*256*256*120;

        if (   s->dsp.fdct == fdct_ifast
#ifndef FAAN_POSTSCALE
            || s->dsp.fdct == ff_faandct
#endif
           )
            dct_coeff= (dct_coeff*ff_inv_aanscales[ scantable[i] ]) >> 12;
        zero_distortion= dct_coeff*dct_coeff;

        for(level_index=0; level_index < coeff_count[i]; level_index++){
            int distortion;
            int level= coeff[level_index][i];
            const int alevel= FFABS(level);
            int unquant_coeff;

            assert(level);

            if(s->out_format == FMT_H263){
                unquant_coeff= alevel*qmul + qadd;
            }else{ //MPEG1
                j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize
                if(s->mb_intra){
                        unquant_coeff = (int)(  alevel  * qscale * s->intra_matrix[j]) >> 3;
                        unquant_coeff =   (unquant_coeff - 1) | 1;
                }else{
                        unquant_coeff = (((  alevel  << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4;
                        unquant_coeff =   (unquant_coeff - 1) | 1;
                }
                unquant_coeff<<= 3;
            }

            distortion= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff) - zero_distortion;
            level+=64;
            if((level&(~127)) == 0){
                for(j=survivor_count-1; j>=0; j--){
                    int run= i - survivor[j];
                    int score= distortion + length[UNI_AC_ENC_INDEX(run, level)]*lambda;
                    score += score_tab[i-run];

                    if(score < best_score){
                        best_score= score;
                        run_tab[i+1]= run;
                        level_tab[i+1]= level-64;
                    }
                }

                if(s->out_format == FMT_H263){
                    for(j=survivor_count-1; j>=0; j--){
                        int run= i - survivor[j];
                        int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda;
                        score += score_tab[i-run];
                        if(score < last_score){
                            last_score= score;
                            last_run= run;
                            last_level= level-64;
                            last_i= i+1;
                        }
                    }
                }
            }else{
                distortion += esc_length*lambda;
                for(j=survivor_count-1; j>=0; j--){
                    int run= i - survivor[j];
                    int score= distortion + score_tab[i-run];

                    if(score < best_score){
                        best_score= score;
                        run_tab[i+1]= run;
                        level_tab[i+1]= level-64;
                    }
                }

                if(s->out_format == FMT_H263){
                  for(j=survivor_count-1; j>=0; j--){
                        int run= i - survivor[j];
                        int score= distortion + score_tab[i-run];
                        if(score < last_score){
                            last_score= score;
                            last_run= run;
                            last_level= level-64;
                            last_i= i+1;
                        }
                    }
                }
            }
        }

        score_tab[i+1]= best_score;

        //Note: there is a vlc code in mpeg4 which is 1 bit shorter then another one with a shorter run and the same level
        if(last_non_zero <= 27){
            for(; survivor_count; survivor_count--){
                if(score_tab[ survivor[survivor_count-1] ] <= best_score)
                    break;
            }
        }else{
            for(; survivor_count; survivor_count--){
                if(score_tab[ survivor[survivor_count-1] ] <= best_score + lambda)
                    break;
            }
        }

        survivor[ survivor_count++ ]= i+1;
    }

    if(s->out_format != FMT_H263){
        last_score= 256*256*256*120;
        for(i= survivor[0]; i<=last_non_zero + 1; i++){
            int score= score_tab[i];
            if(i) score += lambda*2; //FIXME exacter?

            if(score < last_score){
                last_score= score;
                last_i= i;
                last_level= level_tab[i];
                last_run= run_tab[i];
            }
        }
    }

    s->coded_score[n] = last_score;

    dc= FFABS(block[0]);
    last_non_zero= last_i - 1;
    memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));

    if(last_non_zero < start_i)
        return last_non_zero;

    if(last_non_zero == 0 && start_i == 0){
        int best_level= 0;
        int best_score= dc * dc;

        for(i=0; i<coeff_count[0]; i++){
            int level= coeff[i][0];
            int alevel= FFABS(level);
            int unquant_coeff, score, distortion;

            if(s->out_format == FMT_H263){
                    unquant_coeff= (alevel*qmul + qadd)>>3;
            }else{ //MPEG1
                    unquant_coeff = (((  alevel  << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4;
                    unquant_coeff =   (unquant_coeff - 1) | 1;
            }
            unquant_coeff = (unquant_coeff + 4) >> 3;
            unquant_coeff<<= 3 + 3;

            distortion= (unquant_coeff - dc) * (unquant_coeff - dc);
            level+=64;
            if((level&(~127)) == 0) score= distortion + last_length[UNI_AC_ENC_INDEX(0, level)]*lambda;
            else                    score= distortion + esc_length*lambda;

            if(score < best_score){
                best_score= score;
                best_level= level - 64;
            }
        }
        block[0]= best_level;
        s->coded_score[n] = best_score - dc*dc;
        if(best_level == 0) return -1;
        else                return last_non_zero;
    }

    i= last_i;
    assert(last_level);

    block[ perm_scantable[last_non_zero] ]= last_level;
    i -= last_run + 1;

    for(; i>start_i; i -= run_tab[i] + 1){
        block[ perm_scantable[i-1] ]= level_tab[i];
    }

    return last_non_zero;
}

//#define REFINE_STATS 1
static int16_t basis[64][64];

static void build_basis(uint8_t *perm){
    int i, j, x, y;
    emms_c();
    for(i=0; i<8; i++){
        for(j=0; j<8; j++){
            for(y=0; y<8; y++){
                for(x=0; x<8; x++){
                    double s= 0.25*(1<<BASIS_SHIFT);
                    int index= 8*i + j;
                    int perm_index= perm[index];
                    if(i==0) s*= sqrt(0.5);
                    if(j==0) s*= sqrt(0.5);
                    basis[perm_index][8*x + y]= lrintf(s * cos((M_PI/8.0)*i*(x+0.5)) * cos((M_PI/8.0)*j*(y+0.5)));
                }
            }
        }
    }
}

static int dct_quantize_refine(MpegEncContext *s, //FIXME breaks denoise?
                        DCTELEM *block, int16_t *weight, DCTELEM *orig,
                        int n, int qscale){
    int16_t rem[64];
    DECLARE_ALIGNED_16(DCTELEM, d1[64]);
    const int *qmat;
    const uint8_t *scantable= s->intra_scantable.scantable;
    const uint8_t *perm_scantable= s->intra_scantable.permutated;
//    unsigned int threshold1, threshold2;
//    int bias=0;
    int run_tab[65];
    int prev_run=0;
    int prev_level=0;
    int qmul, qadd, start_i, last_non_zero, i, dc;
    uint8_t * length;
    uint8_t * last_length;
    int lambda;
    int rle_index, run, q = 1, sum; //q is only used when s->mb_intra is true
#ifdef REFINE_STATS
static int count=0;
static int after_last=0;
static int to_zero=0;
static int from_zero=0;
static int raise=0;
static int lower=0;
static int messed_sign=0;
#endif

    if(basis[0][0] == 0)
        build_basis(s->dsp.idct_permutation);

    qmul= qscale*2;
    qadd= (qscale-1)|1;
    if (s->mb_intra) {
        if (!s->h263_aic) {
            if (n < 4)
                q = s->y_dc_scale;
            else
                q = s->c_dc_scale;
        } else{
            /* For AIC we skip quant/dequant of INTRADC */
            q = 1;
            qadd=0;
        }
        q <<= RECON_SHIFT-3;
        /* note: block[0] is assumed to be positive */
        dc= block[0]*q;
//        block[0] = (block[0] + (q >> 1)) / q;
        start_i = 1;
        qmat = s->q_intra_matrix[qscale];
//        if(s->mpeg_quant || s->out_format == FMT_MPEG1)
//            bias= 1<<(QMAT_SHIFT-1);
        length     = s->intra_ac_vlc_length;
        last_length= s->intra_ac_vlc_last_length;
    } else {
        dc= 0;
        start_i = 0;
        qmat = s->q_inter_matrix[qscale];
        length     = s->inter_ac_vlc_length;
        last_length= s->inter_ac_vlc_last_length;
    }
    last_non_zero = s->block_last_index[n];

#ifdef REFINE_STATS
{START_TIMER
#endif
    dc += (1<<(RECON_SHIFT-1));
    for(i=0; i<64; i++){
        rem[i]= dc - (orig[i]<<RECON_SHIFT); //FIXME  use orig dirrectly instead of copying to rem[]
    }
#ifdef REFINE_STATS
STOP_TIMER("memset rem[]")}
#endif
    sum=0;
    for(i=0; i<64; i++){
        int one= 36;
        int qns=4;
        int w;

        w= FFABS(weight[i]) + qns*one;
        w= 15 + (48*qns*one + w/2)/w; // 16 .. 63

        weight[i] = w;
//        w=weight[i] = (63*qns + (w/2)) / w;

        assert(w>0);
        assert(w<(1<<6));
        sum += w*w;
    }
    lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
#ifdef REFINE_STATS
{START_TIMER
#endif
    run=0;
    rle_index=0;
    for(i=start_i; i<=last_non_zero; i++){
        int j= perm_scantable[i];
        const int level= block[j];
        int coeff;

        if(level){
            if(level<0) coeff= qmul*level - qadd;
            else        coeff= qmul*level + qadd;
            run_tab[rle_index++]=run;
            run=0;

            s->dsp.add_8x8basis(rem, basis[j], coeff);
        }else{
            run++;
        }
    }
#ifdef REFINE_STATS
if(last_non_zero>0){
STOP_TIMER("init rem[]")
}
}

{START_TIMER
#endif
    for(;;){
        int best_score=s->dsp.try_8x8basis(rem, weight, basis[0], 0);
        int best_coeff=0;
        int best_change=0;
        int run2, best_unquant_change=0, analyze_gradient;
#ifdef REFINE_STATS
{START_TIMER
#endif
        analyze_gradient = last_non_zero > 2 || s->avctx->quantizer_noise_shaping >= 3;

        if(analyze_gradient){
#ifdef REFINE_STATS
{START_TIMER
#endif
            for(i=0; i<64; i++){
                int w= weight[i];

                d1[i] = (rem[i]*w*w + (1<<(RECON_SHIFT+12-1)))>>(RECON_SHIFT+12);
            }
#ifdef REFINE_STATS
STOP_TIMER("rem*w*w")}
{START_TIMER
#endif
            s->dsp.fdct(d1);
#ifdef REFINE_STATS
STOP_TIMER("dct")}
#endif
        }

        if(start_i){
            const int level= block[0];
            int change, old_coeff;

            assert(s->mb_intra);

            old_coeff= q*level;

            for(change=-1; change<=1; change+=2){
                int new_level= level + change;
                int score, new_coeff;

                new_coeff= q*new_level;
                if(new_coeff >= 2048 || new_coeff < 0)
                    continue;

                score= s->dsp.try_8x8basis(rem, weight, basis[0], new_coeff - old_coeff);
                if(score<best_score){
                    best_score= score;
                    best_coeff= 0;
                    best_change= change;
                    best_unquant_change= new_coeff - old_coeff;
                }
            }
        }

        run=0;
        rle_index=0;
        run2= run_tab[rle_index++];
        prev_level=0;
        prev_run=0;

        for(i=start_i; i<64; i++){
            int j= perm_scantable[i];
            const int level= block[j];
            int change, old_coeff;

            if(s->avctx->quantizer_noise_shaping < 3 && i > last_non_zero + 1)
                break;

            if(level){
                if(level<0) old_coeff= qmul*level - qadd;
                else        old_coeff= qmul*level + qadd;
                run2= run_tab[rle_index++]; //FIXME ! maybe after last
            }else{
                old_coeff=0;
                run2--;
                assert(run2>=0 || i >= last_non_zero );
            }

            for(change=-1; change<=1; change+=2){
                int new_level= level + change;
                int score, new_coeff, unquant_change;

                score=0;
                if(s->avctx->quantizer_noise_shaping < 2 && FFABS(new_level) > FFABS(level))
                   continue;

                if(new_level){
                    if(new_level<0) new_coeff= qmul*new_level - qadd;
                    else            new_coeff= qmul*new_level + qadd;
                    if(new_coeff >= 2048 || new_coeff <= -2048)
                        continue;
                    //FIXME check for overflow

                    if(level){
                        if(level < 63 && level > -63){
                            if(i < last_non_zero)
                                score +=   length[UNI_AC_ENC_INDEX(run, new_level+64)]
                                         - length[UNI_AC_ENC_INDEX(run, level+64)];
                            else
                                score +=   last_length[UNI_AC_ENC_INDEX(run, new_level+64)]
                                         - last_length[UNI_AC_ENC_INDEX(run, level+64)];
                        }
                    }else{
                        assert(FFABS(new_level)==1);

                        if(analyze_gradient){
                            int g= d1[ scantable[i] ];
                            if(g && (g^new_level) >= 0)
                                continue;
                        }

                        if(i < last_non_zero){
                            int next_i= i + run2 + 1;
                            int next_level= block[ perm_scantable[next_i] ] + 64;

                            if(next_level&(~127))
                                next_level= 0;

                            if(next_i < last_non_zero)
                                score +=   length[UNI_AC_ENC_INDEX(run, 65)]
                                         + length[UNI_AC_ENC_INDEX(run2, next_level)]
                                         - length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];
                            else
                                score +=  length[UNI_AC_ENC_INDEX(run, 65)]
                                        + last_length[UNI_AC_ENC_INDEX(run2, next_level)]
                                        - last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)];
                        }else{
                            score += last_length[UNI_AC_ENC_INDEX(run, 65)];
                            if(prev_level){
                                score +=  length[UNI_AC_ENC_INDEX(prev_run, prev_level)]
                                        - last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)];
                            }
                        }
                    }
                }else{
                    new_coeff=0;
                    assert(FFABS(level)==1);

                    if(i < last_non_zero){
                        int next_i= i + run2 + 1;
                        int next_level= block[ perm_scantable[next_i] ] + 64;

                        if(next_level&(~127))
                            next_level= 0;

                        if(next_i < last_non_zero)
                            score +=   length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]
                                     - length[UNI_AC_ENC_INDEX(run2, next_level)]
                                     - length[UNI_AC_ENC_INDEX(run, 65)];
                        else
                            score +=   last_length[UNI_AC_ENC_INDEX(run + run2 + 1, next_level)]
                                     - last_length[UNI_AC_ENC_INDEX(run2, next_level)]
                                     - length[UNI_AC_ENC_INDEX(run, 65)];
                    }else{
                        score += -last_length[UNI_AC_ENC_INDEX(run, 65)];
                        if(prev_level){
                            score +=  last_length[UNI_AC_ENC_INDEX(prev_run, prev_level)]
                                    - length[UNI_AC_ENC_INDEX(prev_run, prev_level)];
                        }
                    }
                }

                score *= lambda;

                unquant_change= new_coeff - old_coeff;
                assert((score < 100*lambda && score > -100*lambda) || lambda==0);

                score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);
                if(score<best_score){
                    best_score= score;
                    best_coeff= i;
                    best_change= change;
                    best_unquant_change= unquant_change;
                }
            }
            if(level){
                prev_level= level + 64;
                if(prev_level&(~127))
                    prev_level= 0;
                prev_run= run;
                run=0;
            }else{
                run++;
            }
        }
#ifdef REFINE_STATS
STOP_TIMER("iterative step")}
#endif

        if(best_change){
            int j= perm_scantable[ best_coeff ];

            block[j] += best_change;

            if(best_coeff > last_non_zero){
                last_non_zero= best_coeff;
                assert(block[j]);
#ifdef REFINE_STATS
after_last++;
#endif
            }else{
#ifdef REFINE_STATS
if(block[j]){
    if(block[j] - best_change){
        if(FFABS(block[j]) > FFABS(block[j] - best_change)){
            raise++;
        }else{
            lower++;
        }
    }else{
        from_zero++;
    }
}else{
    to_zero++;
}
#endif
                for(; last_non_zero>=start_i; last_non_zero--){
                    if(block[perm_scantable[last_non_zero]])
                        break;
                }
            }
#ifdef REFINE_STATS
count++;
if(256*256*256*64 % count == 0){
    printf("after_last:%d to_zero:%d from_zero:%d raise:%d lower:%d sign:%d xyp:%d/%d/%d\n", after_last, to_zero, from_zero, raise, lower, messed_sign, s->mb_x, s->mb_y, s->picture_number);
}
#endif
            run=0;
            rle_index=0;
            for(i=start_i; i<=last_non_zero; i++){
                int j= perm_scantable[i];
                const int level= block[j];

                 if(level){
                     run_tab[rle_index++]=run;
                     run=0;
                 }else{
                     run++;
                 }
            }

            s->dsp.add_8x8basis(rem, basis[j], best_unquant_change);
        }else{
            break;
        }
    }
#ifdef REFINE_STATS
if(last_non_zero>0){
STOP_TIMER("iterative search")
}
}
#endif

    return last_non_zero;
}

int dct_quantize_c(MpegEncContext *s,
                        DCTELEM *block, int n,
                        int qscale, int *overflow)
{
    int i, j, level, last_non_zero, q, start_i;
    const int *qmat;
    const uint8_t *scantable= s->intra_scantable.scantable;
    int bias;
    int max=0;
    unsigned int threshold1, threshold2;

    s->dsp.fdct (block);

    if(s->dct_error_sum)
        s->denoise_dct(s, block);

    if (s->mb_intra) {
        if (!s->h263_aic) {
            if (n < 4)
                q = s->y_dc_scale;
            else
                q = s->c_dc_scale;
            q = q << 3;
        } else
            /* For AIC we skip quant/dequant of INTRADC */
            q = 1 << 3;

        /* note: block[0] is assumed to be positive */
        block[0] = (block[0] + (q >> 1)) / q;
        start_i = 1;
        last_non_zero = 0;
        qmat = s->q_intra_matrix[qscale];
        bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
    } else {
        start_i = 0;
        last_non_zero = -1;
        qmat = s->q_inter_matrix[qscale];
        bias= s->inter_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
    }
    threshold1= (1<<QMAT_SHIFT) - bias - 1;
    threshold2= (threshold1<<1);
    for(i=63;i>=start_i;i--) {
        j = scantable[i];
        level = block[j] * qmat[j];

        if(((unsigned)(level+threshold1))>threshold2){
            last_non_zero = i;
            break;
        }else{
            block[j]=0;
        }
    }
    for(i=start_i; i<=last_non_zero; i++) {
        j = scantable[i];
        level = block[j] * qmat[j];

//        if(   bias+level >= (1<<QMAT_SHIFT)
//           || bias-level >= (1<<QMAT_SHIFT)){
        if(((unsigned)(level+threshold1))>threshold2){
            if(level>0){
                level= (bias + level)>>QMAT_SHIFT;
                block[j]= level;
            }else{
                level= (bias - level)>>QMAT_SHIFT;
                block[j]= -level;
            }
            max |=level;
        }else{
            block[j]=0;
        }
    }
    *overflow= s->max_qcoeff < max; //overflow might have happened

    /* we need this permutation so that we correct the IDCT, we only permute the !=0 elements */
    if (s->dsp.idct_permutation_type != FF_NO_IDCT_PERM)
        ff_block_permute(block, s->dsp.idct_permutation, scantable, last_non_zero);

    return last_non_zero;
}

AVCodec h263_encoder = {
    "h263",
    CODEC_TYPE_VIDEO,
    CODEC_ID_H263,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"),
};

AVCodec h263p_encoder = {
    "h263p",
    CODEC_TYPE_VIDEO,
    CODEC_ID_H263P,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("H.263+ / H.263-1998 / H.263 version 2"),
};

AVCodec flv_encoder = {
    "flv",
    CODEC_TYPE_VIDEO,
    CODEC_ID_FLV1,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV)"),
};

AVCodec rv10_encoder = {
    "rv10",
    CODEC_TYPE_VIDEO,
    CODEC_ID_RV10,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
};

AVCodec rv20_encoder = {
    "rv20",
    CODEC_TYPE_VIDEO,
    CODEC_ID_RV20,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
};

AVCodec mpeg4_encoder = {
    "mpeg4",
    CODEC_TYPE_VIDEO,
    CODEC_ID_MPEG4,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .capabilities= CODEC_CAP_DELAY,
    .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
};

AVCodec msmpeg4v1_encoder = {
    "msmpeg4v1",
    CODEC_TYPE_VIDEO,
    CODEC_ID_MSMPEG4V1,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
};

AVCodec msmpeg4v2_encoder = {
    "msmpeg4v2",
    CODEC_TYPE_VIDEO,
    CODEC_ID_MSMPEG4V2,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
};

AVCodec msmpeg4v3_encoder = {
    "msmpeg4",
    CODEC_TYPE_VIDEO,
    CODEC_ID_MSMPEG4V3,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
};

AVCodec wmv1_encoder = {
    "wmv1",
    CODEC_TYPE_VIDEO,
    CODEC_ID_WMV1,
    sizeof(MpegEncContext),
    MPV_encode_init,
    MPV_encode_picture,
    MPV_encode_end,
    .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
    .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
};
