static void vhost_client_set_memory(CPUPhysMemoryClient *client,

                                    target_phys_addr_t start_addr,

                                    ram_addr_t size,

                                    ram_addr_t phys_offset,

                                    bool log_dirty)

{

    struct vhost_dev *dev = container_of(client, struct vhost_dev, client);

    ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;

    int s = offsetof(struct vhost_memory, regions) +

        (dev->mem->nregions + 1) * sizeof dev->mem->regions[0];

    uint64_t log_size;

    int r;

    dev->mem = g_realloc(dev->mem, s);

    if (log_dirty) {

        flags = IO_MEM_UNASSIGNED;

    }

    assert(size);

    /* Optimize no-change case. At least cirrus_vga does this a lot at this time. */

    if (flags == IO_MEM_RAM) {

        if (!vhost_dev_cmp_memory(dev, start_addr, size,

                                  (uintptr_t)qemu_get_ram_ptr(phys_offset))) {

            /* Region exists with same address. Nothing to do. */

            return;

        }

    } else {

        if (!vhost_dev_find_reg(dev, start_addr, size)) {

            /* Removing region that we don't access. Nothing to do. */

            return;

        }

    }

    vhost_dev_unassign_memory(dev, start_addr, size);

    if (flags == IO_MEM_RAM) {

        /* Add given mapping, merging adjacent regions if any */

        vhost_dev_assign_memory(dev, start_addr, size,

                                (uintptr_t)qemu_get_ram_ptr(phys_offset));

    } else {

        /* Remove old mapping for this memory, if any. */

        vhost_dev_unassign_memory(dev, start_addr, size);

    }

    if (!dev->started) {

        return;

    }

    if (dev->started) {

        r = vhost_verify_ring_mappings(dev, start_addr, size);

        assert(r >= 0);

    }

    if (!dev->log_enabled) {

        r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);

        assert(r >= 0);

        return;

    }

    log_size = vhost_get_log_size(dev);

    /* We allocate an extra 4K bytes to log,

     * to reduce the * number of reallocations. */

#define VHOST_LOG_BUFFER (0x1000 / sizeof *dev->log)

    /* To log more, must increase log size before table update. */

    if (dev->log_size < log_size) {

        vhost_dev_log_resize(dev, log_size + VHOST_LOG_BUFFER);

    }

    r = ioctl(dev->control, VHOST_SET_MEM_TABLE, dev->mem);

    assert(r >= 0);

    /* To log less, can only decrease log size after table update. */

    if (dev->log_size > log_size + VHOST_LOG_BUFFER) {

        vhost_dev_log_resize(dev, log_size);

    }

}


static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1,

                           uint8_t *src2, ptrdiff_t stride, int h)

{

    LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);

    int16_t *const bak = temp + 64;

    int sum = 0, i;

    av_assert2(h == 8);

    s->mb_intra = 0;

    s->pdsp.diff_pixels(temp, src1, src2, stride);

    memcpy(bak, temp, 64 * sizeof(int16_t));

    s->block_last_index[0 /* FIXME */] =

        s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);

    s->dct_unquantize_inter(s, temp, 0, s->qscale);

    ff_simple_idct_8(temp); // FIXME

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

        sum += (temp[i] - bak[i]) * (temp[i] - bak[i]);

    return sum;

}


static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)

{

    int ret = 0;

    uint8_t *buffer;

    int offset = 0;

    uint32_t i = 0;

    VHDXMetadataTableEntry md_entry;

    buffer = qemu_blockalign(bs, VHDX_METADATA_TABLE_MAX_SIZE);

    ret = bdrv_pread(bs->file, s->metadata_rt.file_offset, buffer,

                     VHDX_METADATA_TABLE_MAX_SIZE);

    if (ret < 0) {

        goto exit;

    }

    memcpy(&s->metadata_hdr, buffer, sizeof(s->metadata_hdr));

    offset += sizeof(s->metadata_hdr);

    vhdx_metadata_header_le_import(&s->metadata_hdr);

    if (memcmp(&s->metadata_hdr.signature, "metadata", 8)) {

        ret = -EINVAL;

        goto exit;

    }

    s->metadata_entries.present = 0;

    if ((s->metadata_hdr.entry_count * sizeof(md_entry)) >

        (VHDX_METADATA_TABLE_MAX_SIZE - offset)) {

        ret = -EINVAL;

        goto exit;

    }

    for (i = 0; i < s->metadata_hdr.entry_count; i++) {

        memcpy(&md_entry, buffer + offset, sizeof(md_entry));

        offset += sizeof(md_entry);

        vhdx_metadata_entry_le_import(&md_entry);

        if (guid_eq(md_entry.item_id, file_param_guid)) {

            if (s->metadata_entries.present & META_FILE_PARAMETER_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.file_parameters_entry = md_entry;

            s->metadata_entries.present |= META_FILE_PARAMETER_PRESENT;

            continue;

        }

        if (guid_eq(md_entry.item_id, virtual_size_guid)) {

            if (s->metadata_entries.present & META_VIRTUAL_DISK_SIZE_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.virtual_disk_size_entry = md_entry;

            s->metadata_entries.present |= META_VIRTUAL_DISK_SIZE_PRESENT;

            continue;

        }

        if (guid_eq(md_entry.item_id, page83_guid)) {

            if (s->metadata_entries.present & META_PAGE_83_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.page83_data_entry = md_entry;

            s->metadata_entries.present |= META_PAGE_83_PRESENT;

            continue;

        }

        if (guid_eq(md_entry.item_id, logical_sector_guid)) {

            if (s->metadata_entries.present &

                META_LOGICAL_SECTOR_SIZE_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.logical_sector_size_entry = md_entry;

            s->metadata_entries.present |= META_LOGICAL_SECTOR_SIZE_PRESENT;

            continue;

        }

        if (guid_eq(md_entry.item_id, phys_sector_guid)) {

            if (s->metadata_entries.present & META_PHYS_SECTOR_SIZE_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.phys_sector_size_entry = md_entry;

            s->metadata_entries.present |= META_PHYS_SECTOR_SIZE_PRESENT;

            continue;

        }

        if (guid_eq(md_entry.item_id, parent_locator_guid)) {

            if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {

                ret = -EINVAL;

                goto exit;

            }

            s->metadata_entries.parent_locator_entry = md_entry;

            s->metadata_entries.present |= META_PARENT_LOCATOR_PRESENT;

            continue;

        }

        if (md_entry.data_bits & VHDX_META_FLAGS_IS_REQUIRED) {

            /* cannot read vhdx file - required region table entry that

             * we do not understand.  per spec, we must fail to open */

            ret = -ENOTSUP;

            goto exit;

        }

    }

    if (s->metadata_entries.present != META_ALL_PRESENT) {

        ret = -ENOTSUP;

        goto exit;

    }

    ret = bdrv_pread(bs->file,

                     s->metadata_entries.file_parameters_entry.offset

                                         + s->metadata_rt.file_offset,

                     &s->params,

                     sizeof(s->params));

    if (ret < 0) {

        goto exit;

    }

    le32_to_cpus(&s->params.block_size);

    le32_to_cpus(&s->params.data_bits);

    /* We now have the file parameters, so we can tell if this is a

     * differencing file (i.e.. has_parent), is dynamic or fixed

     * sized (leave_blocks_allocated), and the block size */

    /* The parent locator required iff the file parameters has_parent set */

    if (s->params.data_bits & VHDX_PARAMS_HAS_PARENT) {

        if (s->metadata_entries.present & META_PARENT_LOCATOR_PRESENT) {

            /* TODO: parse  parent locator fields */

            ret = -ENOTSUP; /* temp, until differencing files are supported */

            goto exit;

        } else {

            /* if has_parent is set, but there is not parent locator present,

             * then that is an invalid combination */

            ret = -EINVAL;

            goto exit;

        }

    }

    /* determine virtual disk size, logical sector size,

     * and phys sector size */

    ret = bdrv_pread(bs->file,

                     s->metadata_entries.virtual_disk_size_entry.offset

                                           + s->metadata_rt.file_offset,

                     &s->virtual_disk_size,

                     sizeof(uint64_t));

    if (ret < 0) {

        goto exit;

    }

    ret = bdrv_pread(bs->file,

                     s->metadata_entries.logical_sector_size_entry.offset

                                             + s->metadata_rt.file_offset,

                     &s->logical_sector_size,

                     sizeof(uint32_t));

    if (ret < 0) {

        goto exit;

    }

    ret = bdrv_pread(bs->file,

                     s->metadata_entries.phys_sector_size_entry.offset

                                          + s->metadata_rt.file_offset,

                     &s->physical_sector_size,

                     sizeof(uint32_t));

    if (ret < 0) {

        goto exit;

    }

    le64_to_cpus(&s->virtual_disk_size);

    le32_to_cpus(&s->logical_sector_size);

    le32_to_cpus(&s->physical_sector_size);

    if (s->logical_sector_size == 0 || s->params.block_size == 0) {

        ret = -EINVAL;

        goto exit;

    }

    /* both block_size and sector_size are guaranteed powers of 2 */

    s->sectors_per_block = s->params.block_size / s->logical_sector_size;

    s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) *

                     (uint64_t)s->logical_sector_size /

                     (uint64_t)s->params.block_size;

    /* These values are ones we will want to use for division / multiplication

     * later on, and they are all guaranteed (per the spec) to be powers of 2,

     * so we can take advantage of that for shift operations during

     * reads/writes */

    if (s->logical_sector_size & (s->logical_sector_size - 1)) {

        ret = -EINVAL;

        goto exit;

    }

    if (s->sectors_per_block & (s->sectors_per_block - 1)) {

        ret = -EINVAL;

        goto exit;

    }

    if (s->chunk_ratio & (s->chunk_ratio - 1)) {

        ret = -EINVAL;

        goto exit;

    }

    s->block_size = s->params.block_size;

    if (s->block_size & (s->block_size - 1)) {

        ret = -EINVAL;

        goto exit;

    }

    vhdx_set_shift_bits(s);

    ret = 0;

exit:

    qemu_vfree(buffer);

    return ret;

}


void virtio_scsi_handle_cmd_vq(VirtIOSCSI *s, VirtQueue *vq)

{

    VirtIOSCSIReq *req, *next;

    QTAILQ_HEAD(, VirtIOSCSIReq) reqs = QTAILQ_HEAD_INITIALIZER(reqs);

    while ((req = virtio_scsi_pop_req(s, vq))) {

        if (virtio_scsi_handle_cmd_req_prepare(s, req)) {

            QTAILQ_INSERT_TAIL(&reqs, req, next);

        }

    }

    QTAILQ_FOREACH_SAFE(req, &reqs, next, next) {

        virtio_scsi_handle_cmd_req_submit(s, req);

    }

}


static void mch_realize(PCIDevice *d, Error **errp)

{

    int i;

    MCHPCIState *mch = MCH_PCI_DEVICE(d);

    /* setup pci memory mapping */

    pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,

                           mch->pci_address_space);

    /* smram */

    cpu_smm_register(&mch_set_smm, mch);

    memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region",

                             mch->pci_address_space, 0xa0000, 0x20000);

    memory_region_add_subregion_overlap(mch->system_memory, 0xa0000,

                                        &mch->smram_region, 1);

    memory_region_set_enabled(&mch->smram_region, false);

    init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,

             mch->pci_address_space, &mch->pam_regions[0],

             PAM_BIOS_BASE, PAM_BIOS_SIZE);

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

        init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory,

                 mch->pci_address_space, &mch->pam_regions[i+1],

                 PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE);

    }

    /* Intel IOMMU (VT-d) */

    if (qemu_opt_get_bool(qemu_get_machine_opts(), "iommu", false)) {

        mch_init_dmar(mch);

    }

}


