static int _decode_exponents(int expstr, int ngrps, uint8_t absexp, uint8_t *gexps, uint8_t *dexps)

{

    int exps;

    int i = 0;

    while (ngrps--) {

        exps = gexps[i++];

        absexp += exp_1[exps];

        assert(absexp <= 24);

        switch (expstr) {

            case AC3_EXPSTR_D45:

                *(dexps++) = absexp;

                *(dexps++) = absexp;

            case AC3_EXPSTR_D25:

                *(dexps++) = absexp;

            case AC3_EXPSTR_D15:

                *(dexps++) = absexp;

        }

        absexp += exp_2[exps];

        assert(absexp <= 24);

        switch (expstr) {

            case AC3_EXPSTR_D45:

                *(dexps++) = absexp;

                *(dexps++) = absexp;

            case AC3_EXPSTR_D25:

                *(dexps++) = absexp;

            case AC3_EXPSTR_D15:

                *(dexps++) = absexp;

        }

        absexp += exp_3[exps];

        assert(absexp <= 24);

        switch (expstr) {

            case AC3_EXPSTR_D45:

                *(dexps++) = absexp;

                *(dexps++) = absexp;

            case AC3_EXPSTR_D25:

                *(dexps++) = absexp;

            case AC3_EXPSTR_D15:

                *(dexps++) = absexp;

        }

    }

    return 0;

}


static void draw_axis_yuv(AVFrame *out, AVFrame *axis, const ColorFloat *c, int off)

{

    int fmt = out->format, x, y, yh, w = axis->width, h = axis->height;

    int offh = (fmt == AV_PIX_FMT_YUV420P) ? off / 2 : off;

    float a, rcp_255 = 1.0f / 255.0f;

    uint8_t *vy = out->data[0], *vu = out->data[1], *vv = out->data[2];

    uint8_t *vay = axis->data[0], *vau = axis->data[1], *vav = axis->data[2], *vaa = axis->data[3];

    int lsy = out->linesize[0], lsu = out->linesize[1], lsv = out->linesize[2];

    int lsay = axis->linesize[0], lsau = axis->linesize[1], lsav = axis->linesize[2], lsaa = axis->linesize[3];

    uint8_t *lpy, *lpu, *lpv, *lpay, *lpau, *lpav, *lpaa;

    for (y = 0; y < h; y += 2) {

        yh = (fmt == AV_PIX_FMT_YUV420P) ? y / 2 : y;

        lpy = vy + (off + y) * lsy;

        lpu = vu + (offh + yh) * lsu;

        lpv = vv + (offh + yh) * lsv;

        lpay = vay + y * lsay;

        lpau = vau + yh * lsau;

        lpav = vav + yh * lsav;

        lpaa = vaa + y * lsaa;

        for (x = 0; x < w; x += 2) {

            a = rcp_255 * (*lpaa++);

            *lpy++ = a * (*lpay++) + (1.0f - a) * c[x].yuv.y + 0.5f;

            *lpu++ = a * (*lpau++) + (1.0f - a) * c[x].yuv.u + 0.5f;

            *lpv++ = a * (*lpav++) + (1.0f - a) * c[x].yuv.v + 0.5f;

            /* u and v are skipped on yuv422p and yuv420p */

            a = rcp_255 * (*lpaa++);

            *lpy++ = a * (*lpay++) + (1.0f - a) * c[x+1].yuv.y + 0.5f;

            if (fmt == AV_PIX_FMT_YUV444P) {

                *lpu++ = a * (*lpau++) + (1.0f - a) * c[x+1].yuv.u + 0.5f;

                *lpv++ = a * (*lpav++) + (1.0f - a) * c[x+1].yuv.v + 0.5f;

            }

        }

        lpy = vy + (off + y + 1) * lsy;

        lpu = vu + (off + y + 1) * lsu;

        lpv = vv + (off + y + 1) * lsv;

        lpay = vay + (y + 1) * lsay;

        lpau = vau + (y + 1) * lsau;

        lpav = vav + (y + 1) * lsav;

        lpaa = vaa + (y + 1) * lsaa;

        for (x = 0; x < out->width; x += 2) {

            /* u and v are skipped on yuv420p */

            a = rcp_255 * (*lpaa++);

            *lpy++ = a * (*lpay++) + (1.0f - a) * c[x].yuv.y + 0.5f;

            if (fmt != AV_PIX_FMT_YUV420P) {

                *lpu++ = a * (*lpau++) + (1.0f - a) * c[x].yuv.u + 0.5f;

                *lpv++ = a * (*lpav++) + (1.0f - a) * c[x].yuv.v + 0.5f;

            }

            /* u and v are skipped on yuv422p and yuv420p */

            a = rcp_255 * (*lpaa++);

            *lpy++ = a * (*lpay++) + (1.0f - a) * c[x+1].yuv.y + 0.5f;

            if (fmt == AV_PIX_FMT_YUV444P) {

                *lpu++ = a * (*lpau++) + (1.0f - a) * c[x+1].yuv.u + 0.5f;

                *lpv++ = a * (*lpav++) + (1.0f - a) * c[x+1].yuv.v + 0.5f;

            }

        }

    }

}


static int shift_data(AVFormatContext *s)

{

    int ret = 0, moov_size;

    MOVMuxContext *mov = s->priv_data;

    int64_t pos, pos_end = avio_tell(s->pb);

    uint8_t *buf, *read_buf[2];

    int read_buf_id = 0;

    int read_size[2];

    AVIOContext *read_pb;

    if (mov->flags & FF_MOV_FLAG_FRAGMENT)

        moov_size = compute_sidx_size(s);

    else

        moov_size = compute_moov_size(s);

    if (moov_size < 0)

        return moov_size;

    buf = av_malloc(moov_size * 2);

    if (!buf)

        return AVERROR(ENOMEM);

    read_buf[0] = buf;

    read_buf[1] = buf + moov_size;

    /* Shift the data: the AVIO context of the output can only be used for

     * writing, so we re-open the same output, but for reading. It also avoids

     * a read/seek/write/seek back and forth. */

    avio_flush(s->pb);

    ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ);

    if (ret < 0) {

        av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "

               "the second pass (faststart)\n", s->filename);

        goto end;

    }

    /* mark the end of the shift to up to the last data we wrote, and get ready

     * for writing */

    pos_end = avio_tell(s->pb);

    avio_seek(s->pb, mov->reserved_header_pos + moov_size, SEEK_SET);

    /* start reading at where the new moov will be placed */

    avio_seek(read_pb, mov->reserved_header_pos, SEEK_SET);

    pos = avio_tell(read_pb);

#define READ_BLOCK do {                                                             \

    read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size);  \

    read_buf_id ^= 1;                                                               \

} while (0)

    /* shift data by chunk of at most moov_size */

    READ_BLOCK;

    do {

        int n;

        READ_BLOCK;

        n = read_size[read_buf_id];

        if (n <= 0)

            break;

        avio_write(s->pb, read_buf[read_buf_id], n);

        pos += n;

    } while (pos < pos_end);

    avio_close(read_pb);

end:

    av_free(buf);

    return ret;

}


void ff_do_elbg(int *points, int dim, int numpoints, int *codebook,

                int numCB, int max_steps, int *closest_cb,

                AVLFG *rand_state)

{

    int dist;

    elbg_data elbg_d;

    elbg_data *elbg = &elbg_d;

    int i, j, k, last_error, steps=0;

    int *dist_cb = av_malloc(numpoints*sizeof(int));

    int *size_part = av_malloc(numCB*sizeof(int));

    cell *list_buffer = av_malloc(numpoints*sizeof(cell));

    cell *free_cells;

    int best_dist, best_idx = 0;

    elbg->error = INT_MAX;

    elbg->dim = dim;

    elbg->numCB = numCB;

    elbg->codebook = codebook;

    elbg->cells = av_malloc(numCB*sizeof(cell *));

    elbg->utility = av_malloc(numCB*sizeof(int));

    elbg->nearest_cb = closest_cb;

    elbg->points = points;

    elbg->utility_inc = av_malloc(numCB*sizeof(int));

    elbg->scratchbuf = av_malloc(5*dim*sizeof(int));

    elbg->rand_state = rand_state;

    do {

        free_cells = list_buffer;

        last_error = elbg->error;

        steps++;

        memset(elbg->utility, 0, numCB*sizeof(int));

        memset(elbg->cells, 0, numCB*sizeof(cell *));

        elbg->error = 0;

        /* This loop evaluate the actual Voronoi partition. It is the most

           costly part of the algorithm. */

        for (i=0; i < numpoints; i++) {

            best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX);

            for (k=0; k < elbg->numCB; k++) {

                dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist);

                if (dist < best_dist) {

                    best_dist = dist;

                    best_idx = k;

                }

            }

            elbg->nearest_cb[i] = best_idx;

            dist_cb[i] = best_dist;

            elbg->error += dist_cb[i];

            elbg->utility[elbg->nearest_cb[i]] += dist_cb[i];

            free_cells->index = i;

            free_cells->next = elbg->cells[elbg->nearest_cb[i]];

            elbg->cells[elbg->nearest_cb[i]] = free_cells;

            free_cells++;

        }

        do_shiftings(elbg);

        memset(size_part, 0, numCB*sizeof(int));

        memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int));

        for (i=0; i < numpoints; i++) {

            size_part[elbg->nearest_cb[i]]++;

            for (j=0; j < elbg->dim; j++)

                elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] +=

                    elbg->points[i*elbg->dim + j];

        }

        for (i=0; i < elbg->numCB; i++)

            vect_division(elbg->codebook + i*elbg->dim,

                          elbg->codebook + i*elbg->dim, size_part[i], elbg->dim);

    } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) &&

            (steps < max_steps));

    av_free(dist_cb);

    av_free(size_part);

    av_free(elbg->utility);

    av_free(list_buffer);

    av_free(elbg->cells);

    av_free(elbg->utility_inc);

    av_free(elbg->scratchbuf);

}


int ff_h263_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             uint8_t *buf, int buf_size)

{

    MpegEncContext *s = avctx->priv_data;

    int ret;

    AVFrame *pict = data;

#ifdef PRINT_FRAME_TIME

uint64_t time= rdtsc();

#endif

#ifdef DEBUG

    printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);

    printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);

