vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,

               QEMUIOVector *qiov, int flags)

{

    BDRVVdiState *s = bs->opaque;

    QEMUIOVector local_qiov;

    uint32_t bmap_entry;

    uint32_t block_index;

    uint32_t offset_in_block;

    uint32_t n_bytes;

    uint32_t bmap_first = VDI_UNALLOCATED;

    uint32_t bmap_last = VDI_UNALLOCATED;

    uint8_t *block = NULL;

    uint64_t bytes_done = 0;

    int ret = 0;

    logout("\n");

    qemu_iovec_init(&local_qiov, qiov->niov);

    while (ret >= 0 && bytes > 0) {

        block_index = offset / s->block_size;

        offset_in_block = offset % s->block_size;

        n_bytes = MIN(bytes, s->block_size - offset_in_block);

        logout("will write %u bytes starting at offset %" PRIu64 "\n",

               n_bytes, offset);

        /* prepare next AIO request */

        bmap_entry = le32_to_cpu(s->bmap[block_index]);

        if (!VDI_IS_ALLOCATED(bmap_entry)) {

            /* Allocate new block and write to it. */

            uint64_t data_offset;

            bmap_entry = s->header.blocks_allocated;

            s->bmap[block_index] = cpu_to_le32(bmap_entry);

            s->header.blocks_allocated++;

            data_offset = s->header.offset_data +

                          (uint64_t)bmap_entry * s->block_size;

            if (block == NULL) {

                block = g_malloc(s->block_size);

                bmap_first = block_index;

            }

            bmap_last = block_index;

            /* Copy data to be written to new block and zero unused parts. */

            memset(block, 0, offset_in_block);

            qemu_iovec_to_buf(qiov, bytes_done, block + offset_in_block,

                              n_bytes);

            memset(block + offset_in_block + n_bytes, 0,

                   s->block_size - n_bytes - offset_in_block);

            /* Note that this coroutine does not yield anywhere from reading the

             * bmap entry until here, so in regards to all the coroutines trying

             * to write to this cluster, the one doing the allocation will

             * always be the first to try to acquire the lock.

             * Therefore, it is also the first that will actually be able to

             * acquire the lock and thus the padded cluster is written before

             * the other coroutines can write to the affected area. */

            qemu_co_mutex_lock(&s->write_lock);

            ret = bdrv_pwrite(bs->file, data_offset, block, s->block_size);

            qemu_co_mutex_unlock(&s->write_lock);

        } else {

            uint64_t data_offset = s->header.offset_data +

                                   (uint64_t)bmap_entry * s->block_size +

                                   offset_in_block;

            qemu_co_mutex_lock(&s->write_lock);

            /* This lock is only used to make sure the following write operation

             * is executed after the write issued by the coroutine allocating

             * this cluster, therefore we do not need to keep it locked.

             * As stated above, the allocating coroutine will always try to lock

             * the mutex before all the other concurrent accesses to that

             * cluster, therefore at this point we can be absolutely certain

             * that that write operation has returned (there may be other writes

             * in flight, but they do not concern this very operation). */

            qemu_co_mutex_unlock(&s->write_lock);

            qemu_iovec_reset(&local_qiov);

            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);

            ret = bdrv_co_pwritev(bs->file, data_offset, n_bytes,

                                  &local_qiov, 0);

        }

        bytes -= n_bytes;

        offset += n_bytes;

        bytes_done += n_bytes;

        logout("%u bytes written\n", n_bytes);

    }

    qemu_iovec_destroy(&local_qiov);

    logout("finished data write\n");

    if (ret < 0) {

        return ret;

    }

    if (block) {

        /* One or more new blocks were allocated. */

        VdiHeader *header = (VdiHeader *) block;

        uint8_t *base;

        uint64_t offset;

        uint32_t n_sectors;

        logout("now writing modified header\n");

        assert(VDI_IS_ALLOCATED(bmap_first));

        *header = s->header;

        vdi_header_to_le(header);

        ret = bdrv_write(bs->file, 0, block, 1);

        g_free(block);

        block = NULL;

        if (ret < 0) {

            return ret;

        }

        logout("now writing modified block map entry %u...%u\n",

               bmap_first, bmap_last);

        /* Write modified sectors from block map. */

        bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));

        bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));

        n_sectors = bmap_last - bmap_first + 1;

        offset = s->bmap_sector + bmap_first;

        base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;

        logout("will write %u block map sectors starting from entry %u\n",

               n_sectors, bmap_first);

        ret = bdrv_write(bs->file, offset, base, n_sectors);

    }

    return ret;

}


bool bdrv_can_write_zeroes_with_unmap(BlockDriverState *bs)

{

    BlockDriverInfo bdi;

    if (bs->backing_hd || !(bs->open_flags & BDRV_O_UNMAP)) {

        return false;

    }

    if (bdrv_get_info(bs, &bdi) == 0) {

        return bdi.can_write_zeroes_with_unmap;

    }

    return false;

}


static uint32_t read_u32(uint8_t *data, size_t offset)

{

    return ((data[offset] << 24) | (data[offset + 1] << 16) |

	    (data[offset + 2] << 8) | data[offset + 3]);

}


static void check_breakpoint(CPUState *env, DisasContext *dc)

{

    CPUBreakpoint *bp;

    if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {

        TAILQ_FOREACH(bp, &env->breakpoints, entry) {

            if (bp->pc == dc->pc) {

                t_gen_raise_exception(dc, EXCP_DEBUG);

                dc->is_jmp = DISAS_UPDATE;

             }

        }

    }

}


static void dump_json_image_info(ImageInfo *info)

{

    QString *str;

    QObject *obj;

    Visitor *v = qmp_output_visitor_new(&obj);

    visit_type_ImageInfo(v, NULL, &info, &error_abort);

    visit_complete(v, &obj);

    str = qobject_to_json_pretty(obj);

    assert(str != NULL);

    printf("%s\n", qstring_get_str(str));

    qobject_decref(obj);

    visit_free(v);

    QDECREF(str);

}


static CharDriverState *qemu_chr_open_msmouse(const char *id,

                                              ChardevBackend *backend,

                                              ChardevReturn *ret,

                                              Error **errp)

{

    CharDriverState *chr;

    chr = qemu_chr_alloc();

    chr->chr_write = msmouse_chr_write;

    chr->chr_close = msmouse_chr_close;

    chr->explicit_be_open = true;

    qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse");

    return chr;

}


static int iscsi_refresh_limits(BlockDriverState *bs)

{

    IscsiLun *iscsilun = bs->opaque;

    /* We don't actually refresh here, but just return data queried in

     * iscsi_open(): iscsi targets don't change their limits. */

    if (iscsilun->lbp.lbpu || iscsilun->lbp.lbpws) {

        if (iscsilun->bl.max_unmap < 0xffffffff) {

            bs->bl.max_discard = sector_lun2qemu(iscsilun->bl.max_unmap,

                                                 iscsilun);

        }

        bs->bl.discard_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,

                                                   iscsilun);

        if (iscsilun->bl.max_ws_len < 0xffffffff) {

            bs->bl.max_write_zeroes = sector_lun2qemu(iscsilun->bl.max_ws_len,

                                                      iscsilun);

        }

        bs->bl.write_zeroes_alignment = sector_lun2qemu(iscsilun->bl.opt_unmap_gran,

                                                        iscsilun);

        bs->bl.opt_transfer_length = sector_lun2qemu(iscsilun->bl.opt_xfer_len,

                                                     iscsilun);

    }

    return 0;

}


yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,

                      const uint16_t *ubuf0, const uint16_t *ubuf1,

                      const uint16_t *vbuf0, const uint16_t *vbuf1,

                      const uint16_t *abuf0, uint8_t *dest, int dstW,

                      int uvalpha, enum PixelFormat dstFormat,

                      int flags, int y, enum PixelFormat target)

{

    const uint8_t * const d128 = dither_8x8_220[y & 7];

    uint8_t *g = c->table_gU[128] + c->table_gV[128];

    int i;

    for (i = 0; i < dstW - 7; i += 8) {

        int acc =    g[(buf0[i    ] >> 7) + d128[0]];

        acc += acc + g[(buf0[i + 1] >> 7) + d128[1]];

        acc += acc + g[(buf0[i + 2] >> 7) + d128[2]];

        acc += acc + g[(buf0[i + 3] >> 7) + d128[3]];

        acc += acc + g[(buf0[i + 4] >> 7) + d128[4]];

        acc += acc + g[(buf0[i + 5] >> 7) + d128[5]];

        acc += acc + g[(buf0[i + 6] >> 7) + d128[6]];

        acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];

        output_pixel(*dest++, acc);

    }

}


static int decode_cabac_mb_dqp( H264Context *h) {

    MpegEncContext * const s = &h->s;

    int mbn_xy;

    int   ctx = 0;

    int   val = 0;

    if( s->mb_x > 0 )

        mbn_xy = s->mb_x + s->mb_y*s->mb_stride - 1;

    else

        mbn_xy = s->mb_width - 1 + (s->mb_y-1)*s->mb_stride;

    if( h->last_qscale_diff != 0 )

        ctx++;

    while( get_cabac( &h->cabac, &h->cabac_state[60 + ctx] ) ) {

        if( ctx < 2 )

            ctx = 2;

        else

            ctx = 3;

        val++;

        if(val > 102) //prevent infinite loop

            return INT_MIN;

    }

    if( val&0x01 )

        return (val + 1)/2;

    else

        return -(val + 1)/2;

}


static void add_user_command(char *optarg)

{

    cmdline = g_realloc(cmdline, ++ncmdline * sizeof(char *));

    cmdline[ncmdline-1] = optarg;

}


bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev)

{

    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));

    VirtioBusState *vbus = VIRTIO_BUS(qbus);

    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(vbus);

    return !k->query_guest_notifiers ||

           k->query_guest_notifiers(qbus->parent) ||

           hdev->force;

}


static void pc_init_pci_1_3(QEMUMachineInitArgs *args)

{

    enable_compat_apic_id_mode();

    pc_sysfw_flash_vs_rom_bug_compatible = true;

    has_pvpanic = false;

    pc_init_pci(args);

}


static uint8_t get_sot(Jpeg2000DecoderContext *s, int n)

{

    Jpeg2000TilePart *tp;

    uint16_t Isot;

    uint32_t Psot;

    uint8_t TPsot;

    if (s->buf_end - s->buf < 4)

        return AVERROR(EINVAL);

    Isot = bytestream_get_be16(&s->buf);        // Isot

    if (Isot) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Not a DCINEMA JP2K file: more than one tile\n");

        return -1;

    }

    Psot  = bytestream_get_be32(&s->buf);       // Psot

    TPsot = bytestream_get_byte(&s->buf);       // TPsot

    /* Read TNSot but not used */

    bytestream_get_byte(&s->buf);               // TNsot

    tp             = s->tile[s->curtileno].tile_part + TPsot;

    tp->tile_index = Isot;

    tp->tp_len     = Psot;

    tp->tp_idx     = TPsot;

    /* Start of bit stream. Pointer to SOD marker

     * Check SOD marker is present. */

    if (JPEG2000_SOD == bytestream_get_be16(&s->buf))

        tp->tp_start_bstrm = s->buf;

    else {

        av_log(s->avctx, AV_LOG_ERROR, "SOD marker not found \n");

        return -1;

    }

    /* End address of bit stream =

     *     start address + (Psot - size of SOT HEADER(n)

     *     - size of SOT MARKER(2)  - size of SOD marker(2) */

    tp->tp_end_bstrm = s->buf + (tp->tp_len - n - 4);

    // set buffer pointer to end of tile part header

    s->buf = tp->tp_end_bstrm;

    return 0;

}