static uint64_t calc_rice_params(RiceContext *rc, int pmin, int pmax,

                                 int32_t *data, int n, int pred_order)

{

    int i;

    uint64_t bits[MAX_PARTITION_ORDER+1];

    int opt_porder;

    RiceContext tmp_rc;

    uint32_t *udata;

    uint64_t sums[MAX_PARTITION_ORDER + 1][MAX_PARTITIONS] = { { 0 } };

    assert(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);

    assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);

    assert(pmin <= pmax);

    tmp_rc.coding_mode = rc->coding_mode;

    udata = av_malloc(n * sizeof(uint32_t));

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

        udata[i] = (2*data[i]) ^ (data[i]>>31);

    calc_sums(pmin, pmax, udata, n, pred_order, sums);

    opt_porder = pmin;

    bits[pmin] = UINT32_MAX;

    for (i = pmin; i <= pmax; i++) {

        bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums[i], n, pred_order);

        if (bits[i] <= bits[opt_porder]) {

            opt_porder = i;

            *rc = tmp_rc;

        }

    }

    av_freep(&udata);

    return bits[opt_porder];

}


static int handle_http(HTTPContext *c, long cur_time)

{

    int len;

    switch(c->state) {

    case HTTPSTATE_WAIT_REQUEST:

        /* timeout ? */

        if ((c->timeout - cur_time) < 0)

            return -1;

        if (c->poll_entry->revents & (POLLERR | POLLHUP))

            return -1;

        /* no need to read if no events */

        if (!(c->poll_entry->revents & POLLIN))

            return 0;

        /* read the data */

        len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);

        if (len < 0) {

            if (errno != EAGAIN && errno != EINTR)

                return -1;

        } else if (len == 0) {

            return -1;

        } else {

            /* search for end of request. XXX: not fully correct since garbage could come after the end */

            UINT8 *ptr;

            c->buffer_ptr += len;

            ptr = c->buffer_ptr;

            if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||

                (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {

                /* request found : parse it and reply */

                if (http_parse_request(c) < 0)

                    return -1;

            } else if (ptr >= c->buffer_end) {

                /* request too long: cannot do anything */

                return -1;

            }

        }

        break;

    case HTTPSTATE_SEND_HEADER:

        if (c->poll_entry->revents & (POLLERR | POLLHUP))

            return -1;

        /* no need to read if no events */

        if (!(c->poll_entry->revents & POLLOUT))

            return 0;

        len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);

        if (len < 0) {

            if (errno != EAGAIN && errno != EINTR) {

                /* error : close connection */

                return -1;

            }

        } else {

            c->buffer_ptr += len;

            if (c->stream)

                c->stream->bytes_served += len;

            c->data_count += len;

            if (c->buffer_ptr >= c->buffer_end) {

                /* if error, exit */

                if (c->http_error)

                    return -1;

                /* all the buffer was send : synchronize to the incoming stream */

                c->state = HTTPSTATE_SEND_DATA_HEADER;

                c->buffer_ptr = c->buffer_end = c->buffer;

            }

        }

        break;

    case HTTPSTATE_SEND_DATA:

    case HTTPSTATE_SEND_DATA_HEADER:

    case HTTPSTATE_SEND_DATA_TRAILER:

        /* no need to read if no events */

        if (c->poll_entry->revents & (POLLERR | POLLHUP))

            return -1;

        if (!(c->poll_entry->revents & POLLOUT))

            return 0;

        if (http_send_data(c, cur_time) < 0)

            return -1;

        break;

    case HTTPSTATE_RECEIVE_DATA:

        /* no need to read if no events */

        if (c->poll_entry->revents & (POLLERR | POLLHUP))

            return -1;

        if (!(c->poll_entry->revents & POLLIN))

            return 0;

        if (http_receive_data(c) < 0)

            return -1;

        break;

    case HTTPSTATE_WAIT_FEED:

        /* no need to read if no events */

        if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))

            return -1;

        /* nothing to do, we'll be waken up by incoming feed packets */

        break;

    default:

        return -1;

    }

    return 0;

}


static int bfi_read_header(AVFormatContext * s)

{

    BFIContext *bfi = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *vstream;

    AVStream *astream;

    int fps, chunk_header;

    /* Initialize the video codec... */

    vstream = avformat_new_stream(s, NULL);

    if (!vstream)

        return AVERROR(ENOMEM);

    /* Initialize the audio codec... */

    astream = avformat_new_stream(s, NULL);

    if (!astream)

        return AVERROR(ENOMEM);

    /* Set the total number of frames. */

    avio_skip(pb, 8);

    chunk_header           = avio_rl32(pb);

    bfi->nframes           = avio_rl32(pb);

    avio_rl32(pb);

    avio_rl32(pb);

    avio_rl32(pb);

    fps                    = avio_rl32(pb);

    avio_skip(pb, 12);

    vstream->codecpar->width  = avio_rl32(pb);

    vstream->codecpar->height = avio_rl32(pb);

    /*Load the palette to extradata */

    avio_skip(pb, 8);

    vstream->codecpar->extradata      = av_malloc(768);

    if (!vstream->codecpar->extradata)

        return AVERROR(ENOMEM);

    vstream->codecpar->extradata_size = 768;

    avio_read(pb, vstream->codecpar->extradata,

               vstream->codecpar->extradata_size);

    astream->codecpar->sample_rate = avio_rl32(pb);

    if (astream->codecpar->sample_rate <= 0) {

        av_log(s, AV_LOG_ERROR, "Invalid sample rate %d\n", astream->codecpar->sample_rate);

        return AVERROR_INVALIDDATA;

    }

    /* Set up the video codec... */

    avpriv_set_pts_info(vstream, 32, 1, fps);

    vstream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

    vstream->codecpar->codec_id   = AV_CODEC_ID_BFI;

    vstream->codecpar->format     = AV_PIX_FMT_PAL8;

    vstream->nb_frames            =

    vstream->duration             = bfi->nframes;

    /* Set up the audio codec now... */

    astream->codecpar->codec_type      = AVMEDIA_TYPE_AUDIO;

    astream->codecpar->codec_id        = AV_CODEC_ID_PCM_U8;

    astream->codecpar->channels        = 1;

    astream->codecpar->channel_layout  = AV_CH_LAYOUT_MONO;

    astream->codecpar->bits_per_coded_sample = 8;

    astream->codecpar->bit_rate        =

        astream->codecpar->sample_rate * astream->codecpar->bits_per_coded_sample;

    avio_seek(pb, chunk_header - 3, SEEK_SET);

    avpriv_set_pts_info(astream, 64, 1, astream->codecpar->sample_rate);

    return 0;

}


static int event_qdev_init(DeviceState *qdev)

{

    SCLPEvent *event = DO_UPCAST(SCLPEvent, qdev, qdev);

    SCLPEventClass *child = SCLP_EVENT_GET_CLASS(event);

    return child->init(event);

}


static void gen_rfid(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    /* Restore CPU state */

    if (unlikely(!ctx->mem_idx)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_helper_rfid();

    gen_sync_exception(ctx);

#endif

}


static void vga_update_text(void *opaque, console_ch_t *chardata)
{
    VGACommonState *s =  opaque;
    int graphic_mode, i, cursor_offset, cursor_visible;
    int cw, cheight, width, height, size, c_min, c_max;
    uint32_t *src;
    console_ch_t *dst, val;
    char msg_buffer[80];
    int full_update = 0;
    if (!(s->ar_index & 0x20)) {
        graphic_mode = GMODE_BLANK;
    } else {
        graphic_mode = s->gr[6] & 1;
    }
    if (graphic_mode != s->graphic_mode) {
        s->graphic_mode = graphic_mode;
        full_update = 1;
    }
    if (s->last_width == -1) {
        s->last_width = 0;
        full_update = 1;
    }
    switch (graphic_mode) {
    case GMODE_TEXT:
        /* TODO: update palette */
        full_update |= update_basic_params(s);
        /* total width & height */
        cheight = (s->cr[9] & 0x1f) + 1;
        cw = 8;
        if (!(s->sr[1] & 0x01))
            cw = 9;
        if (s->sr[1] & 0x08)
            cw = 16; /* NOTE: no 18 pixel wide */
        width = (s->cr[0x01] + 1);
        if (s->cr[0x06] == 100) {
            /* ugly hack for CGA 160x100x16 - explain me the logic */
            height = 100;
        } else {
            height = s->cr[0x12] |
                ((s->cr[0x07] & 0x02) << 7) |
                ((s->cr[0x07] & 0x40) << 3);
            height = (height + 1) / cheight;
        }
        size = (height * width);
        if (size > CH_ATTR_SIZE) {
            if (!full_update)
                return;
            snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
                     width, height);
            break;
        }
        if (width != s->last_width || height != s->last_height ||
            cw != s->last_cw || cheight != s->last_ch) {
            s->last_scr_width = width * cw;
            s->last_scr_height = height * cheight;
            s->ds->surface->width = width;
            s->ds->surface->height = height;
            dpy_resize(s->ds);
            s->last_width = width;
            s->last_height = height;
            s->last_ch = cheight;
            s->last_cw = cw;
            full_update = 1;
        }
        /* Update "hardware" cursor */
        cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
        if (cursor_offset != s->cursor_offset ||
            s->cr[0xa] != s->cursor_start ||
            s->cr[0xb] != s->cursor_end || full_update) {
            cursor_visible = !(s->cr[0xa] & 0x20);
            if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
                dpy_cursor(s->ds,
                           TEXTMODE_X(cursor_offset),
                           TEXTMODE_Y(cursor_offset));
            else
                dpy_cursor(s->ds, -1, -1);
            s->cursor_offset = cursor_offset;
            s->cursor_start = s->cr[0xa];
            s->cursor_end = s->cr[0xb];
        }
        src = (uint32_t *) s->vram_ptr + s->start_addr;
        dst = chardata;
        if (full_update) {
            for (i = 0; i < size; src ++, dst ++, i ++)
                console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
            dpy_update(s->ds, 0, 0, width, height);
        } else {
            c_max = 0;
            for (i = 0; i < size; src ++, dst ++, i ++) {
                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                if (*dst != val) {
                    *dst = val;
                    c_max = i;
                    break;
                }
            }
            c_min = i;
            for (; i < size; src ++, dst ++, i ++) {
                console_write_ch(&val, VMEM2CHTYPE(le32_to_cpu(*src)));
                if (*dst != val) {
                    *dst = val;
                    c_max = i;
                }
            }
            if (c_min <= c_max) {
                i = TEXTMODE_Y(c_min);
                dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
            }
        }
        return;
    case GMODE_GRAPH:
        if (!full_update)
            return;
        s->get_resolution(s, &width, &height);
        snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
                 width, height);
        break;
    case GMODE_BLANK:
    default:
        if (!full_update)
            return;
        snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
        break;
    }
    /* Display a message */
    s->last_width = 60;
    s->last_height = height = 3;
    dpy_cursor(s->ds, -1, -1);
    s->ds->surface->width = s->last_width;
    s->ds->surface->height = height;
    dpy_resize(s->ds);
    for (dst = chardata, i = 0; i < s->last_width * height; i ++)
        console_write_ch(dst ++, ' ');
    size = strlen(msg_buffer);
    width = (s->last_width - size) / 2;
    dst = chardata + s->last_width + width;
    for (i = 0; i < size; i ++)
        console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
    dpy_update(s->ds, 0, 0, s->last_width, height);
}


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

                        int *got_frame_ptr, AVPacket *pkt)

