static void qdm2_decode_fft_packets(QDM2Context *q)

{

    int i, j, min, max, value, type, unknown_flag;

    GetBitContext gb;

    if (q->sub_packet_list_B[0].packet == NULL)

        return;

    /* reset minimum indexes for FFT coefficients */

    q->fft_coefs_index = 0;

    for (i = 0; i < 5; i++)

        q->fft_coefs_min_index[i] = -1;

    /* process subpackets ordered by type, largest type first */

    for (i = 0, max = 256; i < q->sub_packets_B; i++) {

        QDM2SubPacket *packet = NULL;

        /* find subpacket with largest type less than max */

        for (j = 0, min = 0; j < q->sub_packets_B; j++) {

            value = q->sub_packet_list_B[j].packet->type;

            if (value > min && value < max) {

                min    = value;

                packet = q->sub_packet_list_B[j].packet;

            }

        }

        max = min;

        /* check for errors (?) */

        if (!packet)

            return;

        if (i == 0 &&

            (packet->type < 16 || packet->type >= 48 ||

             fft_subpackets[packet->type - 16]))

            return;

        /* decode FFT tones */

        init_get_bits(&gb, packet->data, packet->size * 8);

        if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16])

            unknown_flag = 1;

        else

            unknown_flag = 0;

        type = packet->type;

        if ((type >= 17 && type < 24) || (type >= 33 && type < 40)) {

            int duration = q->sub_sampling + 5 - (type & 15);

            if (duration >= 0 && duration < 4)

                qdm2_fft_decode_tones(q, duration, &gb, unknown_flag);

        } else if (type == 31) {

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

                qdm2_fft_decode_tones(q, j, &gb, unknown_flag);

        } else if (type == 46) {

            for (j = 0; j < 6; j++)

                q->fft_level_exp[j] = get_bits(&gb, 6);

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

                qdm2_fft_decode_tones(q, j, &gb, unknown_flag);

        }

    } // Loop on B packets

    /* calculate maximum indexes for FFT coefficients */

    for (i = 0, j = -1; i < 5; i++)

        if (q->fft_coefs_min_index[i] >= 0) {

            if (j >= 0)

                q->fft_coefs_max_index[j] = q->fft_coefs_min_index[i];

            j = i;

        }

    if (j >= 0)

        q->fft_coefs_max_index[j] = q->fft_coefs_index;

}


void ff_avg_h264_qpel16_mc22_msa(uint8_t *dst, const uint8_t *src,

                                 ptrdiff_t stride)

{

    avc_luma_mid_and_aver_dst_16x16_msa(src - (2 * stride) - 2,

                                        stride, dst, stride);

}


int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)

{

    AVFilterContext *ret;

    *filter_ctx = NULL;

    if (!filter)

        return AVERROR(EINVAL);

    ret = av_mallocz(sizeof(AVFilterContext));

    ret->av_class = &avfilter_class;

    ret->filter   = filter;

    ret->name     = inst_name ? av_strdup(inst_name) : NULL;

    if (filter->priv_size)

        ret->priv     = av_mallocz(filter->priv_size);

    ret->input_count  = pad_count(filter->inputs);

    if (ret->input_count) {

        ret->input_pads   = av_malloc(sizeof(AVFilterPad) * ret->input_count);

        memcpy(ret->input_pads, filter->inputs, sizeof(AVFilterPad) * ret->input_count);

        ret->inputs       = av_mallocz(sizeof(AVFilterLink*) * ret->input_count);

    }

    ret->output_count = pad_count(filter->outputs);

    if (ret->output_count) {

        ret->output_pads  = av_malloc(sizeof(AVFilterPad) * ret->output_count);

        memcpy(ret->output_pads, filter->outputs, sizeof(AVFilterPad) * ret->output_count);

        ret->outputs      = av_mallocz(sizeof(AVFilterLink*) * ret->output_count);

    }

    *filter_ctx = ret;

    return 0;

}


static void test_panic(void)

{

    uint8_t val;

    QDict *response, *data;

    val = inb(0x505);

    g_assert_cmpuint(val, ==, 1);

    outb(0x505, 0x1);

    response = qmp_receive();

    g_assert(qdict_haskey(response, "event"));

    g_assert_cmpstr(qdict_get_str(response, "event"), ==, "GUEST_PANICKED");

    g_assert(qdict_haskey(response, "data"));

    data = qdict_get_qdict(response, "data");

    g_assert(qdict_haskey(data, "action"));

    g_assert_cmpstr(qdict_get_str(data, "action"), ==, "pause");

}


static void spr_write_decr(DisasContext *ctx, int sprn, int gprn)

{

    if (ctx->tb->cflags & CF_USE_ICOUNT) {

        gen_io_start();

    }

    gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);

    if (ctx->tb->cflags & CF_USE_ICOUNT) {

        gen_io_end();

        gen_stop_exception(ctx);

    }

}


PPC_OP(b_T1)

{

    regs->nip = T1 & ~3;

    RETURN();

}


static int make_cdt15_entry(int p1, int p2, int16_t *cdt)

{

    int r, b, lo;

    b = cdt[p2];

    r = cdt[p1] * 1024;

    lo = b + r;

    return (lo + (lo * (1 << 16))) * 2;

}


static int ogg_build_flac_headers(AVCodecContext *avctx,

                                  OGGStreamContext *oggstream, int bitexact)

{

    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;

    enum FLACExtradataFormat format;

    uint8_t *streaminfo;

    uint8_t *p;

    if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))

        return -1;

    oggstream->header_len[0] = 51;

    oggstream->header[0] = av_mallocz(51); // per ogg flac specs

    p = oggstream->header[0];

    bytestream_put_byte(&p, 0x7F);

    bytestream_put_buffer(&p, "FLAC", 4);

    bytestream_put_byte(&p, 1); // major version

    bytestream_put_byte(&p, 0); // minor version

    bytestream_put_be16(&p, 1); // headers packets without this one

    bytestream_put_buffer(&p, "fLaC", 4);

    bytestream_put_byte(&p, 0x00); // streaminfo

    bytestream_put_be24(&p, 34);

    bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE);

    oggstream->header_len[1] = 1+3+4+strlen(vendor)+4;

    oggstream->header[1] = av_mallocz(oggstream->header_len[1]);

    p = oggstream->header[1];

    bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment

    bytestream_put_be24(&p, oggstream->header_len[1] - 4);

    bytestream_put_le32(&p, strlen(vendor));

    bytestream_put_buffer(&p, vendor, strlen(vendor));

    bytestream_put_le32(&p, 0); // user comment list length

    return 0;

}


void qmp_netdev_del(const char *id, Error **errp)

{

    NetClientState *nc;

    nc = qemu_find_netdev(id);

    if (!nc) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, id);

        return;

    }

    qemu_del_net_client(nc);

    qemu_opts_del(qemu_opts_find(qemu_find_opts_err("netdev", errp), id));

}


int qemu_savevm_state_iterate(QEMUFile *f)