static int xa_probe(AVProbeData *p)

{

    switch(AV_RL32(p->buf)) {

    case XA00_TAG:

    case XAI0_TAG:

    case XAJ0_TAG:

        return AVPROBE_SCORE_MAX;

    }

    return 0;

}


static void qemu_chr_fe_write_log(CharDriverState *s,

                                  const uint8_t *buf, size_t len)

{

    size_t done = 0;

    ssize_t ret;

    if (s->logfd < 0) {

        return;

    }

    while (done < len) {

        do {

            ret = write(s->logfd, buf + done, len - done);

            if (ret == -1 && errno == EAGAIN) {

                g_usleep(100);

            }

        } while (ret == -1 && errno == EAGAIN);

        if (ret <= 0) {

            return;

        }

        done += ret;

    }

}


void av_vlog(void* avcl, int level, const char *fmt, va_list vl)

{

    if(av_log_callback)

        av_log_callback(avcl, level, fmt, vl);

}


void kvm_setup_guest_memory(void *start, size_t size)

{

    if (!kvm_has_sync_mmu()) {

#ifdef MADV_DONTFORK

        int ret = madvise(start, size, MADV_DONTFORK);

        if (ret) {

            perror("madvice");

            exit(1);

        }

#else

        fprintf(stderr,

                "Need MADV_DONTFORK in absence of synchronous KVM MMU\n");

        exit(1);

#endif

    }

}


static int read_packet(AVFormatContext *s, AVPacket *pkt)

{

    ASSContext *ass = s->priv_data;

    uint8_t *p, *end;

    if (ass->event_index >= ass->event_count)

        return AVERROR(EIO);

    p = ass->event[ass->event_index];

    end = strchr(p, '\n');

    av_new_packet(pkt, end ? end - p + 1 : strlen(p));

    pkt->flags |= AV_PKT_FLAG_KEY;

    pkt->pos    = p - ass->event_buffer + s->streams[0]->codec->extradata_size;

    pkt->pts    = pkt->dts = get_pts(p);

    memcpy(pkt->data, p, pkt->size);

    ass->event_index++;

    return 0;

}


static av_cold int xwd_encode_close(AVCodecContext *avctx)

{

    av_freep(&avctx->coded_frame);

    return 0;

}


av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx,

                                 unsigned high_bit_depth)

{

    int cpu_flags = av_get_cpu_flags();

    if (INLINE_MMX(cpu_flags)) {

        if (!high_bit_depth &&

            avctx->lowres == 0 &&

            (avctx->idct_algo == FF_IDCT_AUTO ||

             avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||

             avctx->idct_algo == FF_IDCT_SIMPLEMMX)) {

                c->idct_put  = ff_simple_idct_put_mmx;

                c->idct_add  = ff_simple_idct_add_mmx;

                c->idct      = ff_simple_idct_mmx;

                c->perm_type = FF_IDCT_PERM_SIMPLE;

        }

    }

    if (EXTERNAL_MMX(cpu_flags)) {

        c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;

        c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;

        c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;

    }

    if (EXTERNAL_SSE2(cpu_flags)) {

        c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_sse2;

        c->put_pixels_clamped        = ff_put_pixels_clamped_sse2;

        c->add_pixels_clamped        = ff_add_pixels_clamped_sse2;

    }

    if (ARCH_X86_64 &&

        avctx->bits_per_raw_sample == 10 && avctx->lowres == 0 &&

        (avctx->idct_algo == FF_IDCT_AUTO ||

         avctx->idct_algo == FF_IDCT_SIMPLEAUTO ||

         avctx->idct_algo == FF_IDCT_SIMPLE)) {

        if (EXTERNAL_SSE2(cpu_flags)) {

            c->idct_put  = ff_simple_idct10_put_sse2;

            c->idct_add  = NULL;

            c->idct      = ff_simple_idct10_sse2;

            c->perm_type = FF_IDCT_PERM_TRANSPOSE;

        }

        if (EXTERNAL_AVX(cpu_flags)) {

            c->idct_put  = ff_simple_idct10_put_avx;

            c->idct_add  = NULL;

            c->idct      = ff_simple_idct10_avx;

            c->perm_type = FF_IDCT_PERM_TRANSPOSE;

        }

    }

}


static void send_msg(IPMIBmcSim *ibs,

                     uint8_t *cmd, unsigned int cmd_len,

                     uint8_t *rsp, unsigned int *rsp_len,

                     unsigned int max_rsp_len)

{

    IPMIInterface *s = ibs->parent.intf;

    IPMIInterfaceClass *k = IPMI_INTERFACE_GET_CLASS(s);

    IPMIRcvBufEntry *msg;

    uint8_t *buf;

    uint8_t netfn, rqLun, rsLun, rqSeq;

    IPMI_CHECK_CMD_LEN(3);

    if (cmd[2] != 0) {

        /* We only handle channel 0 with no options */

        rsp[2] = IPMI_CC_INVALID_DATA_FIELD;

        return;

    }

    IPMI_CHECK_CMD_LEN(10);

    if (cmd[3] != 0x40) {

        /* We only emulate a MC at address 0x40. */

        rsp[2] = 0x83; /* NAK on write */

        return;

    }

    cmd += 3; /* Skip the header. */

    cmd_len -= 3;

    /*

     * At this point we "send" the message successfully.  Any error will

     * be returned in the response.

     */

    if (ipmb_checksum(cmd, cmd_len, 0) != 0 ||

        cmd[3] != 0x20) { /* Improper response address */

        return; /* No response */

    }

    netfn = cmd[1] >> 2;

    rqLun = cmd[4] & 0x3;

    rsLun = cmd[1] & 0x3;

    rqSeq = cmd[4] >> 2;

    if (rqLun != 2) {

        /* We only support LUN 2 coming back to us. */

        return;

    }

    msg = g_malloc(sizeof(*msg));

    msg->buf[0] = ((netfn | 1) << 2) | rqLun; /* NetFN, and make a response */

    msg->buf[1] = ipmb_checksum(msg->buf, 1, 0);

    msg->buf[2] = cmd[0]; /* rsSA */

    msg->buf[3] = (rqSeq << 2) | rsLun;

    msg->buf[4] = cmd[5]; /* Cmd */

    msg->buf[5] = 0; /* Completion Code */

    msg->len = 6;

    if ((cmd[1] >> 2) != IPMI_NETFN_APP || cmd[5] != IPMI_CMD_GET_DEVICE_ID) {

        /* Not a command we handle. */

        msg->buf[5] = IPMI_CC_INVALID_CMD;

        goto end_msg;

    }

    buf = msg->buf + msg->len; /* After the CC */

    buf[0] = 0;

    buf[1] = 0;

    buf[2] = 0;

    buf[3] = 0;

    buf[4] = 0x51;

    buf[5] = 0;

    buf[6] = 0;

    buf[7] = 0;

    buf[8] = 0;

    buf[9] = 0;

    buf[10] = 0;

    msg->len += 11;

 end_msg:

    msg->buf[msg->len] = ipmb_checksum(msg->buf, msg->len, 0);

    msg->len++;

    qemu_mutex_lock(&ibs->lock);

    QTAILQ_INSERT_TAIL(&ibs->rcvbufs, msg, entry);

    ibs->msg_flags |= IPMI_BMC_MSG_FLAG_RCV_MSG_QUEUE;

    k->set_atn(s, 1, attn_irq_enabled(ibs));

    qemu_mutex_unlock(&ibs->lock);

}


static void render_slice(Vp3DecodeContext *s, int slice)

{

    int x, y, i, j, fragment;

    LOCAL_ALIGNED_16(DCTELEM, block, [64]);

    int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;

    int motion_halfpel_index;

    uint8_t *motion_source;

    int plane, first_pixel;

    if (slice >= s->c_superblock_height)

        return;

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

        uint8_t *output_plane = s->current_frame.data    [plane] + s->data_offset[plane];

        uint8_t *  last_plane = s->   last_frame.data    [plane] + s->data_offset[plane];

        uint8_t *golden_plane = s-> golden_frame.data    [plane] + s->data_offset[plane];

        int stride            = s->current_frame.linesize[plane];

        int plane_width       = s->width  >> (plane && s->chroma_x_shift);

        int plane_height      = s->height >> (plane && s->chroma_y_shift);

        int8_t (*motion_val)[2] = s->motion_val[!!plane];

        int sb_x, sb_y        = slice << (!plane && s->chroma_y_shift);

        int slice_height      = sb_y + 1 + (!plane && s->chroma_y_shift);

        int slice_width       = plane ? s->c_superblock_width : s->y_superblock_width;

        int fragment_width    = s->fragment_width[!!plane];

        int fragment_height   = s->fragment_height[!!plane];

        int fragment_start    = s->fragment_start[plane];

        int do_await          = !plane && HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME);

        if (!s->flipped_image) stride = -stride;

        if (CONFIG_GRAY && plane && (s->avctx->flags & CODEC_FLAG_GRAY))

            continue;

        /* for each superblock row in the slice (both of them)... */

        for (; sb_y < slice_height; sb_y++) {

            /* for each superblock in a row... */

            for (sb_x = 0; sb_x < slice_width; sb_x++) {

                /* for each block in a superblock... */

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

                    x = 4*sb_x + hilbert_offset[j][0];

                    y = 4*sb_y + hilbert_offset[j][1];

                    fragment = y*fragment_width + x;

                    i = fragment_start + fragment;

                    // bounds check

                    if (x >= fragment_width || y >= fragment_height)

                        continue;

                first_pixel = 8*y*stride + 8*x;

                if (do_await && s->all_fragments[i].coding_method != MODE_INTRA)

                    await_reference_row(s, &s->all_fragments[i], motion_val[fragment][1], (16*y) >> s->chroma_y_shift);

                /* transform if this block was coded */

                if (s->all_fragments[i].coding_method != MODE_COPY) {

                    if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) ||

                        (s->all_fragments[i].coding_method == MODE_GOLDEN_MV))

                        motion_source= golden_plane;

                    else

                        motion_source= last_plane;

                    motion_source += first_pixel;

                    motion_halfpel_index = 0;

                    /* sort out the motion vector if this fragment is coded

                     * using a motion vector method */

                    if ((s->all_fragments[i].coding_method > MODE_INTRA) &&

                        (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) {

                        int src_x, src_y;

                        motion_x = motion_val[fragment][0];

                        motion_y = motion_val[fragment][1];

                        src_x= (motion_x>>1) + 8*x;

                        src_y= (motion_y>>1) + 8*y;

                        motion_halfpel_index = motion_x & 0x01;

                        motion_source += (motion_x >> 1);

                        motion_halfpel_index |= (motion_y & 0x01) << 1;

                        motion_source += ((motion_y >> 1) * stride);

                        if(src_x<0 || src_y<0 || src_x + 9 >= plane_width || src_y + 9 >= plane_height){

                            uint8_t *temp= s->edge_emu_buffer;

                            if(stride<0) temp -= 8*stride;

                            s->dsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);

                            motion_source= temp;

                        }

                    }

                    /* first, take care of copying a block from either the

                     * previous or the golden frame */

                    if (s->all_fragments[i].coding_method != MODE_INTRA) {

                        /* Note, it is possible to implement all MC cases with

                           put_no_rnd_pixels_l2 which would look more like the

                           VP3 source but this would be slower as

                           put_no_rnd_pixels_tab is better optimzed */

                        if(motion_halfpel_index != 3){

                            s->dsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](

                                output_plane + first_pixel,

                                motion_source, stride, 8);

                        }else{

                            int d= (motion_x ^ motion_y)>>31; // d is 0 if motion_x and _y have the same sign, else -1

                            s->dsp.put_no_rnd_pixels_l2[1](

                                output_plane + first_pixel,

                                motion_source - d,

                                motion_source + stride + 1 + d,

                                stride, 8);

                        }

                    }

                        s->dsp.clear_block(block);

                    /* invert DCT and place (or add) in final output */

                    if (s->all_fragments[i].coding_method == MODE_INTRA) {

                        int index;

                        index = vp3_dequant(s, s->all_fragments + i, plane, 0, block);

                        if (index > 63)

                            continue;

                        if(s->avctx->idct_algo!=FF_IDCT_VP3)

                            block[0] += 128<<3;

                        s->dsp.idct_put(

                            output_plane + first_pixel,

                            stride,

                            block);

                    } else {

                        int index = vp3_dequant(s, s->all_fragments + i, plane, 1, block);

                        if (index > 63)

                            continue;

                        if (index > 0) {

                        s->dsp.idct_add(

                            output_plane + first_pixel,

                            stride,

                            block);

                        } else {

                            s->dsp.vp3_idct_dc_add(output_plane + first_pixel, stride, block);

                        }

                    }

                } else {

                    /* copy directly from the previous frame */

                    s->dsp.put_pixels_tab[1][0](

                        output_plane + first_pixel,

                        last_plane + first_pixel,

                        stride, 8);

                }

                }

            }

            // Filter up to the last row in the superblock row

            if (!s->skip_loop_filter)

                apply_loop_filter(s, plane, 4*sb_y - !!sb_y, FFMIN(4*sb_y+3, fragment_height-1));

        }

    }

     /* this looks like a good place for slice dispatch... */

     /* algorithm:

      *   if (slice == s->macroblock_height - 1)

      *     dispatch (both last slice & 2nd-to-last slice);

      *   else if (slice > 0)

      *     dispatch (slice - 1);

      */

    vp3_draw_horiz_band(s, FFMIN((32 << s->chroma_y_shift) * (slice + 1) -16, s->height-16));

}