{

    SANMVideoContext *ctx = avctx->priv_data;

    int i, ret;

    bytestream2_init(&ctx->gb, pkt->data, pkt->size);

    if (ctx->output->data[0])

        avctx->release_buffer(avctx, ctx->output);

    if (!ctx->version) {

        int to_store = 0;

        while (bytestream2_get_bytes_left(&ctx->gb) >= 8) {

            uint32_t sig, size;

            int pos;

            sig  = bytestream2_get_be32u(&ctx->gb);

            size = bytestream2_get_be32u(&ctx->gb);

            pos  = bytestream2_tell(&ctx->gb);

            if (bytestream2_get_bytes_left(&ctx->gb) < size) {

                av_log(avctx, AV_LOG_ERROR, "incorrect chunk size %d\n", size);

                break;

            }

            switch (sig) {

            case MKBETAG('N', 'P', 'A', 'L'):

                if (size != 256 * 3) {

                    av_log(avctx, AV_LOG_ERROR, "incorrect palette block size %d\n",

                           size);

                    return AVERROR_INVALIDDATA;

                }

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

                    ctx->pal[i] = 0xFF << 24 | bytestream2_get_be24u(&ctx->gb);

                break;

            case MKBETAG('F', 'O', 'B', 'J'):

                if (size < 16)

                    return AVERROR_INVALIDDATA;

                if (ret = process_frame_obj(ctx))

                    return ret;

                break;

            case MKBETAG('X', 'P', 'A', 'L'):

                if (size == 6 || size == 4) {

                    uint8_t tmp[3];

                    int j;

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

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

                            int t = (ctx->pal[i] >> (16 - j * 8)) & 0xFF;

                            tmp[j] = av_clip_uint8((t * 129 + ctx->delta_pal[i * 3 + j]) >> 7);

                        }

                        ctx->pal[i] = 0xFF << 24 | AV_RB24(tmp);

                    }

                } else {

                    if (size < 768 * 2 + 4) {

                        av_log(avctx, AV_LOG_ERROR, "incorrect palette change block size %d\n",

                               size);

                        return AVERROR_INVALIDDATA;

                    }

                    bytestream2_skipu(&ctx->gb, 4);

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

                        ctx->delta_pal[i] = bytestream2_get_le16u(&ctx->gb);

                    if (size >= 768 * 5 + 4) {

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

                            ctx->pal[i] = 0xFF << 24 | bytestream2_get_be24u(&ctx->gb);

                    } else {

                        memset(ctx->pal, 0, sizeof(ctx->pal));

                    }

                }

                break;

            case MKBETAG('S', 'T', 'O', 'R'):

                to_store = 1;

                break;

            case MKBETAG('F', 'T', 'C', 'H'):

                memcpy(ctx->frm0, ctx->stored_frame, ctx->buf_size);

                break;

            default:

                bytestream2_skip(&ctx->gb, size);

                av_log(avctx, AV_LOG_DEBUG, "unknown/unsupported chunk %x\n", sig);

                break;

            }

            bytestream2_seek(&ctx->gb, pos + size, SEEK_SET);

            if (size & 1)

                bytestream2_skip(&ctx->gb, 1);

        }

        if (to_store)

            memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size);

        if ((ret = copy_output(ctx, NULL)))

            return ret;

        memcpy(ctx->output->data[1], ctx->pal, 1024);

    } else {

        SANMFrameHeader header;

        if ((ret = read_frame_header(ctx, &header)))

            return ret;

        ctx->rotate_code = header.rotate_code;

        if ((ctx->output->key_frame = !header.seq_num)) {

            ctx->output->pict_type = AV_PICTURE_TYPE_I;

            fill_frame(ctx->frm1, ctx->npixels, header.bg_color);

            fill_frame(ctx->frm2, ctx->npixels, header.bg_color);

        } else {

            ctx->output->pict_type = AV_PICTURE_TYPE_P;

        }

        if (header.codec < FF_ARRAY_ELEMS(v1_decoders)) {

            if ((ret = v1_decoders[header.codec](ctx))) {

                av_log(avctx, AV_LOG_ERROR,

                       "subcodec %d: error decoding frame\n", header.codec);

                return ret;

            }

        } else {

            av_log_ask_for_sample(avctx, "subcodec %d is not implemented\n",

                   header.codec);

            return AVERROR_PATCHWELCOME;

        }

        if ((ret = copy_output(ctx, &header)))

            return ret;

    }

    if (ctx->rotate_code)

        rotate_bufs(ctx, ctx->rotate_code);

    *got_frame_ptr  = 1;

    *(AVFrame*)data = *ctx->output;

    return pkt->size;

}


static RAMBlock *unqueue_page(RAMState *rs, ram_addr_t *offset,

                              ram_addr_t *ram_addr_abs)

{

    RAMBlock *block = NULL;

    qemu_mutex_lock(&rs->src_page_req_mutex);

    if (!QSIMPLEQ_EMPTY(&rs->src_page_requests)) {

        struct RAMSrcPageRequest *entry =

                                QSIMPLEQ_FIRST(&rs->src_page_requests);

        block = entry->rb;

        *offset = entry->offset;

        *ram_addr_abs = (entry->offset + entry->rb->offset) &

                        TARGET_PAGE_MASK;

        if (entry->len > TARGET_PAGE_SIZE) {

            entry->len -= TARGET_PAGE_SIZE;

            entry->offset += TARGET_PAGE_SIZE;

        } else {

            memory_region_unref(block->mr);

            QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);

            g_free(entry);

        }

    }

    qemu_mutex_unlock(&rs->src_page_req_mutex);

    return block;

}


static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist)

{

    int i, tdist = 0.0f;

    OpusRangeCoder dump;

    ff_opus_rc_enc_init(&dump);

    ff_celt_enc_bitalloc(f, &dump);

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

        float bits = 0.0f;

        float dist = f->pvq->band_cost(f->pvq, f, &dump, i, &bits, s->lambda);

        tdist += dist;

    }

    *total_dist = tdist;

    return 0;

}


static inline void apply_motion_generic(RoqContext *ri, int x, int y, int deltax,

                                        int deltay, int sz)

{

    int mx, my, cp;

    mx = x + deltax;

    my = y + deltay;

    /* check MV against frame boundaries */

    if ((mx < 0) || (mx > ri->width - sz) ||

        (my < 0) || (my > ri->height - sz)) {

        av_log(ri->avctx, AV_LOG_ERROR, "motion vector out of bounds: MV = (%d, %d), boundaries = (0, 0, %d, %d)\n",

            mx, my, ri->width, ri->height);

        return;

    }

    if (ri->last_frame->data[0] == NULL) {

        av_log(ri->avctx, AV_LOG_ERROR, "Invalid decode type. Invalid header?\n");

        return;

    }

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

        int outstride = ri->current_frame->linesize[cp];

        int instride  = ri->last_frame   ->linesize[cp];

        block_copy(ri->current_frame->data[cp] + y*outstride + x,

                   ri->last_frame->data[cp] + my*instride + mx,

                   outstride, instride, sz);

    }

}


QGuestAllocator *pc_alloc_init(void)
{
    PCAlloc *s = g_malloc0(sizeof(*s));
    uint64_t ram_size;
    QFWCFG *fw_cfg = pc_fw_cfg_init();
    s->alloc.alloc = pc_alloc;
    s->alloc.free = pc_free;
    ram_size = qfw_cfg_get_u64(fw_cfg, FW_CFG_RAM_SIZE);
    /* Start at 1MB */
    s->start = 1 << 20;
    /* Respect PCI hole */
    s->end = MIN(ram_size, 0xE0000000);
    return &s->alloc;
}


static int update_error_limit(WavpackFrameContext *ctx)

{

    int i, br[2], sl[2];

    for (i = 0; i <= ctx->stereo_in; i++) {

        if (ctx->ch[i].bitrate_acc > UINT_MAX - ctx->ch[i].bitrate_delta)

            return AVERROR_INVALIDDATA;

        ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;

        br[i]                   = ctx->ch[i].bitrate_acc >> 16;

        sl[i]                   = LEVEL_DECAY(ctx->ch[i].slow_level);

    }

    if (ctx->stereo_in && ctx->hybrid_bitrate) {

        int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;

        if (balance > br[0]) {

            br[1] = br[0] << 1;

            br[0] = 0;

        } else if (-balance > br[0]) {

            br[0] <<= 1;

            br[1]   = 0;

        } else {

            br[1] = br[0] + balance;

            br[0] = br[0] - balance;

        }

    }

    for (i = 0; i <= ctx->stereo_in; i++) {

        if (ctx->hybrid_bitrate) {

            if (sl[i] - br[i] > -0x100)

                ctx->ch[i].error_limit = wp_exp2(sl[i] - br[i] + 0x100);

            else

                ctx->ch[i].error_limit = 0;

        } else {

            ctx->ch[i].error_limit = wp_exp2(br[i]);

        }

    }

    return 0;

}


static void bdrv_co_io_em_complete(void *opaque, int ret)

{

    CoroutineIOCompletion *co = opaque;

    co->ret = ret;

    qemu_coroutine_enter(co->coroutine, NULL);

}


void HELPER(diag)(CPUS390XState *env, uint32_t r1, uint32_t r3, uint32_t num)

{

    uint64_t r;

    switch (num) {

    case 0x500:

        /* KVM hypercall */

        r = s390_virtio_hypercall(env);

        break;

    case 0x44:

        /* yield */

        r = 0;

        break;

    case 0x308:

        /* ipl */

        handle_diag_308(env, r1, r3);

        r = 0;

        break;

    case 0x288:

        /* time bomb (watchdog) */

        r = handle_diag_288(env, r1, r3);

        break;

    default:

        r = -1;

        break;

    }

    if (r) {

        program_interrupt(env, PGM_SPECIFICATION, ILEN_AUTO);

    }

}