{

    SaveStateEntry *se;

    int ret = 1;

    trace_savevm_state_iterate();

    QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {

        if (!se->ops || !se->ops->save_live_iterate) {

            continue;

        }

        if (se->ops && se->ops->is_active) {

            if (!se->ops->is_active(se->opaque)) {

                continue;

            }

        }

        if (qemu_file_rate_limit(f)) {

            return 0;

        }

        trace_savevm_section_start(se->idstr, se->section_id);

        save_section_header(f, se, QEMU_VM_SECTION_PART);

        ret = se->ops->save_live_iterate(f, se->opaque);

        trace_savevm_section_end(se->idstr, se->section_id, ret);

        if (ret < 0) {

            qemu_file_set_error(f, ret);

        }

        if (ret <= 0) {

            /* Do not proceed to the next vmstate before this one reported

               completion of the current stage. This serializes the migration

               and reduces the probability that a faster changing state is

               synchronized over and over again. */

            break;

        }

    }

    return ret;

}


yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2],

                       const int32_t *ubuf[2], const int32_t *vbuf[2],

                       const int32_t *abuf[2], uint16_t *dest, int dstW,

                       int yalpha, int uvalpha, int y,

                       enum AVPixelFormat target, int hasAlpha)

{

    const int32_t *buf0  = buf[0],  *buf1  = buf[1],

                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],

                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],

                  *abuf0 = hasAlpha ? abuf[0] : NULL,

                  *abuf1 = hasAlpha ? abuf[1] : NULL;

    int  yalpha1 = 4096 - yalpha;

    int uvalpha1 = 4096 - uvalpha;

    int i;

    for (i = 0; i < ((dstW + 1) >> 1); i++) {

        int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha) >> 14;

        int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha) >> 14;

        int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha + (-128 << 23)) >> 14;

        int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha + (-128 << 23)) >> 14;

        int A1, A2;

        int R, G, B;

        Y1 -= c->yuv2rgb_y_offset;

        Y2 -= c->yuv2rgb_y_offset;

        Y1 *= c->yuv2rgb_y_coeff;

        Y2 *= c->yuv2rgb_y_coeff;

        Y1 += 1 << 13;

        Y2 += 1 << 13;

        R = V * c->yuv2rgb_v2r_coeff;

        G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff;

        B =                            U * c->yuv2rgb_u2b_coeff;

        if (hasAlpha) {

            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 1;

            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 1;

            A1 += 1 << 13;

            A2 += 1 << 13;

        }

        output_pixel(&dest[0], av_clip_uintp2(B_R + Y1, 30) >> 14);

        output_pixel(&dest[1], av_clip_uintp2(  G + Y1, 30) >> 14);

        output_pixel(&dest[2], av_clip_uintp2(R_B + Y1, 30) >> 14);

        output_pixel(&dest[3], av_clip_uintp2(A1      , 30) >> 14);

        output_pixel(&dest[4], av_clip_uintp2(B_R + Y2, 30) >> 14);

        output_pixel(&dest[5], av_clip_uintp2(  G + Y2, 30) >> 14);

        output_pixel(&dest[6], av_clip_uintp2(R_B + Y2, 30) >> 14);

        output_pixel(&dest[7], av_clip_uintp2(A2      , 30) >> 14);

        dest += 8;

    }

}


static int ogg_restore(AVFormatContext *s)

{

    struct ogg *ogg = s->priv_data;

    AVIOContext *bc = s->pb;

    struct ogg_state *ost = ogg->state;

    int i, err;

    if (!ost)

        return 0;

    ogg->state = ost->next;

        for (i = 0; i < ogg->nstreams; i++)

            av_freep(&ogg->streams[i].buf);

        avio_seek(bc, ost->pos, SEEK_SET);

        ogg->page_pos = -1;

        ogg->curidx   = ost->curidx;

        ogg->nstreams = ost->nstreams;

        if ((err = av_reallocp_array(&ogg->streams, ogg->nstreams,

                                     sizeof(*ogg->streams))) < 0) {

            ogg->nstreams = 0;

            return err;

        } else

            memcpy(ogg->streams, ost->streams,

                   ost->nstreams * sizeof(*ogg->streams));

    av_free(ost);

    return 0;

}


static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,

                                             DECODER_BUFFER_DESC *bs,

                                             DECODER_BUFFER_DESC *sc)

{

    const H264Context *h = avctx->priv_data;

    const unsigned mb_count = h->mb_width * h->mb_height;

    AVDXVAContext *ctx = avctx->hwaccel_context;

    const H264Picture *current_picture = h->cur_pic_ptr;

    struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;

    DXVA_Slice_H264_Short *slice = NULL;

    void     *dxva_data_ptr;

    uint8_t  *dxva_data, *current, *end;

    unsigned dxva_size;

    void     *slice_data;

    unsigned slice_size;

    unsigned padding;

    unsigned i;

    unsigned type;

    /* Create an annex B bitstream buffer with only slice NAL and finalize slice */

#if CONFIG_D3D11VA

    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {

        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;

        if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,

                                                       D3D11VA_CONTEXT(ctx)->decoder,

                                                       type,

                                                       &dxva_size, &dxva_data_ptr)))

            return -1;

    }

#endif

#if CONFIG_DXVA2

    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {

        type = DXVA2_BitStreamDateBufferType;

        if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,

                                                  type,

                                                  &dxva_data_ptr, &dxva_size)))

            return -1;

    }

#endif

    dxva_data = dxva_data_ptr;

    current = dxva_data;

    end = dxva_data + dxva_size;

    for (i = 0; i < ctx_pic->slice_count; i++) {

        static const uint8_t start_code[] = { 0, 0, 1 };

        static const unsigned start_code_size = sizeof(start_code);

        unsigned position, size;

        assert(offsetof(DXVA_Slice_H264_Short, BSNALunitDataLocation) ==

               offsetof(DXVA_Slice_H264_Long,  BSNALunitDataLocation));

        assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==

               offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));

        if (is_slice_short(avctx, ctx))

            slice = &ctx_pic->slice_short[i];

        else

            slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];

        position = slice->BSNALunitDataLocation;

        size     = slice->SliceBytesInBuffer;

        if (start_code_size + size > end - current) {

            av_log(avctx, AV_LOG_ERROR, "Failed to build bitstream");

            break;

        }

        slice->BSNALunitDataLocation = current - dxva_data;

        slice->SliceBytesInBuffer    = start_code_size + size;

        if (!is_slice_short(avctx, ctx)) {

            DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;

            if (i < ctx_pic->slice_count - 1)

                slice_long->NumMbsForSlice =

                    slice_long[1].first_mb_in_slice - slice_long[0].first_mb_in_slice;

            else

                slice_long->NumMbsForSlice = mb_count - slice_long->first_mb_in_slice;

        }

        memcpy(current, start_code, start_code_size);

        current += start_code_size;

        memcpy(current, &ctx_pic->bitstream[position], size);

        current += size;

    }

    padding = FFMIN(128 - ((current - dxva_data) & 127), end - current);

    if (slice && padding > 0) {

        memset(current, 0, padding);

        current += padding;

        slice->SliceBytesInBuffer += padding;

    }