#endif

    s->flags= avctx->flags;

    s->flags2= avctx->flags2;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict= *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr= NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(s->flags&CODEC_FLAG_TRUNCATED){

        int next;

        if(s->codec_id==CODEC_ID_MPEG4){

            next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);

        }else if(s->codec_id==CODEC_ID_H263){

            next= h263_find_frame_end(&s->parse_context, buf, buf_size);

        }else{

            av_log(s->avctx, AV_LOG_ERROR, "this codec doesnt support truncated bitstreams\n");

            return -1;

        }

        if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )

            return buf_size;

    }

retry:

    if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder

        init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);

    }else

        init_get_bits(&s->gb, buf, buf_size*8);

    s->bitstream_buffer_size=0;

    if (!s->context_initialized) {

        if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix

            return -1;

    }

    //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there

    if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){

        int i= ff_find_unused_picture(s, 0);

        s->current_picture_ptr= &s->picture[i];

    }

    /* let's go :-) */

    if (s->msmpeg4_version==5) {

        ret= ff_wmv2_decode_picture_header(s);

    } else if (s->msmpeg4_version) {

        ret = msmpeg4_decode_picture_header(s);

    } else if (s->h263_pred) {

        if(s->avctx->extradata_size && s->picture_number==0){

            GetBitContext gb;

            init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8);

            ret = ff_mpeg4_decode_picture_header(s, &gb);

        }

        ret = ff_mpeg4_decode_picture_header(s, &s->gb);

        if(s->flags& CODEC_FLAG_LOW_DELAY)

            s->low_delay=1;

    } else if (s->codec_id == CODEC_ID_H263I) {

        ret = intel_h263_decode_picture_header(s);

    } else if (s->h263_flv) {

        ret = flv_h263_decode_picture_header(s);

    } else {

        ret = h263_decode_picture_header(s);

    }

    if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size);

    /* skip if the header was thrashed */

    if (ret < 0){

        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");

        return -1;

    }

    avctx->has_b_frames= !s->low_delay;

    if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){

        if(s->avctx->stream_codec_tag == ff_get_fourcc("XVID") ||

           s->avctx->codec_tag == ff_get_fourcc("XVID") || s->avctx->codec_tag == ff_get_fourcc("XVIX"))

            s->xvid_build= -1;

#if 0

        if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==1

           && s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc

            s->xvid_build= -1;

#endif

    }

    if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){

        if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==0)

            s->divx_version= 400; //divx 4

    }

    if(s->workaround_bugs&FF_BUG_AUTODETECT){

        s->workaround_bugs &= ~FF_BUG_NO_PADDING;

        if(s->padding_bug_score > -2 && !s->data_partitioning && (s->divx_version || !s->resync_marker))

            s->workaround_bugs |=  FF_BUG_NO_PADDING;

        if(s->avctx->codec_tag == ff_get_fourcc("XVIX"))

            s->workaround_bugs|= FF_BUG_XVID_ILACE;

        if(s->avctx->codec_tag == ff_get_fourcc("UMP4")){

            s->workaround_bugs|= FF_BUG_UMP4;

        }

        if(s->divx_version>=500){

            s->workaround_bugs|= FF_BUG_QPEL_CHROMA;

        }

        if(s->divx_version>502){

            s->workaround_bugs|= FF_BUG_QPEL_CHROMA2;

        }

        if(s->xvid_build && s->xvid_build<=3)

            s->padding_bug_score= 256*256*256*64;

        if(s->xvid_build && s->xvid_build<=1)

            s->workaround_bugs|= FF_BUG_QPEL_CHROMA;

        if(s->xvid_build && s->xvid_build<=12)

            s->workaround_bugs|= FF_BUG_EDGE;

        if(s->xvid_build && s->xvid_build<=32)

            s->workaround_bugs|= FF_BUG_DC_CLIP;

#define SET_QPEL_FUNC(postfix1, postfix2) \

    s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\

    s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\

    s->dsp.avg_ ## postfix1 = ff_avg_ ## postfix2;

        if(s->lavc_build && s->lavc_build<4653)

            s->workaround_bugs|= FF_BUG_STD_QPEL;

        if(s->lavc_build && s->lavc_build<4655)

            s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;

        if(s->lavc_build && s->lavc_build<4670){

            s->workaround_bugs|= FF_BUG_EDGE;

        }

        if(s->lavc_build && s->lavc_build<=4712)

            s->workaround_bugs|= FF_BUG_DC_CLIP;

        if(s->divx_version)

            s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;

//printf("padding_bug_score: %d\n", s->padding_bug_score);

        if(s->divx_version==501 && s->divx_build==20020416)

            s->padding_bug_score= 256*256*256*64;

        if(s->divx_version && s->divx_version<500){

            s->workaround_bugs|= FF_BUG_EDGE;

        }

        if(s->divx_version)

            s->workaround_bugs|= FF_BUG_HPEL_CHROMA;

#if 0

        if(s->divx_version==500)

            s->padding_bug_score= 256*256*256*64;

        /* very ugly XVID padding bug detection FIXME/XXX solve this differently

         * lets hope this at least works

         */

        if(   s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==0

           && s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0)

            s->workaround_bugs|= FF_BUG_NO_PADDING;

        if(s->lavc_build && s->lavc_build<4609) //FIXME not sure about the version num but a 4609 file seems ok

            s->workaround_bugs|= FF_BUG_NO_PADDING;

#endif

    }

    if(s->workaround_bugs& FF_BUG_STD_QPEL){

        SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[0][ 9], qpel16_mc12_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][ 5], qpel8_mc11_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][ 7], qpel8_mc31_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][ 9], qpel8_mc12_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)

        SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)

    }

    if(avctx->debug & FF_DEBUG_BUGS)

        av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",

               s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build,

               s->divx_packed ? "p" : "");

#if 0 // dump bits per frame / qp / complexity

{

    static FILE *f=NULL;

    if(!f) f=fopen("rate_qp_cplx.txt", "w");

    fprintf(f, "%d %d %f\n", buf_size, s->qscale, buf_size*(double)s->qscale);

}

#endif

        /* After H263 & mpeg4 header decode we have the height, width,*/

        /* and other parameters. So then we could init the picture   */

        /* FIXME: By the way H263 decoder is evolving it should have */

        /* an H263EncContext                                         */

    if (   s->width != avctx->width || s->height != avctx->height) {

        /* H.263 could change picture size any time */

        ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat

        s->parse_context.buffer=0;

        MPV_common_end(s);

        s->parse_context= pc;

    }

    if (!s->context_initialized) {

        avctx->width = s->width;

        avctx->height = s->height;

        goto retry;

    }

    if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P))

        s->gob_index = ff_h263_get_gob_height(s);

    // for hurry_up==5

    s->current_picture.pict_type= s->pict_type;

    s->current_picture.key_frame= s->pict_type == I_TYPE;

    /* skip b frames if we dont have reference frames */

    if(s->last_picture_ptr==NULL && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);

    /* skip b frames if we are in a hurry */

    if(avctx->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);

    /* skip everything if we are in a hurry>=5 */

    if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size);

    if(s->next_p_frame_damaged){

        if(s->pict_type==B_TYPE)

            return get_consumed_bytes(s, buf_size);

        else

            s->next_p_frame_damaged=0;

    }

    if(MPV_frame_start(s, avctx) < 0)

        return -1;

#ifdef DEBUG

    printf("qscale=%d\n", s->qscale);

#endif

    ff_er_frame_start(s);

    //the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type

    //which isnt available before MPV_frame_start()

    if (s->msmpeg4_version==5){

        if(ff_wmv2_decode_secondary_picture_header(s) < 0)

            return -1;

    }

    /* decode each macroblock */

    s->mb_x=0;

    s->mb_y=0;

    decode_slice(s);

    while(s->mb_y<s->mb_height){

        if(s->msmpeg4_version){

            if(s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits)

                break;

        }else{

            if(ff_h263_resync(s)<0)

                break;

        }

        if(s->msmpeg4_version<4 && s->h263_pred)

            ff_mpeg4_clean_buffers(s);

        decode_slice(s);

    }

    if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)

        if(msmpeg4_decode_ext_header(s, buf_size) < 0){

            s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR;

        }

    /* divx 5.01+ bistream reorder stuff */

    if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){

        int current_pos= get_bits_count(&s->gb)>>3;

        int startcode_found=0;

        if(   buf_size - current_pos > 5

           && buf_size - current_pos < BITSTREAM_BUFFER_SIZE){

            int i;

            for(i=current_pos; i<buf_size-3; i++){

                if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){

                    startcode_found=1;

                    break;

                }

            }

        }

        if(s->gb.buffer == s->bitstream_buffer && buf_size>20){ //xvid style

            startcode_found=1;

            current_pos=0;

        }

        if(startcode_found){

            memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);

            s->bitstream_buffer_size= buf_size - current_pos;

        }

    }

    ff_er_frame_end(s);

    MPV_frame_end(s);

assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);

assert(s->current_picture.pict_type == s->pict_type);

    if(s->pict_type==B_TYPE || s->low_delay){

        *pict= *(AVFrame*)&s->current_picture;

        ff_print_debug_info(s, pict);

    } else {

        *pict= *(AVFrame*)&s->last_picture;

        if(pict)

            ff_print_debug_info(s, pict);

    }

    /* Return the Picture timestamp as the frame number */

    /* we substract 1 because it is added on utils.c    */

    avctx->frame_number = s->picture_number - 1;

    /* dont output the last pic after seeking */

    if(s->last_picture_ptr || s->low_delay)

        *data_size = sizeof(AVFrame);

#ifdef PRINT_FRAME_TIME

printf("%Ld\n", rdtsc()-time);

#endif

    return get_consumed_bytes(s, buf_size);

}


static void vnc_dpy_copy(DisplayChangeListener *dcl,

                         DisplayState *ds,

                         int src_x, int src_y,

                         int dst_x, int dst_y, int w, int h)