static void disas_xtensa_insn(DisasContext *dc)

{

#define HAS_OPTION(opt) do { \

        if (!option_enabled(dc, opt)) { \

            qemu_log("Option %d is not enabled %s:%d\n", \

                    (opt), __FILE__, __LINE__); \

            goto invalid_opcode; \

        } \

    } while (0)

#ifdef TARGET_WORDS_BIGENDIAN

#define OP0 (((b0) & 0xf0) >> 4)

#define OP1 (((b2) & 0xf0) >> 4)

#define OP2 ((b2) & 0xf)

#define RRR_R ((b1) & 0xf)

#define RRR_S (((b1) & 0xf0) >> 4)

#define RRR_T ((b0) & 0xf)

#else

#define OP0 (((b0) & 0xf))

#define OP1 (((b2) & 0xf))

#define OP2 (((b2) & 0xf0) >> 4)

#define RRR_R (((b1) & 0xf0) >> 4)

#define RRR_S (((b1) & 0xf))

#define RRR_T (((b0) & 0xf0) >> 4)

#endif

#define RRRN_R RRR_R

#define RRRN_S RRR_S

#define RRRN_T RRR_T

#define RRI8_R RRR_R

#define RRI8_S RRR_S

#define RRI8_T RRR_T

#define RRI8_IMM8 (b2)

#define RRI8_IMM8_SE ((((b2) & 0x80) ? 0xffffff00 : 0) | RRI8_IMM8)

#ifdef TARGET_WORDS_BIGENDIAN

#define RI16_IMM16 (((b1) << 8) | (b2))

#else

#define RI16_IMM16 (((b2) << 8) | (b1))

#endif

#ifdef TARGET_WORDS_BIGENDIAN

#define CALL_N (((b0) & 0xc) >> 2)

#define CALL_OFFSET ((((b0) & 0x3) << 16) | ((b1) << 8) | (b2))

#else

#define CALL_N (((b0) & 0x30) >> 4)

#define CALL_OFFSET ((((b0) & 0xc0) >> 6) | ((b1) << 2) | ((b2) << 10))

#endif

#define CALL_OFFSET_SE \

    (((CALL_OFFSET & 0x20000) ? 0xfffc0000 : 0) | CALL_OFFSET)

#define CALLX_N CALL_N

#ifdef TARGET_WORDS_BIGENDIAN

#define CALLX_M ((b0) & 0x3)

#else

#define CALLX_M (((b0) & 0xc0) >> 6)

#endif

#define CALLX_S RRR_S

#define BRI12_M CALLX_M

#define BRI12_S RRR_S

#ifdef TARGET_WORDS_BIGENDIAN

#define BRI12_IMM12 ((((b1) & 0xf) << 8) | (b2))

#else

#define BRI12_IMM12 ((((b1) & 0xf0) >> 4) | ((b2) << 4))

#endif

#define BRI12_IMM12_SE (((BRI12_IMM12 & 0x800) ? 0xfffff000 : 0) | BRI12_IMM12)

#define BRI8_M BRI12_M

#define BRI8_R RRI8_R

#define BRI8_S RRI8_S

#define BRI8_IMM8 RRI8_IMM8

#define BRI8_IMM8_SE RRI8_IMM8_SE

#define RSR_SR (b1)

    uint8_t b0 = ldub_code(dc->pc);

    uint8_t b1 = ldub_code(dc->pc + 1);

    uint8_t b2 = ldub_code(dc->pc + 2);

    static const uint32_t B4CONST[] = {

        0xffffffff, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256

    };

    static const uint32_t B4CONSTU[] = {

        32768, 65536, 2, 3, 4, 5, 6, 7, 8, 10, 12, 16, 32, 64, 128, 256

    };

    if (OP0 >= 8) {

        dc->next_pc = dc->pc + 2;

        HAS_OPTION(XTENSA_OPTION_CODE_DENSITY);

    } else {

        dc->next_pc = dc->pc + 3;

    }

    switch (OP0) {

    case 0: /*QRST*/

        switch (OP1) {

        case 0: /*RST0*/

            switch (OP2) {

            case 0: /*ST0*/

                if ((RRR_R & 0xc) == 0x8) {

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                }

                switch (RRR_R) {

                case 0: /*SNM0*/

                    switch (CALLX_M) {

                    case 0: /*ILL*/

                        break;

                    case 1: /*reserved*/

                        break;

                    case 2: /*JR*/

                        switch (CALLX_N) {

                        case 0: /*RET*/

                        case 2: /*JX*/

                            gen_jump(dc, cpu_R[CALLX_S]);

                            break;

                        case 1: /*RETWw*/

                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                            break;

                        case 3: /*reserved*/

                            break;

                        }

                        break;

                    case 3: /*CALLX*/

                        switch (CALLX_N) {

                        case 0: /*CALLX0*/

                            {

                                TCGv_i32 tmp = tcg_temp_new_i32();

                                tcg_gen_mov_i32(tmp, cpu_R[CALLX_S]);

                                tcg_gen_movi_i32(cpu_R[0], dc->next_pc);

                                gen_jump(dc, tmp);

                                tcg_temp_free(tmp);

                            }

                            break;

                        case 1: /*CALLX4w*/

                        case 2: /*CALLX8w*/

                        case 3: /*CALLX12w*/

                            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                            break;

                        }

                        break;

                    }

                    break;

                case 1: /*MOVSPw*/

                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                    break;

                case 2: /*SYNC*/

                    break;

                case 3:

                    break;

                }

                break;

            case 1: /*AND*/

                tcg_gen_and_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 2: /*OR*/

                tcg_gen_or_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 3: /*XOR*/

                tcg_gen_xor_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 4: /*ST1*/

                switch (RRR_R) {

                case 0: /*SSR*/

                    gen_right_shift_sar(dc, cpu_R[RRR_S]);

                    break;

                case 1: /*SSL*/

                    gen_left_shift_sar(dc, cpu_R[RRR_S]);

                    break;

                case 2: /*SSA8L*/

                    {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);

                        gen_right_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 3: /*SSA8B*/

                    {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], 3);

                        gen_left_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 4: /*SSAI*/

                    {

                        TCGv_i32 tmp = tcg_const_i32(

                                RRR_S | ((RRR_T & 1) << 4));

                        gen_right_shift_sar(dc, tmp);

                        tcg_temp_free(tmp);

                    }

                    break;

                case 6: /*RER*/

                    break;

                case 7: /*WER*/

                    break;

                case 8: /*ROTWw*/

                    HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                    break;

                case 14: /*NSAu*/

                    HAS_OPTION(XTENSA_OPTION_MISC_OP);

                    gen_helper_nsa(cpu_R[RRR_T], cpu_R[RRR_S]);

                    break;

                case 15: /*NSAUu*/

                    HAS_OPTION(XTENSA_OPTION_MISC_OP);

                    gen_helper_nsau(cpu_R[RRR_T], cpu_R[RRR_S]);

                    break;

                default: /*reserved*/

                    break;

                }

                break;

            case 5: /*TLB*/

                break;

            case 6: /*RT0*/

                switch (RRR_S) {

                case 0: /*NEG*/

                    tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                    break;

                case 1: /*ABS*/

                    {

                        int label = gen_new_label();

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                        tcg_gen_brcondi_i32(

                                TCG_COND_GE, cpu_R[RRR_R], 0, label);

                        tcg_gen_neg_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                        gen_set_label(label);

                    }

                    break;

                default: /*reserved*/

                    break;

                }

                break;

            case 7: /*reserved*/

                break;

            case 8: /*ADD*/

                tcg_gen_add_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 9: /*ADD**/

            case 10:

            case 11:

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 8);

                    tcg_gen_add_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);

                    tcg_temp_free(tmp);

                }

                break;

            case 12: /*SUB*/

                tcg_gen_sub_i32(cpu_R[RRR_R], cpu_R[RRR_S], cpu_R[RRR_T]);

                break;

            case 13: /*SUB**/

            case 14:

            case 15:

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_shli_i32(tmp, cpu_R[RRR_S], OP2 - 12);

                    tcg_gen_sub_i32(cpu_R[RRR_R], tmp, cpu_R[RRR_T]);

                    tcg_temp_free(tmp);

                }

                break;

            }

            break;

        case 1: /*RST1*/

            switch (OP2) {

            case 0: /*SLLI*/

            case 1:

                tcg_gen_shli_i32(cpu_R[RRR_R], cpu_R[RRR_S],

                        32 - (RRR_T | ((OP2 & 1) << 4)));

                break;

            case 2: /*SRAI*/

            case 3:

                tcg_gen_sari_i32(cpu_R[RRR_R], cpu_R[RRR_T],

                        RRR_S | ((OP2 & 1) << 4));

                break;

            case 4: /*SRLI*/

                tcg_gen_shri_i32(cpu_R[RRR_R], cpu_R[RRR_T], RRR_S);

                break;

            case 6: /*XSR*/

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);

                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);

                    gen_wsr(dc, RSR_SR, tmp);

                    tcg_temp_free(tmp);

                }

                break;

                /*

                 * Note: 64 bit ops are used here solely because SAR values

                 * have range 0..63

                 */

#define gen_shift_reg(cmd, reg) do { \

                    TCGv_i64 tmp = tcg_temp_new_i64(); \

                    tcg_gen_extu_i32_i64(tmp, reg); \

                    tcg_gen_##cmd##_i64(v, v, tmp); \

                    tcg_gen_trunc_i64_i32(cpu_R[RRR_R], v); \

                    tcg_temp_free_i64(v); \

                    tcg_temp_free_i64(tmp); \

                } while (0)