#if CONFIG_D3D11VA

    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)

        if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))

            return -1;

#endif

#if CONFIG_DXVA2

    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)

        if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))

            return -1;

#endif

    if (i < ctx_pic->slice_count)

        return -1;

#if CONFIG_D3D11VA

    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {

        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;

        memset(dsc11, 0, sizeof(*dsc11));

        dsc11->BufferType           = type;

        dsc11->DataSize             = current - dxva_data;

        dsc11->NumMBsInBuffer       = mb_count;

        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;

    }

#endif

#if CONFIG_DXVA2

    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {

        DXVA2_DecodeBufferDesc *dsc2 = bs;

        memset(dsc2, 0, sizeof(*dsc2));

        dsc2->CompressedBufferType = type;

        dsc2->DataSize             = current - dxva_data;

        dsc2->NumMBsInBuffer       = mb_count;

        type = DXVA2_SliceControlBufferType;

    }

#endif

    if (is_slice_short(avctx, ctx)) {

        slice_data = ctx_pic->slice_short;

        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);

    } else {

        slice_data = ctx_pic->slice_long;

        slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_long);

    }

    assert((bs->DataSize & 127) == 0);

    return ff_dxva2_commit_buffer(avctx, ctx, sc,

                                  type,

                                  slice_data, slice_size, mb_count);

}


static int qtrle_decode_frame(AVCodecContext *avctx,

                              void *data, int *got_frame,

                              AVPacket *avpkt)

{

    QtrleContext *s = avctx->priv_data;

    int header, start_line;

    int height, row_ptr;

    int has_palette = 0;

    int ret;

    bytestream2_init(&s->g, avpkt->data, avpkt->size);

    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)

        return ret;

    /* check if this frame is even supposed to change */

    if (avpkt->size < 8)

        goto done;

    /* start after the chunk size */

    bytestream2_seek(&s->g, 4, SEEK_SET);

    /* fetch the header */

    header = bytestream2_get_be16(&s->g);

    /* if a header is present, fetch additional decoding parameters */

    if (header & 0x0008) {

        if (avpkt->size < 14)

            goto done;

        start_line = bytestream2_get_be16(&s->g);

        bytestream2_skip(&s->g, 2);

        height     = bytestream2_get_be16(&s->g);

        bytestream2_skip(&s->g, 2);

        if (height > s->avctx->height - start_line)

            goto done;

    } else {

        start_line = 0;

        height     = s->avctx->height;

    }

    row_ptr = s->frame->linesize[0] * start_line;

    switch (avctx->bits_per_coded_sample) {

    case 1:

    case 33:

        qtrle_decode_1bpp(s, row_ptr, height);

        has_palette = 1;

        break;

    case 2:

    case 34:

        qtrle_decode_2n4bpp(s, row_ptr, height, 2);

        has_palette = 1;

        break;

    case 4:

    case 36:

        qtrle_decode_2n4bpp(s, row_ptr, height, 4);

        has_palette = 1;

        break;

    case 8:

    case 40:

        qtrle_decode_8bpp(s, row_ptr, height);

        has_palette = 1;

        break;

    case 16:

        qtrle_decode_16bpp(s, row_ptr, height);

        break;

    case 24:

        qtrle_decode_24bpp(s, row_ptr, height);

        break;

    case 32:

        qtrle_decode_32bpp(s, row_ptr, height);

        break;

    default:

        av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",

            avctx->bits_per_coded_sample);

        break;

    }

    if(has_palette) {

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

        if (pal) {

            s->frame->palette_has_changed = 1;

            memcpy(s->pal, pal, AVPALETTE_SIZE);

        }

        /* make the palette available on the way out */

        memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);

    }

done:

    if ((ret = av_frame_ref(data, s->frame)) < 0)

        return ret;

    *got_frame      = 1;

    /* always report that the buffer was completely consumed */

    return avpkt->size;

}


int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags,

                       const AVIOInterruptCB *int_cb, AVDictionary **options)

{

    return avio_open2(pb, url, flags, int_cb, options);

}


static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)

{

    int ret;

    rcb->ret = rbd_aio_get_return_value(c);

    rbd_aio_release(c);

    ret = qemu_rbd_send_pipe(rcb->s, rcb);

    if (ret < 0) {

        error_report("failed writing to acb->s->fds");

        g_free(rcb);

    }

}


static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)

{

    struct pci_status *g = opaque;

    switch (addr) {

        case PCI_BASE:

            g->up = val;

            break;

        case PCI_BASE + 4:

            g->down = val;

            break;

   }

    PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val);

}


static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels,

                                 int line_size)

{

    int i;

    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    /* read the pixels */

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

        pixels[0] = cm[block[0]];

        pixels[1] = cm[block[1]];

        pixels += line_size;

        block += 8;

    }

}


bool qemu_file_is_writable(QEMUFile *f)