{

    VncDisplay *vd = ds->opaque;

    VncState *vs, *vn;

    uint8_t *src_row;

    uint8_t *dst_row;

    int i, x, y, pitch, inc, w_lim, s;

    int cmp_bytes;

    vnc_refresh_server_surface(vd);

    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {

        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

            vs->force_update = 1;

            vnc_update_client_sync(vs, 1);

            /* vs might be free()ed here */

        }

    }

    /* do bitblit op on the local surface too */

    pitch = vnc_server_fb_stride(vd);

    src_row = vnc_server_fb_ptr(vd, src_x, src_y);

    dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);

    y = dst_y;

    inc = 1;

    if (dst_y > src_y) {

        /* copy backwards */

        src_row += pitch * (h-1);

        dst_row += pitch * (h-1);

        pitch = -pitch;

        y = dst_y + h - 1;

        inc = -1;

    }

    w_lim = w - (16 - (dst_x % 16));

    if (w_lim < 0)

        w_lim = w;

    else

        w_lim = w - (w_lim % 16);

    for (i = 0; i < h; i++) {

        for (x = 0; x <= w_lim;

                x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {

            if (x == w_lim) {

                if ((s = w - w_lim) == 0)

                    break;

            } else if (!x) {

                s = (16 - (dst_x % 16));

                s = MIN(s, w_lim);

            } else {

                s = 16;

            }

            cmp_bytes = s * VNC_SERVER_FB_BYTES;

            if (memcmp(src_row, dst_row, cmp_bytes) == 0)

                continue;

            memmove(dst_row, src_row, cmp_bytes);

            QTAILQ_FOREACH(vs, &vd->clients, next) {

                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

                    set_bit(((x + dst_x) / 16), vs->dirty[y]);

                }

            }

        }

        src_row += pitch - w * VNC_SERVER_FB_BYTES;

        dst_row += pitch - w * VNC_SERVER_FB_BYTES;

        y += inc;

    }

    QTAILQ_FOREACH(vs, &vd->clients, next) {

        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {

            vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);

        }

    }

}


static void FUNCC(pred8x8_vertical)(uint8_t *_src, int _stride){

    int i;

    pixel *src = (pixel*)_src;

    int stride = _stride/sizeof(pixel);

    const pixel4 a= ((pixel4*)(src-stride))[0];

    const pixel4 b= ((pixel4*)(src-stride))[1];

    for(i=0; i<8; i++){

        ((pixel4*)(src+i*stride))[0]= a;

        ((pixel4*)(src+i*stride))[1]= b;

    }

}


static int videotoolbox_buffer_create(AVCodecContext *avctx, AVFrame *frame)

{

    VTContext *vtctx = avctx->internal->hwaccel_priv_data;

    CVPixelBufferRef pixbuf = (CVPixelBufferRef)vtctx->frame;

    OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);

    enum AVPixelFormat sw_format = av_map_videotoolbox_format_to_pixfmt(pixel_format);

    int width = CVPixelBufferGetWidth(pixbuf);

    int height = CVPixelBufferGetHeight(pixbuf);

    AVHWFramesContext *cached_frames;

    int ret;

    ret = ff_videotoolbox_buffer_create(vtctx, frame);

    if (ret < 0)

        return ret;

    // Old API code path.

    if (!vtctx->cached_hw_frames_ctx)

        return 0;

    cached_frames = (AVHWFramesContext*)vtctx->cached_hw_frames_ctx->data;

    if (cached_frames->sw_format != sw_format ||

        cached_frames->width != width ||

        cached_frames->height != height) {

        AVBufferRef *hw_frames_ctx = av_hwframe_ctx_alloc(cached_frames->device_ref);

        AVHWFramesContext *hw_frames;

        if (!hw_frames_ctx)

            return AVERROR(ENOMEM);

        hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;

        hw_frames->format = cached_frames->format;

        hw_frames->sw_format = sw_format;

        hw_frames->width = width;

        hw_frames->height = height;

        ret = av_hwframe_ctx_init(hw_frames_ctx);

        if (ret < 0) {

            av_buffer_unref(&hw_frames_ctx);

            return ret;

        }

        av_buffer_unref(&vtctx->cached_hw_frames_ctx);

        vtctx->cached_hw_frames_ctx = hw_frames_ctx;

    }

    av_assert0(!frame->hw_frames_ctx);

    frame->hw_frames_ctx = av_buffer_ref(vtctx->cached_hw_frames_ctx);

    if (!frame->hw_frames_ctx)

        return AVERROR(ENOMEM);

    return 0;

}


static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const long obmc_stride, uint8_t * * block, int b_w, long b_h,

                      int src_x, int src_y, long src_stride, slice_buffer * sb, int add, uint8_t * dst8){

snow_inner_add_yblock_sse2_header

snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0")

snow_inner_add_yblock_sse2_accum_16("2", "16")

snow_inner_add_yblock_sse2_accum_16("1", "512")

snow_inner_add_yblock_sse2_accum_16("0", "528")

             "mov %0, %%"REG_d"              \n\t"

             "movdqa %%xmm1, %%xmm0          \n\t"

             "movdqa %%xmm5, %%xmm4          \n\t"

             "punpcklwd %%xmm7, %%xmm0       \n\t"

             "paddd (%%"REG_D"), %%xmm0      \n\t"

             "punpckhwd %%xmm7, %%xmm1       \n\t"

             "paddd 16(%%"REG_D"), %%xmm1    \n\t"

             "punpcklwd %%xmm7, %%xmm4       \n\t"

             "paddd 32(%%"REG_D"), %%xmm4    \n\t"

             "punpckhwd %%xmm7, %%xmm5       \n\t"

             "paddd 48(%%"REG_D"), %%xmm5    \n\t"

             "paddd %%xmm3, %%xmm0           \n\t"

             "paddd %%xmm3, %%xmm1           \n\t"

             "paddd %%xmm3, %%xmm4           \n\t"

             "paddd %%xmm3, %%xmm5           \n\t"

             "psrad $8, %%xmm0               \n\t" /* FRAC_BITS. */

             "psrad $8, %%xmm1               \n\t" /* FRAC_BITS. */

             "psrad $8, %%xmm4               \n\t" /* FRAC_BITS. */

             "psrad $8, %%xmm5               \n\t" /* FRAC_BITS. */

             "packssdw %%xmm1, %%xmm0        \n\t"

             "packssdw %%xmm5, %%xmm4        \n\t"

             "packuswb %%xmm4, %%xmm0        \n\t"

             "movdqu %%xmm0, (%%"REG_d")       \n\t"

snow_inner_add_yblock_sse2_end_16

}


restore_fpu_state(CPUSPARCState *env, qemu_siginfo_fpu_t *fpu)

{

        int err;

#if 0

#ifdef CONFIG_SMP

        if (current->flags & PF_USEDFPU)

                regs->psr &= ~PSR_EF;

#else

        if (current == last_task_used_math) {

                last_task_used_math = 0;

                regs->psr &= ~PSR_EF;

        }

#endif

        current->used_math = 1;

        current->flags &= ~PF_USEDFPU;

#endif

#if 0

        if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))

                return -EFAULT;

#endif

#if 0

        /* XXX: incorrect */

        err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0],

	                             (sizeof(unsigned long) * 32));

#endif

        err |= __get_user(env->fsr, &fpu->si_fsr);

#if 0

        err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth);

        if (current->thread.fpqdepth != 0)

                err |= __copy_from_user(&current->thread.fpqueue[0],

                                        &fpu->si_fpqueue[0],

                                        ((sizeof(unsigned long) +

                                        (sizeof(unsigned long *)))*16));

#endif

        return err;

}


static void gen_vfp_msr(TCGv tmp)

{

    tcg_gen_mov_i32(cpu_F0s, tmp);

    dead_tmp(tmp);

}


static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)

{

    ASFContext *asf = s->priv_data;

    uint32_t packet_length, padsize;

    int rsize = 8;

    int c, d, e, off;

    // if we do not know packet size, allow skipping up to 32 kB

    off= 32768;

    if (s->packet_size > 0)

        off= (avio_tell(pb) - s->data_offset) % s->packet_size + 3;

    c=d=e=-1;

    while(off-- > 0){

        c=d; d=e;

        e= avio_r8(pb);

        if(c == 0x82 && !d && !e)

            break;

    }

    if (c != 0x82) {

        /**

         * This code allows handling of -EAGAIN at packet boundaries (i.e.

         * if the packet sync code above triggers -EAGAIN). This does not

         * imply complete -EAGAIN handling support at random positions in

         * the stream.

         */

        if (pb->error == AVERROR(EAGAIN))

            return AVERROR(EAGAIN);

        if (!url_feof(pb))

            av_log(s, AV_LOG_ERROR, "ff asf bad header %x  at:%"PRId64"\n", c, avio_tell(pb));

    }

    if ((c & 0x8f) == 0x82) {

        if (d || e) {

            if (!url_feof(pb))

                av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");

            return -1;

        }

        c= avio_r8(pb);

        d= avio_r8(pb);

        rsize+=3;

    }else{

        avio_seek(pb, -1, SEEK_CUR); //FIXME

    }

    asf->packet_flags    = c;

    asf->packet_property = d;

    DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size);

    DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored

    DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length

    //the following checks prevent overflows and infinite loops

    if(!packet_length || packet_length >= (1U<<29)){

        av_log(s, AV_LOG_ERROR, "invalid packet_length %d at:%"PRId64"\n", packet_length, avio_tell(pb));

        return -1;

    }

    if(padsize >= packet_length){

        av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));

        return -1;

    }

    asf->packet_timestamp = avio_rl32(pb);

    avio_rl16(pb); /* duration */

    // rsize has at least 11 bytes which have to be present

    if (asf->packet_flags & 0x01) {

        asf->packet_segsizetype = avio_r8(pb); rsize++;

        asf->packet_segments = asf->packet_segsizetype & 0x3f;

    } else {

        asf->packet_segments = 1;

        asf->packet_segsizetype = 0x80;

    }

    asf->packet_size_left = packet_length - padsize - rsize;

    if (packet_length < asf->hdr.min_pktsize)

        padsize += asf->hdr.min_pktsize - packet_length;

    asf->packet_padsize = padsize;

    av_dlog(s, "packet: size=%d padsize=%d  left=%d\n", s->packet_size, asf->packet_padsize, asf->packet_size_left);

    return 0;

}