static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)

{

    fdrive_t *cur_drv;

    uint32_t retval = 0;

    int pos, len;

    cur_drv = get_cur_drv(fdctrl);

    fdctrl->state &= ~FD_CTRL_SLEEP;

    if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) {

        FLOPPY_ERROR("can't read data in CMD state\n");

        return 0;

    }

    pos = fdctrl->data_pos;

    if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {

        pos %= FD_SECTOR_LEN;

        if (pos == 0) {

            len = fdctrl->data_len - fdctrl->data_pos;

            if (len > FD_SECTOR_LEN)

                len = FD_SECTOR_LEN;

            bdrv_read(cur_drv->bs, fd_sector(cur_drv),

                      fdctrl->fifo, len);

        }

    }

    retval = fdctrl->fifo[pos];

    if (++fdctrl->data_pos == fdctrl->data_len) {

        fdctrl->data_pos = 0;

        /* Switch from transfer mode to status mode

         * then from status mode to command mode

         */

        if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {

            fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);

        } else {

            fdctrl_reset_fifo(fdctrl);

            fdctrl_reset_irq(fdctrl);

        }

    }

    FLOPPY_DPRINTF("data register: 0x%02x\n", retval);

    return retval;

}


static void scsi_dma_complete(void *opaque, int ret)

{

    SCSIDiskReq *r = (SCSIDiskReq *)opaque;

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    if (r->req.aiocb != NULL) {

        r->req.aiocb = NULL;

        bdrv_acct_done(s->qdev.conf.bs, &r->acct);

    }

    if (ret < 0) {

        if (scsi_handle_rw_error(r, -ret)) {

            goto done;

        }

    }

    r->sector += r->sector_count;

    r->sector_count = 0;

    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {

        scsi_write_do_fua(r);

        return;

    } else {

        scsi_req_complete(&r->req, GOOD);

    }

done:

    if (!r->req.io_canceled) {

        scsi_req_unref(&r->req);

    }

}


static inline void validate_seg(int seg_reg, int cpl)

{

    int dpl;

    uint32_t e2;

    e2 = env->segs[seg_reg].flags;

    dpl = (e2 >> DESC_DPL_SHIFT) & 3;

    if (!(e2 & DESC_CS_MASK) || !(e2 & DESC_C_MASK)) {

        /* data or non conforming code segment */

        if (dpl < cpl) {

            cpu_x86_load_seg_cache(env, seg_reg, 0, 0, 0, 0);

        }

    }

}


static void realize(DeviceState *d, Error **errp)

{

    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);

    sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    Object *root_container;

    char link_name[256];

    gchar *child_name;

    Error *err = NULL;

    DPRINTFN("drc realize: %x", drck->get_index(drc));

    /* NOTE: we do this as part of realize/unrealize due to the fact

     * that the guest will communicate with the DRC via RTAS calls

     * referencing the global DRC index. By unlinking the DRC

     * from DRC_CONTAINER_PATH/<drc_index> we effectively make it

     * inaccessible by the guest, since lookups rely on this path

     * existing in the composition tree

     */

    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);

    snprintf(link_name, sizeof(link_name), "%x", drck->get_index(drc));

    child_name = object_get_canonical_path_component(OBJECT(drc));

    DPRINTFN("drc child name: %s", child_name);

    object_property_add_alias(root_container, link_name,

                              drc->owner, child_name, &err);

    if (err) {

        error_report("%s", error_get_pretty(err));

        error_free(err);

        object_unref(OBJECT(drc));

    }

    DPRINTFN("drc realize complete");

}


connect_to_qemu(

    const char *host,

    const char *port

) {

    struct addrinfo hints;

    struct addrinfo *server;

    int ret, sock;

    sock = qemu_socket(AF_INET, SOCK_STREAM, 0);

    if (sock < 0) {

        /* Error */

        fprintf(stderr, "Error opening socket!\n");

        return -1;

    }

    memset(&hints, 0, sizeof(struct addrinfo));

    hints.ai_family = AF_UNSPEC;

    hints.ai_socktype = SOCK_STREAM;

    hints.ai_flags = 0;

    hints.ai_protocol = 0;          /* Any protocol */

    ret = getaddrinfo(host, port, &hints, &server);

    if (ret != 0) {

        /* Error */

        fprintf(stderr, "getaddrinfo failed\n");

        return -1;

    }

    if (connect(sock, server->ai_addr, server->ai_addrlen) < 0) {

        /* Error */

        fprintf(stderr, "Could not connect\n");

        return -1;

    }

    if (verbose) {

        printf("Connected (sizeof Header=%zd)!\n", sizeof(VSCMsgHeader));

    }

    return sock;

}


void ff_init_block_index(MpegEncContext *s){ //FIXME maybe rename

    const int linesize   = s->current_picture.f.linesize[0]; //not s->linesize as this would be wrong for field pics

    const int uvlinesize = s->current_picture.f.linesize[1];

    const int mb_size= 4;

    s->block_index[0]= s->b8_stride*(s->mb_y*2    ) - 2 + s->mb_x*2;

    s->block_index[1]= s->b8_stride*(s->mb_y*2    ) - 1 + s->mb_x*2;

    s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2;

    s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2;

    s->block_index[4]= s->mb_stride*(s->mb_y + 1)                + s->b8_stride*s->mb_height*2 + s->mb_x - 1;

    s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;

    //block_index is not used by mpeg2, so it is not affected by chroma_format

    s->dest[0] = s->current_picture.f.data[0] + ((s->mb_x - 1) <<  mb_size);

    s->dest[1] = s->current_picture.f.data[1] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));

    s->dest[2] = s->current_picture.f.data[2] + ((s->mb_x - 1) << (mb_size - s->chroma_x_shift));

    if(!(s->pict_type==AV_PICTURE_TYPE_B && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME))

    {

        if(s->picture_structure==PICT_FRAME){

        s->dest[0] += s->mb_y *   linesize << mb_size;

        s->dest[1] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);

        s->dest[2] += s->mb_y * uvlinesize << (mb_size - s->chroma_y_shift);

        }else{

            s->dest[0] += (s->mb_y>>1) *   linesize << mb_size;

            s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);

            s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);

            assert((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD));

        }

    }

}


static void virtio_net_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->exit = virtio_net_device_exit;

    dc->props = virtio_net_properties;

    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);

    vdc->init = virtio_net_device_init;

    vdc->get_config = virtio_net_get_config;

    vdc->set_config = virtio_net_set_config;

    vdc->get_features = virtio_net_get_features;

    vdc->set_features = virtio_net_set_features;

    vdc->bad_features = virtio_net_bad_features;

    vdc->reset = virtio_net_reset;

    vdc->set_status = virtio_net_set_status;

    vdc->guest_notifier_mask = virtio_net_guest_notifier_mask;

    vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;

}


static int decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)

{

    int compno, reslevelno, bandno;

    int x, y;

    uint8_t *line;

    Jpeg2000T1Context t1;

    /* Loop on tile components */

    for (compno = 0; compno < s->ncomponents; compno++) {

        Jpeg2000Component *comp     = tile->comp + compno;

        Jpeg2000CodingStyle *codsty = tile->codsty + compno;

        /* Loop on resolution levels */

        for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {

            Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;

            /* Loop on bands */

            for (bandno = 0; bandno < rlevel->nbands; bandno++) {

                int nb_precincts, precno;

                Jpeg2000Band *band = rlevel->band + bandno;

                int cblkno=0, bandpos;

                bandpos = bandno + (reslevelno > 0);

                if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])

                    continue;

                nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;

                /* Loop on precincts */

                for (precno = 0; precno < nb_precincts; precno++) {

                    Jpeg2000Prec *prec = band->prec + precno;

                    /* Loop on codeblocks */

                    for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {

                        int x, y;

                        Jpeg2000Cblk *cblk = prec->cblk + cblkno;

                        decode_cblk(s, codsty, &t1, cblk,

                                    cblk->coord[0][1] - cblk->coord[0][0],

                                    cblk->coord[1][1] - cblk->coord[1][0],

                                    bandpos);

                        /* Manage band offsets */

                        x = cblk->coord[0][0];

                        y = cblk->coord[1][0];

                        if (codsty->transform == FF_DWT97)

                            dequantization_float(x, y, cblk, comp, &t1, band);

                        else

                            dequantization_int(x, y, cblk, comp, &t1, band);

                   } /* end cblk */

                } /*end prec */

            } /* end band */

        } /* end reslevel */

        ff_dwt_decode(&comp->dwt, comp->data);

    } /*end comp */

    /* inverse MCT transformation */

    if (tile->codsty[0].mct)

        mct_decode(s, tile);

    if (s->precision <= 8) {

        for (compno = 0; compno < s->ncomponents; compno++) {

            Jpeg2000Component *comp = tile->comp + compno;

            float *datap = (float*)comp->data;

            int32_t *i_datap = (int32_t *) comp->data;

            y = tile->comp[compno].coord[1][0] - s->image_offset_y;

            line = s->picture->data[0] + y * s->picture->linesize[0];

            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {

                uint8_t *dst;

                x   = tile->comp[compno].coord[0][0] - s->image_offset_x;

                dst = line + x * s->ncomponents + compno;

                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) {

                     int val;

                    /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */

                    if (tile->codsty->transform == FF_DWT97)

                        val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));

                    else

                        val = *i_datap + (1 << (s->cbps[compno] - 1));

                    val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);

                    *dst = val << (8 - s->cbps[compno]);

                    datap++;

                    i_datap++;

                    dst += s->ncomponents;

                }

                line += s->picture->linesize[0];

            }

        }

    } else {

        for (compno = 0; compno < s->ncomponents; compno++) {

            Jpeg2000Component *comp = tile->comp + compno;

            float *datap = (float*)comp->data;

            int32_t *i_datap = (int32_t *) comp->data;

            uint16_t *linel;

            y     = tile->comp[compno].coord[1][0] - s->image_offset_y;

            linel = (uint16_t*)s->picture->data[0] + y * (s->picture->linesize[0] >> 1);

            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {

                uint16_t *dst;

                x = tile->comp[compno].coord[0][0] - s->image_offset_x;

                dst = linel + (x * s->ncomponents + compno);

                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) {

                     int val;

                    /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */

                    if (tile->codsty->transform == FF_DWT97)

                        val = lrintf(*datap) + (1 << (s->cbps[compno] - 1));

                    else

                        val = *i_datap + (1 << (s->cbps[compno] - 1));

                    val = av_clip(val, 0, (1 << s->cbps[compno]) - 1);

                    /* align 12 bit values in little-endian mode */

                    *dst = val << (16 - s->cbps[compno]);

                    datap++;

                    i_datap++;

                    dst += s->ncomponents;

                }

                linel += s->picture->linesize[0]>>1;

            }

        }

    }

    return 0;

}


int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,

                          const uint8_t *buf, int nb_sectors)