{

    return f->ops->writev_buffer || f->ops->put_buffer;

}


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];

    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.f.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 AV_CODEC_ID_H263:

    case AV_CODEC_ID_H263P:

    case AV_CODEC_ID_FLV1:

        if (CONFIG_H263_ENCODER)

            s->gob_index = ff_h263_get_gob_height(s);

        break;

    case AV_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++) {

        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 == AV_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 AV_CODEC_ID_H263:

                case AV_CODEC_ID_H263P:

                    if(!s->h263_slice_structured)

                        if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0;

                    break;

                case AV_CODEC_ID_MPEG2VIDEO:

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

                case AV_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==AV_CODEC_ID_MPEG4 && s->partitioned_frame){

                            ff_mpeg4_init_partitions(s);

                        }

                    }

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

                    current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob;

                    if (s->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->error_rate;

                        if(r % d == 0){

                            current_packet_size=0;

                            s->pb.buf_ptr= s->ptr_lastgob;

                            assert(put_bits_ptr(&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);

                    }

                    update_mb_info(s, 1);

                    switch(s->codec_id){

                    case AV_CODEC_ID_MPEG4:

                        if (CONFIG_MPEG4_ENCODER) {

                            ff_mpeg4_encode_video_packet_header(s);

                            ff_mpeg4_clean_buffers(s);

                        }

                    break;

                    case AV_CODEC_ID_MPEG1VIDEO:

                    case AV_CODEC_ID_MPEG2VIDEO:

                        if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) {

                            ff_mpeg1_encode_slice_header(s);

                            ff_mpeg1_clean_buffers(s);

                        }

                    break;

                    case AV_CODEC_ID_H263:

                    case AV_CODEC_ID_H263P:

                        if (CONFIG_H263_ENCODER)

                            ff_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

            update_mb_info(s, 0);

            if (mb_type & (mb_type-1) || (s->mpv_flags & FF_MPV_FLAG_QP_RD)) { // more than 1 MB type possible or FF_MPV_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->mpv_flags & FF_MPV_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];

                        int16_t 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 == AV_PICTURE_TYPE_B ? 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(int16_t)*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(int16_t)*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->mpv_flags & FF_MPV_FLAG_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);

                avpriv_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);

                    avpriv_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);

                    avpriv_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_H263_ENCODER &&

                    s->out_format == FMT_H263 && s->pict_type!=AV_PICTURE_TYPE_B)

                    ff_h263_update_motion_val(s);

                if(next_block==0){ //FIXME 16 vs linesize16

                    s->hdsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);

                    s->hdsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);

                    s->hdsp.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)

                    ff_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];

                    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_H263_ENCODER &&

                    s->out_format == FMT_H263 && s->pict_type!=AV_PICTURE_TYPE_B)

                    ff_h263_update_motion_val(s);

                ff_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.f.error[0] += sse(

                    s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,

                    s->dest[0], w, h, s->linesize);

                s->current_picture.f.error[1] += sse(

                    s, s->new_picture.f.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.f.error[2] += sse(

                    s, s->new_picture.f.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_H263_ENCODER && s->out_format == FMT_H263)

                    ff_h263_loop_filter(s);

            }

            av_dlog(s->avctx, "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 == AV_PICTURE_TYPE_I)

        ff_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 = put_bits_ptr(&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;

}


static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors)
{
    return bdrv_check_byte_request(bs, sector_num * BDRV_SECTOR_SIZE,
                                   nb_sectors * BDRV_SECTOR_SIZE);


int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) {

    if(avccontext->coded_frame->quality) /* VBR requested */

	return vorbis_encode_init_vbr(vi, avccontext->channels,

		  avccontext->sample_rate, (float)avccontext->coded_frame->quality / 1000) ;

    return vorbis_encode_init(vi, avccontext->channels,

	          avccontext->sample_rate, -1, avccontext->bit_rate, -1) ;

}


static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,

                         uint64_t value)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    int timeridx = ri->crm & 1;

    uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;

    env->cp15.c14_timer[timeridx].ctl = value & 3;

    if ((oldval ^ value) & 1) {

        /* Enable toggled */

        gt_recalc_timer(cpu, timeridx);

    } else if ((oldval & value) & 2) {

        /* IMASK toggled: don't need to recalculate,

         * just set the interrupt line based on ISTATUS

         */

        qemu_set_irq(cpu->gt_timer_outputs[timeridx],

                     (oldval & 4) && (value & 2));

    }

}


static av_cold int vp8_decode_free(AVCodecContext *avctx)

{

    vp8_decode_flush_impl(avctx, 0, 1);

    release_queued_segmaps(avctx->priv_data, 1);

    return 0;

}


static int a64_write_header(AVFormatContext *s)

{

    AVCodecContext *avctx = s->streams[0]->codec;

    uint8_t header[5] = {

        0x00, //load

        0x40, //address

        0x00, //mode

        0x00, //charset_lifetime (multi only)

        0x00  //fps in 50/fps;

    };

    if (avctx->extradata_size < 4) {

        av_log(s, AV_LOG_ERROR, "Missing extradata\n");

        return AVERROR(EINVAL);

    }

    switch (avctx->codec->id) {

    case AV_CODEC_ID_A64_MULTI:

        header[2] = 0x00;

        header[3] = AV_RB32(avctx->extradata+0);

        header[4] = 2;

        break;

    case AV_CODEC_ID_A64_MULTI5:

        header[2] = 0x01;

        header[3] = AV_RB32(avctx->extradata+0);

        header[4] = 3;

        break;

    default:

        return AVERROR(EINVAL);

    }

    avio_write(s->pb, header, 2);

    return 0;

}


static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)

{

    BDRVBochsState *s = bs->opaque;

    uint64_t offset = sector_num * 512;

    uint64_t extent_index, extent_offset, bitmap_offset;

    char bitmap_entry;

    // seek to sector

    extent_index = offset / s->extent_size;

    extent_offset = (offset % s->extent_size) / 512;

    if (s->catalog_bitmap[extent_index] == 0xffffffff) {

	return -1; /* not allocated */

    }

    bitmap_offset = s->data_offset +

        (512 * (uint64_t) s->catalog_bitmap[extent_index] *

        (s->extent_blocks + s->bitmap_blocks));

    /* read in bitmap for current extent */

    if (bdrv_pread(bs->file, bitmap_offset + (extent_offset / 8),

                   &bitmap_entry, 1) != 1) {

        return -1;

    }

    if (!((bitmap_entry >> (extent_offset % 8)) & 1)) {

	return -1; /* not allocated */

    }

    return bitmap_offset + (512 * (s->bitmap_blocks + extent_offset));

}


static void slirp_bootp_save(QEMUFile *f, Slirp *slirp)

{

    int i;

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

        qemu_put_be16(f, slirp->bootp_clients[i].allocated);

        qemu_put_buffer(f, slirp->bootp_clients[i].macaddr, 6);

    }

}


int qemu_opts_id_wellformed(const char *id)

{

    int i;

    if (!qemu_isalpha(id[0])) {

        return 0;

    }

    for (i = 1; id[i]; i++) {

        if (!qemu_isalnum(id[i]) && !strchr("-._", id[i])) {

            return 0;

        }

    }

    return 1;

}


ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)

{

	if (so->s == -1 && so->extra) {

		qemu_chr_fe_write(so->extra, buf, len);

		return len;

	}

	return send(so->s, buf, len, flags);

}


int nbd_init(int fd, int csock, uint32_t flags, off_t size, size_t blocksize)

{

    TRACE("Setting NBD socket");

    if (ioctl(fd, NBD_SET_SOCK, csock) < 0) {

        int serrno = errno;

        LOG("Failed to set NBD socket");

        errno = serrno;

        return -1;

    }

    TRACE("Setting block size to %lu", (unsigned long)blocksize);

    if (ioctl(fd, NBD_SET_BLKSIZE, blocksize) < 0) {

        int serrno = errno;

        LOG("Failed setting NBD block size");

        errno = serrno;

        return -1;

    }

        TRACE("Setting size to %zd block(s)", (size_t)(size / blocksize));

    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, size / blocksize) < 0) {

        int serrno = errno;

        LOG("Failed setting size (in blocks)");

        errno = serrno;

        return -1;

    }

    if (flags & NBD_FLAG_READ_ONLY) {

        int read_only = 1;

        TRACE("Setting readonly attribute");

        if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {

            int serrno = errno;

            LOG("Failed setting read-only attribute");

            errno = serrno;

            return -1;

        }

    }

    if (ioctl(fd, NBD_SET_FLAGS, flags) < 0

        && errno != ENOTTY) {

        int serrno = errno;

        LOG("Failed setting flags");

        errno = serrno;

        return -1;

    }

    TRACE("Negotiation ended");

    return 0;

}