#define gen_shift(cmd) gen_shift_reg(cmd, cpu_SR[SAR])

            case 8: /*SRC*/

                {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_concat_i32_i64(v, cpu_R[RRR_T], cpu_R[RRR_S]);

                    gen_shift(shr);

                }

                break;

            case 9: /*SRL*/

                if (dc->sar_5bit) {

                    tcg_gen_shr_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_T]);

                    gen_shift(shr);

                }

                break;

            case 10: /*SLL*/

                if (dc->sar_m32_5bit) {

                    tcg_gen_shl_i32(cpu_R[RRR_R], cpu_R[RRR_S], dc->sar_m32);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    TCGv_i32 s = tcg_const_i32(32);

                    tcg_gen_sub_i32(s, s, cpu_SR[SAR]);

                    tcg_gen_andi_i32(s, s, 0x3f);

                    tcg_gen_extu_i32_i64(v, cpu_R[RRR_S]);

                    gen_shift_reg(shl, s);

                    tcg_temp_free(s);

                }

                break;

            case 11: /*SRA*/

                if (dc->sar_5bit) {

                    tcg_gen_sar_i32(cpu_R[RRR_R], cpu_R[RRR_T], cpu_SR[SAR]);

                } else {

                    TCGv_i64 v = tcg_temp_new_i64();

                    tcg_gen_ext_i32_i64(v, cpu_R[RRR_T]);

                    gen_shift(sar);

                }

                break;

#undef gen_shift

#undef gen_shift_reg

            case 12: /*MUL16U*/

                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);

                {

                    TCGv_i32 v1 = tcg_temp_new_i32();

                    TCGv_i32 v2 = tcg_temp_new_i32();

                    tcg_gen_ext16u_i32(v1, cpu_R[RRR_S]);

                    tcg_gen_ext16u_i32(v2, cpu_R[RRR_T]);

                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);

                    tcg_temp_free(v2);

                    tcg_temp_free(v1);

                }

                break;

            case 13: /*MUL16S*/

                HAS_OPTION(XTENSA_OPTION_16_BIT_IMUL);

                {

                    TCGv_i32 v1 = tcg_temp_new_i32();

                    TCGv_i32 v2 = tcg_temp_new_i32();

                    tcg_gen_ext16s_i32(v1, cpu_R[RRR_S]);

                    tcg_gen_ext16s_i32(v2, cpu_R[RRR_T]);

                    tcg_gen_mul_i32(cpu_R[RRR_R], v1, v2);

                    tcg_temp_free(v2);

                    tcg_temp_free(v1);

                }

                break;

            default: /*reserved*/

                break;

            }

            break;

        case 2: /*RST2*/

            break;

        case 3: /*RST3*/

            switch (OP2) {

            case 0: /*RSR*/

                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);

                break;

            case 1: /*WSR*/

                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);

                break;

            case 2: /*SEXTu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP);

                {

                    int shift = 24 - RRR_T;

                    if (shift == 24) {

                        tcg_gen_ext8s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    } else if (shift == 16) {

                        tcg_gen_ext16s_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    } else {

                        TCGv_i32 tmp = tcg_temp_new_i32();

                        tcg_gen_shli_i32(tmp, cpu_R[RRR_S], shift);

                        tcg_gen_sari_i32(cpu_R[RRR_R], tmp, shift);

                        tcg_temp_free(tmp);

                    }

                }

                break;

            case 3: /*CLAMPSu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP);

                {

                    TCGv_i32 tmp1 = tcg_temp_new_i32();

                    TCGv_i32 tmp2 = tcg_temp_new_i32();

                    int label = gen_new_label();

                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 24 - RRR_T);

                    tcg_gen_xor_i32(tmp2, tmp1, cpu_R[RRR_S]);

                    tcg_gen_andi_i32(tmp2, tmp2, 0xffffffff << (RRR_T + 7));

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    tcg_gen_brcondi_i32(TCG_COND_EQ, tmp2, 0, label);

                    tcg_gen_sari_i32(tmp1, cpu_R[RRR_S], 31);

                    tcg_gen_xori_i32(cpu_R[RRR_R], tmp1,

                            0xffffffff >> (25 - RRR_T));

                    gen_set_label(label);

                    tcg_temp_free(tmp1);

                    tcg_temp_free(tmp2);

                }

                break;

            case 4: /*MINu*/

            case 5: /*MAXu*/

            case 6: /*MINUu*/

            case 7: /*MAXUu*/

                HAS_OPTION(XTENSA_OPTION_MISC_OP);

                {

                    static const TCGCond cond[] = {

                        TCG_COND_LE,

                        TCG_COND_GE,

                        TCG_COND_LEU,

                        TCG_COND_GEU

                    };

                    int label = gen_new_label();

                    if (RRR_R != RRR_T) {

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                        tcg_gen_brcond_i32(cond[OP2 - 4],

                                cpu_R[RRR_S], cpu_R[RRR_T], label);

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_T]);

                    } else {

                        tcg_gen_brcond_i32(cond[OP2 - 4],

                                cpu_R[RRR_T], cpu_R[RRR_S], label);

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    }

                    gen_set_label(label);

                }

                break;

            case 8: /*MOVEQZ*/

            case 9: /*MOVNEZ*/

            case 10: /*MOVLTZ*/

            case 11: /*MOVGEZ*/

                {

                    static const TCGCond cond[] = {

                        TCG_COND_NE,

                        TCG_COND_EQ,

                        TCG_COND_GE,

                        TCG_COND_LT

                    };

                    int label = gen_new_label();

                    tcg_gen_brcondi_i32(cond[OP2 - 8], cpu_R[RRR_T], 0, label);

                    tcg_gen_mov_i32(cpu_R[RRR_R], cpu_R[RRR_S]);

                    gen_set_label(label);

                }

                break;

            case 12: /*MOVFp*/

                HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                break;

            case 13: /*MOVTp*/

                HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                break;

            case 14: /*RUR*/

                {

                    int st = (RRR_S << 4) + RRR_T;

                    if (uregnames[st]) {

                        tcg_gen_mov_i32(cpu_R[RRR_R], cpu_UR[st]);

                    } else {

                        qemu_log("RUR %d not implemented, ", st);

                    }

                }

                break;

            case 15: /*WUR*/

                {

                    if (uregnames[RSR_SR]) {

                        tcg_gen_mov_i32(cpu_UR[RSR_SR], cpu_R[RRR_T]);

                    } else {

                        qemu_log("WUR %d not implemented, ", RSR_SR);

                    }

                }

                break;

            }

            break;

        case 4: /*EXTUI*/

        case 5:

            {

                int shiftimm = RRR_S | (OP1 << 4);

                int maskimm = (1 << (OP2 + 1)) - 1;

                TCGv_i32 tmp = tcg_temp_new_i32();

                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);

                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);

                tcg_temp_free(tmp);

            }

            break;

        case 6: /*CUST0*/

            break;

        case 7: /*CUST1*/

            break;

        case 8: /*LSCXp*/

            HAS_OPTION(XTENSA_OPTION_COPROCESSOR);

            break;

        case 9: /*LSC4*/

            break;

        case 10: /*FP0*/

            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

            break;

        case 11: /*FP1*/

            HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);

            break;

        default: /*reserved*/

            break;

        }

        break;

    case 1: /*L32R*/

        {

            TCGv_i32 tmp = tcg_const_i32(

                    (0xfffc0000 | (RI16_IMM16 << 2)) +

                    ((dc->pc + 3) & ~3));

            /* no ext L32R */

            tcg_gen_qemu_ld32u(cpu_R[RRR_T], tmp, 0);

            tcg_temp_free(tmp);

        }

        break;

    case 2: /*LSAI*/

#define gen_load_store(type, shift) do { \

            TCGv_i32 addr = tcg_temp_new_i32(); \

            tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << shift); \

            tcg_gen_qemu_##type(cpu_R[RRI8_T], addr, 0); \

            tcg_temp_free(addr); \

        } while (0)

        switch (RRI8_R) {

        case 0: /*L8UI*/

            gen_load_store(ld8u, 0);

            break;

        case 1: /*L16UI*/

            gen_load_store(ld16u, 1);

            break;

        case 2: /*L32I*/

            gen_load_store(ld32u, 2);

            break;

        case 4: /*S8I*/

            gen_load_store(st8, 0);

            break;

        case 5: /*S16I*/

            gen_load_store(st16, 1);

            break;

        case 6: /*S32I*/

            gen_load_store(st32, 2);

            break;

        case 7: /*CACHEc*/

            break;

        case 9: /*L16SI*/

            gen_load_store(ld16s, 1);

            break;

        case 10: /*MOVI*/

            tcg_gen_movi_i32(cpu_R[RRI8_T],

                    RRI8_IMM8 | (RRI8_S << 8) |

                    ((RRI8_S & 0x8) ? 0xfffff000 : 0));

            break;

        case 11: /*L32AIy*/

            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);

            gen_load_store(ld32u, 2); /*TODO acquire?*/

            break;

        case 12: /*ADDI*/

            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE);

            break;

        case 13: /*ADDMI*/

            tcg_gen_addi_i32(cpu_R[RRI8_T], cpu_R[RRI8_S], RRI8_IMM8_SE << 8);

            break;

        case 14: /*S32C1Iy*/

            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);

            {

                int label = gen_new_label();

                TCGv_i32 tmp = tcg_temp_local_new_i32();

                TCGv_i32 addr = tcg_temp_local_new_i32();

                tcg_gen_mov_i32(tmp, cpu_R[RRI8_T]);

                tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);

                tcg_gen_qemu_ld32u(cpu_R[RRI8_T], addr, 0);

                tcg_gen_brcond_i32(TCG_COND_NE, cpu_R[RRI8_T],

                        cpu_SR[SCOMPARE1], label);

                tcg_gen_qemu_st32(tmp, addr, 0);

                gen_set_label(label);

                tcg_temp_free(addr);

                tcg_temp_free(tmp);

            }

            break;

        case 15: /*S32RIy*/

            HAS_OPTION(XTENSA_OPTION_MP_SYNCHRO);

            gen_load_store(st32, 2); /*TODO release?*/

            break;

        default: /*reserved*/

            break;

        }

        break;