void checkasm_check_blockdsp(void)

{

    LOCAL_ALIGNED_16(uint16_t, buf0, [6 * 8 * 8]);

    LOCAL_ALIGNED_16(uint16_t, buf1, [6 * 8 * 8]);

    AVCodecContext avctx = { 0 };

    BlockDSPContext h;

    ff_blockdsp_init(&h, &avctx);

    check_clear(clear_block,  8 * 8);

    check_clear(clear_blocks, 8 * 8 * 6);

    report("blockdsp");

}


void stellaris_enet_init(NICInfo *nd, uint32_t base, qemu_irq irq)

{

    stellaris_enet_state *s;

    int iomemtype;

    qemu_check_nic_model(nd, "stellaris");

    s = (stellaris_enet_state *)qemu_mallocz(sizeof(stellaris_enet_state));

    iomemtype = cpu_register_io_memory(0, stellaris_enet_readfn,

                                       stellaris_enet_writefn, s);

    cpu_register_physical_memory(base, 0x00001000, iomemtype);

    s->irq = irq;

    memcpy(s->macaddr, nd->macaddr, 6);

    if (nd->vlan) {

        s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,

                                     stellaris_enet_receive, stellaris_enet_can_receive, s);

        qemu_format_nic_info_str(s->vc, s->macaddr);

    }

    stellaris_enet_reset(s);

    register_savevm("stellaris_enet", -1, 1,

                    stellaris_enet_save, stellaris_enet_load, s);

}


static int mkv_write_chapters(AVFormatContext *s)

{

    MatroskaMuxContext *mkv = s->priv_data;

    AVIOContext *pb = s->pb;

    ebml_master chapters, editionentry;

    AVRational scale = {1, 1E9};

    int i, ret;

    if (!s->nb_chapters || mkv->wrote_chapters)

        return 0;

    ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb));

    if (ret < 0) return ret;

    chapters     = start_ebml_master(pb, MATROSKA_ID_CHAPTERS    , 0);

    editionentry = start_ebml_master(pb, MATROSKA_ID_EDITIONENTRY, 0);

    put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGDEFAULT, 1);

    put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGHIDDEN , 0);

    for (i = 0; i < s->nb_chapters; i++) {

        ebml_master chapteratom, chapterdisplay;

        AVChapter *c     = s->chapters[i];

        int chapterstart = av_rescale_q(c->start, c->time_base, scale);

        int chapterend   = av_rescale_q(c->end,   c->time_base, scale);

        AVDictionaryEntry *t = NULL;

        if (chapterstart < 0 || chapterstart > chapterend)

            return AVERROR_INVALIDDATA;

        chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0);

        put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id + mkv->chapter_id_offset);

        put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART, chapterstart);

        put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND, chapterend);

        put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0);

        put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1);

        if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {

            chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0);

            put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value);

            put_ebml_string(pb, MATROSKA_ID_CHAPLANG  , "und");

            end_ebml_master(pb, chapterdisplay);

        }

        end_ebml_master(pb, chapteratom);

    }

    end_ebml_master(pb, editionentry);

    end_ebml_master(pb, chapters);

    mkv->wrote_chapters = 1;

    return 0;

}


static inline void vring_set_avail_event(VirtQueue *vq, uint16_t val)

{

    VRingMemoryRegionCaches *caches;

    hwaddr pa;

    if (!vq->notification) {

        return;

    }

    caches = atomic_rcu_read(&vq->vring.caches);

    pa = offsetof(VRingUsed, ring[vq->vring.num]);

    virtio_stw_phys_cached(vq->vdev, &caches->used, pa, val);

    address_space_cache_invalidate(&caches->used, pa, sizeof(val));

}


void ff_er_frame_end(ERContext *s)

{

    int *linesize = s->cur_pic->f.linesize;

    int i, mb_x, mb_y, error, error_type, dc_error, mv_error, ac_error;

    int distance;

    int threshold_part[4] = { 100, 100, 100 };

    int threshold = 50;

    int is_intra_likely;

    int size = s->b8_stride * 2 * s->mb_height;

    /* We do not support ER of field pictures yet,

     * though it should not crash if enabled. */

    if (!s->avctx->error_concealment || s->error_count == 0            ||

        s->avctx->lowres                                               ||

        s->avctx->hwaccel                                              ||

        s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU          ||

        !s->cur_pic || s->cur_pic->field_picture                               ||

        s->error_count == 3 * s->mb_width *

                          (s->avctx->skip_top + s->avctx->skip_bottom)) {

        return;

    }

    for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

        int status = s->error_status_table[mb_x + (s->mb_height - 1) * s->mb_stride];

        if (status != 0x7F)

            break;

    }

    if (   mb_x == s->mb_width

        && s->avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO

        && (s->avctx->height&16)

        && s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom + 1)

    ) {

        av_log(s->avctx, AV_LOG_DEBUG, "ignoring last missing slice\n");

        return;

    }

    if (s->last_pic) {

        if (s->last_pic->f.width  != s->cur_pic->f.width  ||

            s->last_pic->f.height != s->cur_pic->f.height ||

            s->last_pic->f.format != s->cur_pic->f.format) {

            av_log(s->avctx, AV_LOG_WARNING, "Cannot use previous picture in error concealment\n");

            s->last_pic = NULL;

        }

    }

    if (s->next_pic) {

        if (s->next_pic->f.width  != s->cur_pic->f.width  ||

            s->next_pic->f.height != s->cur_pic->f.height ||

            s->next_pic->f.format != s->cur_pic->f.format) {

            av_log(s->avctx, AV_LOG_WARNING, "Cannot use next picture in error concealment\n");

            s->next_pic = NULL;

        }

    }

    if (s->cur_pic->motion_val[0] == NULL) {

        av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");

        for (i = 0; i < 2; i++) {

            s->cur_pic->ref_index_buf[i]  = av_buffer_allocz(s->mb_stride * s->mb_height * 4 * sizeof(uint8_t));

            s->cur_pic->motion_val_buf[i] = av_buffer_allocz((size + 4) * 2 * sizeof(uint16_t));

            if (!s->cur_pic->ref_index_buf[i] || !s->cur_pic->motion_val_buf[i])

                break;

            s->cur_pic->ref_index[i]  = s->cur_pic->ref_index_buf[i]->data;

            s->cur_pic->motion_val[i] = (int16_t (*)[2])s->cur_pic->motion_val_buf[i]->data + 4;

        }

        if (i < 2) {

            for (i = 0; i < 2; i++) {

                av_buffer_unref(&s->cur_pic->ref_index_buf[i]);

                av_buffer_unref(&s->cur_pic->motion_val_buf[i]);

                s->cur_pic->ref_index[i]  = NULL;

                s->cur_pic->motion_val[i] = NULL;

            }

            return;

        }

    }

    if (s->avctx->debug & FF_DEBUG_ER) {

        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

                int status = s->error_status_table[mb_x + mb_y * s->mb_stride];

                av_log(s->avctx, AV_LOG_DEBUG, "%2X ", status);

            }

            av_log(s->avctx, AV_LOG_DEBUG, "\n");

        }

    }

#if 1

    /* handle overlapping slices */

    for (error_type = 1; error_type <= 3; error_type++) {

        int end_ok = 0;

        for (i = s->mb_num - 1; i >= 0; i--) {

            const int mb_xy = s->mb_index2xy[i];

            int error       = s->error_status_table[mb_xy];

            if (error & (1 << error_type))

                end_ok = 1;

            if (error & (8 << error_type))

                end_ok = 1;

            if (!end_ok)

                s->error_status_table[mb_xy] |= 1 << error_type;

            if (error & VP_START)

                end_ok = 0;

        }

    }

#endif

#if 1

    /* handle slices with partitions of different length */

    if (s->partitioned_frame) {

        int end_ok = 0;

        for (i = s->mb_num - 1; i >= 0; i--) {

            const int mb_xy = s->mb_index2xy[i];

            int error       = s->error_status_table[mb_xy];

            if (error & ER_AC_END)

                end_ok = 0;

            if ((error & ER_MV_END) ||

                (error & ER_DC_END) ||

                (error & ER_AC_ERROR))

                end_ok = 1;

            if (!end_ok)

                s->error_status_table[mb_xy]|= ER_AC_ERROR;

            if (error & VP_START)

                end_ok = 0;

        }

    }

#endif

    /* handle missing slices */

    if (s->avctx->err_recognition & AV_EF_EXPLODE) {

        int end_ok = 1;

        // FIXME + 100 hack

        for (i = s->mb_num - 2; i >= s->mb_width + 100; i--) {

            const int mb_xy = s->mb_index2xy[i];

            int error1 = s->error_status_table[mb_xy];

            int error2 = s->error_status_table[s->mb_index2xy[i + 1]];

            if (error1 & VP_START)

                end_ok = 1;

            if (error2 == (VP_START | ER_MB_ERROR | ER_MB_END) &&

                error1 != (VP_START | ER_MB_ERROR | ER_MB_END) &&

                ((error1 & ER_AC_END) || (error1 & ER_DC_END) ||

                (error1 & ER_MV_END))) {

                // end & uninit

                end_ok = 0;

            }

            if (!end_ok)

                s->error_status_table[mb_xy] |= ER_MB_ERROR;

        }

    }

#if 1

    /* backward mark errors */

    distance = 9999999;

    for (error_type = 1; error_type <= 3; error_type++) {

        for (i = s->mb_num - 1; i >= 0; i--) {

            const int mb_xy = s->mb_index2xy[i];

            int       error = s->error_status_table[mb_xy];

            if (!s->mbskip_table[mb_xy]) // FIXME partition specific

                distance++;

            if (error & (1 << error_type))

                distance = 0;

            if (s->partitioned_frame) {

                if (distance < threshold_part[error_type - 1])

                    s->error_status_table[mb_xy] |= 1 << error_type;

            } else {

                if (distance < threshold)

                    s->error_status_table[mb_xy] |= 1 << error_type;

            }

            if (error & VP_START)

                distance = 9999999;

        }

    }