{

    BlockDriver *drv = bs->drv;

    if (!drv)

        return -ENOMEDIUM;

    if (!drv->bdrv_write_compressed)

        return -ENOTSUP;

    if (bdrv_check_request(bs, sector_num, nb_sectors))

        return -EIO;

    if (bs->dirty_tracking) {

        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);

    }

    return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);

}


static void moxie_cpu_class_init(ObjectClass *oc, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    CPUClass *cc = CPU_CLASS(oc);

    MoxieCPUClass *mcc = MOXIE_CPU_CLASS(oc);

    mcc->parent_realize = dc->realize;

    dc->realize = moxie_cpu_realizefn;

    mcc->parent_reset = cc->reset;

    cc->reset = moxie_cpu_reset;

    cc->class_by_name = moxie_cpu_class_by_name;

    cc->has_work = moxie_cpu_has_work;

    cc->do_interrupt = moxie_cpu_do_interrupt;

    cc->dump_state = moxie_cpu_dump_state;

    cc->set_pc = moxie_cpu_set_pc;

#ifdef CONFIG_USER_ONLY

    cc->handle_mmu_fault = moxie_cpu_handle_mmu_fault;

#else

    cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;

    cc->vmsd = &vmstate_moxie_cpu;

#endif

    cc->disas_set_info = moxie_cpu_disas_set_info;

    /*

     * Reason: moxie_cpu_initfn() calls cpu_exec_init(), which saves

     * the object in cpus -> dangling pointer after final

     * object_unref().

     */

    dc->cannot_destroy_with_object_finalize_yet = true;

}


static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb)

{

    int ret;

    MpegEncContext *s     = &v->s;

    AVCodecContext *avctx = s->avctx;

    SpriteData sd;

    memset(&sd, 0, sizeof(sd));

    ret = vc1_parse_sprites(v, gb, &sd);

    if (ret < 0)

        return ret;

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

        av_log(avctx, AV_LOG_ERROR, "Got no sprites\n");

        return -1;

    }

    if (v->two_sprites && (!s->last_picture_ptr || !s->last_picture.f->data[0])) {

        av_log(avctx, AV_LOG_WARNING, "Need two sprites, only got one\n");

        v->two_sprites = 0;

    }

    av_frame_unref(v->sprite_output_frame);

    if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0)

        return ret;

    vc1_draw_sprites(v, &sd);

    return 0;

}


yuv2yuvX_altivec_real(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

		      int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

		      uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)

{

  const vector signed int vini = {(1 << 18), (1 << 18), (1 << 18), (1 << 18)};

  register int i, j;

  {

    int __attribute__ ((aligned (16))) val[dstW];

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

      vec_st(vini, i << 2, val);

    }

    for (; i < dstW; i++) {

      val[i] = (1 << 18);

    }

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

      vector signed short l1, vLumFilter = vec_ld(j << 1, lumFilter);

      vector unsigned char perm, perm0 = vec_lvsl(j << 1, lumFilter);

      vLumFilter = vec_perm(vLumFilter, vLumFilter, perm0);

      vLumFilter = vec_splat(vLumFilter, 0); // lumFilter[j] is loaded 8 times in vLumFilter

      perm = vec_lvsl(0, lumSrc[j]);

      l1 = vec_ld(0, lumSrc[j]);

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

	int offset = i << 2;

	vector signed short l2 = vec_ld((i << 1) + 16, lumSrc[j]);

	vector signed int v1 = vec_ld(offset, val);

	vector signed int v2 = vec_ld(offset + 16, val);

	vector signed short ls = vec_perm(l1, l2, perm); // lumSrc[j][i] ... lumSrc[j][i+7]

	vector signed int i1 = vec_mule(vLumFilter, ls);

	vector signed int i2 = vec_mulo(vLumFilter, ls);

	vector signed int vf1 = vec_mergeh(i1, i2);

	vector signed int vf2 = vec_mergel(i1, i2); // lumSrc[j][i] * lumFilter[j] ... lumSrc[j][i+7] * lumFilter[j]

	vector signed int vo1 = vec_add(v1, vf1);

	vector signed int vo2 = vec_add(v2, vf2);

	vec_st(vo1, offset, val);

	vec_st(vo2, offset + 16, val);

	l1 = l2;

      }

      for ( ; i < dstW; i++) {

	val[i] += lumSrc[j][i] * lumFilter[j];

      }

    }

    altivec_packIntArrayToCharArray(val,dest,dstW);

  }

  if (uDest != 0) {

    int  __attribute__ ((aligned (16))) u[chrDstW];

    int  __attribute__ ((aligned (16))) v[chrDstW];

    for (i = 0; i < (chrDstW -7); i+=4) {

      vec_st(vini, i << 2, u);

      vec_st(vini, i << 2, v);

    }

    for (; i < chrDstW; i++) {

      u[i] = (1 << 18);

      v[i] = (1 << 18);

    }

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

      vector signed short l1, l1_V, vChrFilter = vec_ld(j << 1, chrFilter);

      vector unsigned char perm, perm0 = vec_lvsl(j << 1, chrFilter);

      vChrFilter = vec_perm(vChrFilter, vChrFilter, perm0);

      vChrFilter = vec_splat(vChrFilter, 0); // chrFilter[j] is loaded 8 times in vChrFilter

      perm = vec_lvsl(0, chrSrc[j]);

      l1 = vec_ld(0, chrSrc[j]);

      l1_V = vec_ld(2048 << 1, chrSrc[j]);

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

	int offset = i << 2;

	vector signed short l2 = vec_ld((i << 1) + 16, chrSrc[j]);

	vector signed short l2_V = vec_ld(((i + 2048) << 1) + 16, chrSrc[j]);

	vector signed int v1 = vec_ld(offset, u);

	vector signed int v2 = vec_ld(offset + 16, u);

	vector signed int v1_V = vec_ld(offset, v);

	vector signed int v2_V = vec_ld(offset + 16, v);

	vector signed short ls = vec_perm(l1, l2, perm); // chrSrc[j][i] ... chrSrc[j][i+7]

	vector signed short ls_V = vec_perm(l1_V, l2_V, perm); // chrSrc[j][i+2048] ... chrSrc[j][i+2055]

	vector signed int i1 = vec_mule(vChrFilter, ls);

	vector signed int i2 = vec_mulo(vChrFilter, ls);

	vector signed int i1_V = vec_mule(vChrFilter, ls_V);

	vector signed int i2_V = vec_mulo(vChrFilter, ls_V);

	vector signed int vf1 = vec_mergeh(i1, i2);

	vector signed int vf2 = vec_mergel(i1, i2); // chrSrc[j][i] * chrFilter[j] ... chrSrc[j][i+7] * chrFilter[j]

	vector signed int vf1_V = vec_mergeh(i1_V, i2_V);

	vector signed int vf2_V = vec_mergel(i1_V, i2_V); // chrSrc[j][i] * chrFilter[j] ... chrSrc[j][i+7] * chrFilter[j]

	vector signed int vo1 = vec_add(v1, vf1);

	vector signed int vo2 = vec_add(v2, vf2);

	vector signed int vo1_V = vec_add(v1_V, vf1_V);

	vector signed int vo2_V = vec_add(v2_V, vf2_V);

	vec_st(vo1, offset, u);

	vec_st(vo2, offset + 16, u);

	vec_st(vo1_V, offset, v);

	vec_st(vo2_V, offset + 16, v);

	l1 = l2;

	l1_V = l2_V;

      }

      for ( ; i < chrDstW; i++) {

	u[i] += chrSrc[j][i] * chrFilter[j];

	v[i] += chrSrc[j][i + 2048] * chrFilter[j];

      }

    }

    altivec_packIntArrayToCharArray(u,uDest,chrDstW);

    altivec_packIntArrayToCharArray(v,vDest,chrDstW);

  }

}


static void m5206_mbar_writeb(void *opaque, target_phys_addr_t offset,

                              uint32_t value)

{

    m5206_mbar_state *s = (m5206_mbar_state *)opaque;

    int width;

    offset &= 0x3ff;

    if (offset > 0x200) {

        hw_error("Bad MBAR write offset 0x%x", (int)offset);

    }

    width = m5206_mbar_width[offset >> 2];

    if (width > 1) {

        uint32_t tmp;

        tmp = m5206_mbar_readw(opaque, offset & ~1);

        if (offset & 1) {

            tmp = (tmp & 0xff00) | value;

        } else {

            tmp = (tmp & 0x00ff) | (value << 8);

        }

        m5206_mbar_writew(opaque, offset & ~1, tmp);

        return;

    }

    m5206_mbar_write(s, offset, value, 1);

}


static bool is_zero_sectors(BlockDriverState *bs, int64_t start,
                            uint32_t count)
{
    int nr;
    BlockDriverState *file;
    int64_t res;
    if (!count) {
        return true;
    res = bdrv_get_block_status_above(bs, NULL, start, count,
                                      &nr, &file);
    return res >= 0 && (res & BDRV_BLOCK_ZERO) && nr == count;


static void mxf_write_multi_descriptor(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    AVIOContext *pb = s->pb;

    const uint8_t *ul;

    int i;

    mxf_write_metadata_key(pb, 0x014400);

    PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16);

    klv_encode_ber_length(pb, 64 + 16 * s->nb_streams);

    mxf_write_local_tag(pb, 16, 0x3C0A);

    mxf_write_uuid(pb, MultipleDescriptor, 0);

    PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16);

    // write sample rate

    mxf_write_local_tag(pb, 8, 0x3001);

    avio_wb32(pb, mxf->time_base.den);

    avio_wb32(pb, mxf->time_base.num);

    // write essence container ul

    mxf_write_local_tag(pb, 16, 0x3004);

    if (mxf->essence_container_count > 1)

        ul = multiple_desc_ul;

    else {

        MXFStreamContext *sc = s->streams[0]->priv_data;

        ul = mxf_essence_container_uls[sc->index].container_ul;

    }

    avio_write(pb, ul, 16);

    // write sub descriptor refs

    mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01);

    mxf_write_refs_count(pb, s->nb_streams);

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

        mxf_write_uuid(pb, SubDescriptor, i);

}


BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)