static void rgb24_to_yuvj420p(AVPicture *dst, AVPicture *src,

                              int width, int height)

{

    int wrap, wrap3, width2;

    int r, g, b, r1, g1, b1, w;

    uint8_t *lum, *cb, *cr;

    const uint8_t *p;

    lum = dst->data[0];

    cb = dst->data[1];

    cr = dst->data[2];

    width2 = (width + 1) >> 1;

    wrap = dst->linesize[0];

    wrap3 = src->linesize[0];

    p = src->data[0];

    for(;height>=2;height -= 2) {

        for(w = width; w >= 2; w -= 2) {

            RGB_IN(r, g, b, p);

            r1 = r;

            g1 = g;

            b1 = b;

            lum[0] = RGB_TO_Y(r, g, b);

            RGB_IN(r, g, b, p + BPP);

            r1 += r;

            g1 += g;

            b1 += b;

            lum[1] = RGB_TO_Y(r, g, b);

            p += wrap3;

            lum += wrap;

            RGB_IN(r, g, b, p);

            r1 += r;

            g1 += g;

            b1 += b;

            lum[0] = RGB_TO_Y(r, g, b);

            RGB_IN(r, g, b, p + BPP);

            r1 += r;

            g1 += g;

            b1 += b;

            lum[1] = RGB_TO_Y(r, g, b);

            cb[0] = RGB_TO_U(r1, g1, b1, 2);

            cr[0] = RGB_TO_V(r1, g1, b1, 2);

            cb++;

            cr++;

            p += -wrap3 + 2 * BPP;

            lum += -wrap + 2;

        }

        if (w) {

            RGB_IN(r, g, b, p);

            r1 = r;

            g1 = g;

            b1 = b;

            lum[0] = RGB_TO_Y(r, g, b);

            p += wrap3;

            lum += wrap;

            RGB_IN(r, g, b, p);

            r1 += r;

            g1 += g;

            b1 += b;

            lum[0] = RGB_TO_Y(r, g, b);

            cb[0] = RGB_TO_U(r1, g1, b1, 1);

            cr[0] = RGB_TO_V(r1, g1, b1, 1);

            cb++;

            cr++;

            p += -wrap3 + BPP;

            lum += -wrap + 1;

        }

        p += wrap3 + (wrap3 - width * BPP);

        lum += wrap + (wrap - width);

        cb += dst->linesize[1] - width2;

        cr += dst->linesize[2] - width2;

    }

    /* handle odd height */

    if (height) {

        for(w = width; w >= 2; w -= 2) {

            RGB_IN(r, g, b, p);

            r1 = r;

            g1 = g;

            b1 = b;

            lum[0] = RGB_TO_Y(r, g, b);

            RGB_IN(r, g, b, p + BPP);

            r1 += r;

            g1 += g;

            b1 += b;

            lum[1] = RGB_TO_Y(r, g, b);

            cb[0] = RGB_TO_U(r1, g1, b1, 1);

            cr[0] = RGB_TO_V(r1, g1, b1, 1);

            cb++;

            cr++;

            p += 2 * BPP;

           lum += 2;

        }

        if (w) {

            RGB_IN(r, g, b, p);

            lum[0] = RGB_TO_Y(r, g, b);

            cb[0] = RGB_TO_U(r, g, b, 0);

            cr[0] = RGB_TO_V(r, g, b, 0);

        }

    }

}


static void do_multiwrite(BlockDriverState *bs, BlockRequest *blkreq,

    int num_writes)

{

    int i, ret;

    ret = bdrv_aio_multiwrite(bs, blkreq, num_writes);

    if (ret != 0) {

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

            if (blkreq[i].error) {

                virtio_blk_rw_complete(blkreq[i].opaque, -EIO);

            }

        }

    }

}


static void qjson_register_types(void)

{

    type_register_static(&qjson_type_info);

}


void css_generate_sch_crws(uint8_t cssid, uint8_t ssid, uint16_t schid,

                           int hotplugged, int add)

{

    uint8_t guest_cssid;

    bool chain_crw;

    if (add && !hotplugged) {

        return;

    }

    if (channel_subsys.max_cssid == 0) {

        /* Default cssid shows up as 0. */

        guest_cssid = (cssid == channel_subsys.default_cssid) ? 0 : cssid;

    } else {

        /* Show real cssid to the guest. */

        guest_cssid = cssid;

    }

    /*

     * Only notify for higher subchannel sets/channel subsystems if the

     * guest has enabled it.

     */

    if ((ssid > channel_subsys.max_ssid) ||

        (guest_cssid > channel_subsys.max_cssid) ||

        ((channel_subsys.max_cssid == 0) &&

         (cssid != channel_subsys.default_cssid))) {

        return;

    }

    chain_crw = (channel_subsys.max_ssid > 0) ||

            (channel_subsys.max_cssid > 0);

    css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, chain_crw ? 1 : 0, schid);

    if (chain_crw) {

        css_queue_crw(CRW_RSC_SUBCH, CRW_ERC_IPI, 0,

                      (guest_cssid << 8) | (ssid << 4));

    }

    /* RW_ERC_IPI --> clear pending interrupts */

    css_clear_io_interrupt(css_do_build_subchannel_id(cssid, ssid), schid);

}


static void term_insert_char(int ch)

{

    if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {

        memmove(term_cmd_buf + term_cmd_buf_index + 1,

                term_cmd_buf + term_cmd_buf_index,

                term_cmd_buf_size - term_cmd_buf_index);

        term_cmd_buf[term_cmd_buf_index] = ch;

        term_cmd_buf_size++;

        term_cmd_buf_index++;

    }

}


static void spapr_phb_add_pci_device(sPAPRDRConnector *drc,

                                     sPAPRPHBState *phb,

                                     PCIDevice *pdev,

                                     Error **errp)

{

    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    DeviceState *dev = DEVICE(pdev);

    int drc_index = drck->get_index(drc);

    void *fdt = NULL;

    int fdt_start_offset = 0, fdt_size;

    if (dev->hotplugged) {

        fdt = create_device_tree(&fdt_size);

        fdt_start_offset = spapr_create_pci_child_dt(phb, pdev,

                                                     drc_index, NULL,

                                                     fdt, 0);

        if (!fdt_start_offset) {

            error_setg(errp, "Failed to create pci child device tree node");

            goto out;

        }

    }

    drck->attach(drc, DEVICE(pdev),

                 fdt, fdt_start_offset, !dev->hotplugged, errp);

out:

    if (*errp) {

        g_free(fdt);

    }

}


static void decode_scaling_matrices(H264Context *h, SPS *sps,

                                    PPS *pps, int is_sps,

                                    uint8_t(*scaling_matrix4)[16],

                                    uint8_t(*scaling_matrix8)[64])