#endif

    /* forward mark errors */

    error = 0;

    for (i = 0; i < s->mb_num; i++) {

        const int mb_xy = s->mb_index2xy[i];

        int old_error   = s->error_status_table[mb_xy];

        if (old_error & VP_START) {

            error = old_error & ER_MB_ERROR;

        } else {

            error |= old_error & ER_MB_ERROR;

            s->error_status_table[mb_xy] |= error;

        }

    }

#if 1

    /* handle not partitioned case */

    if (!s->partitioned_frame) {

        for (i = 0; i < s->mb_num; i++) {

            const int mb_xy = s->mb_index2xy[i];

            error = s->error_status_table[mb_xy];

            if (error & ER_MB_ERROR)

                error |= ER_MB_ERROR;

            s->error_status_table[mb_xy] = error;

        }

    }

#endif

    dc_error = ac_error = mv_error = 0;

    for (i = 0; i < s->mb_num; i++) {

        const int mb_xy = s->mb_index2xy[i];

        error = s->error_status_table[mb_xy];

        if (error & ER_DC_ERROR)

            dc_error++;

        if (error & ER_AC_ERROR)

            ac_error++;

        if (error & ER_MV_ERROR)

            mv_error++;

    }

    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors in %c frame\n",

           dc_error, ac_error, mv_error, av_get_picture_type_char(s->cur_pic->f.pict_type));

    is_intra_likely = is_intra_more_likely(s);

    /* set unknown mb-type to most likely */

    for (i = 0; i < s->mb_num; i++) {

        const int mb_xy = s->mb_index2xy[i];

        error = s->error_status_table[mb_xy];

        if (!((error & ER_DC_ERROR) && (error & ER_MV_ERROR)))

            continue;

        if (is_intra_likely)

            s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;

        else

            s->cur_pic->mb_type[mb_xy] = MB_TYPE_16x16 | MB_TYPE_L0;

    }

    // change inter to intra blocks if no reference frames are available

    if (!(s->last_pic && s->last_pic->f.data[0]) &&

        !(s->next_pic && s->next_pic->f.data[0]))

        for (i = 0; i < s->mb_num; i++) {

            const int mb_xy = s->mb_index2xy[i];

            if (!IS_INTRA(s->cur_pic->mb_type[mb_xy]))

                s->cur_pic->mb_type[mb_xy] = MB_TYPE_INTRA4x4;

        }

    /* handle inter blocks with damaged AC */

    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

            const int mb_xy   = mb_x + mb_y * s->mb_stride;

            const int mb_type = s->cur_pic->mb_type[mb_xy];

            const int dir     = !(s->last_pic && s->last_pic->f.data[0]);

            const int mv_dir  = dir ? MV_DIR_BACKWARD : MV_DIR_FORWARD;

            int mv_type;

            error = s->error_status_table[mb_xy];

            if (IS_INTRA(mb_type))

                continue; // intra

            if (error & ER_MV_ERROR)

                continue; // inter with damaged MV

            if (!(error & ER_AC_ERROR))

                continue; // undamaged inter

            if (IS_8X8(mb_type)) {

                int mb_index = mb_x * 2 + mb_y * 2 * s->b8_stride;

                int j;

                mv_type = MV_TYPE_8X8;

                for (j = 0; j < 4; j++) {

                    s->mv[0][j][0] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][0];

                    s->mv[0][j][1] = s->cur_pic->motion_val[dir][mb_index + (j & 1) + (j >> 1) * s->b8_stride][1];

                }

            } else {

                mv_type     = MV_TYPE_16X16;

                s->mv[0][0][0] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][0];

                s->mv[0][0][1] = s->cur_pic->motion_val[dir][mb_x * 2 + mb_y * 2 * s->b8_stride][1];

            }

            s->decode_mb(s->opaque, 0 /* FIXME h264 partitioned slices need this set */,

                         mv_dir, mv_type, &s->mv, mb_x, mb_y, 0, 0);

        }

    }

    /* guess MVs */

    if (s->cur_pic->f.pict_type == AV_PICTURE_TYPE_B) {

        for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

                int       xy      = mb_x * 2 + mb_y * 2 * s->b8_stride;

                const int mb_xy   = mb_x + mb_y * s->mb_stride;

                const int mb_type = s->cur_pic->mb_type[mb_xy];

                int mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;

                error = s->error_status_table[mb_xy];

                if (IS_INTRA(mb_type))

                    continue;

                if (!(error & ER_MV_ERROR))

                    continue; // inter with undamaged MV

                if (!(error & ER_AC_ERROR))

                    continue; // undamaged inter

                if (!(s->last_pic && s->last_pic->f.data[0]))

                    mv_dir &= ~MV_DIR_FORWARD;

                if (!(s->next_pic && s->next_pic->f.data[0]))

                    mv_dir &= ~MV_DIR_BACKWARD;

                if (s->pp_time) {

                    int time_pp = s->pp_time;

                    int time_pb = s->pb_time;

                    av_assert0(s->avctx->codec_id != AV_CODEC_ID_H264);

                    ff_thread_await_progress(&s->next_pic->tf, mb_y, 0);

                    s->mv[0][0][0] = s->next_pic->motion_val[0][xy][0] *  time_pb            / time_pp;

                    s->mv[0][0][1] = s->next_pic->motion_val[0][xy][1] *  time_pb            / time_pp;

                    s->mv[1][0][0] = s->next_pic->motion_val[0][xy][0] * (time_pb - time_pp) / time_pp;

                    s->mv[1][0][1] = s->next_pic->motion_val[0][xy][1] * (time_pb - time_pp) / time_pp;

                } else {

                    s->mv[0][0][0] = 0;

                    s->mv[0][0][1] = 0;

                    s->mv[1][0][0] = 0;

                    s->mv[1][0][1] = 0;

                }

                s->decode_mb(s->opaque, 0, mv_dir, MV_TYPE_16X16, &s->mv,

                             mb_x, mb_y, 0, 0);

            }

        }

    } else

        guess_mv(s);

#if FF_API_XVMC

FF_DISABLE_DEPRECATION_WARNINGS

    /* the filters below are not XvMC compatible, skip them */

    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)

        goto ec_clean;

FF_ENABLE_DEPRECATION_WARNINGS

#endif /* FF_API_XVMC */

    /* fill DC for inter blocks */

    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

            int dc, dcu, dcv, y, n;

            int16_t *dc_ptr;

            uint8_t *dest_y, *dest_cb, *dest_cr;

            const int mb_xy   = mb_x + mb_y * s->mb_stride;

            const int mb_type = s->cur_pic->mb_type[mb_xy];

            error = s->error_status_table[mb_xy];

            if (IS_INTRA(mb_type) && s->partitioned_frame)

                continue;

            // if (error & ER_MV_ERROR)

            //     continue; // inter data damaged FIXME is this good?

            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];

            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];

            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];

            dc_ptr = &s->dc_val[0][mb_x * 2 + mb_y * 2 * s->b8_stride];

            for (n = 0; n < 4; n++) {

                dc = 0;

                for (y = 0; y < 8; y++) {

                    int x;

                    for (x = 0; x < 8; x++)

                       dc += dest_y[x + (n & 1) * 8 +

                             (y + (n >> 1) * 8) * linesize[0]];

                }

                dc_ptr[(n & 1) + (n >> 1) * s->b8_stride] = (dc + 4) >> 3;

            }

            dcu = dcv = 0;

            for (y = 0; y < 8; y++) {

                int x;

                for (x = 0; x < 8; x++) {

                    dcu += dest_cb[x + y * linesize[1]];

                    dcv += dest_cr[x + y * linesize[2]];

                }

            }

            s->dc_val[1][mb_x + mb_y * s->mb_stride] = (dcu + 4) >> 3;

            s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;

        }

    }

#if 1

    /* guess DC for damaged blocks */

    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);

    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);

    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);

#endif

    /* filter luma DC */

    filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);

#if 1

    /* render DC only intra */

    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

            uint8_t *dest_y, *dest_cb, *dest_cr;

            const int mb_xy   = mb_x + mb_y * s->mb_stride;

            const int mb_type = s->cur_pic->mb_type[mb_xy];

            error = s->error_status_table[mb_xy];

            if (IS_INTER(mb_type))

                continue;

            if (!(error & ER_AC_ERROR))

                continue; // undamaged

            dest_y  = s->cur_pic->f.data[0] + mb_x * 16 + mb_y * 16 * linesize[0];

            dest_cb = s->cur_pic->f.data[1] + mb_x *  8 + mb_y *  8 * linesize[1];

            dest_cr = s->cur_pic->f.data[2] + mb_x *  8 + mb_y *  8 * linesize[2];

            put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);

        }

    }

#endif

    if (s->avctx->error_concealment & FF_EC_DEBLOCK) {

        /* filter horizontal block boundaries */

        h_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,

                       s->mb_height * 2, linesize[0], 1);

        h_block_filter(s, s->cur_pic->f.data[1], s->mb_width,

                       s->mb_height, linesize[1], 0);

        h_block_filter(s, s->cur_pic->f.data[2], s->mb_width,

                       s->mb_height, linesize[2], 0);

        /* filter vertical block boundaries */

        v_block_filter(s, s->cur_pic->f.data[0], s->mb_width * 2,

                       s->mb_height * 2, linesize[0], 1);

        v_block_filter(s, s->cur_pic->f.data[1], s->mb_width,

                       s->mb_height, linesize[1], 0);

        v_block_filter(s, s->cur_pic->f.data[2], s->mb_width,

                       s->mb_height, linesize[2], 0);

    }

ec_clean:

    /* clean a few tables */

    for (i = 0; i < s->mb_num; i++) {

        const int mb_xy = s->mb_index2xy[i];

        int       error = s->error_status_table[mb_xy];

        if (s->cur_pic->f.pict_type != AV_PICTURE_TYPE_B &&

            (error & (ER_DC_ERROR | ER_MV_ERROR | ER_AC_ERROR))) {

            s->mbskip_table[mb_xy] = 0;

        }

        s->mbintra_table[mb_xy] = 1;

    }

    s->cur_pic = NULL;

    s->next_pic    = NULL;

    s->last_pic    = NULL;

}