#undef gen_load_store

    case 3: /*LSCIp*/

        HAS_OPTION(XTENSA_OPTION_COPROCESSOR);

        break;

    case 4: /*MAC16d*/

        HAS_OPTION(XTENSA_OPTION_MAC16);

        break;

    case 5: /*CALLN*/

        switch (CALL_N) {

        case 0: /*CALL0*/

            tcg_gen_movi_i32(cpu_R[0], dc->next_pc);

            gen_jumpi(dc, (dc->pc & ~3) + (CALL_OFFSET_SE << 2) + 4, 0);

            break;

        case 1: /*CALL4w*/

        case 2: /*CALL8w*/

        case 3: /*CALL12w*/

            HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

            break;

        }

        break;

    case 6: /*SI*/

        switch (CALL_N) {

        case 0: /*J*/

            gen_jumpi(dc, dc->pc + 4 + CALL_OFFSET_SE, 0);

            break;

        case 1: /*BZ*/

            {

                static const TCGCond cond[] = {

                    TCG_COND_EQ, /*BEQZ*/

                    TCG_COND_NE, /*BNEZ*/

                    TCG_COND_LT, /*BLTZ*/

                    TCG_COND_GE, /*BGEZ*/

                };

                gen_brcondi(dc, cond[BRI12_M & 3], cpu_R[BRI12_S], 0,

                        4 + BRI12_IMM12_SE);

            }

            break;

        case 2: /*BI0*/

            {

                static const TCGCond cond[] = {

                    TCG_COND_EQ, /*BEQI*/

                    TCG_COND_NE, /*BNEI*/

                    TCG_COND_LT, /*BLTI*/

                    TCG_COND_GE, /*BGEI*/

                };

                gen_brcondi(dc, cond[BRI8_M & 3],

                        cpu_R[BRI8_S], B4CONST[BRI8_R], 4 + BRI8_IMM8_SE);

            }

            break;

        case 3: /*BI1*/

            switch (BRI8_M) {

            case 0: /*ENTRYw*/

                HAS_OPTION(XTENSA_OPTION_WINDOWED_REGISTER);

                break;

            case 1: /*B1*/

                switch (BRI8_R) {

                case 0: /*BFp*/

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                    break;

                case 1: /*BTp*/

                    HAS_OPTION(XTENSA_OPTION_BOOLEAN);

                    break;

                case 8: /*LOOP*/

                    break;

                case 9: /*LOOPNEZ*/

                    break;

                case 10: /*LOOPGTZ*/

                    break;

                default: /*reserved*/

                    break;

                }

                break;

            case 2: /*BLTUI*/

            case 3: /*BGEUI*/

                gen_brcondi(dc, BRI8_M == 2 ? TCG_COND_LTU : TCG_COND_GEU,

                        cpu_R[BRI8_S], B4CONSTU[BRI8_R], 4 + BRI8_IMM8_SE);

                break;

            }

            break;

        }

        break;

    case 7: /*B*/

        {

            TCGCond eq_ne = (RRI8_R & 8) ? TCG_COND_NE : TCG_COND_EQ;

            switch (RRI8_R & 7) {

            case 0: /*BNONE*/ /*BANY*/

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            case 1: /*BEQ*/ /*BNE*/

            case 2: /*BLT*/ /*BGE*/

            case 3: /*BLTU*/ /*BGEU*/

                {

                    static const TCGCond cond[] = {

                        [1] = TCG_COND_EQ,

                        [2] = TCG_COND_LT,

                        [3] = TCG_COND_LTU,

                        [9] = TCG_COND_NE,

                        [10] = TCG_COND_GE,

                        [11] = TCG_COND_GEU,

                    };

                    gen_brcond(dc, cond[RRI8_R], cpu_R[RRI8_S], cpu_R[RRI8_T],

                            4 + RRI8_IMM8_SE);

                }

                break;

            case 4: /*BALL*/ /*BNALL*/

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], cpu_R[RRI8_T]);

                    gen_brcond(dc, eq_ne, tmp, cpu_R[RRI8_T],

                            4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            case 5: /*BBC*/ /*BBS*/

                {

                    TCGv_i32 bit = tcg_const_i32(1);

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_T], 0x1f);

                    tcg_gen_shl_i32(bit, bit, tmp);

                    tcg_gen_and_i32(tmp, cpu_R[RRI8_S], bit);

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                    tcg_temp_free(bit);

                }

                break;

            case 6: /*BBCI*/ /*BBSI*/

            case 7:

                {

                    TCGv_i32 tmp = tcg_temp_new_i32();

                    tcg_gen_andi_i32(tmp, cpu_R[RRI8_S],

                            1 << (((RRI8_R & 1) << 4) | RRI8_T));

                    gen_brcondi(dc, eq_ne, tmp, 0, 4 + RRI8_IMM8_SE);

                    tcg_temp_free(tmp);

                }

                break;

            }

        }

        break;

#define gen_narrow_load_store(type) do { \

            TCGv_i32 addr = tcg_temp_new_i32(); \

            tcg_gen_addi_i32(addr, cpu_R[RRRN_S], RRRN_R << 2); \

            tcg_gen_qemu_##type(cpu_R[RRRN_T], addr, 0); \

            tcg_temp_free(addr); \

        } while (0)

    case 8: /*L32I.Nn*/

        gen_narrow_load_store(ld32u);

        break;

    case 9: /*S32I.Nn*/

        gen_narrow_load_store(st32);

        break;

#undef gen_narrow_load_store

    case 10: /*ADD.Nn*/

        tcg_gen_add_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], cpu_R[RRRN_T]);

        break;

    case 11: /*ADDI.Nn*/

        tcg_gen_addi_i32(cpu_R[RRRN_R], cpu_R[RRRN_S], RRRN_T ? RRRN_T : -1);

        break;

    case 12: /*ST2n*/

        if (RRRN_T < 8) { /*MOVI.Nn*/

            tcg_gen_movi_i32(cpu_R[RRRN_S],

                    RRRN_R | (RRRN_T << 4) |

                    ((RRRN_T & 6) == 6 ? 0xffffff80 : 0));

        } else { /*BEQZ.Nn*/ /*BNEZ.Nn*/

            TCGCond eq_ne = (RRRN_T & 4) ? TCG_COND_NE : TCG_COND_EQ;

            gen_brcondi(dc, eq_ne, cpu_R[RRRN_S], 0,

                    4 + (RRRN_R | ((RRRN_T & 3) << 4)));

        }

        break;

    case 13: /*ST3n*/

        switch (RRRN_R) {

        case 0: /*MOV.Nn*/

            tcg_gen_mov_i32(cpu_R[RRRN_T], cpu_R[RRRN_S]);

            break;

        case 15: /*S3*/

            switch (RRRN_T) {

            case 0: /*RET.Nn*/

                gen_jump(dc, cpu_R[0]);

                break;

            case 1: /*RETW.Nn*/

                break;

            case 2: /*BREAK.Nn*/

                break;

            case 3: /*NOP.Nn*/

                break;

            case 6: /*ILL.Nn*/

                break;

            default: /*reserved*/

                break;

            }

            break;

        default: /*reserved*/

            break;

        }

        break;

    default: /*reserved*/

        break;

    }

    dc->pc = dc->next_pc;

    return;

invalid_opcode:

    qemu_log("INVALID(pc = %08x)\n", dc->pc);

    dc->pc = dc->next_pc;

#undef HAS_OPTION

}


void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)

{

    BdrvChild *child;

    Error *local_err = NULL;

    int ret;

    if (!bs->drv)  {

        return;

    }

    if (!(bs->open_flags & BDRV_O_INACTIVE)) {

        return;

    }

    bs->open_flags &= ~BDRV_O_INACTIVE;

    if (bs->drv->bdrv_invalidate_cache) {

        bs->drv->bdrv_invalidate_cache(bs, &local_err);

        if (local_err) {

            bs->open_flags |= BDRV_O_INACTIVE;

            error_propagate(errp, local_err);

            return;

        }

    }

    QLIST_FOREACH(child, &bs->children, next) {

        bdrv_invalidate_cache(child->bs, &local_err);

        if (local_err) {

            bs->open_flags |= BDRV_O_INACTIVE;

            error_propagate(errp, local_err);

            return;

        }

    }

    ret = refresh_total_sectors(bs, bs->total_sectors);

    if (ret < 0) {

        bs->open_flags |= BDRV_O_INACTIVE;

        error_setg_errno(errp, -ret, "Could not refresh total sector count");

        return;

    }

}


static int context_init(H264Context *h){

    MpegEncContext * const s = &h->s;

    CHECKED_ALLOCZ(h->top_borders[0], h->s.mb_width * (16+8+8) * sizeof(uint8_t))

    CHECKED_ALLOCZ(h->top_borders[1], h->s.mb_width * (16+8+8) * sizeof(uint8_t))

    // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)

    CHECKED_ALLOCZ(s->allocated_edge_emu_buffer,

                   (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance

    s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;

    return 0;

fail:

    return -1; // free_tables will clean up for us

}


int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,

                          AVFrame *pic_arg, int *got_packet)

{

    MpegEncContext *s = avctx->priv_data;

    int i, stuffing_count, ret;

    int context_count = s->slice_context_count;

    s->picture_in_gop_number++;

    if (load_input_picture(s, pic_arg) < 0)

        return -1;

    if (select_input_picture(s) < 0) {

        return -1;

    }

    /* output? */

    if (s->new_picture.f.data[0]) {

        if ((ret = ff_alloc_packet2(avctx, pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)

            return ret;

        if (s->mb_info) {

            s->mb_info_ptr = av_packet_new_side_data(pkt,

                                 AV_PKT_DATA_H263_MB_INFO,

                                 s->mb_width*s->mb_height*12);

            s->prev_mb_info = s->last_mb_info = s->mb_info_size = 0;

        }

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

            int start_y = s->thread_context[i]->start_mb_y;

            int   end_y = s->thread_context[i]->  end_mb_y;

            int h       = s->mb_height;

            uint8_t *start = pkt->data + (size_t)(((int64_t) pkt->size) * start_y / h);

            uint8_t *end   = pkt->data + (size_t)(((int64_t) pkt->size) *   end_y / h);

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

        }

        s->pict_type = s->new_picture.f.pict_type;

        //emms_c();

        //printf("qs:%f %f %d\n", s->new_picture.quality,

        //       s->current_picture.quality, s->qscale);

        ff_MPV_frame_start(s, avctx);

vbv_retry:

        if (encode_picture(s, s->picture_number) < 0)

            return -1;

        avctx->header_bits = s->header_bits;

        avctx->mv_bits     = s->mv_bits;

        avctx->misc_bits   = s->misc_bits;

        avctx->i_tex_bits  = s->i_tex_bits;

        avctx->p_tex_bits  = s->p_tex_bits;

        avctx->i_count     = s->i_count;

        // FIXME f/b_count in avctx

        avctx->p_count     = s->mb_num - s->i_count - s->skip_count;

        avctx->skip_count  = s->skip_count;

        ff_MPV_frame_end(s);

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

            ff_mjpeg_encode_picture_trailer(s);

        if (avctx->rc_buffer_size) {

            RateControlContext *rcc = &s->rc_context;

            int max_size = rcc->buffer_index * avctx->rc_max_available_vbv_use;

            if (put_bits_count(&s->pb) > max_size &&

                s->lambda < s->avctx->lmax) {

                s->next_lambda = FFMAX(s->lambda + 1, s->lambda *

                                       (s->qscale + 1) / s->qscale);

                if (s->adaptive_quant) {

                    int i;

                    for (i = 0; i < s->mb_height * s->mb_stride; i++)

                        s->lambda_table[i] =

                            FFMAX(s->lambda_table[i] + 1,

                                  s->lambda_table[i] * (s->qscale + 1) /

                                  s->qscale);

                }

                s->mb_skipped = 0;        // done in MPV_frame_start()

                // done in encode_picture() so we must undo it

                if (s->pict_type == AV_PICTURE_TYPE_P) {

                    if (s->flipflop_rounding          ||

                        s->codec_id == CODEC_ID_H263P ||

                        s->codec_id == CODEC_ID_MPEG4)

                        s->no_rounding ^= 1;

                }

                if (s->pict_type != AV_PICTURE_TYPE_B) {

                    s->time_base       = s->last_time_base;

                    s->last_non_b_time = s->time - s->pp_time;

                }

                //av_log(NULL, AV_LOG_ERROR, "R:%d ", s->next_lambda);

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

                    PutBitContext *pb = &s->thread_context[i]->pb;

                    init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);

                }

                goto vbv_retry;

            }

            assert(s->avctx->rc_max_rate);

        }

        if (s->flags & CODEC_FLAG_PASS1)

            ff_write_pass1_stats(s);

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

            s->current_picture_ptr->f.error[i] = s->current_picture.f.error[i];

            avctx->error[i] += s->current_picture_ptr->f.error[i];

        }

        if (s->flags & CODEC_FLAG_PASS1)

            assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits +

                   avctx->i_tex_bits + avctx->p_tex_bits ==

                       put_bits_count(&s->pb));

        flush_put_bits(&s->pb);

        s->frame_bits  = put_bits_count(&s->pb);

        stuffing_count = ff_vbv_update(s, s->frame_bits);

        if (stuffing_count) {

            if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <

                    stuffing_count + 50) {

                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");

                return -1;

            }

            switch (s->codec_id) {

            case CODEC_ID_MPEG1VIDEO:

            case CODEC_ID_MPEG2VIDEO:

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0);

                }

            break;

            case CODEC_ID_MPEG4:

                put_bits(&s->pb, 16, 0);

                put_bits(&s->pb, 16, 0x1C3);

                stuffing_count -= 4;

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0xFF);

                }

            break;

            default:

                av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");

            }

            flush_put_bits(&s->pb);

            s->frame_bits  = put_bits_count(&s->pb);

        }

        /* update mpeg1/2 vbv_delay for CBR */

        if (s->avctx->rc_max_rate                          &&

            s->avctx->rc_min_rate == s->avctx->rc_max_rate &&

            s->out_format == FMT_MPEG1                     &&

            90000LL * (avctx->rc_buffer_size - 1) <=

                s->avctx->rc_max_rate * 0xFFFFLL) {

            int vbv_delay, min_delay;

            double inbits  = s->avctx->rc_max_rate *

                             av_q2d(s->avctx->time_base);

            int    minbits = s->frame_bits - 8 *

                             (s->vbv_delay_ptr - s->pb.buf - 1);

            double bits    = s->rc_context.buffer_index + minbits - inbits;

            if (bits < 0)

                av_log(s->avctx, AV_LOG_ERROR,

                       "Internal error, negative bits\n");

            assert(s->repeat_first_field == 0);

            vbv_delay = bits * 90000 / s->avctx->rc_max_rate;

            min_delay = (minbits * 90000LL + s->avctx->rc_max_rate - 1) /

                        s->avctx->rc_max_rate;

            vbv_delay = FFMAX(vbv_delay, min_delay);

            assert(vbv_delay < 0xFFFF);

            s->vbv_delay_ptr[0] &= 0xF8;

            s->vbv_delay_ptr[0] |= vbv_delay >> 13;

            s->vbv_delay_ptr[1]  = vbv_delay >> 5;

            s->vbv_delay_ptr[2] &= 0x07;

            s->vbv_delay_ptr[2] |= vbv_delay << 3;

            avctx->vbv_delay     = vbv_delay * 300;

        }

        s->total_bits     += s->frame_bits;

        avctx->frame_bits  = s->frame_bits;

        pkt->pts = s->current_picture.f.pts;

        if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {

            if (!s->current_picture.f.coded_picture_number)

                pkt->dts = pkt->pts - s->dts_delta;

            else

                pkt->dts = s->reordered_pts;

            s->reordered_pts = pkt->pts;

        } else

            pkt->dts = pkt->pts;

        if (s->current_picture.f.key_frame)

            pkt->flags |= AV_PKT_FLAG_KEY;

        if (s->mb_info)

            av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);

    } else {

        assert((put_bits_ptr(&s->pb) == s->pb.buf));

        s->frame_bits = 0;

    }

    assert((s->frame_bits & 7) == 0);

    pkt->size = s->frame_bits / 8;

    *got_packet = !!pkt->size;

    return 0;

}