{

    BlockDeviceInfo *info = g_malloc0(sizeof(*info));

    info->file                   = g_strdup(bs->filename);

    info->ro                     = bs->read_only;

    info->drv                    = g_strdup(bs->drv->format_name);

    info->encrypted              = bs->encrypted;

    info->encryption_key_missing = bdrv_key_required(bs);

    info->cache = g_new(BlockdevCacheInfo, 1);

    *info->cache = (BlockdevCacheInfo) {

        .writeback      = bdrv_enable_write_cache(bs),

        .direct         = !!(bs->open_flags & BDRV_O_NOCACHE),

        .no_flush       = !!(bs->open_flags & BDRV_O_NO_FLUSH),

    };

    if (bs->node_name[0]) {

        info->has_node_name = true;

        info->node_name = g_strdup(bs->node_name);

    }

    if (bs->backing_file[0]) {

        info->has_backing_file = true;

        info->backing_file = g_strdup(bs->backing_file);

    }

    info->backing_file_depth = bdrv_get_backing_file_depth(bs);

    info->detect_zeroes = bs->detect_zeroes;

    if (bs->io_limits_enabled) {

        ThrottleConfig cfg;

        throttle_get_config(&bs->throttle_state, &cfg);

        info->bps     = cfg.buckets[THROTTLE_BPS_TOTAL].avg;

        info->bps_rd  = cfg.buckets[THROTTLE_BPS_READ].avg;

        info->bps_wr  = cfg.buckets[THROTTLE_BPS_WRITE].avg;

        info->iops    = cfg.buckets[THROTTLE_OPS_TOTAL].avg;

        info->iops_rd = cfg.buckets[THROTTLE_OPS_READ].avg;

        info->iops_wr = cfg.buckets[THROTTLE_OPS_WRITE].avg;

        info->has_bps_max     = cfg.buckets[THROTTLE_BPS_TOTAL].max;

        info->bps_max         = cfg.buckets[THROTTLE_BPS_TOTAL].max;

        info->has_bps_rd_max  = cfg.buckets[THROTTLE_BPS_READ].max;

        info->bps_rd_max      = cfg.buckets[THROTTLE_BPS_READ].max;

        info->has_bps_wr_max  = cfg.buckets[THROTTLE_BPS_WRITE].max;

        info->bps_wr_max      = cfg.buckets[THROTTLE_BPS_WRITE].max;

        info->has_iops_max    = cfg.buckets[THROTTLE_OPS_TOTAL].max;

        info->iops_max        = cfg.buckets[THROTTLE_OPS_TOTAL].max;

        info->has_iops_rd_max = cfg.buckets[THROTTLE_OPS_READ].max;

        info->iops_rd_max     = cfg.buckets[THROTTLE_OPS_READ].max;

        info->has_iops_wr_max = cfg.buckets[THROTTLE_OPS_WRITE].max;

        info->iops_wr_max     = cfg.buckets[THROTTLE_OPS_WRITE].max;

        info->has_iops_size = cfg.op_size;

        info->iops_size = cfg.op_size;

    }

    info->write_threshold = bdrv_write_threshold_get(bs);

    return info;

}


void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)

{

    GtkDisplayState *s = g_malloc0(sizeof(*s));

    char *filename;

    gtk_init(NULL, NULL);

    s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

#if GTK_CHECK_VERSION(3, 2, 0)

    s->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

#else

    s->vbox = gtk_vbox_new(FALSE, 0);

#endif

    s->notebook = gtk_notebook_new();

    s->menu_bar = gtk_menu_bar_new();

    s->free_scale = FALSE;

    setlocale(LC_ALL, "");

    bindtextdomain("qemu", CONFIG_QEMU_LOCALEDIR);

    textdomain("qemu");

    s->null_cursor = gdk_cursor_new(GDK_BLANK_CURSOR);

    s->mouse_mode_notifier.notify = gd_mouse_mode_change;

    qemu_add_mouse_mode_change_notifier(&s->mouse_mode_notifier);

    qemu_add_vm_change_state_handler(gd_change_runstate, s);

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu_logo_no_text.svg");

    if (filename) {

        GError *error = NULL;

        GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error);

        if (pixbuf) {

            gtk_window_set_icon(GTK_WINDOW(s->window), pixbuf);

        } else {

            g_error_free(error);

        }

        g_free(filename);

    }

    gd_create_menus(s);

    gd_connect_signals(s);

    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(s->notebook), FALSE);

    gtk_notebook_set_show_border(GTK_NOTEBOOK(s->notebook), FALSE);

    gd_update_caption(s);

    gtk_box_pack_start(GTK_BOX(s->vbox), s->menu_bar, FALSE, TRUE, 0);

    gtk_box_pack_start(GTK_BOX(s->vbox), s->notebook, TRUE, TRUE, 0);

    gtk_container_add(GTK_CONTAINER(s->window), s->vbox);

    gtk_widget_show_all(s->window);

#ifdef VTE_RESIZE_HACK

    {

        VirtualConsole *cur = gd_vc_find_current(s);

        int i;

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

            VirtualConsole *vc = &s->vc[i];

            if (vc && vc->type == GD_VC_VTE && vc != cur) {

                gtk_widget_hide(vc->vte.terminal);

            }

        }

        gd_update_windowsize(cur);

    }

#endif

    if (full_screen) {

        gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));

    }

    if (grab_on_hover) {

        gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));

    }

    gd_set_keycode_type(s);

}


static int analyze(const uint8_t *buf, int size, int packet_size,

                   int probe)

{

    int stat[TS_MAX_PACKET_SIZE];

    int stat_all = 0;

    int i;

    int best_score = 0;

    memset(stat, 0, packet_size * sizeof(*stat));

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

        if (buf[i] == 0x47 &&

            (!probe || (buf[i + 3] & 0x30))) {

            int x = i % packet_size;

            stat[x]++;

            stat_all++;

            if (stat[x] > best_score) {

                best_score = stat[x];

            }

        }

    }

    return best_score - FFMAX(stat_all - 10*best_score, 0)/10;

}


static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat,

                           Node *nodes, int node,

                           uint32_t pfx, int pl, int *pos)

{

    int s;

    s = nodes[node].sym;

    if (s != -1) {

        bits[*pos] = (~pfx) & ((1U << FFMAX(pl, 1)) - 1);

        lens[*pos] = FFMAX(pl, 1);

        xlat[*pos] = s + (pl == 0);

        (*pos)++;

    } else {

        pfx <<= 1;

        pl++;

        get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl,

                       pos);

        pfx |= 1;

        get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl,

                       pos);

    }

}


static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size,

                  const uint8_t *n_val)

{

    OMAContext *oc = s->priv_data;

    uint64_t pos;

    uint32_t taglen, datalen;

    struct AVDES av_des;

    if (!enc_header || !n_val ||

        size < OMA_ENC_HEADER_SIZE + oc->k_size + 4)

        return -1;

    pos = OMA_ENC_HEADER_SIZE + oc->k_size;

    if (!memcmp(&enc_header[pos], "EKB ", 4))

        pos += 32;

    if (size < pos + 44)

        return -1;

    if (AV_RB32(&enc_header[pos]) != oc->rid)

        av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");

    taglen  = AV_RB32(&enc_header[pos + 32]);

    datalen = AV_RB32(&enc_header[pos + 36]) >> 4;

    pos += 44;

    if (size - pos < taglen)

        return -1;

    pos += taglen;

    if (pos + (((uint64_t)datalen) << 4) > size)

        return -1;

    av_des_init(&av_des, n_val, 192, 1);

    while (datalen-- > 0) {

        av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);

        kset(s, oc->r_val, NULL, 16);

        if (!rprobe(s, enc_header, size, oc->r_val))

            return 0;

        pos += 16;

    }

    return -1;

}


static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitch)

{

    int x, y;

    pitch -= block_size;

    for (y = 0; y != block_size; y++, pdest += pitch)

        for (x = 0; x != block_size; x++)

            *pdest++ = color;

}


static void ini_print_section_header(WriterContext *wctx)

{

    INIContext *ini = wctx->priv;

    AVBPrint buf;

    int i;

    const struct section *section = wctx->section[wctx->level];

    const struct section *parent_section = wctx->level ?

        wctx->section[wctx->level-1] : NULL;

    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);

    if (wctx->level == 0) {

        printf("# ffprobe output\n\n");

        return;

    }

    if (wctx->nb_item[wctx->level-1])

        printf("\n");

    for (i = 1; i <= wctx->level; i++) {

        if (ini->hierarchical ||

            !(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER)))

            av_bprintf(&buf, "%s%s", i>1 ? "." : "", wctx->section[i]->name);

    }

    if (parent_section->flags & SECTION_FLAG_IS_ARRAY) {

        int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ?

            wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1];

        av_bprintf(&buf, ".%d", n);

    }

    if (!(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER)))

        printf("[%s]\n", buf.str);

    av_bprint_finalize(&buf, NULL);

}


static int vtd_interrupt_remap_msi(IntelIOMMUState *iommu,

                                   MSIMessage *origin,

                                   MSIMessage *translated)

{

    int ret = 0;

    VTD_IR_MSIAddress addr;

    uint16_t index;

    VTDIrq irq = {0};

    assert(origin && translated);

    if (!iommu || !iommu->intr_enabled) {

        goto do_not_translate;

    }

    if (origin->address & VTD_MSI_ADDR_HI_MASK) {

        VTD_DPRINTF(GENERAL, "error: MSI addr high 32 bits nonzero"

                    " during interrupt remapping: 0x%"PRIx32,

                    (uint32_t)((origin->address & VTD_MSI_ADDR_HI_MASK) >> \

                    VTD_MSI_ADDR_HI_SHIFT));

        return -VTD_FR_IR_REQ_RSVD;

    }

    addr.data = origin->address & VTD_MSI_ADDR_LO_MASK;

    if (le16_to_cpu(addr.__head) != 0xfee) {

        VTD_DPRINTF(GENERAL, "error: MSI addr low 32 bits invalid: "

                    "0x%"PRIx32, addr.data);

        return -VTD_FR_IR_REQ_RSVD;

    }

    /* This is compatible mode. */

    if (addr.int_mode != VTD_IR_INT_FORMAT_REMAP) {

        goto do_not_translate;

    }

    index = addr.index_h << 15 | le16_to_cpu(addr.index_l);

#define  VTD_IR_MSI_DATA_SUBHANDLE       (0x0000ffff)

#define  VTD_IR_MSI_DATA_RESERVED        (0xffff0000)

    if (addr.sub_valid) {

        /* See VT-d spec 5.1.2.2 and 5.1.3 on subhandle */

        index += origin->data & VTD_IR_MSI_DATA_SUBHANDLE;

    }

    ret = vtd_remap_irq_get(iommu, index, &irq);

    if (ret) {

        return ret;

    }

    if (addr.sub_valid) {

        VTD_DPRINTF(IR, "received MSI interrupt");

        if (origin->data & VTD_IR_MSI_DATA_RESERVED) {

            VTD_DPRINTF(GENERAL, "error: MSI data bits non-zero for "

                        "interrupt remappable entry: 0x%"PRIx32,

                        origin->data);

            return -VTD_FR_IR_REQ_RSVD;

        }

    } else {

        uint8_t vector = origin->data & 0xff;

        VTD_DPRINTF(IR, "received IOAPIC interrupt");

        /* IOAPIC entry vector should be aligned with IRTE vector

         * (see vt-d spec 5.1.5.1). */

        if (vector != irq.vector) {

            VTD_DPRINTF(GENERAL, "IOAPIC vector inconsistent: "

                        "entry: %d, IRTE: %d, index: %d",

                        vector, irq.vector, index);

        }

    }

    /*

     * We'd better keep the last two bits, assuming that guest OS

     * might modify it. Keep it does not hurt after all.

     */

    irq.msi_addr_last_bits = addr.__not_care;

    /* Translate VTDIrq to MSI message */

    vtd_generate_msi_message(&irq, translated);

    VTD_DPRINTF(IR, "mapping MSI 0x%"PRIx64":0x%"PRIx32 " -> "

                "0x%"PRIx64":0x%"PRIx32, origin->address, origin->data,

                translated->address, translated->data);

    return 0;

do_not_translate:

    memcpy(translated, origin, sizeof(*origin));

    return 0;

}