static void init_excp_601 (CPUPPCState *env)

{

#if !defined(CONFIG_USER_ONLY)

    env->excp_vectors[POWERPC_EXCP_RESET]    = 0x00000100;

    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;

    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;

    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;

    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;

    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;

    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;

    env->excp_vectors[POWERPC_EXCP_FPU]      = 0x00000800;

    env->excp_vectors[POWERPC_EXCP_DECR]     = 0x00000900;

    env->excp_vectors[POWERPC_EXCP_IO]       = 0x00000A00;

    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;

    env->excp_vectors[POWERPC_EXCP_RUNM]     = 0x00002000;

    env->excp_prefix = 0xFFF00000;

    /* Hardware reset vector */

    env->hreset_vector = 0x00000100UL;

#endif

}


void ff_acelp_weighted_filter(

        int16_t *out,

        const int16_t* in,

        const int16_t *weight_pow,

        int filter_length)

{

    int n;

    for(n=0; n<filter_length; n++)

        out[n] = (in[n] * weight_pow[n] + 0x4000) >> 15; /* (3.12) = (0.15) * (3.12) with rounding */

}


void ff_vp3_idct_c(DCTELEM *block/* align 16*/){

    idct(NULL, 0, block, 0);

}


static int seq_fill_buffer(SeqDemuxContext *seq, ByteIOContext *pb, int buffer_num, unsigned int data_offs, int data_size)

{

    TiertexSeqFrameBuffer *seq_buffer;

    if (buffer_num >= SEQ_NUM_FRAME_BUFFERS)

        return AVERROR_INVALIDDATA;

    seq_buffer = &seq->frame_buffers[buffer_num];

    if (seq_buffer->fill_size + data_size > seq_buffer->data_size)

        return AVERROR_INVALIDDATA;

    url_fseek(pb, seq->current_frame_offs + data_offs, SEEK_SET);

    if (get_buffer(pb, seq_buffer->data + seq_buffer->fill_size, data_size) != data_size)

        return AVERROR(EIO);

    seq_buffer->fill_size += data_size;

    return 0;

}


static av_always_inline av_flatten void h264_loop_filter_luma_c(uint8_t *pix, int xstride, int ystride, int alpha, int beta, int8_t *tc0)

{

    int i, d;

    for( i = 0; i < 4; i++ ) {

        if( tc0[i] < 0 ) {

            pix += 4*ystride;

            continue;

        }

        for( d = 0; d < 4; d++ ) {

            const int p0 = pix[-1*xstride];

            const int p1 = pix[-2*xstride];

            const int p2 = pix[-3*xstride];

            const int q0 = pix[0];

            const int q1 = pix[1*xstride];

            const int q2 = pix[2*xstride];

            if( FFABS( p0 - q0 ) < alpha &&

                FFABS( p1 - p0 ) < beta &&

                FFABS( q1 - q0 ) < beta ) {

                int tc = tc0[i];

                int i_delta;

                if( FFABS( p2 - p0 ) < beta ) {

                    if(tc0[i])

                    pix[-2*xstride] = p1 + av_clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] );

                    tc++;

                }

                if( FFABS( q2 - q0 ) < beta ) {

                    if(tc0[i])

                    pix[   xstride] = q1 + av_clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] );

                    tc++;

                }

                i_delta = av_clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );

                pix[-xstride] = av_clip_uint8( p0 + i_delta );    /* p0' */

                pix[0]        = av_clip_uint8( q0 - i_delta );    /* q0' */

            }

            pix += ystride;

        }

    }

}


static int io_open_default(AVFormatContext *s, AVIOContext **pb,

                           const char *url, int flags, AVDictionary **options)

{

    return avio_open2(pb, url, flags, &s->interrupt_callback, options);

}


static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length)

{

    GetBitContext gb;

    int i;

    init_get_bits(&gb, src, length * 8);

    for (i = 0; i < 3; i++) {

        if (read_len_table(s->len[i], &gb) < 0)

            return -1;

        if (ff_huffyuv_generate_bits_table(s->bits[i], s->len[i]) < 0)

            return -1;

        ff_free_vlc(&s->vlc[i]);

        init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1,

                 s->bits[i], 4, 4, 0);

    }

    generate_joint_tables(s);

    return (get_bits_count(&gb) + 7) / 8;

}


int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)

{

    char buf1[32], tuple_type[32];

    int h, w, depth, maxval;

    pnm_get(s, buf1, sizeof(buf1));

    s->type= buf1[1]-'0';

    if(buf1[0] != 'P')

        return -1;

    if (s->type==1 || s->type==4) {

        avctx->pix_fmt = PIX_FMT_MONOWHITE;

    } else if (s->type==2 || s->type==5) {

        if (avctx->codec_id == CODEC_ID_PGMYUV)

            avctx->pix_fmt = PIX_FMT_YUV420P;

        else

            avctx->pix_fmt = PIX_FMT_GRAY8;

    } else if (s->type==3 || s->type==6) {

        avctx->pix_fmt = PIX_FMT_RGB24;

    } else if (s->type==7) {

        w      = -1;

        h      = -1;

        maxval = -1;

        depth  = -1;

        tuple_type[0] = '\0';

        for (;;) {

            pnm_get(s, buf1, sizeof(buf1));

            if (!strcmp(buf1, "WIDTH")) {

                pnm_get(s, buf1, sizeof(buf1));

                w = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "HEIGHT")) {

                pnm_get(s, buf1, sizeof(buf1));

                h = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "DEPTH")) {

                pnm_get(s, buf1, sizeof(buf1));

                depth = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "MAXVAL")) {

                pnm_get(s, buf1, sizeof(buf1));

                maxval = strtol(buf1, NULL, 10);

            } else if (!strcmp(buf1, "TUPLTYPE") ||

            // FFmpeg used to write invalid files

                       !strcmp(buf1, "TUPLETYPE")) {

                pnm_get(s, tuple_type, sizeof(tuple_type));

            } else if (!strcmp(buf1, "ENDHDR")) {

                break;

            } else {

                return -1;

            }

        }

        /* check that all tags are present */

        if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx))

            return -1;

        avctx->width  = w;

        avctx->height = h;

        if (depth == 1) {

            if (maxval == 1)

                avctx->pix_fmt = PIX_FMT_MONOWHITE;

            else

                avctx->pix_fmt = PIX_FMT_GRAY8;

        } else if (depth == 3) {

            if (maxval < 256) {

            avctx->pix_fmt = PIX_FMT_RGB24;

            } else {

                av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n");

                avctx->pix_fmt = PIX_FMT_NONE;

                return -1;

            }

        } else if (depth == 4) {

            avctx->pix_fmt = PIX_FMT_RGB32;

        } else {

            return -1;

        }

        return 0;

    } else {

        return -1;

    }

    pnm_get(s, buf1, sizeof(buf1));

    avctx->width = atoi(buf1);

    if (avctx->width <= 0)

        return -1;

    pnm_get(s, buf1, sizeof(buf1));

    avctx->height = atoi(buf1);

    if(avctx->height <= 0 || av_image_check_size(avctx->width, avctx->height, 0, avctx))

        return -1;

    if (avctx->pix_fmt != PIX_FMT_MONOWHITE) {

        pnm_get(s, buf1, sizeof(buf1));

        s->maxval = atoi(buf1);

        if (s->maxval <= 0) {

            av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval);

            s->maxval = 255;

        }

        if (s->maxval >= 256) {

            if (avctx->pix_fmt == PIX_FMT_GRAY8) {

                avctx->pix_fmt = PIX_FMT_GRAY16BE;

                if (s->maxval != 65535)

                    avctx->pix_fmt = PIX_FMT_GRAY16;

            } else if (avctx->pix_fmt == PIX_FMT_RGB24) {

                if (s->maxval > 255)

                    avctx->pix_fmt = PIX_FMT_RGB48BE;

            } else {

                av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");

                avctx->pix_fmt = PIX_FMT_NONE;

                return -1;

            }

        }

    }else

        s->maxval=1;

    /* more check if YUV420 */

    if (avctx->pix_fmt == PIX_FMT_YUV420P) {

        if ((avctx->width & 1) != 0)

            return -1;

        h = (avctx->height * 2);

        if ((h % 3) != 0)

            return -1;

        h /= 3;

        avctx->height = h;

    }

    return 0;

}


static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,

                               TCGMemOpIdx oi, uintptr_t retaddr)

{

    size_t mmu_idx = get_mmuidx(oi);

    size_t index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);

    CPUTLBEntry *tlbe = &env->tlb_table[mmu_idx][index];

    target_ulong tlb_addr = tlbe->addr_write;

    TCGMemOp mop = get_memop(oi);

    int a_bits = get_alignment_bits(mop);

    int s_bits = mop & MO_SIZE;

    /* Adjust the given return address.  */

    retaddr -= GETPC_ADJ;

    /* Enforce guest required alignment.  */

    if (unlikely(a_bits > 0 && (addr & ((1 << a_bits) - 1)))) {

        /* ??? Maybe indicate atomic op to cpu_unaligned_access */

        cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,

                             mmu_idx, retaddr);

    }

    /* Enforce qemu required alignment.  */

    if (unlikely(addr & ((1 << s_bits) - 1))) {

        /* We get here if guest alignment was not requested,

           or was not enforced by cpu_unaligned_access above.

           We might widen the access and emulate, but for now

           mark an exception and exit the cpu loop.  */

        goto stop_the_world;

    }

    /* Check TLB entry and enforce page permissions.  */

    if ((addr & TARGET_PAGE_MASK)

        != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {

        if (!VICTIM_TLB_HIT(addr_write, addr)) {

            tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);

        }

        tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;

    }

    /* Check notdirty */

    if (unlikely(tlb_addr & TLB_NOTDIRTY)) {

        tlb_set_dirty(ENV_GET_CPU(env), addr);

        tlb_addr = tlb_addr & ~TLB_NOTDIRTY;

    }

    /* Notice an IO access  */

    if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {

        /* There's really nothing that can be done to

           support this apart from stop-the-world.  */

        goto stop_the_world;

    }

    /* Let the guest notice RMW on a write-only page.  */

    if (unlikely(tlbe->addr_read != tlb_addr)) {

        tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_LOAD, mmu_idx, retaddr);

        /* Since we don't support reads and writes to different addresses,

           and we do have the proper page loaded for write, this shouldn't

           ever return.  But just in case, handle via stop-the-world.  */

        goto stop_the_world;

    }

    return (void *)((uintptr_t)addr + tlbe->addend);

 stop_the_world:

    cpu_loop_exit_atomic(ENV_GET_CPU(env), retaddr);

}