static int check_slice_end(RV34DecContext *r, MpegEncContext *s)

{

    int bits;

    if(s->mb_y >= s->mb_height)

        return 1;

    if(!s->mb_num_left)

        return 1;

    if(r->s.mb_skip_run > 1)

        return 0;

    bits = get_bits_left(&s->gb);

    if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))

        return 1;

    return 0;

}


static int alloc_frame_buffer(AVCodecContext *avctx,  Picture *pic,

                              MotionEstContext *me, ScratchpadContext *sc,

                              int chroma_x_shift, int chroma_y_shift,

                              int linesize, int uvlinesize)

{

    int edges_needed = av_codec_is_encoder(avctx->codec);

    int r, ret;

    pic->tf.f = pic->f;

    if (avctx->codec_id != AV_CODEC_ID_WMV3IMAGE &&

        avctx->codec_id != AV_CODEC_ID_VC1IMAGE  &&

        avctx->codec_id != AV_CODEC_ID_MSS2) {

        if (edges_needed) {

            pic->f->width  = avctx->width  + 2 * EDGE_WIDTH;

            pic->f->height = avctx->height + 2 * EDGE_WIDTH;

        }

        r = ff_thread_get_buffer(avctx, &pic->tf,

                                 pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);

    } else {

        pic->f->width  = avctx->width;

        pic->f->height = avctx->height;

        pic->f->format = avctx->pix_fmt;

        r = avcodec_default_get_buffer2(avctx, pic->f, 0);

    }

    if (r < 0 || !pic->f->buf[0]) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed (%d %p)\n",

               r, pic->f->data[0]);

        return -1;

    }

    if (edges_needed) {

        int i;

        for (i = 0; pic->f->data[i]; i++) {

            int offset = (EDGE_WIDTH >> (i ? chroma_y_shift : 0)) *

                         pic->f->linesize[i] +

                         (EDGE_WIDTH >> (i ? chroma_x_shift : 0));

            pic->f->data[i] += offset;

        }

        pic->f->width  = avctx->width;

        pic->f->height = avctx->height;

    }

    if (avctx->hwaccel) {

        assert(!pic->hwaccel_picture_private);

        if (avctx->hwaccel->frame_priv_data_size) {

            pic->hwaccel_priv_buf = av_buffer_allocz(avctx->hwaccel->frame_priv_data_size);

            if (!pic->hwaccel_priv_buf) {

                av_log(avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");

                return -1;

            }

            pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data;

        }

    }

    if (linesize && (linesize   != pic->f->linesize[0] ||

                     uvlinesize != pic->f->linesize[1])) {

        av_log(avctx, AV_LOG_ERROR,

               "get_buffer() failed (stride changed)\n");

        ff_mpeg_unref_picture(avctx, pic);

        return -1;

    }

    if (pic->f->linesize[1] != pic->f->linesize[2]) {

        av_log(avctx, AV_LOG_ERROR,

               "get_buffer() failed (uv stride mismatch)\n");

        ff_mpeg_unref_picture(avctx, pic);

        return -1;

    }

    if (!sc->edge_emu_buffer &&

        (ret = ff_mpeg_framesize_alloc(avctx, me, sc,

                                       pic->f->linesize[0])) < 0) {

        av_log(avctx, AV_LOG_ERROR,

               "get_buffer() failed to allocate context scratch buffers.\n");

        ff_mpeg_unref_picture(avctx, pic);

        return ret;

    }

    return 0;

}


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

                                ptrdiff_t stride)

{

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

                                          stride, dst, stride, 4, 1);

}


static void show_programs(WriterContext *w, AVFormatContext *fmt_ctx)

{

    int i;

    writer_print_section_header(w, SECTION_ID_PROGRAMS);

    for (i = 0; i < fmt_ctx->nb_programs; i++) {

        AVProgram *program = fmt_ctx->programs[i];

        if (!program)

            continue;

        show_program(w, fmt_ctx, program);

    }

    writer_print_section_footer(w);

}


static int put_flac_codecpriv(AVFormatContext *s,

                              AVIOContext *pb, AVCodecContext *codec)

{

    int write_comment = (codec->channel_layout &&

                         !(codec->channel_layout & ~0x3ffffULL) &&

                         !ff_flac_is_native_layout(codec->channel_layout));

    int ret = ff_flac_write_header(pb, codec->extradata, codec->extradata_size,

                                   !write_comment);

    if (ret < 0)

        return ret;

    if (write_comment) {

        const char *vendor = (s->flags & AVFMT_FLAG_BITEXACT) ?

                             "Lavf" : LIBAVFORMAT_IDENT;

        AVDictionary *dict = NULL;

        uint8_t buf[32], *data, *p;

        int len;

        snprintf(buf, sizeof(buf), "0x%"PRIx64, codec->channel_layout);

        av_dict_set(&dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0);

        len = ff_vorbiscomment_length(dict, vendor);

        data = av_malloc(len + 4);

        if (!data) {

            av_dict_free(&dict);

            return AVERROR(ENOMEM);

        }

        data[0] = 0x84;

        AV_WB24(data + 1, len);

        p = data + 4;

        ff_vorbiscomment_write(&p, &dict, vendor);

        avio_write(pb, data, len + 4);

        av_freep(&data);

        av_dict_free(&dict);

    }

    return 0;

}