static int decode_mb_cabac(H264Context *h) {

    MpegEncContext * const s = &h->s;

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

    int mb_type, partition_count, cbp = 0;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong?)

    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);

    if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE ) {

        int skip;

        /* a skipped mb needs the aff flag from the following mb */

        if( FRAME_MBAFF && s->mb_x==0 && (s->mb_y&1)==0 )

            predict_field_decoding_flag(h);

        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )

            skip = h->next_mb_skipped;

        else

            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );

        /* read skip flags */

        if( skip ) {

            if( FRAME_MBAFF && (s->mb_y&1)==0 ){

                s->current_picture.mb_type[mb_xy] = MB_TYPE_SKIP;

                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );

                if(h->next_mb_skipped)

                    predict_field_decoding_flag(h);

                else

                    h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

            }

            decode_mb_skip(h);

            h->cbp_table[mb_xy] = 0;

            h->chroma_pred_mode_table[mb_xy] = 0;

            h->last_qscale_diff = 0;

            return 0;

        }

    }

    if(FRAME_MBAFF){

        if( (s->mb_y&1) == 0 )

            h->mb_mbaff =

            h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

    }else

        h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME);

    h->prev_mb_skipped = 0;

    compute_mb_neighbors(h);

    if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) {

        av_log( h->s.avctx, AV_LOG_ERROR, "decode_cabac_mb_type failed\n" );

        return -1;

    }

    if( h->slice_type == B_TYPE ) {

        if( mb_type < 23 ){

            partition_count= b_mb_type_info[mb_type].partition_count;

            mb_type=         b_mb_type_info[mb_type].type;

        }else{

            mb_type -= 23;

            goto decode_intra_mb;

        }

    } else if( h->slice_type == P_TYPE ) {

        if( mb_type < 5) {

            partition_count= p_mb_type_info[mb_type].partition_count;

            mb_type=         p_mb_type_info[mb_type].type;

        } else {

            mb_type -= 5;

            goto decode_intra_mb;

        }

    } else {

       assert(h->slice_type == I_TYPE);

decode_intra_mb:

        partition_count = 0;

        cbp= i_mb_type_info[mb_type].cbp;

        h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;

        mb_type= i_mb_type_info[mb_type].type;

    }

    if(MB_FIELD)

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[ mb_xy ]= h->slice_num;

    if(IS_INTRA_PCM(mb_type)) {

        const uint8_t *ptr;

        unsigned int x, y;

        // We assume these blocks are very rare so we do not optimize it.

        // FIXME The two following lines get the bitstream position in the cabac

        // decode, I think it should be done by a function in cabac.h (or cabac.c).

        ptr= h->cabac.bytestream;

        if(h->cabac.low&0x1) ptr--;

        if(CABAC_BITS==16){

            if(h->cabac.low&0x1FF) ptr--;

        }

        // The pixels are stored in the same order as levels in h->mb array.

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

            const int index= 4*(y&3) + 32*((y>>2)&1) + 128*(y>>3);

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

                tprintf(s->avctx, "LUMA ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*((x>>2)&1) + 64*(x>>3)]= *ptr++;

            }

        }

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

            const int index= 256 + 4*(y&3) + 32*(y>>2);

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

                tprintf(s->avctx, "CHROMA U ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*(x>>2)]= *ptr++;

            }

        }

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

            const int index= 256 + 64 + 4*(y&3) + 32*(y>>2);

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

                tprintf(s->avctx, "CHROMA V ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*(x>>2)]= *ptr++;

            }

        }

        ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);

        // All blocks are present

        h->cbp_table[mb_xy] = 0x1ef;

        h->chroma_pred_mode_table[mb_xy] = 0;

        // In deblocking, the quantizer is 0

        s->current_picture.qscale_table[mb_xy]= 0;

        h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0);

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 16);

        s->current_picture.mb_type[mb_xy]= mb_type;

        return 0;

    }

    if(MB_MBAFF){

        h->ref_count[0] <<= 1;

        h->ref_count[1] <<= 1;

    }

    fill_caches(h, mb_type, 0);

    if( IS_INTRA( mb_type ) ) {

        int i, pred_mode;

        if( IS_INTRA4x4( mb_type ) ) {

            if( dct8x8_allowed && decode_cabac_mb_transform_size( h ) ) {

                mb_type |= MB_TYPE_8x8DCT;

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

                    int pred = pred_intra_mode( h, i );

                    int mode = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                    fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );

                }

            } else {

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

                    int pred = pred_intra_mode( h, i );

                    h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                //av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );

                }

            }

            write_back_intra_pred_mode(h);

            if( check_intra4x4_pred_mode(h) < 0 ) return -1;

        } else {

            h->intra16x16_pred_mode= check_intra_pred_mode( h, h->intra16x16_pred_mode );

            if( h->intra16x16_pred_mode < 0 ) return -1;

        }

        h->chroma_pred_mode_table[mb_xy] =

        pred_mode                        = decode_cabac_mb_chroma_pre_mode( h );

        pred_mode= check_intra_pred_mode( h, pred_mode );

        if( pred_mode < 0 ) return -1;

        h->chroma_pred_mode= pred_mode;

    } else if( partition_count == 4 ) {

        int i, j, sub_partition_count[4], list, ref[2][4];

        if( h->slice_type == B_TYPE ) {

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

                h->sub_mb_type[i] = decode_cabac_b_mb_sub_type( h );

                sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      b_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

            if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] |

                          h->sub_mb_type[2] | h->sub_mb_type[3]) ) {

                pred_direct_motion(h, &mb_type);

                if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) {

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

                        if( IS_DIRECT(h->sub_mb_type[i]) )

                            fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, 1, 1 );

                }

            }

        } else {

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

                h->sub_mb_type[i] = decode_cabac_p_mb_sub_type( h );

                sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      p_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

        }

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

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

                    if(IS_DIRECT(h->sub_mb_type[i])) continue;

                    if(IS_DIR(h->sub_mb_type[i], 0, list)){

                        if( h->ref_count[list] > 1 )

                            ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );

                        else

                            ref[list][i] = 0;

                    } else {

                        ref[list][i] = -1;

                    }

                                                       h->ref_cache[list][ scan8[4*i]+1 ]=

                    h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h);

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

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

                if(IS_DIRECT(h->sub_mb_type[i])){

                    fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 4);

                    continue;

                }

                h->ref_cache[list][ scan8[4*i]   ]=h->ref_cache[list][ scan8[4*i]+1 ];

                if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){

                    const int sub_mb_type= h->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mpx, mpy;

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];

                        int16_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];

                        pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, index, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, index, 1 );

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                            mvd_cache[ 1 ][0]=

                            mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mx - mpx;

                            mvd_cache[ 1 ][1]=

                            mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= my - mpy;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                            mvd_cache[ 1 ][0]= mx - mpx;

                            mvd_cache[ 1 ][1]= my - mpy;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                            mvd_cache[ 8 ][0]= mx - mpx;

                            mvd_cache[ 8 ][1]= my - mpy;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                        mvd_cache[ 0 ][0]= mx - mpx;

                        mvd_cache[ 0 ][1]= my - mpy;

                    }

                }else{

                    uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];

                    uint32_t *pd= (uint32_t *)&h->mvd_cache[list][ scan8[4*i] ][0];

                    p[0] = p[1] = p[8] = p[9] = 0;

                    pd[0]= pd[1]= pd[8]= pd[9]= 0;

                }

            }

        }

    } else if( IS_DIRECT(mb_type) ) {

        pred_direct_motion(h, &mb_type);

        fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4);

        fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 4);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    } else {

        int list, mx, my, i, mpx, mpy;

        if(IS_16X16(mb_type)){

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

                if(IS_DIR(mb_type, 0, list)){

                        const int ref = h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 0 ) : 0;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);

                }else

                    fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1); //FIXME factorize and the other fill_rect below too

            }

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

                if(IS_DIR(mb_type, 0, list)){

                    pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mpx, &mpy);

                    mx = mpx + decode_cabac_mb_mvd( h, list, 0, 0 );

                    my = mpy + decode_cabac_mb_mvd( h, list, 0, 1 );

                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                    fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx-mpx,my-mpy), 4);

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }else

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, 0, 4);

            }

        }

        else if(IS_16X8(mb_type)){

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

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

                        if(IS_DIR(mb_type, i, list)){

                            const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 8*i ) : 0;

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

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

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

                    if(IS_DIR(mb_type, i, list)){

                        pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, 8*i, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, 8*i, 1 );

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx-mpx,my-mpy), 4);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                    }

                }

            }

        }else{

            assert(IS_8X16(mb_type));

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

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

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 4*i ) : 0;

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

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

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

                    if(IS_DIR(mb_type, i, list)){

                        pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, 4*i, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, 4*i, 1 );

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx-mpx,my-mpy), 4);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                    }

                }

            }

        }

    }

   if( IS_INTER( mb_type ) ) {

        h->chroma_pred_mode_table[mb_xy] = 0;

        write_back_motion( h, mb_type );

   }

    if( !IS_INTRA16x16( mb_type ) ) {

        cbp  = decode_cabac_mb_cbp_luma( h );

        cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;

    }

    h->cbp_table[mb_xy] = h->cbp = cbp;

    if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {

        if( decode_cabac_mb_transform_size( h ) )

            mb_type |= MB_TYPE_8x8DCT;

    }

    s->current_picture.mb_type[mb_xy]= mb_type;

    if( cbp || IS_INTRA16x16( mb_type ) ) {

        const uint8_t *scan, *scan8x8, *dc_scan;

        int dqp;

        if(IS_INTERLACED(mb_type)){

            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;

            scan= s->qscale ? h->field_scan : h->field_scan_q0;

            dc_scan= luma_dc_field_scan;

        }else{

            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;

            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

            dc_scan= luma_dc_zigzag_scan;

        }

        h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h );

        if( dqp == INT_MIN ){

            av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);

            return -1;

        }

        s->qscale += dqp;

        if(((unsigned)s->qscale) > 51){

            if(s->qscale<0) s->qscale+= 52;

            else            s->qscale-= 52;

        }

        h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale);

        if( IS_INTRA16x16( mb_type ) ) {

            int i;

            //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" );

            if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0)

                return -1;

            if( cbp&15 ) {

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

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i );

                    if( decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 )

                        return -1;

                }

            } else {

                fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);

            }

        } else {

            int i8x8, i4x4;

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

                if( cbp & (1<<i8x8) ) {

                    if( IS_8x8DCT(mb_type) ) {

                        if( decode_cabac_residual(h, h->mb + 64*i8x8, 5, 4*i8x8,

                            scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64) < 0 )

                            return -1;

                    } else

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

                        const int index = 4*i8x8 + i4x4;

                        //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index );

//START_TIMER

                        if( decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) < 0 )

                            return -1;

//STOP_TIMER("decode_residual")

                    }

                } else {

                    uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];

                    nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;

                }

            }

        }

        if( cbp&0x30 ){

            int c;

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

                //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );

                if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0)

                    return -1;

            }

        }

        if( cbp&0x20 ) {

            int c, i;

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

                const uint32_t *qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp];

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

                    const int index = 16 + 4 * c + i;

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 );

                    if( decode_cabac_residual(h, h->mb + 16*index, 4, index - 16, scan + 1, qmul, 15) < 0)

                        return -1;

                }

            }

        } else {

            uint8_t * const nnz= &h->non_zero_count_cache[0];

            nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

            nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

        }

    } else {

        uint8_t * const nnz= &h->non_zero_count_cache[0];

        fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1);

        nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

        nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

        h->last_qscale_diff = 0;

    }

    s->current_picture.qscale_table[mb_xy]= s->qscale;

    write_back_non_zero_count(h);

    if(MB_MBAFF){

        h->ref_count[0] >>= 1;

        h->ref_count[1] >>= 1;

    }

    return 0;

}