static int decode_ref_pic_list_reordering(H264Context *h){

    MpegEncContext * const s = &h->s;

    int list, index, pic_structure;

    print_short_term(h);

    print_long_term(h);

    if(h->slice_type==FF_I_TYPE || h->slice_type==FF_SI_TYPE) return 0; //FIXME move before func

    for(list=0; list<h->list_count; list++){

        memcpy(h->ref_list[list], h->default_ref_list[list], sizeof(Picture)*h->ref_count[list]);

        if(get_bits1(&s->gb)){

            int pred= h->curr_pic_num;

            for(index=0; ; index++){

                unsigned int reordering_of_pic_nums_idc= get_ue_golomb(&s->gb);

                unsigned int pic_id;

                int i;

                Picture *ref = NULL;

                if(reordering_of_pic_nums_idc==3)

                    break;

                if(index >= h->ref_count[list]){

                    av_log(h->s.avctx, AV_LOG_ERROR, "reference count overflow\n");

                    return -1;

                }

                if(reordering_of_pic_nums_idc<3){

                    if(reordering_of_pic_nums_idc<2){

                        const unsigned int abs_diff_pic_num= get_ue_golomb(&s->gb) + 1;

                        int frame_num;

                        if(abs_diff_pic_num > h->max_pic_num){

                            av_log(h->s.avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n");

                            return -1;

                        }

                        if(reordering_of_pic_nums_idc == 0) pred-= abs_diff_pic_num;

                        else                                pred+= abs_diff_pic_num;

                        pred &= h->max_pic_num - 1;

                        frame_num = pic_num_extract(h, pred, &pic_structure);

                        for(i= h->short_ref_count-1; i>=0; i--){

                            ref = h->short_ref[i];

                            assert(ref->reference);

                            assert(!ref->long_ref);

                            if(ref->data[0] != NULL &&

                                   ref->frame_num == frame_num &&

                                   (ref->reference & pic_structure) &&

                                   ref->long_ref == 0) // ignore non existing pictures by testing data[0] pointer

                                break;

                        }

                        if(i>=0)

                            ref->pic_id= pred;

                    }else{

                        int long_idx;

                        pic_id= get_ue_golomb(&s->gb); //long_term_pic_idx

                        long_idx= pic_num_extract(h, pic_id, &pic_structure);

                        if(long_idx>31){

                            av_log(h->s.avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n");

                            return -1;

                        }

                        ref = h->long_ref[long_idx];

                        assert(!(ref && !ref->reference));

                        if(ref && (ref->reference & pic_structure)){

                            ref->pic_id= pic_id;

                            assert(ref->long_ref);

                            i=0;

                        }else{

                            i=-1;

                        }

                    }

                    if (i < 0) {

                        av_log(h->s.avctx, AV_LOG_ERROR, "reference picture missing during reorder\n");

                        memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME

                    } else {

                        for(i=index; i+1<h->ref_count[list]; i++){

                            if(ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id)

                                break;

                        }

                        for(; i > index; i--){

                            h->ref_list[list][i]= h->ref_list[list][i-1];

                        }

                        h->ref_list[list][index]= *ref;

                        if (FIELD_PICTURE){

                            pic_as_field(&h->ref_list[list][index], pic_structure);

                        }

                    }

                }else{

                    av_log(h->s.avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n");

                    return -1;

                }

            }

        }

    }

    for(list=0; list<h->list_count; list++){

        for(index= 0; index < h->ref_count[list]; index++){

            if(!h->ref_list[list][index].data[0])

                h->ref_list[list][index]= s->current_picture;

        }

    }

    if(h->slice_type==FF_B_TYPE && !h->direct_spatial_mv_pred)

        direct_dist_scale_factor(h);

    direct_ref_list_init(h);

    return 0;

}


static av_cold int X264_close(AVCodecContext *avctx)

{

    X264Context *x4 = avctx->priv_data;

    av_freep(&avctx->extradata);

    av_freep(&x4->sei);

    if (x4->enc) {

        x264_encoder_close(x4->enc);

        x4->enc = NULL;

    }

    av_frame_free(&avctx->coded_frame);

    return 0;

}


static int v9fs_receive_status(V9fsProxy *proxy,

                               struct iovec *reply, int *status)

{

    int retval;

    ProxyHeader header;

    *status = 0;

    reply->iov_len = 0;

    retval = socket_read(proxy->sockfd, reply->iov_base, PROXY_HDR_SZ);

    if (retval < 0) {

        return retval;

    }

    reply->iov_len = PROXY_HDR_SZ;

    proxy_unmarshal(reply, 0, "dd", &header.type, &header.size);

    if (header.size != sizeof(int)) {

        *status = -ENOBUFS;

        return 0;

    }

    retval = socket_read(proxy->sockfd,

                         reply->iov_base + PROXY_HDR_SZ, header.size);

    if (retval < 0) {

        return retval;

    }

    reply->iov_len += header.size;

    proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status);

    return 0;

}


static target_long monitor_get_xer (const struct MonitorDef *md, int val)

{

    CPUState *env = mon_get_cpu();

    if (!env)

        return 0;

    return env->xer;

}


static ssize_t qemu_fill_buffer(QEMUFile *f)

{

    int len;

    int pending;

    assert(!qemu_file_is_writable(f));

    pending = f->buf_size - f->buf_index;

    if (pending > 0) {

        memmove(f->buf, f->buf + f->buf_index, pending);

    }

    f->buf_index = 0;

    f->buf_size = pending;

    len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,

                        IO_BUF_SIZE - pending);

    if (len > 0) {

        f->buf_size += len;

        f->pos += len;

    } else if (len == 0) {

        qemu_file_set_error(f, -EIO);

    } else if (len != -EAGAIN) {

        qemu_file_set_error(f, len);

    }

    return len;

}


static void unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)

{

    int i, j, k;

    int coding_mode;

    int motion_x[6];

    int motion_y[6];

    int last_motion_x = 0;

    int last_motion_y = 0;

    int prior_last_motion_x = 0;

    int prior_last_motion_y = 0;

    int current_macroblock;

    int current_fragment;

    debug_vp3("  vp3: unpacking motion vectors\n");

    if (s->keyframe) {

        debug_vp3("    keyframe-- there are no motion vectors\n");

    } else {

        memset(motion_x, 0, 6 * sizeof(int));

        memset(motion_y, 0, 6 * sizeof(int));

        /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */

        coding_mode = get_bits(gb, 1);

        debug_vectors("    using %s scheme for unpacking motion vectors\n",

            (coding_mode == 0) ? "VLC" : "fixed-length");

        /* iterate through all of the macroblocks that contain 1 or more

         * coded fragments */

        for (i = 0; i < s->u_superblock_start; i++) {

            for (j = 0; j < 4; j++) {

                current_macroblock = s->superblock_macroblocks[i * 4 + j];

                if ((current_macroblock == -1) ||

                    (!s->macroblock_coded[current_macroblock]))

                    continue;

                current_fragment = s->macroblock_fragments[current_macroblock * 6];

                switch (s->all_fragments[current_fragment].coding_method) {

                case MODE_INTER_PLUS_MV:

                case MODE_GOLDEN_MV:

                    /* all 6 fragments use the same motion vector */

                    if (coding_mode == 0) {

                        motion_x[0] = get_motion_vector_vlc(gb);

                        motion_y[0] = get_motion_vector_vlc(gb);

                    } else {

                        motion_x[0] = get_motion_vector_fixed(gb);

                        motion_y[0] = get_motion_vector_fixed(gb);

                    }

                    for (k = 1; k < 6; k++) {

                        motion_x[k] = motion_x[0];

                        motion_y[k] = motion_y[0];

                    }

                    /* vector maintenance, only on MODE_INTER_PLUS_MV */

                    if (s->all_fragments[current_fragment].coding_method ==

                        MODE_INTER_PLUS_MV) {

                        prior_last_motion_x = last_motion_x;

                        prior_last_motion_y = last_motion_y;

                        last_motion_x = motion_x[0];

                        last_motion_y = motion_y[0];

                    }

                    break;

                case MODE_INTER_FOURMV:

                    /* fetch 4 vectors from the bitstream, one for each

                     * Y fragment, then average for the C fragment vectors */

                    motion_x[4] = motion_y[4] = 0;

                    for (k = 0; k < 4; k++) {

                        if (coding_mode == 0) {

                            motion_x[k] = get_motion_vector_vlc(gb);

                            motion_y[k] = get_motion_vector_vlc(gb);

                        } else {

                            motion_x[k] = get_motion_vector_fixed(gb);

                            motion_y[k] = get_motion_vector_fixed(gb);

                        }

                        motion_x[4] += motion_x[k];

                        motion_y[4] += motion_y[k];

                    }

                    if (motion_x[4] >= 0)

                        motion_x[4] = (motion_x[4] + 2) / 4;

                    else

                        motion_x[4] = (motion_x[4] - 2) / 4;

                    motion_x[5] = motion_x[4];

                    if (motion_y[4] >= 0)

                        motion_y[4] = (motion_y[4] + 2) / 4;

                    else

                        motion_y[4] = (motion_y[4] - 2) / 4;

                    motion_y[5] = motion_y[4];

                    /* vector maintenance; vector[3] is treated as the

                     * last vector in this case */

                    prior_last_motion_x = last_motion_x;

                    prior_last_motion_y = last_motion_y;

                    last_motion_x = motion_x[3];

                    last_motion_y = motion_y[3];

                    break;

                case MODE_INTER_LAST_MV:

                    /* all 6 fragments use the last motion vector */

                    motion_x[0] = last_motion_x;

                    motion_y[0] = last_motion_y;

                    for (k = 1; k < 6; k++) {

                        motion_x[k] = motion_x[0];

                        motion_y[k] = motion_y[0];

                    }

                    /* no vector maintenance (last vector remains the

                     * last vector) */

                    break;

                case MODE_INTER_PRIOR_LAST:

                    /* all 6 fragments use the motion vector prior to the

                     * last motion vector */

                    motion_x[0] = prior_last_motion_x;

                    motion_y[0] = prior_last_motion_y;

                    for (k = 1; k < 6; k++) {

                        motion_x[k] = motion_x[0];

                        motion_y[k] = motion_y[0];

                    }

                    /* vector maintenance */

                    prior_last_motion_x = last_motion_x;

                    prior_last_motion_y = last_motion_y;

                    last_motion_x = motion_x[0];

                    last_motion_y = motion_y[0];

                    break;

                }

                /* assign the motion vectors to the correct fragments */

                debug_vectors("    vectors for macroblock starting @ fragment %d (coding method %d):\n",

                    current_fragment,

                    s->all_fragments[current_fragment].coding_method);

                for (k = 0; k < 6; k++) {

                    current_fragment =

                        s->macroblock_fragments[current_macroblock * 6 + k];

                    s->all_fragments[current_fragment].motion_x = motion_x[k];

                    s->all_fragments[current_fragment].motion_x = motion_y[k];

                    debug_vectors("    vector %d: fragment %d = (%d, %d)\n",

                        k, current_fragment, motion_x[k], motion_y[k]);

                }

            }

        }

    }

}