{

    int fallback_sps = !is_sps && sps->scaling_matrix_present;

    const uint8_t *fallback[4] = {

        fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],

        fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1],

        fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],

        fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]

    };

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

        sps->scaling_matrix_present |= is_sps;

        decode_scaling_list(h, scaling_matrix4[0], 16, default_scaling4[0], fallback[0]);        // Intra, Y

        decode_scaling_list(h, scaling_matrix4[1], 16, default_scaling4[0], scaling_matrix4[0]); // Intra, Cr

        decode_scaling_list(h, scaling_matrix4[2], 16, default_scaling4[0], scaling_matrix4[1]); // Intra, Cb

        decode_scaling_list(h, scaling_matrix4[3], 16, default_scaling4[1], fallback[1]);        // Inter, Y

        decode_scaling_list(h, scaling_matrix4[4], 16, default_scaling4[1], scaling_matrix4[3]); // Inter, Cr

        decode_scaling_list(h, scaling_matrix4[5], 16, default_scaling4[1], scaling_matrix4[4]); // Inter, Cb

        if (is_sps || pps->transform_8x8_mode) {

            decode_scaling_list(h, scaling_matrix8[0], 64, default_scaling8[0], fallback[2]); // Intra, Y

            if (sps->chroma_format_idc == 3) {

                decode_scaling_list(h, scaling_matrix8[1], 64, default_scaling8[0], scaling_matrix8[0]); // Intra, Cr

                decode_scaling_list(h, scaling_matrix8[2], 64, default_scaling8[0], scaling_matrix8[1]); // Intra, Cb

            }

            decode_scaling_list(h, scaling_matrix8[3], 64, default_scaling8[1], fallback[3]); // Inter, Y

            if (sps->chroma_format_idc == 3) {

                decode_scaling_list(h, scaling_matrix8[4], 64, default_scaling8[1], scaling_matrix8[3]); // Inter, Cr

                decode_scaling_list(h, scaling_matrix8[5], 64, default_scaling8[1], scaling_matrix8[4]); // Inter, Cb

            }

        }

    }

}


static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr,

                               uint64_t value, unsigned size)

{

    MacIONVRAMState *s = opaque;

    addr = (addr >> s->it_shift) & (s->size - 1);

    s->data[addr] = value;

    NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);

}


static void fill_prstatus(struct target_elf_prstatus *prstatus,

                          const TaskState *ts, int signr)

{

    (void) memset(prstatus, 0, sizeof (*prstatus));

    prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;

    prstatus->pr_pid = ts->ts_tid;

    prstatus->pr_ppid = getppid();

    prstatus->pr_pgrp = getpgrp();

    prstatus->pr_sid = getsid(0);

#ifdef BSWAP_NEEDED

    bswap_prstatus(prstatus);

#endif

}


static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name)

{

    FILE *f;

    int ret = 0;

    char filename[PATH_MAX];

    snprintf(filename, PATH_MAX, device_file, device_name);

    f = fopen(filename, "r");

    if (f) {

        fgets(line, line_size, f);

        fclose(f);

        ret = 1;

    } else {

        term_printf("husb: could not open %s\n", filename);

    }

    return ret;

}


static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)

{

    uint32_t value = 0;

    int i;

    /* first check that a valid data exists in host controller input buffer */

    if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {

        ERRPRINT("Trying to read from empty buffer\n");

        return 0;

    }

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

        value |= s->fifo_buffer[s->data_count] << i * 8;

        s->data_count++;

        /* check if we've read all valid data (blksize bytes) from buffer */

        if ((s->data_count) >= (s->blksize & 0x0fff)) {

            DPRINT_L2("All %u bytes of data have been read from input buffer\n",

                    s->data_count);

            s->prnsts &= ~SDHC_DATA_AVAILABLE; /* no more data in a buffer */

            s->data_count = 0;  /* next buff read must start at position [0] */

            if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {

                s->blkcnt--;

            }

            /* if that was the last block of data */

            if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||

                ((s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) ||

                 /* stop at gap request */

                (s->stopped_state == sdhc_gap_read &&

                 !(s->prnsts & SDHC_DAT_LINE_ACTIVE))) {

                SDHCI_GET_CLASS(s)->end_data_transfer(s);

            } else { /* if there are more data, read next block from card */

                SDHCI_GET_CLASS(s)->read_block_from_card(s);

            }

            break;

        }

    }

    return value;

}


static void pc_fw_add_pflash_drv(void)

{

    QemuOpts *opts;

    QEMUMachine *machine;

    char *filename;

    if (bios_name == NULL) {

        bios_name = BIOS_FILENAME;

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    opts = drive_add(IF_PFLASH, -1, filename, "readonly=on");

    g_free(filename);

    if (opts == NULL) {

      return;

    }

    machine = find_default_machine();

    if (machine == NULL) {

      return;

    }

    if (!drive_init(opts, machine->use_scsi)) {

        qemu_opts_del(opts);

    }

}


static void escc_mem_write(void *opaque, target_phys_addr_t addr,

                           uint64_t val, unsigned size)

{

    SerialState *serial = opaque;

    ChannelState *s;

    uint32_t saddr;

    int newreg, channel;

    val &= 0xff;

    saddr = (addr >> serial->it_shift) & 1;

    channel = (addr >> (serial->it_shift + 1)) & 1;

    s = &serial->chn[channel];

    switch (saddr) {

    case SERIAL_CTRL:

        trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);

        newreg = 0;

        switch (s->reg) {

        case W_CMD:

            newreg = val & CMD_PTR_MASK;

            val &= CMD_CMD_MASK;

            switch (val) {

            case CMD_HI:

                newreg |= CMD_HI;

                break;

            case CMD_CLR_TXINT:

                clr_txint(s);

                break;

            case CMD_CLR_IUS:

                if (s->rxint_under_svc) {

                    s->rxint_under_svc = 0;

                    if (s->txint) {

                        set_txint(s);

                    }

                } else if (s->txint_under_svc) {

                    s->txint_under_svc = 0;

                }

                escc_update_irq(s);

                break;

            default:

                break;

            }

            break;

        case W_INTR ... W_RXCTRL:

        case W_SYNC1 ... W_TXBUF:

        case W_MISC1 ... W_CLOCK:

        case W_MISC2 ... W_EXTINT:

            s->wregs[s->reg] = val;

            break;

        case W_TXCTRL1:

        case W_TXCTRL2:

            s->wregs[s->reg] = val;

            escc_update_parameters(s);

            break;

        case W_BRGLO:

        case W_BRGHI:

            s->wregs[s->reg] = val;

            s->rregs[s->reg] = val;

            escc_update_parameters(s);

            break;

        case W_MINTR:

            switch (val & MINTR_RST_MASK) {

            case 0:

            default:

                break;

            case MINTR_RST_B:

                escc_reset_chn(&serial->chn[0]);

                return;

            case MINTR_RST_A:

                escc_reset_chn(&serial->chn[1]);

                return;

            case MINTR_RST_ALL:

                escc_reset(&serial->busdev.qdev);

                return;

            }

            break;

        default:

            break;

        }

        if (s->reg == 0)

            s->reg = newreg;

        else

            s->reg = 0;

        break;

    case SERIAL_DATA:

        trace_escc_mem_writeb_data(CHN_C(s), val);

        s->tx = val;

        if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled

            if (s->chr)

                qemu_chr_fe_write(s->chr, &s->tx, 1);

            else if (s->type == kbd && !s->disabled) {

                handle_kbd_command(s, val);

            }

        }

        s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty

        s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent

        set_txint(s);

        break;

    default:

        break;

    }

}