static int mjpegb_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    MJpegDecodeContext *s = avctx->priv_data;

    const uint8_t *buf_end, *buf_ptr;

    AVFrame *picture = data;

    GetBitContext hgb; /* for the header */

    uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs;

    uint32_t field_size, sod_offs;

    buf_ptr = buf;

    buf_end = buf + buf_size;

read_header:

    /* reset on every SOI */

    s->restart_interval = 0;

    s->restart_count = 0;

    s->mjpb_skiptosod = 0;

    if (buf_end - buf_ptr >= 1 << 28)

        return AVERROR_INVALIDDATA;

    init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8);

    skip_bits(&hgb, 32); /* reserved zeros */

    if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))

    {

        av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");

        return 0;

    }

    field_size = get_bits_long(&hgb, 32); /* field size */

    av_log(avctx, AV_LOG_DEBUG, "field size: 0x%x\n", field_size);

    skip_bits(&hgb, 32); /* padded field size */

    second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%x\n", second_field_offs);

    dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%x\n", dqt_offs);

    if (dqt_offs)

    {

        init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8);

        s->start_code = DQT;

        if (ff_mjpeg_decode_dqt(s) < 0 &&

            (avctx->err_recognition & AV_EF_EXPLODE))

          return AVERROR_INVALIDDATA;

    }

    dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%x\n", dht_offs);

    if (dht_offs)

    {

        init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - (buf_ptr+dht_offs))*8);

        s->start_code = DHT;

        ff_mjpeg_decode_dht(s);

    }

    sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%x\n", sof_offs);

    if (sof_offs)

    {

        init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - (buf_ptr+sof_offs))*8);

        s->start_code = SOF0;

        if (ff_mjpeg_decode_sof(s) < 0)

            return -1;

    }

    sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%x\n", sos_offs);

    sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n");

    av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs);

    if (sos_offs)

    {

        init_get_bits(&s->gb, buf_ptr + sos_offs,

                      8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));

        s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));

        s->start_code = SOS;

        if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 &&

            (avctx->err_recognition & AV_EF_EXPLODE))

          return AVERROR_INVALIDDATA;

    }

    if (s->interlaced) {

        s->bottom_field ^= 1;

        /* if not bottom field, do not output image yet */

        if (s->bottom_field != s->interlace_polarity && second_field_offs)

        {

            buf_ptr = buf + second_field_offs;

            second_field_offs = 0;

            goto read_header;

            }

    }

    //XXX FIXME factorize, this looks very similar to the EOI code

    *picture= *s->picture_ptr;

    *data_size = sizeof(AVFrame);

    if(!s->lossless){

        picture->quality= FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2]);

        picture->qstride= 0;

        picture->qscale_table= s->qscale_table;

        memset(picture->qscale_table, picture->quality, (s->width+15)/16);

        if(avctx->debug & FF_DEBUG_QP)

            av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", picture->quality);

        picture->quality*= FF_QP2LAMBDA;

    }

    return buf_ptr - buf;

}


static void test_ivshmem_single(void)

{

    IVState state, *s;

    uint32_t data[1024];

    int i;

    setup_vm(&state);

    s = &state;

    /* valid io */

    out_reg(s, INTRMASK, 0);

    in_reg(s, INTRSTATUS);

    in_reg(s, IVPOSITION);

    out_reg(s, INTRMASK, 0xffffffff);

    g_assert_cmpuint(in_reg(s, INTRMASK), ==, 0xffffffff);

    out_reg(s, INTRSTATUS, 1);

    /* XXX: intercept IRQ, not seen in resp */

    g_assert_cmpuint(in_reg(s, INTRSTATUS), ==, 1);

    /* invalid io */

    out_reg(s, IVPOSITION, 1);

    out_reg(s, DOORBELL, 8 << 16);

    for (i = 0; i < G_N_ELEMENTS(data); i++) {

        data[i] = i;

    }

    qtest_memwrite(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));

    for (i = 0; i < G_N_ELEMENTS(data); i++) {

        g_assert_cmpuint(((uint32_t *)tmpshmem)[i], ==, i);

    }

    memset(data, 0, sizeof(data));

    qtest_memread(s->qtest, (uintptr_t)s->mem_base, data, sizeof(data));

    for (i = 0; i < G_N_ELEMENTS(data); i++) {

        g_assert_cmpuint(data[i], ==, i);

    }

    qtest_quit(s->qtest);

}


static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

    AVStream *st;

    MOVStreamContext *sc;

    unsigned int i, entries, sample_size, field_size, num_bytes;

    GetBitContext gb;

    unsigned char* buf;

    if (c->fc->nb_streams < 1)

        return 0;

    st = c->fc->streams[c->fc->nb_streams-1];

    sc = st->priv_data;

    get_byte(pb); /* version */

    get_be24(pb); /* flags */

    if (atom.type == MKTAG('s','t','s','z')) {

        sample_size = get_be32(pb);

        if (!sc->sample_size) /* do not overwrite value computed in stsd */

            sc->sample_size = sample_size;

        field_size = 32;

    } else {

        sample_size = 0;

        get_be24(pb); /* reserved */

        field_size = get_byte(pb);

    }

    entries = get_be32(pb);

    dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries);

    sc->sample_count = entries;

    if (sample_size)

        return 0;

    if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {

        av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size);

        return -1;

    }

    if(entries >= UINT_MAX / sizeof(int))

        return -1;

    sc->sample_sizes = av_malloc(entries * sizeof(int));

    if (!sc->sample_sizes)

        return AVERROR(ENOMEM);

    num_bytes = (entries*field_size+4)>>3;

    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);

    if (!buf) {

        av_freep(&sc->sample_sizes);

        return AVERROR(ENOMEM);

    }

    if (get_buffer(pb, buf, num_bytes) < num_bytes) {

        av_freep(&sc->sample_sizes);

        av_free(buf);

        return -1;

    }

    init_get_bits(&gb, buf, 8*num_bytes);

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

        sc->sample_sizes[i] = get_bits_long(&gb, field_size);

    av_free(buf);

    return 0;

}


static void init_band_stepsize(AVCodecContext *avctx,

                               Jpeg2000Band *band,

                               Jpeg2000CodingStyle *codsty,

                               Jpeg2000QuantStyle *qntsty,

                               int bandno, int gbandno, int reslevelno,

                               int cbps)

{

    /* TODO: Implementation of quantization step not finished,

     * see ISO/IEC 15444-1:2002 E.1 and A.6.4. */

    switch (qntsty->quantsty) {

        uint8_t gain;

    case JPEG2000_QSTY_NONE:

        /* TODO: to verify. No quantization in this case */

        band->f_stepsize = 1;

        break;

    case JPEG2000_QSTY_SI:

        /*TODO: Compute formula to implement. */

//         numbps = cbps +

//                  lut_gain[codsty->transform == FF_DWT53][bandno + (reslevelno > 0)];

//         band->f_stepsize = SHL(2048 + qntsty->mant[gbandno],

//                                2 + numbps - qntsty->expn[gbandno]);

//         break;

    case JPEG2000_QSTY_SE:

        /* Exponent quantization step.

         * Formula:

         * delta_b = 2 ^ (R_b - expn_b) * (1 + (mant_b / 2 ^ 11))

         * R_b = R_I + log2 (gain_b )

         * see ISO/IEC 15444-1:2002 E.1.1 eqn. E-3 and E-4 */

        gain            = cbps;

        band->f_stepsize  = pow(2.0, gain - qntsty->expn[gbandno]);

        band->f_stepsize *= qntsty->mant[gbandno] / 2048.0 + 1.0;

        break;

    default:

        band->f_stepsize = 0;

        av_log(avctx, AV_LOG_ERROR, "Unknown quantization format\n");

        break;

    }

    if (codsty->transform != FF_DWT53) {

        int lband = 0;

        switch (bandno + (reslevelno > 0)) {

            case 1:

            case 2:

                band->f_stepsize *= F_LFTG_X * 2;

                lband = 1;

                break;

            case 3:

                band->f_stepsize *= F_LFTG_X * F_LFTG_X * 4;

                break;

        }

        if (codsty->transform == FF_DWT97) {

            band->f_stepsize *= pow(F_LFTG_K, 2*(codsty->nreslevels2decode - reslevelno) + lband - 2);

        }

    }

    band->i_stepsize = band->f_stepsize * (1 << 15);

    /* FIXME: In openjepg code stespize = stepsize * 0.5. Why?

     * If not set output of entropic decoder is not correct. */

    if (!av_codec_is_encoder(avctx->codec))

        band->f_stepsize *= 0.5;

}


static int teletext_init_decoder(AVCodecContext *avctx)

{

    TeletextContext *ctx = avctx->priv_data;

    unsigned int maj, min, rev;

    vbi_version(&maj, &min, &rev);

    if (!(maj > 0 || min > 2 || min == 2 && rev >= 26)) {

        av_log(avctx, AV_LOG_ERROR, "decoder needs zvbi version >= 0.2.26.\n");

        return AVERROR_EXTERNAL;

    }

    if (ctx->format_id == 0) {

        avctx->width  = 41 * BITMAP_CHAR_WIDTH;

        avctx->height = 25 * BITMAP_CHAR_HEIGHT;

    }

    ctx->dx = NULL;

    ctx->vbi = NULL;

    ctx->pts = AV_NOPTS_VALUE;

#ifdef DEBUG

    {

        char *t;

        ctx->ex = vbi_export_new("text", &t);

    }

#endif

    av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno);

    return (ctx->format_id == 1) ? ff_ass_subtitle_header_default(avctx) : 0;

}


static void block_job_ref(BlockJob *job)

{

    ++job->refcnt;

}