static int imc_decode_block(AVCodecContext *avctx, IMCContext *q, int ch)
{
    int stream_format_code;
    int imc_hdr, i, j, ret;
    int flag;
    int bits, summer;
    int counter, bitscount;
    IMCChannel *chctx = q->chctx + ch;
    /* Check the frame header */
    imc_hdr = get_bits(&q->gb, 9);
    if (imc_hdr & 0x18) {
        av_log(avctx, AV_LOG_ERROR, "frame header check failed!\n");
        av_log(avctx, AV_LOG_ERROR, "got %X.\n", imc_hdr);
    stream_format_code = get_bits(&q->gb, 3);
    if (stream_format_code & 1) {
        av_log_ask_for_sample(avctx, "Stream format %X is not supported\n",
                              stream_format_code);
        return AVERROR_PATCHWELCOME;
    if (stream_format_code & 0x04)
        chctx->decoder_reset = 1;
    if (chctx->decoder_reset) {
        for (i = 0; i < BANDS; i++)
            chctx->old_floor[i] = 1.0;
        for (i = 0; i < COEFFS; i++)
            chctx->CWdecoded[i] = 0;
        chctx->decoder_reset = 0;
    flag = get_bits1(&q->gb);
    imc_read_level_coeffs(q, stream_format_code, chctx->levlCoeffBuf);
    if (stream_format_code & 0x4)
        imc_decode_level_coefficients(q, chctx->levlCoeffBuf,
                                      chctx->flcoeffs1, chctx->flcoeffs2);
    else
        imc_decode_level_coefficients2(q, chctx->levlCoeffBuf, chctx->old_floor,
                                       chctx->flcoeffs1, chctx->flcoeffs2);
    memcpy(chctx->old_floor, chctx->flcoeffs1, 32 * sizeof(float));
    counter = 0;
    for (i = 0; i < BANDS; i++) {
        if (chctx->levlCoeffBuf[i] == 16) {
            chctx->bandWidthT[i] = 0;
            counter++;
        } else
            chctx->bandWidthT[i] = band_tab[i + 1] - band_tab[i];
    memset(chctx->bandFlagsBuf, 0, BANDS * sizeof(int));
    for (i = 0; i < BANDS - 1; i++) {
        if (chctx->bandWidthT[i])
            chctx->bandFlagsBuf[i] = get_bits1(&q->gb);
    imc_calculate_coeffs(q, chctx->flcoeffs1, chctx->flcoeffs2, chctx->bandWidthT, chctx->flcoeffs3, chctx->flcoeffs5);
    bitscount = 0;
    /* first 4 bands will be assigned 5 bits per coefficient */
    if (stream_format_code & 0x2) {
        bitscount += 15;
        chctx->bitsBandT[0] = 5;
        chctx->CWlengthT[0] = 5;
        chctx->CWlengthT[1] = 5;
        chctx->CWlengthT[2] = 5;
        for (i = 1; i < 4; i++) {
            bits = (chctx->levlCoeffBuf[i] == 16) ? 0 : 5;
            chctx->bitsBandT[i] = bits;
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
                chctx->CWlengthT[j] = bits;
                bitscount      += bits;
    if (avctx->codec_id == AV_CODEC_ID_IAC) {
        bitscount += !!chctx->bandWidthT[BANDS - 1];
        if (!(stream_format_code & 0x2))
            bitscount += 16;
    if ((ret = bit_allocation(q, chctx, stream_format_code,
                              512 - bitscount - get_bits_count(&q->gb),
                              flag)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Bit allocations failed\n");
        chctx->decoder_reset = 1;
        return ret;
    for (i = 0; i < BANDS; i++) {
        chctx->sumLenArr[i]   = 0;
        chctx->skipFlagRaw[i] = 0;
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
            chctx->sumLenArr[i] += chctx->CWlengthT[j];
        if (chctx->bandFlagsBuf[i])
            if ((((band_tab[i + 1] - band_tab[i]) * 1.5) > chctx->sumLenArr[i]) && (chctx->sumLenArr[i] > 0))
                chctx->skipFlagRaw[i] = 1;
    imc_get_skip_coeff(q, chctx);
    for (i = 0; i < BANDS; i++) {
        chctx->flcoeffs6[i] = chctx->flcoeffs1[i];
        /* band has flag set and at least one coded coefficient */
        if (chctx->bandFlagsBuf[i] && (band_tab[i + 1] - band_tab[i]) != chctx->skipFlagCount[i]) {
            chctx->flcoeffs6[i] *= q->sqrt_tab[ band_tab[i + 1] - band_tab[i]] /
                                   q->sqrt_tab[(band_tab[i + 1] - band_tab[i] - chctx->skipFlagCount[i])];
    /* calculate bits left, bits needed and adjust bit allocation */
    bits = summer = 0;
    for (i = 0; i < BANDS; i++) {
        if (chctx->bandFlagsBuf[i]) {
            for (j = band_tab[i]; j < band_tab[i + 1]; j++) {
                if (chctx->skipFlags[j]) {
                    summer += chctx->CWlengthT[j];
                    chctx->CWlengthT[j] = 0;
            bits   += chctx->skipFlagBits[i];
            summer -= chctx->skipFlagBits[i];
    imc_adjust_bit_allocation(q, chctx, summer);
    for (i = 0; i < BANDS; i++) {
        chctx->sumLenArr[i] = 0;
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
            if (!chctx->skipFlags[j])
                chctx->sumLenArr[i] += chctx->CWlengthT[j];
    memset(chctx->codewords, 0, sizeof(chctx->codewords));
    if (imc_get_coeffs(q, chctx) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Read coefficients failed\n");
        chctx->decoder_reset = 1;
    if (inverse_quant_coeff(q, chctx, stream_format_code) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Inverse quantization of coefficients failed\n");
        chctx->decoder_reset = 1;
    memset(chctx->skipFlags, 0, sizeof(chctx->skipFlags));
    imc_imdct256(q, chctx, avctx->channels);
    return 0;


static int get_audio_frame_size(AVCodecContext *enc, int size)

{

    int frame_size;

    if(enc->codec_id == CODEC_ID_VORBIS)

        return -1;

    if (enc->frame_size <= 1) {

        int bits_per_sample = av_get_bits_per_sample(enc->codec_id);

        if (bits_per_sample) {

            if (enc->channels == 0)

                return -1;

            frame_size = (size << 3) / (bits_per_sample * enc->channels);

        } else {

            /* used for example by ADPCM codecs */

            if (enc->bit_rate == 0)

                return -1;

            frame_size = (size * 8 * enc->sample_rate) / enc->bit_rate;

        }

    } else {

        frame_size = enc->frame_size;

    }

    return frame_size;

}


static void apply_dependent_coupling_fixed(AACContext *ac,

                                     SingleChannelElement *target,

                                     ChannelElement *cce, int index)

{

    IndividualChannelStream *ics = &cce->ch[0].ics;

    const uint16_t *offsets = ics->swb_offset;

    int *dest = target->coeffs;

    const int *src = cce->ch[0].coeffs;

    int g, i, group, k, idx = 0;

    if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {

        av_log(ac->avctx, AV_LOG_ERROR,

               "Dependent coupling is not supported together with LTP\n");

        return;

    }

    for (g = 0; g < ics->num_window_groups; g++) {

        for (i = 0; i < ics->max_sfb; i++, idx++) {

            if (cce->ch[0].band_type[idx] != ZERO_BT) {

                const int gain = cce->coup.gain[index][idx];

                int shift, round, c, tmp;

                if (gain < 0) {

                    c = -cce_scale_fixed[-gain & 7];

                    shift = (-gain-1024) >> 3;

                }

                else {

                    c = cce_scale_fixed[gain & 7];

                    shift = (gain-1024) >> 3;

                }

                if (shift < -31) {

                    // Nothing to do

                } else if (shift < 0) {

                    shift = -shift;

                    round = 1 << (shift - 1);

                    for (group = 0; group < ics->group_len[g]; group++) {

                        for (k = offsets[i]; k < offsets[i + 1]; k++) {

                            tmp = (int)(((int64_t)src[group * 128 + k] * c + \

                                       (int64_t)0x1000000000) >> 37);

                            dest[group * 128 + k] += (tmp + round) >> shift;

                        }

                    }

                }

                else {

                    for (group = 0; group < ics->group_len[g]; group++) {

                        for (k = offsets[i]; k < offsets[i + 1]; k++) {

                            tmp = (int)(((int64_t)src[group * 128 + k] * c + \

                                        (int64_t)0x1000000000) >> 37);

                            dest[group * 128 + k] += tmp << shift;

                        }

                    }

                }

            }

        }

        dest += ics->group_len[g] * 128;

        src  += ics->group_len[g] * 128;

    }

}