int ff_cbs_write_packet(CodedBitstreamContext *ctx,

                        AVPacket *pkt,

                        CodedBitstreamFragment *frag)

{

    int err;

    err = ff_cbs_write_fragment_data(ctx, frag);

    if (err < 0)

        return err;

    av_new_packet(pkt, frag->data_size);

    if (err < 0)

        return err;

    memcpy(pkt->data, frag->data, frag->data_size);

    pkt->size = frag->data_size;

    return 0;

}


static av_cold int sunrast_encode_close(AVCodecContext *avctx)

{

    av_frame_free(&avctx->coded_frame);

    return 0;

}


static void RENAME(yadif_filter_line)(uint8_t *dst, uint8_t *prev, uint8_t *cur,

                                      uint8_t *next, int w, int prefs,

                                      int mrefs, int parity, int mode)

{

    DECLARE_ALIGNED(16, uint8_t, tmp0)[16];

    DECLARE_ALIGNED(16, uint8_t, tmp1)[16];

    DECLARE_ALIGNED(16, uint8_t, tmp2)[16];

    DECLARE_ALIGNED(16, uint8_t, tmp3)[16];

    int x;

#define FILTER\

    for(x=0; x<w; x+=STEP){\

        __asm__ volatile(\

            "pxor      "MM"7, "MM"7 \n\t"\

            LOAD("(%[cur],%[mrefs])", MM"0") /* c = cur[x-refs] */\

            LOAD("(%[cur],%[prefs])", MM"1") /* e = cur[x+refs] */\

            LOAD("(%["prev2"])", MM"2") /* prev2[x] */\

            LOAD("(%["next2"])", MM"3") /* next2[x] */\

            MOVQ"      "MM"3, "MM"4 \n\t"\

            "paddw     "MM"2, "MM"3 \n\t"\

            "psraw     $1,    "MM"3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\

            MOVQ"      "MM"0, %[tmp0] \n\t" /* c */\

            MOVQ"      "MM"3, %[tmp1] \n\t" /* d */\

            MOVQ"      "MM"1, %[tmp2] \n\t" /* e */\

            "psubw     "MM"4, "MM"2 \n\t"\

            PABS(      MM"4", MM"2") /* temporal_diff0 */\

            LOAD("(%[prev],%[mrefs])", MM"3") /* prev[x-refs] */\

            LOAD("(%[prev],%[prefs])", MM"4") /* prev[x+refs] */\

            "psubw     "MM"0, "MM"3 \n\t"\

            "psubw     "MM"1, "MM"4 \n\t"\

            PABS(      MM"5", MM"3")\

            PABS(      MM"5", MM"4")\

            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff1 */\

            "psrlw     $1,    "MM"2 \n\t"\

            "psrlw     $1,    "MM"3 \n\t"\

            "pmaxsw    "MM"3, "MM"2 \n\t"\

            LOAD("(%[next],%[mrefs])", MM"3") /* next[x-refs] */\

            LOAD("(%[next],%[prefs])", MM"4") /* next[x+refs] */\

            "psubw     "MM"0, "MM"3 \n\t"\

            "psubw     "MM"1, "MM"4 \n\t"\

            PABS(      MM"5", MM"3")\

            PABS(      MM"5", MM"4")\

            "paddw     "MM"4, "MM"3 \n\t" /* temporal_diff2 */\

            "psrlw     $1,    "MM"3 \n\t"\

            "pmaxsw    "MM"3, "MM"2 \n\t"\

            MOVQ"      "MM"2, %[tmp3] \n\t" /* diff */\

\

            "paddw     "MM"0, "MM"1 \n\t"\

            "paddw     "MM"0, "MM"0 \n\t"\

            "psubw     "MM"1, "MM"0 \n\t"\

            "psrlw     $1,    "MM"1 \n\t" /* spatial_pred */\

            PABS(      MM"2", MM"0")      /* ABS(c-e) */\

\

            MOVQU" -1(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1] */\

            MOVQU" -1(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1] */\

            MOVQ"      "MM"2, "MM"4 \n\t"\

            "psubusb   "MM"3, "MM"2 \n\t"\

            "psubusb   "MM"4, "MM"3 \n\t"\

            "pmaxub    "MM"3, "MM"2 \n\t"\

            PSHUF(MM"3", MM"2") \

            "punpcklbw "MM"7, "MM"2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\

            "punpcklbw "MM"7, "MM"3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\

            "paddw     "MM"2, "MM"0 \n\t"\

            "paddw     "MM"3, "MM"0 \n\t"\

            "psubw    "MANGLE(pw_1)", "MM"0 \n\t" /* spatial_score */\

\

            CHECK(-2,0)\

            CHECK1\

            CHECK(-3,1)\

            CHECK2\

            CHECK(0,-2)\

            CHECK1\

            CHECK(1,-3)\

            CHECK2\

\

            /* if(p->mode<2) ... */\

            MOVQ"    %[tmp3], "MM"6 \n\t" /* diff */\

            "cmpl      $2, %[mode] \n\t"\

            "jge       1f \n\t"\

            LOAD("(%["prev2"],%[mrefs],2)", MM"2") /* prev2[x-2*refs] */\

            LOAD("(%["next2"],%[mrefs],2)", MM"4") /* next2[x-2*refs] */\

            LOAD("(%["prev2"],%[prefs],2)", MM"3") /* prev2[x+2*refs] */\

            LOAD("(%["next2"],%[prefs],2)", MM"5") /* next2[x+2*refs] */\

            "paddw     "MM"4, "MM"2 \n\t"\

            "paddw     "MM"5, "MM"3 \n\t"\

            "psrlw     $1,    "MM"2 \n\t" /* b */\

            "psrlw     $1,    "MM"3 \n\t" /* f */\

            MOVQ"    %[tmp0], "MM"4 \n\t" /* c */\

            MOVQ"    %[tmp1], "MM"5 \n\t" /* d */\

            MOVQ"    %[tmp2], "MM"7 \n\t" /* e */\

            "psubw     "MM"4, "MM"2 \n\t" /* b-c */\

            "psubw     "MM"7, "MM"3 \n\t" /* f-e */\

            MOVQ"      "MM"5, "MM"0 \n\t"\

            "psubw     "MM"4, "MM"5 \n\t" /* d-c */\

            "psubw     "MM"7, "MM"0 \n\t" /* d-e */\

            MOVQ"      "MM"2, "MM"4 \n\t"\

            "pminsw    "MM"3, "MM"2 \n\t"\

            "pmaxsw    "MM"4, "MM"3 \n\t"\

            "pmaxsw    "MM"5, "MM"2 \n\t"\

            "pminsw    "MM"5, "MM"3 \n\t"\

            "pmaxsw    "MM"0, "MM"2 \n\t" /* max */\

            "pminsw    "MM"0, "MM"3 \n\t" /* min */\

            "pxor      "MM"4, "MM"4 \n\t"\

            "pmaxsw    "MM"3, "MM"6 \n\t"\

            "psubw     "MM"2, "MM"4 \n\t" /* -max */\

            "pmaxsw    "MM"4, "MM"6 \n\t" /* diff= MAX3(diff, min, -max); */\

            "1: \n\t"\

\

            MOVQ"    %[tmp1], "MM"2 \n\t" /* d */\

            MOVQ"      "MM"2, "MM"3 \n\t"\

            "psubw     "MM"6, "MM"2 \n\t" /* d-diff */\

            "paddw     "MM"6, "MM"3 \n\t" /* d+diff */\

            "pmaxsw    "MM"2, "MM"1 \n\t"\

            "pminsw    "MM"3, "MM"1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\

            "packuswb  "MM"1, "MM"1 \n\t"\

\

            :[tmp0]"=m"(tmp0),\

             [tmp1]"=m"(tmp1),\

             [tmp2]"=m"(tmp2),\

             [tmp3]"=m"(tmp3)\

            :[prev] "r"(prev),\

             [cur]  "r"(cur),\

             [next] "r"(next),\

             [prefs]"r"((x86_reg)prefs),\

             [mrefs]"r"((x86_reg)mrefs),\

             [mode] "g"(mode)\

        );\

        __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\

        dst += STEP;\

        prev+= STEP;\

        cur += STEP;\

        next+= STEP;\

    }

    if (parity) {

#define prev2 "prev"

#define next2 "cur"

        FILTER

#undef prev2

#undef next2

    } else {

#define prev2 "cur"

#define next2 "next"

        FILTER

#undef prev2

#undef next2

    }

}