static uint64_t get_cluster_offset(BlockDriverState *bs,
                                   uint64_t offset, int *num)
{
    BDRVQcowState *s = bs->opaque;
    int l1_index, l2_index;
    uint64_t l2_offset, *l2_table, cluster_offset;
    int l1_bits, c;
    int index_in_cluster, nb_available, nb_needed, nb_clusters;
    index_in_cluster = (offset >> 9) & (s->cluster_sectors - 1);
    nb_needed = *num + index_in_cluster;
    l1_bits = s->l2_bits + s->cluster_bits;
    /* compute how many bytes there are between the offset and
     * the end of the l1 entry
     */
    nb_available = (1 << l1_bits) - (offset & ((1 << l1_bits) - 1));
    /* compute the number of available sectors */
    nb_available = (nb_available >> 9) + index_in_cluster;
    cluster_offset = 0;
    /* seek the the l2 offset in the l1 table */
    l1_index = offset >> l1_bits;
    if (l1_index >= s->l1_size)
        goto out;
    l2_offset = s->l1_table[l1_index];
    /* seek the l2 table of the given l2 offset */
    if (!l2_offset)
        goto out;
    /* load the l2 table in memory */
    l2_offset &= ~QCOW_OFLAG_COPIED;
    l2_table = l2_load(bs, l2_offset);
    if (l2_table == NULL)
        return 0;
    /* find the cluster offset for the given disk offset */
    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
    cluster_offset = be64_to_cpu(l2_table[l2_index]);
    nb_clusters = size_to_clusters(s, nb_needed << 9);
    if (!cluster_offset) {
        /* how many empty clusters ? */
        c = count_contiguous_free_clusters(nb_clusters, &l2_table[l2_index]);
    } else {
        /* how many allocated clusters ? */
        c = count_contiguous_clusters(nb_clusters, s->cluster_size,
                &l2_table[l2_index], 0, QCOW_OFLAG_COPIED);
   nb_available = (c * s->cluster_sectors);
out:
    if (nb_available > nb_needed)
        nb_available = nb_needed;
    *num = nb_available - index_in_cluster;
    return cluster_offset & ~QCOW_OFLAG_COPIED;


static int rscc_decode_frame(AVCodecContext *avctx, void *data,

                                     int *got_frame, AVPacket *avpkt)

{

    RsccContext *ctx = avctx->priv_data;

    GetByteContext *gbc = &ctx->gbc;

    GetByteContext tiles_gbc;

    AVFrame *frame = data;

    const uint8_t *pixels, *raw;

    uint8_t *inflated_tiles = NULL;

    int tiles_nb, packed_size, pixel_size = 0;

    int i, ret = 0;

    bytestream2_init(gbc, avpkt->data, avpkt->size);

    /* Size check */

    if (bytestream2_get_bytes_left(gbc) < 12) {

        av_log(avctx, AV_LOG_ERROR, "Packet too small (%d)\n", avpkt->size);

        return AVERROR_INVALIDDATA;

    /* Read number of tiles, and allocate the array */

    tiles_nb = bytestream2_get_le16(gbc);

    av_fast_malloc(&ctx->tiles, &ctx->tiles_size,

                   tiles_nb * sizeof(*ctx->tiles));

    if (!ctx->tiles) {

        ret = AVERROR(ENOMEM);

    av_log(avctx, AV_LOG_DEBUG, "Frame with %d tiles.\n", tiles_nb);

    /* When there are more than 5 tiles, they are packed together with

     * a size header. When that size does not match the number of tiles

     * times the tile size, it means it needs to be inflated as well */

    if (tiles_nb > 5) {

        uLongf packed_tiles_size;

        if (tiles_nb < 32)

            packed_tiles_size = bytestream2_get_byte(gbc);

        else

            packed_tiles_size = bytestream2_get_le16(gbc);

        ff_dlog(avctx, "packed tiles of size %lu.\n", packed_tiles_size);

        /* If necessary, uncompress tiles, and hijack the bytestream reader */

        if (packed_tiles_size != tiles_nb * TILE_SIZE) {

            uLongf length = tiles_nb * TILE_SIZE;

            inflated_tiles = av_malloc(length);

            if (!inflated_tiles) {

                ret = AVERROR(ENOMEM);

            ret = uncompress(inflated_tiles, &length,

                             gbc->buffer, packed_tiles_size);

            if (ret) {

                av_log(avctx, AV_LOG_ERROR, "Tile deflate error %d.\n", ret);

                ret = AVERROR_UNKNOWN;

            /* Skip the compressed tile section in the main byte reader,

             * and point it to read the newly uncompressed data */

            bytestream2_skip(gbc, packed_tiles_size);

            bytestream2_init(&tiles_gbc, inflated_tiles, length);

            gbc = &tiles_gbc;

    /* Fill in array of tiles, keeping track of how many pixels are updated */

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

        ctx->tiles[i].x = bytestream2_get_le16(gbc);

        ctx->tiles[i].w = bytestream2_get_le16(gbc);

        ctx->tiles[i].y = bytestream2_get_le16(gbc);

        ctx->tiles[i].h = bytestream2_get_le16(gbc);

        pixel_size += ctx->tiles[i].w * ctx->tiles[i].h * ctx->component_size;

        ff_dlog(avctx, "tile %d orig(%d,%d) %dx%d.\n", i,

                ctx->tiles[i].x, ctx->tiles[i].y,

                ctx->tiles[i].w, ctx->tiles[i].h);

        if (ctx->tiles[i].w == 0 || ctx->tiles[i].h == 0) {

            av_log(avctx, AV_LOG_ERROR,

                   "invalid tile %d at (%d.%d) with size %dx%d.\n", i,

                   ctx->tiles[i].x, ctx->tiles[i].y,

                   ctx->tiles[i].w, ctx->tiles[i].h);

        } else if (ctx->tiles[i].x + ctx->tiles[i].w > avctx->width ||

                   ctx->tiles[i].y + ctx->tiles[i].h > avctx->height) {

            av_log(avctx, AV_LOG_ERROR,

                   "out of bounds tile %d at (%d.%d) with size %dx%d.\n", i,

                   ctx->tiles[i].x, ctx->tiles[i].y,

                   ctx->tiles[i].w, ctx->tiles[i].h);

    /* Reset the reader in case it had been modified before */

    gbc = &ctx->gbc;

    /* Extract how much pixel data the tiles contain */

    if (pixel_size < 0x100)

        packed_size = bytestream2_get_byte(gbc);

    else if (pixel_size < 0x10000)

        packed_size = bytestream2_get_le16(gbc);

    else if (pixel_size < 0x1000000)

        packed_size = bytestream2_get_le24(gbc);

    else

        packed_size = bytestream2_get_le32(gbc);

    ff_dlog(avctx, "pixel_size %d packed_size %d.\n", pixel_size, packed_size);

    if (packed_size < 0) {

        av_log(avctx, AV_LOG_ERROR, "Invalid tile size %d\n", packed_size);

    /* Get pixels buffer, it may be deflated or just raw */

    if (pixel_size == packed_size) {

        if (bytestream2_get_bytes_left(gbc) < pixel_size) {

            av_log(avctx, AV_LOG_ERROR, "Insufficient input for %d\n", pixel_size);

        pixels = gbc->buffer;

    } else {

        uLongf len = ctx->inflated_size;

        ret = uncompress(ctx->inflated_buf, &len, gbc->buffer, packed_size);

        if (ret) {

            av_log(avctx, AV_LOG_ERROR, "Pixel deflate error %d.\n", ret);

            ret = AVERROR_UNKNOWN;

        pixels = ctx->inflated_buf;

    /* Allocate when needed */

    ret = ff_reget_buffer(avctx, ctx->reference);

    if (ret < 0)

    /* Pointer to actual pixels, will be updated when data is consumed */

    raw = pixels;

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

        uint8_t *dst = ctx->reference->data[0] + ctx->reference->linesize[0] *

                       (avctx->height - ctx->tiles[i].y - 1) +

                       ctx->tiles[i].x * ctx->component_size;

        av_image_copy_plane(dst, -1 * ctx->reference->linesize[0],

                            raw, ctx->tiles[i].w * ctx->component_size,

                            ctx->tiles[i].w * ctx->component_size,

                            ctx->tiles[i].h);

        raw += ctx->tiles[i].w * ctx->component_size * ctx->tiles[i].h;

    /* Frame is ready to be output */

    ret = av_frame_ref(frame, ctx->reference);

    if (ret < 0)

    /* Keyframe when the number of pixels updated matches the whole surface */

    if (pixel_size == ctx->inflated_size) {

        frame->pict_type = AV_PICTURE_TYPE_I;

        frame->key_frame = 1;

    } else {

        frame->pict_type = AV_PICTURE_TYPE_P;

    *got_frame = 1;

end:

    av_free(inflated_tiles);

    return ret;


static int64_t wrap_timestamp(AVStream *st, int64_t timestamp)

{

    if (st->pts_wrap_behavior != AV_PTS_WRAP_IGNORE && st->pts_wrap_bits < 64 &&

        st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) {

        if (st->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET &&

            timestamp < st->pts_wrap_reference)

            return timestamp + (1LL<<st->pts_wrap_bits);

        else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET &&

            timestamp >= st->pts_wrap_reference)

            return timestamp - (1LL<<st->pts_wrap_bits);

    }

    return timestamp;

}


static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,

                               const uint8_t *buf, int buf_size, int is_start)

{

    MpegTSContext *ts = s->priv_data;

    MpegTSSectionFilter *tss = &tss1->u.section_filter;

    int len;

    if (is_start) {

        memcpy(tss->section_buf, buf, buf_size);

        tss->section_index = buf_size;

        tss->section_h_size = -1;

        tss->end_of_section_reached = 0;

    } else {

        if (tss->end_of_section_reached)

            return;

        len = 4096 - tss->section_index;

        if (buf_size < len)

            len = buf_size;

        memcpy(tss->section_buf + tss->section_index, buf, len);

        tss->section_index += len;

    }

    /* compute section length if possible */

    if (tss->section_h_size == -1 && tss->section_index >= 3) {

        len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3;

        if (len > 4096)

            return;

        tss->section_h_size = len;

    }

    if (tss->section_h_size != -1 &&

        tss->section_index >= tss->section_h_size) {

        int crc_valid = 1;

        tss->end_of_section_reached = 1;

        if (tss->check_crc) {

            crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size);

            if (crc_valid) {

                ts->crc_validity[ tss1->pid ] = 100;

            }else if (ts->crc_validity[ tss1->pid ] > -10) {

                ts->crc_validity[ tss1->pid ]--;

            }else

                crc_valid = 2;

        }

        if (crc_valid)

            tss->section_cb(tss1, tss->section_buf, tss->section_h_size);

    }

}


bool migrate_auto_converge(void)

{

    MigrationState *s;

    s = migrate_get_current();

    return s->enabled_capabilities[MIGRATION_CAPABILITY_AUTO_CONVERGE];

}


static int dpcm_decode_frame(AVCodecContext *avctx, void *data,

                             int *got_frame_ptr, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    const uint8_t *buf_end = buf + buf_size;

    DPCMContext *s = avctx->priv_data;

    int out = 0, ret;

    int predictor[2];

    int ch = 0;

    int stereo = s->channels - 1;

    int16_t *output_samples;

    /* calculate output size */

    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:

        out = buf_size - 8;

        break;

    case CODEC_ID_INTERPLAY_DPCM:

        out = buf_size - 6 - s->channels;

        break;

    case CODEC_ID_XAN_DPCM:

        out = buf_size - 2 * s->channels;

        break;

    case CODEC_ID_SOL_DPCM:

        if (avctx->codec_tag != 3)

            out = buf_size * 2;

        else

            out = buf_size;

        break;

    }

    if (out <= 0) {

        av_log(avctx, AV_LOG_ERROR, "packet is too small\n");

        return AVERROR(EINVAL);

    }

    /* get output buffer */

    s->frame.nb_samples = out / s->channels;

    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    output_samples = (int16_t *)s->frame.data[0];

    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:

        buf += 6;

        if (stereo) {

            predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8);

            predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8);

        } else {

            predictor[0] = (int16_t)bytestream_get_le16(&buf);

        }

        /* decode the samples */

        while (buf < buf_end) {

            predictor[ch] += s->roq_square_array[*buf++];

            predictor[ch]  = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    case CODEC_ID_INTERPLAY_DPCM:

        buf += 6;  /* skip over the stream mask and stream length */

        for (ch = 0; ch < s->channels; ch++) {

            predictor[ch] = (int16_t)bytestream_get_le16(&buf);

            *output_samples++ = predictor[ch];

        }

        ch = 0;

        while (buf < buf_end) {

            predictor[ch] += interplay_delta_table[*buf++];

            predictor[ch]  = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    case CODEC_ID_XAN_DPCM:

    {

        int shift[2] = { 4, 4 };

        for (ch = 0; ch < s->channels; ch++)

            predictor[ch] = (int16_t)bytestream_get_le16(&buf);

        ch = 0;

        while (buf < buf_end) {

            uint8_t n = *buf++;

            int16_t diff = (n & 0xFC) << 8;

            if ((n & 0x03) == 3)

                shift[ch]++;

            else

                shift[ch] -= (2 * (n & 3));

            /* saturate the shifter to a lower limit of 0 */

            if (shift[ch] < 0)

                shift[ch] = 0;

            diff >>= shift[ch];

            predictor[ch] += diff;

            predictor[ch] = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    }

    case CODEC_ID_SOL_DPCM:

        if (avctx->codec_tag != 3) {

            uint8_t *output_samples_u8 = data;

            while (buf < buf_end) {

                uint8_t n = *buf++;

                s->sample[0] += s->sol_table[n >> 4];

                s->sample[0]  = av_clip_uint8(s->sample[0]);

                *output_samples_u8++ = s->sample[0];

                s->sample[stereo] += s->sol_table[n & 0x0F];

                s->sample[stereo]  = av_clip_uint8(s->sample[stereo]);

                *output_samples_u8++ = s->sample[stereo];

            }

        } else {

            while (buf < buf_end) {

                uint8_t n = *buf++;

                if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];

                else          s->sample[ch] += sol_table_16[n & 0x7F];

                s->sample[ch] = av_clip_int16(s->sample[ch]);

                *output_samples++ = s->sample[ch];

                /* toggle channel */

                ch ^= stereo;

            }

        }

        break;

    }

    *got_frame_ptr   = 1;

    *(AVFrame *)data = s->frame;

    return buf_size;

}


static int get_cluster_table(BlockDriverState *bs, uint64_t offset,

                             uint64_t **new_l2_table,

                             uint64_t *new_l2_offset,

                             int *new_l2_index)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int l1_index, l2_index;

    uint64_t l2_offset;

    uint64_t *l2_table = NULL;

    int ret;

    /* seek the the l2 offset in the l1 table */

    l1_index = offset >> (s->l2_bits + s->cluster_bits);

    if (l1_index >= s->l1_size) {

        ret = qcow2_grow_l1_table(bs, l1_index + 1, false);

        if (ret < 0) {

            return ret;

        }

    }

    l2_offset = s->l1_table[l1_index];

    /* seek the l2 table of the given l2 offset */

    if (l2_offset & QCOW_OFLAG_COPIED) {

        /* load the l2 table in memory */

        l2_offset &= ~QCOW_OFLAG_COPIED;

        ret = l2_load(bs, l2_offset, &l2_table);

        if (ret < 0) {

            return ret;

        }

    } else {

        /* FIXME Order */

        if (l2_offset)

            qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t));

        ret = l2_allocate(bs, l1_index, &l2_table);

        if (ret < 0) {

            return ret;

        }

        l2_offset = s->l1_table[l1_index] & ~QCOW_OFLAG_COPIED;

    }

    /* find the cluster offset for the given disk offset */

    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);

    *new_l2_table = l2_table;

    *new_l2_offset = l2_offset;

    *new_l2_index = l2_index;

    return 0;

}


static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height)

{

    const uint8_t *frame_start = frame;

    const uint8_t *frame_end   = frame + width * height;

    int mask = 0x10000, bitbuf = 0;

    int i, v, offset, count, segments;

    segments = bytestream2_get_le16(gb);

    while (segments--) {

        if (bytestream2_get_bytes_left(gb) < 2)

            return AVERROR_INVALIDDATA;

        if (mask == 0x10000) {

            bitbuf = bytestream2_get_le16u(gb);

            mask = 1;

        }

        if (bitbuf & mask) {

            v = bytestream2_get_le16(gb);

            offset = (v & 0x1FFF) << 2;

            count = ((v >> 13) + 2) << 1;

            if (frame - frame_start < offset || frame_end - frame < count*2 + width)

                return AVERROR_INVALIDDATA;

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

                frame[0] = frame[1] =

                frame[width] = frame[width + 1] = frame[-offset];

                frame += 2;

            }

        } else if (bitbuf & (mask << 1)) {

            v = bytestream2_get_le16(gb)*2;

            if (frame - frame_end < v)

                return AVERROR_INVALIDDATA;

            frame += v;

        } else {

            if (frame_end - frame < width + 3)

                return AVERROR_INVALIDDATA;

            frame[0] = frame[1] =

            frame[width] = frame[width + 1] =  bytestream2_get_byte(gb);

            frame += 2;

            frame[0] = frame[1] =

            frame[width] = frame[width + 1] =  bytestream2_get_byte(gb);

            frame += 2;

        }

        mask <<= 2;

    }

    return 0;

}


int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,

                                  ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header)

{

    uint8_t rps_predict = 0;

    int delta_poc;

    int k0 = 0;

    int k1 = 0;

    int k  = 0;

    int i;

    if (rps != sps->st_rps && sps->nb_st_rps)

        rps_predict = get_bits1(gb);

    if (rps_predict) {

        const ShortTermRPS *rps_ridx;

        int delta_rps;

        unsigned abs_delta_rps;

        uint8_t use_delta_flag = 0;

        uint8_t delta_rps_sign;

        if (is_slice_header) {

            unsigned int delta_idx = get_ue_golomb_long(gb) + 1;

            if (delta_idx > sps->nb_st_rps) {

                       "Invalid value of delta_idx in slice header RPS: %d > %d.\n",

                       delta_idx, sps->nb_st_rps);

            rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];

            rps->rps_idx_num_delta_pocs = rps_ridx->num_delta_pocs;

        } else

            rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];

        delta_rps_sign = get_bits1(gb);

        abs_delta_rps  = get_ue_golomb_long(gb) + 1;

        if (abs_delta_rps < 1 || abs_delta_rps > 32768) {

                   "Invalid value of abs_delta_rps: %d\n",

                   abs_delta_rps);

        delta_rps      = (1 - (delta_rps_sign << 1)) * abs_delta_rps;

        for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {

            int used = rps->used[k] = get_bits1(gb);

            if (!used)

                use_delta_flag = get_bits1(gb);

            if (used || use_delta_flag) {

                if (i < rps_ridx->num_delta_pocs)

                    delta_poc = delta_rps + rps_ridx->delta_poc[i];

                else

                    delta_poc = delta_rps;

                rps->delta_poc[k] = delta_poc;

                if (delta_poc < 0)

                    k0++;

                else

                    k1++;

                k++;

        if (k >= FF_ARRAY_ELEMS(rps->used)) {

                   "Invalid num_delta_pocs: %d\n", k);

        rps->num_delta_pocs    = k;

        rps->num_negative_pics = k0;

        // sort in increasing order (smallest first)

        if (rps->num_delta_pocs != 0) {

            int used, tmp;

            for (i = 1; i < rps->num_delta_pocs; i++) {

                delta_poc = rps->delta_poc[i];

                used      = rps->used[i];

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

                    tmp = rps->delta_poc[k];

                    if (delta_poc < tmp) {

                        rps->delta_poc[k + 1] = tmp;

                        rps->used[k + 1]      = rps->used[k];

                        rps->delta_poc[k]     = delta_poc;

                        rps->used[k]          = used;

        if ((rps->num_negative_pics >> 1) != 0) {

            int used;

            k = rps->num_negative_pics - 1;

            // flip the negative values to largest first

            for (i = 0; i < rps->num_negative_pics >> 1; i++) {

                delta_poc         = rps->delta_poc[i];

                used              = rps->used[i];

                rps->delta_poc[i] = rps->delta_poc[k];

                rps->used[i]      = rps->used[k];

                rps->delta_poc[k] = delta_poc;

                rps->used[k]      = used;

                k--;

    } else {

        unsigned int prev, nb_positive_pics;

        rps->num_negative_pics = get_ue_golomb_long(gb);

        nb_positive_pics       = get_ue_golomb_long(gb);

        if (rps->num_negative_pics >= HEVC_MAX_REFS ||

            nb_positive_pics >= HEVC_MAX_REFS) {

            av_log(avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");

        rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;

        if (rps->num_delta_pocs) {

            prev = 0;

            for (i = 0; i < rps->num_negative_pics; i++) {

                delta_poc = get_ue_golomb_long(gb) + 1;

                prev -= delta_poc;

                rps->delta_poc[i] = prev;

                rps->used[i]      = get_bits1(gb);

            prev = 0;

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

                delta_poc = get_ue_golomb_long(gb) + 1;

                prev += delta_poc;

                rps->delta_poc[rps->num_negative_pics + i] = prev;

                rps->used[rps->num_negative_pics + i]      = get_bits1(gb);

    return 0;


static ssize_t nic_receive(VLANClientState *vc, const uint8_t * buf, size_t size)

{

    /* TODO:

     * - Magic packets should set bit 30 in power management driver register.

     * - Interesting packets should set bit 29 in power management driver register.

     */

    EEPRO100State *s = vc->opaque;

    uint16_t rfd_status = 0xa000;

    static const uint8_t broadcast_macaddr[6] =

        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

    /* TODO: check multiple IA bit. */

    assert(!(s->configuration[20] & BIT(6)));

    if (s->configuration[8] & 0x80) {

        /* CSMA is disabled. */

        logout("%p received while CSMA is disabled\n", s);

        return -1;

    } else if (size < 64 && (s->configuration[7] & 1)) {

        /* Short frame and configuration byte 7/0 (discard short receive) set:

         * Short frame is discarded */

        logout("%p received short frame (%zu byte)\n", s, size);

        s->statistics.rx_short_frame_errors++;

        //~ return -1;

    } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 8)) {

        /* Long frame and configuration byte 18/3 (long receive ok) not set:

         * Long frames are discarded. */

        logout("%p received long frame (%zu byte), ignored\n", s, size);

        return -1;

    } else if (memcmp(buf, s->macaddr, 6) == 0) {       // !!!

        /* Frame matches individual address. */

        /* TODO: check configuration byte 15/4 (ignore U/L). */

        TRACE(RXTX, logout("%p received frame for me, len=%zu\n", s, size));

    } else if (memcmp(buf, broadcast_macaddr, 6) == 0) {

        /* Broadcast frame. */

        TRACE(RXTX, logout("%p received broadcast, len=%zu\n", s, size));

        rfd_status |= 0x0002;

    } else if (buf[0] & 0x01) { // !!!

        /* Multicast frame. */

        TRACE(RXTX, logout("%p received multicast, len=%zu\n", s, size));

        /* TODO: check multicast all bit. */

        assert(!(s->configuration[21] & BIT(3)));

        int mcast_idx = compute_mcast_idx(buf);

        if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) {

            return size;

        }

        rfd_status |= 0x0002;

    } else if (s->configuration[15] & 1) {

        /* Promiscuous: receive all. */

        TRACE(RXTX, logout("%p received frame in promiscuous mode, len=%zu\n", s, size));

        rfd_status |= 0x0004;

    } else {

        TRACE(RXTX, logout("%p received frame, ignored, len=%zu,%s\n", s, size,

              nic_dump(buf, size)));

        return size;

    }

    if (get_ru_state(s) != ru_ready) {

        /* No resources available. */

        logout("no resources, state=%u\n", get_ru_state(s));

        s->statistics.rx_resource_errors++;

        //~ assert(!"no resources");

        return -1;

    }

    //~ !!!

//~ $3 = {status = 0x0, command = 0xc000, link = 0x2d220, rx_buf_addr = 0x207dc, count = 0x0, size = 0x5f8, packet = {0x0 <repeats 1518 times>}}

    eepro100_rx_t rx;

    cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,

                             offsetof(eepro100_rx_t, packet));

    uint16_t rfd_command = le16_to_cpu(rx.command);

    uint16_t rfd_size = le16_to_cpu(rx.size);

    assert(size <= rfd_size);

    if (size < 64) {

        rfd_status |= 0x0080;

    }

    TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size %u\n",

          rfd_command, rx.link, rx.rx_buf_addr, rfd_size));

    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),

             rfd_status);

    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);

    /* Early receive interrupt not supported. */

    //~ eepro100_er_interrupt(s);

    /* Receive CRC Transfer not supported. */

    assert(!(s->configuration[18] & 4));

    /* TODO: check stripping enable bit. */

    //~ assert(!(s->configuration[17] & 1));

    cpu_physical_memory_write(s->ru_base + s->ru_offset +

                              offsetof(eepro100_rx_t, packet), buf, size);

    s->statistics.rx_good_frames++;

    eepro100_fr_interrupt(s);

    s->ru_offset = le32_to_cpu(rx.link);

    if (rfd_command & 0x8000) {

        /* EL bit is set, so this was the last frame. */

        assert(0);

    }

    if (rfd_command & 0x4000) {

        /* S bit is set. */

        set_ru_state(s, ru_suspended);

    }

    return size;

}


static BlockAIOCB *read_quorum_children(QuorumAIOCB *acb)

{

    BDRVQuorumState *s = acb->common.bs->opaque;

    int i;

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

        acb->qcrs[i].buf = qemu_blockalign(s->children[i]->bs, acb->qiov->size);

        qemu_iovec_init(&acb->qcrs[i].qiov, acb->qiov->niov);

        qemu_iovec_clone(&acb->qcrs[i].qiov, acb->qiov, acb->qcrs[i].buf);

    }

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

        bdrv_aio_readv(s->children[i]->bs, acb->sector_num, &acb->qcrs[i].qiov,

                       acb->nb_sectors, quorum_aio_cb, &acb->qcrs[i]);

    }

    return &acb->common;

}