static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){

    int count, y, x, i, j, split, best_mean, best_score, best_count;

    int best_vector[6];

    int block_sum[7]= {0, 0, 0, 0, 0, 0};

    int w= 2<<((level+2)>>1);

    int h= 2<<((level+1)>>1);

    int size=w*h;

    int16_t block[7][256];

    const int8_t *codebook_sum, *codebook;

    const uint16_t (*mean_vlc)[2];

    const uint8_t (*multistage_vlc)[2];

    best_score=0;

    //FIXME optimize, this doenst need to be done multiple times

    if(intra){

        codebook_sum= svq1_intra_codebook_sum[level];

        codebook= svq1_intra_codebooks[level];

        mean_vlc= svq1_intra_mean_vlc;

        multistage_vlc= svq1_intra_multistage_vlc[level];

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

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

                int v= src[x + y*stride];

                block[0][x + w*y]= v;

                best_score += v*v;

                block_sum[0] += v;

            }

        }

    }else{

        codebook_sum= svq1_inter_codebook_sum[level];

        codebook= svq1_inter_codebooks[level];

        mean_vlc= svq1_inter_mean_vlc + 256;

        multistage_vlc= svq1_inter_multistage_vlc[level];

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

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

                int v= src[x + y*stride] - ref[x + y*stride];

                block[0][x + w*y]= v;

                best_score += v*v;

                block_sum[0] += v;

            }

        }

    }

    best_count=0;

    best_score -= ((block_sum[0]*block_sum[0])>>(level+3));

    best_mean= (block_sum[0] + (size>>1)) >> (level+3);

    if(level<4){

        for(count=1; count<7; count++){

            int best_vector_score= INT_MAX;

            int best_vector_sum=-999, best_vector_mean=-999;

            const int stage= count-1;

            const int8_t *vector;

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

                int sum= codebook_sum[stage*16 + i];

                int sqr, diff, mean, score;

                vector = codebook + stage*size*16 + i*size;

                sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size);

                diff= block_sum[stage] - sum;

                mean= (diff + (size>>1)) >> (level+3);

                assert(mean >-300 && mean<300);

                if(intra) mean= av_clip(mean, 0, 255);

                else      mean= av_clip(mean, -256, 255);

                score= sqr - ((diff*(int64_t)diff)>>(level+3)); //FIXME 64bit slooow

                if(score < best_vector_score){

                    best_vector_score= score;

                    best_vector[stage]= i;

                    best_vector_sum= sum;

                    best_vector_mean= mean;

                }

            }

            assert(best_vector_mean != -999);

            vector= codebook + stage*size*16 + best_vector[stage]*size;

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

                block[stage+1][j] = block[stage][j] - vector[j];

            }

            block_sum[stage+1]= block_sum[stage] - best_vector_sum;

            best_vector_score +=

                lambda*(+ 1 + 4*count

                        + multistage_vlc[1+count][1]

                        + mean_vlc[best_vector_mean][1]);

            if(best_vector_score < best_score){

                best_score= best_vector_score;

                best_count= count;

                best_mean= best_vector_mean;

            }

        }

    }

    split=0;

    if(best_score > threshold && level){

        int score=0;

        int offset= (level&1) ? stride*h/2 : w/2;

        PutBitContext backup[6];

        for(i=level-1; i>=0; i--){

            backup[i]= s->reorder_pb[i];

        }

        score += encode_block(s, src         , ref         , decoded         , stride, level-1, threshold>>1, lambda, intra);

        score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra);

        score += lambda;

        if(score < best_score){

            best_score= score;

            split=1;

        }else{

            for(i=level-1; i>=0; i--){

                s->reorder_pb[i]= backup[i];

            }

        }

    }

    if (level > 0)

        put_bits(&s->reorder_pb[level], 1, split);

    if(!split){

        assert((best_mean >= 0 && best_mean<256) || !intra);

        assert(best_mean >= -256 && best_mean<256);

        assert(best_count >=0 && best_count<7);

        assert(level<4 || best_count==0);

        /* output the encoding */

        put_bits(&s->reorder_pb[level],

            multistage_vlc[1 + best_count][1],

            multistage_vlc[1 + best_count][0]);

        put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1],

            mean_vlc[best_mean][0]);

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

            assert(best_vector[i]>=0 && best_vector[i]<16);

            put_bits(&s->reorder_pb[level], 4, best_vector[i]);

        }

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

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

                decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean;

            }

        }

    }

    return best_score;

}


int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame)

{

    V4L2Buffer* avbuf = NULL;

    /* if we are draining, we are no longer inputing data, therefore enable a

     * timeout so we can dequeue and flag the last valid buffer.

     *

     * blocks until:

     *  1. decoded frame available

     *  2. an input buffer is ready to be dequeued

     */

    avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1);

    if (!avbuf) {

        if (ctx->done)

            return AVERROR_EOF;

        return AVERROR(EAGAIN);

    }

    return ff_v4l2_buffer_buf_to_avframe(frame, avbuf);

}