static int ehci_process_itd(EHCIState *ehci,

                            EHCIitd *itd,

                            uint32_t addr)

{

    USBDevice *dev;

    USBEndpoint *ep;

    uint32_t i, len, pid, dir, devaddr, endp;

    uint32_t pg, off, ptr1, ptr2, max, mult;

    ehci->periodic_sched_active = PERIODIC_ACTIVE;

    dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION);

    devaddr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR);

    endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP);

    max = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT);

    mult = get_field(itd->bufptr[2], ITD_BUFPTR_MULT);

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

        if (itd->transact[i] & ITD_XACT_ACTIVE) {

            pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);

            off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;

            len  = get_field(itd->transact[i], ITD_XACT_LENGTH);

            if (len > max * mult) {

                len = max * mult;

            }

            if (len > BUFF_SIZE || pg > 6) {

                return -1;

            }

            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);

            qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);

            if (off + len > 4096) {

                /* transfer crosses page border */

                if (pg == 6) {

                    return -1;  /* avoid page pg + 1 */

                }

                ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);

                uint32_t len2 = off + len - 4096;

                uint32_t len1 = len - len2;

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);

                qemu_sglist_add(&ehci->isgl, ptr2, len2);

            } else {

                qemu_sglist_add(&ehci->isgl, ptr1 + off, len);

            }

            pid = dir ? USB_TOKEN_IN : USB_TOKEN_OUT;

            dev = ehci_find_device(ehci, devaddr);

            ep = usb_ep_get(dev, pid, endp);

            if (ep && ep->type == USB_ENDPOINT_XFER_ISOC) {

                usb_packet_setup(&ehci->ipacket, pid, ep, 0, addr, false,

                                 (itd->transact[i] & ITD_XACT_IOC) != 0);

                usb_packet_map(&ehci->ipacket, &ehci->isgl);

                usb_handle_packet(dev, &ehci->ipacket);

                usb_packet_unmap(&ehci->ipacket, &ehci->isgl);

            } else {

                DPRINTF("ISOCH: attempt to addess non-iso endpoint\n");

                ehci->ipacket.status = USB_RET_NAK;

                ehci->ipacket.actual_length = 0;

            }

            switch (ehci->ipacket.status) {

            case USB_RET_SUCCESS:

                break;

            default:

                fprintf(stderr, "Unexpected iso usb result: %d\n",

                        ehci->ipacket.status);

                /* Fall through */

            case USB_RET_IOERROR:

            case USB_RET_NODEV:

                /* 3.3.2: XACTERR is only allowed on IN transactions */

                if (dir) {

                    itd->transact[i] |= ITD_XACT_XACTERR;

                    ehci_raise_irq(ehci, USBSTS_ERRINT);

                }

                break;

            case USB_RET_BABBLE:

                itd->transact[i] |= ITD_XACT_BABBLE;

                ehci_raise_irq(ehci, USBSTS_ERRINT);

                break;

            case USB_RET_NAK:

                /* no data for us, so do a zero-length transfer */

                ehci->ipacket.actual_length = 0;

                break;

            }

            if (!dir) {

                set_field(&itd->transact[i], len - ehci->ipacket.actual_length,

                          ITD_XACT_LENGTH); /* OUT */

            } else {

                set_field(&itd->transact[i], ehci->ipacket.actual_length,

                          ITD_XACT_LENGTH); /* IN */

            }

            if (itd->transact[i] & ITD_XACT_IOC) {

                ehci_raise_irq(ehci, USBSTS_INT);

            }

            itd->transact[i] &= ~ITD_XACT_ACTIVE;

        }

    }

    return 0;

}


void *g_try_malloc0(size_t n_bytes)

{

    __coverity_negative_sink__(n_bytes);

    return calloc(1, n_bytes == 0 ? 1 : n_bytes);

}


void gdb_register_coprocessor(CPUState * env,

                             gdb_reg_cb get_reg, gdb_reg_cb set_reg,

                             int num_regs, const char *xml, int g_pos)

{

    GDBRegisterState *s;

    GDBRegisterState **p;

    static int last_reg = NUM_CORE_REGS;

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

    s->base_reg = last_reg;

    s->num_regs = num_regs;

    s->get_reg = get_reg;

    s->set_reg = set_reg;

    s->xml = xml;

    p = &env->gdb_regs;

    while (*p) {

        /* Check for duplicates.  */

        if (strcmp((*p)->xml, xml) == 0)

            return;

        p = &(*p)->next;

    }

    /* Add to end of list.  */

    last_reg += num_regs;

    *p = s;

    if (g_pos) {

        if (g_pos != s->base_reg) {

            fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"

                    "Expected %d got %d\n", xml, g_pos, s->base_reg);

        } else {

            num_g_regs = last_reg;

        }

    }

}


static int check_refcounts_l1(BlockDriverState *bs,

                              uint16_t *refcount_table,

                              int refcount_table_size,

                              int64_t l1_table_offset, int l1_size,

                              int check_copied)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l1_table, l2_offset, l1_size2;

    int i, refcount, ret;

    int errors = 0;

    l1_size2 = l1_size * sizeof(uint64_t);

    /* Mark L1 table as used */

    errors += inc_refcounts(bs, refcount_table, refcount_table_size,

                  l1_table_offset, l1_size2);

    /* Read L1 table entries from disk */

    if (l1_size2 == 0) {

        l1_table = NULL;

    } else {

        l1_table = qemu_malloc(l1_size2);

        if (bdrv_pread(bs->file, l1_table_offset,

                       l1_table, l1_size2) != l1_size2)

            goto fail;

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

            be64_to_cpus(&l1_table[i]);

    }

    /* Do the actual checks */

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

        l2_offset = l1_table[i];

        if (l2_offset) {

            /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */

            if (check_copied) {

                refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)

                    >> s->cluster_bits);

                if (refcount < 0) {

                    fprintf(stderr, "Can't get refcount for l2_offset %"

                        PRIx64 ": %s\n", l2_offset, strerror(-refcount));

                }

                if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {

                    fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64

                        " refcount=%d\n", l2_offset, refcount);

                    errors++;

                }

            }

            /* Mark L2 table as used */

            l2_offset &= ~QCOW_OFLAG_COPIED;

            errors += inc_refcounts(bs, refcount_table,

                          refcount_table_size,

                          l2_offset,

                          s->cluster_size);

            /* L2 tables are cluster aligned */

            if (l2_offset & (s->cluster_size - 1)) {

                fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not "

                    "cluster aligned; L1 entry corrupted\n", l2_offset);

                errors++;

            }

            /* Process and check L2 entries */

            ret = check_refcounts_l2(bs, refcount_table, refcount_table_size,

                l2_offset, check_copied);

            if (ret < 0) {

                goto fail;

            }

            errors += ret;

        }

    }

    qemu_free(l1_table);

    return errors;

fail:

    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");

    qemu_free(l1_table);

    return -EIO;

}


static int alloc_refcount_block(BlockDriverState *bs,

                                int64_t cluster_index, void **refcount_block)

{

    BDRVQcow2State *s = bs->opaque;

    unsigned int refcount_table_index;

    int ret;

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC);

    /* Find the refcount block for the given cluster */

    refcount_table_index = cluster_index >> s->refcount_block_bits;

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t refcount_block_offset =

            s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK;

        /* If it's already there, we're done */

        if (refcount_block_offset) {

            if (offset_into_cluster(s, refcount_block_offset)) {

                qcow2_signal_corruption(bs, true, -1, -1, "Refblock offset %#"

                                        PRIx64 " unaligned (reftable index: "

                                        "%#x)", refcount_block_offset,

                                        refcount_table_index);

                return -EIO;

            }

             return load_refcount_block(bs, refcount_block_offset,

                                        refcount_block);

        }

    }

    /*

     * If we came here, we need to allocate something. Something is at least

     * a cluster for the new refcount block. It may also include a new refcount

     * table if the old refcount table is too small.

     *

     * Note that allocating clusters here needs some special care:

     *

     * - We can't use the normal qcow2_alloc_clusters(), it would try to

     *   increase the refcount and very likely we would end up with an endless

     *   recursion. Instead we must place the refcount blocks in a way that

     *   they can describe them themselves.

     *

     * - We need to consider that at this point we are inside update_refcounts

     *   and potentially doing an initial refcount increase. This means that

     *   some clusters have already been allocated by the caller, but their

     *   refcount isn't accurate yet. If we allocate clusters for metadata, we

     *   need to return -EAGAIN to signal the caller that it needs to restart

     *   the search for free clusters.

     *

     * - alloc_clusters_noref and qcow2_free_clusters may load a different

     *   refcount block into the cache

     */

    *refcount_block = NULL;

    /* We write to the refcount table, so we might depend on L2 tables */

    ret = qcow2_cache_flush(bs, s->l2_table_cache);

    if (ret < 0) {

        return ret;

    }

    /* Allocate the refcount block itself and mark it as used */

    int64_t new_block = alloc_clusters_noref(bs, s->cluster_size);

    if (new_block < 0) {

        return new_block;

    }

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64

        " at %" PRIx64 "\n",

        refcount_table_index, cluster_index << s->cluster_bits, new_block);

#endif

    if (in_same_refcount_block(s, new_block, cluster_index << s->cluster_bits)) {

        /* Zero the new refcount block before updating it */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

                                    refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

        /* The block describes itself, need to update the cache */

        int block_index = (new_block >> s->cluster_bits) &

            (s->refcount_block_size - 1);

        s->set_refcount(*refcount_block, block_index, 1);

    } else {

        /* Described somewhere else. This can recurse at most twice before we

         * arrive at a block that describes itself. */

        ret = update_refcount(bs, new_block, s->cluster_size, 1, false,

                              QCOW2_DISCARD_NEVER);

        if (ret < 0) {

            goto fail_block;

        }

        ret = qcow2_cache_flush(bs, s->refcount_block_cache);

        if (ret < 0) {

            goto fail_block;

        }

        /* Initialize the new refcount block only after updating its refcount,

         * update_refcount uses the refcount cache itself */

        ret = qcow2_cache_get_empty(bs, s->refcount_block_cache, new_block,

                                    refcount_block);

        if (ret < 0) {

            goto fail_block;

        }

        memset(*refcount_block, 0, s->cluster_size);

    }

    /* Now the new refcount block needs to be written to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE);

    qcow2_cache_entry_mark_dirty(bs, s->refcount_block_cache, *refcount_block);

    ret = qcow2_cache_flush(bs, s->refcount_block_cache);

    if (ret < 0) {

        goto fail_block;

    }

    /* If the refcount table is big enough, just hook the block up there */

    if (refcount_table_index < s->refcount_table_size) {

        uint64_t data64 = cpu_to_be64(new_block);

        BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);

        ret = bdrv_pwrite_sync(bs->file->bs,

            s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),

            &data64, sizeof(data64));

        if (ret < 0) {

            goto fail_block;

        }

        s->refcount_table[refcount_table_index] = new_block;

        /* The new refcount block may be where the caller intended to put its

         * data, so let it restart the search. */

        return -EAGAIN;

    }

    qcow2_cache_put(bs, s->refcount_block_cache, refcount_block);

    /*

     * If we come here, we need to grow the refcount table. Again, a new

     * refcount table needs some space and we can't simply allocate to avoid

     * endless recursion.

     *

     * Therefore let's grab new refcount blocks at the end of the image, which

     * will describe themselves and the new refcount table. This way we can

     * reference them only in the new table and do the switch to the new

     * refcount table at once without producing an inconsistent state in

     * between.

     */

    BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_GROW);

    /* Calculate the number of refcount blocks needed so far; this will be the

     * basis for calculating the index of the first cluster used for the

     * self-describing refcount structures which we are about to create.

     *

     * Because we reached this point, there cannot be any refcount entries for

     * cluster_index or higher indices yet. However, because new_block has been

     * allocated to describe that cluster (and it will assume this role later

     * on), we cannot use that index; also, new_block may actually have a higher

     * cluster index than cluster_index, so it needs to be taken into account

     * here (and 1 needs to be added to its value because that cluster is used).

     */

    uint64_t blocks_used = DIV_ROUND_UP(MAX(cluster_index + 1,

                                            (new_block >> s->cluster_bits) + 1),

                                        s->refcount_block_size);

    if (blocks_used > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) {

        return -EFBIG;

    }

    /* And now we need at least one block more for the new metadata */

    uint64_t table_size = next_refcount_table_size(s, blocks_used + 1);

    uint64_t last_table_size;

    uint64_t blocks_clusters;

    do {

        uint64_t table_clusters =

            size_to_clusters(s, table_size * sizeof(uint64_t));

        blocks_clusters = 1 +

            ((table_clusters + s->refcount_block_size - 1)

            / s->refcount_block_size);

        uint64_t meta_clusters = table_clusters + blocks_clusters;

        last_table_size = table_size;

        table_size = next_refcount_table_size(s, blocks_used +

            ((meta_clusters + s->refcount_block_size - 1)

            / s->refcount_block_size));

    } while (last_table_size != table_size);

#ifdef DEBUG_ALLOC2

    fprintf(stderr, "qcow2: Grow refcount table %" PRId32 " => %" PRId64 "\n",

        s->refcount_table_size, table_size);

#endif

    /* Create the new refcount table and blocks */

    uint64_t meta_offset = (blocks_used * s->refcount_block_size) *

        s->cluster_size;

    uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;

    uint64_t *new_table = g_try_new0(uint64_t, table_size);

    void *new_blocks = g_try_malloc0(blocks_clusters * s->cluster_size);

    assert(table_size > 0 && blocks_clusters > 0);

    if (new_table == NULL || new_blocks == NULL) {

        ret = -ENOMEM;

        goto fail_table;

    }

    /* Fill the new refcount table */

    memcpy(new_table, s->refcount_table,

        s->refcount_table_size * sizeof(uint64_t));

    new_table[refcount_table_index] = new_block;

    int i;

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

        new_table[blocks_used + i] = meta_offset + (i * s->cluster_size);

    }

    /* Fill the refcount blocks */

    uint64_t table_clusters = size_to_clusters(s, table_size * sizeof(uint64_t));

    int block = 0;

    for (i = 0; i < table_clusters + blocks_clusters; i++) {

        s->set_refcount(new_blocks, block++, 1);

    }

    /* Write refcount blocks to disk */

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);

    ret = bdrv_pwrite_sync(bs->file->bs, meta_offset, new_blocks,

        blocks_clusters * s->cluster_size);

    g_free(new_blocks);

    new_blocks = NULL;

    if (ret < 0) {

        goto fail_table;

    }

    /* Write refcount table to disk */

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

        cpu_to_be64s(&new_table[i]);

    }

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);

    ret = bdrv_pwrite_sync(bs->file->bs, table_offset, new_table,

        table_size * sizeof(uint64_t));

    if (ret < 0) {

        goto fail_table;

    }

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

        be64_to_cpus(&new_table[i]);

    }

    /* Hook up the new refcount table in the qcow2 header */

    uint8_t data[12];

    cpu_to_be64w((uint64_t*)data, table_offset);

    cpu_to_be32w((uint32_t*)(data + 8), table_clusters);

    BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE);

    ret = bdrv_pwrite_sync(bs->file->bs,

                           offsetof(QCowHeader, refcount_table_offset),

                           data, sizeof(data));

    if (ret < 0) {

        goto fail_table;

    }

    /* And switch it in memory */

    uint64_t old_table_offset = s->refcount_table_offset;

    uint64_t old_table_size = s->refcount_table_size;

    g_free(s->refcount_table);

    s->refcount_table = new_table;

    s->refcount_table_size = table_size;

    s->refcount_table_offset = table_offset;

    /* Free old table. */

    qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t),

                        QCOW2_DISCARD_OTHER);

    ret = load_refcount_block(bs, new_block, refcount_block);

    if (ret < 0) {

        return ret;

    }

    /* If we were trying to do the initial refcount update for some cluster

     * allocation, we might have used the same clusters to store newly

     * allocated metadata. Make the caller search some new space. */

    return -EAGAIN;

fail_table:

    g_free(new_blocks);

    g_free(new_table);

fail_block:

    if (*refcount_block != NULL) {

        qcow2_cache_put(bs, s->refcount_block_cache, refcount_block);

    }

    return ret;

}


void ppc6xx_irq_init (CPUState *env)

{

    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);

}


static void coroutine_fn v9fs_create(void *opaque)

{

    int32_t fid;

    int err = 0;

    size_t offset = 7;

    V9fsFidState *fidp;

    V9fsQID qid;

    int32_t perm;

    int8_t mode;

    V9fsPath path;

    struct stat stbuf;

    V9fsString name;

    V9fsString extension;

    int iounit;

    V9fsPDU *pdu = opaque;

    v9fs_path_init(&path);

    v9fs_string_init(&name);

    v9fs_string_init(&extension);

    err = pdu_unmarshal(pdu, offset, "dsdbs", &fid, &name,

                        &perm, &mode, &extension);

    if (err < 0) {

        goto out_nofid;

    trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode);

    if (name_is_illegal(name.data)) {

        err = -ENOENT;

        goto out_nofid;

    if (!strcmp(".", name.data) || !strcmp("..", name.data)) {

        err = -EEXIST;

        goto out_nofid;

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        goto out_nofid;

    if (perm & P9_STAT_MODE_DIR) {

        err = v9fs_co_mkdir(pdu, fidp, &name, perm & 0777,

                            fidp->uid, -1, &stbuf);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

        v9fs_path_copy(&fidp->path, &path);

        err = v9fs_co_opendir(pdu, fidp);

        if (err < 0) {

        fidp->fid_type = P9_FID_DIR;

    } else if (perm & P9_STAT_MODE_SYMLINK) {

        err = v9fs_co_symlink(pdu, fidp, &name,

                              extension.data, -1 , &stbuf);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

        v9fs_path_copy(&fidp->path, &path);

    } else if (perm & P9_STAT_MODE_LINK) {

        int32_t ofid = atoi(extension.data);

        V9fsFidState *ofidp = get_fid(pdu, ofid);

        if (ofidp == NULL) {

        err = v9fs_co_link(pdu, ofidp, fidp, &name);

        put_fid(pdu, ofidp);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

            fidp->fid_type = P9_FID_NONE;

        v9fs_path_copy(&fidp->path, &path);

        err = v9fs_co_lstat(pdu, &fidp->path, &stbuf);

        if (err < 0) {

            fidp->fid_type = P9_FID_NONE;

    } else if (perm & P9_STAT_MODE_DEVICE) {

        char ctype;

        uint32_t major, minor;

        mode_t nmode = 0;

        if (sscanf(extension.data, "%c %u %u", &ctype, &major, &minor) != 3) {

            err = -errno;

        switch (ctype) {

        case 'c':

            nmode = S_IFCHR;

            break;

        case 'b':

            nmode = S_IFBLK;

            break;

        default:

            err = -EIO;

        nmode |= perm & 0777;

        err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,

                            makedev(major, minor), nmode, &stbuf);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

        v9fs_path_copy(&fidp->path, &path);

    } else if (perm & P9_STAT_MODE_NAMED_PIPE) {

        err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,

                            0, S_IFIFO | (perm & 0777), &stbuf);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

        v9fs_path_copy(&fidp->path, &path);

    } else if (perm & P9_STAT_MODE_SOCKET) {

        err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1,

                            0, S_IFSOCK | (perm & 0777), &stbuf);

        if (err < 0) {

        err = v9fs_co_name_to_path(pdu, &fidp->path, name.data, &path);

        if (err < 0) {

        v9fs_path_copy(&fidp->path, &path);

    } else {

        err = v9fs_co_open2(pdu, fidp, &name, -1,

                            omode_to_uflags(mode)|O_CREAT, perm, &stbuf);

        if (err < 0) {

        fidp->fid_type = P9_FID_FILE;

        fidp->open_flags = omode_to_uflags(mode);

        if (fidp->open_flags & O_EXCL) {

            /*

             * We let the host file system do O_EXCL check

             * We should not reclaim such fd

             */

            fidp->flags |= FID_NON_RECLAIMABLE;

    iounit = get_iounit(pdu, &fidp->path);

    stat_to_qid(&stbuf, &qid);

    err = pdu_marshal(pdu, offset, "Qd", &qid, iounit);

    if (err < 0) {

    err += offset;

    trace_v9fs_create_return(pdu->tag, pdu->id,

                             qid.type, qid.version, qid.path, iounit);

out:

    put_fid(pdu, fidp);

out_nofid:

   pdu_complete(pdu, err);

   v9fs_string_free(&name);

   v9fs_string_free(&extension);

   v9fs_path_free(&path);


static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)

{

    int     h, w, mv_x, mv_y, offset, offset_dst;

    uint8_t *src, *dst;

    /* setup output and reference pointers */

    offset_dst  = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);

    dst         = plane->pixels[ctx->buf_sel] + offset_dst;

    mv_y        = cell->mv_ptr[0];

    mv_x        = cell->mv_ptr[1];

    /* -1 because there is an extra line on top for prediction */

    if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||

        ((cell->ypos + cell->height) << 2) + mv_y >= plane->height    ||

        ((cell->xpos + cell->width)  << 2) + mv_x >= plane->width) {

        av_log(ctx->avctx, AV_LOG_ERROR,

               "Motion vectors point out of the frame.\n");

        return AVERROR_INVALIDDATA;

    }

    offset      = offset_dst + mv_y * plane->pitch + mv_x;

    src         = plane->pixels[ctx->buf_sel ^ 1] + offset;

    h = cell->height << 2;

    for (w = cell->width; w > 0;) {

        /* copy using 16xH blocks */

        if (!((cell->xpos << 2) & 15) && w >= 4) {

            for (; w >= 4; src += 16, dst += 16, w -= 4)

                ctx->hdsp.put_no_rnd_pixels_tab[0][0](dst, src, plane->pitch, h);

        }

        /* copy using 8xH blocks */

        if (!((cell->xpos << 2) & 7) && w >= 2) {

            ctx->hdsp.put_no_rnd_pixels_tab[1][0](dst, src, plane->pitch, h);

            w -= 2;

            src += 8;

            dst += 8;

        }

        if (w >= 1) {

            ctx->hdsp.put_no_rnd_pixels_tab[2][0](dst, src, plane->pitch, h);

            w--;

            src += 4;

            dst += 4;

        }

    }

    return 0;

}


static int serial_can_receive(SerialState *s)

{

    return !(s->lsr & UART_LSR_DR);

}


static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,

                                    AVStream *st, MOVStreamContext *sc,

                                    int size)

{

    // ttxt stsd contains display flags, justification, background

    // color, fonts, and default styles, so fake an atom to read it

    MOVAtom fake_atom = { .size = size };

    // mp4s contains a regular esds atom

    if (st->codec->codec_tag != AV_RL32("mp4s"))

        mov_read_glbl(c, pb, fake_atom);

    st->codec->width  = sc->width;

    st->codec->height = sc->height;

}


static void virgl_cmd_get_capset_info(VirtIOGPU *g,

                                      struct virtio_gpu_ctrl_command *cmd)

{

    struct virtio_gpu_get_capset_info info;

    struct virtio_gpu_resp_capset_info resp;

    VIRTIO_GPU_FILL_CMD(info);

    if (info.capset_index == 0) {

        resp.capset_id = VIRTIO_GPU_CAPSET_VIRGL;

        virgl_renderer_get_cap_set(resp.capset_id,

                                   &resp.capset_max_version,

                                   &resp.capset_max_size);

    } else {

        resp.capset_max_version = 0;

        resp.capset_max_size = 0;

    }

    resp.hdr.type = VIRTIO_GPU_RESP_OK_CAPSET_INFO;

    virtio_gpu_ctrl_response(g, cmd, &resp.hdr, sizeof(resp));

}


static int virtio_rng_pci_init(VirtIOPCIProxy *vpci_dev)

{

    VirtIORngPCI *vrng = VIRTIO_RNG_PCI(vpci_dev);

    DeviceState *vdev = DEVICE(&vrng->vdev);

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));

    if (qdev_init(vdev) < 0) {

        return -1;

    }

    object_property_set_link(OBJECT(vrng),

                             OBJECT(vrng->vdev.conf.default_backend), "rng",

                             NULL);

    return 0;

}


static int usb_linux_update_endp_table(USBHostDevice *s)

{

    uint8_t *descriptors;

    uint8_t devep, type, configuration, alt_interface;

    struct usb_ctrltransfer ct;

    int interface, ret, length, i;

    ct.bRequestType = USB_DIR_IN;

    ct.bRequest = USB_REQ_GET_CONFIGURATION;

    ct.wValue = 0;

    ct.wIndex = 0;

    ct.wLength = 1;

    ct.data = &configuration;

    ct.timeout = 50;

    ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);

    if (ret < 0) {

        perror("usb_linux_update_endp_table");

        return 1;

    }

    /* in address state */

    if (configuration == 0)

        return 1;

    /* get the desired configuration, interface, and endpoint descriptors

     * from device description */

    descriptors = &s->descr[18];

    length = s->descr_len - 18;

    i = 0;

    if (descriptors[i + 1] != USB_DT_CONFIG ||

        descriptors[i + 5] != configuration) {

        DPRINTF("invalid descriptor data - configuration\n");

        return 1;

    }

    i += descriptors[i];

    while (i < length) {

        if (descriptors[i + 1] != USB_DT_INTERFACE ||

            (descriptors[i + 1] == USB_DT_INTERFACE &&

             descriptors[i + 4] == 0)) {

            i += descriptors[i];

            continue;

        }

        interface = descriptors[i + 2];

        ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;

        ct.bRequest = USB_REQ_GET_INTERFACE;

        ct.wValue = 0;

        ct.wIndex = interface;

        ct.wLength = 1;

        ct.data = &alt_interface;

        ct.timeout = 50;

        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);

        if (ret < 0) {

            alt_interface = interface;

        }

        /* the current interface descriptor is the active interface

         * and has endpoints */

        if (descriptors[i + 3] != alt_interface) {

            i += descriptors[i];

            continue;

        }

        /* advance to the endpoints */

        while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)

            i += descriptors[i];

        if (i >= length)

            break;

        while (i < length) {

            if (descriptors[i + 1] != USB_DT_ENDPOINT)

                break;

            devep = descriptors[i + 2];

            switch (descriptors[i + 3] & 0x3) {

            case 0x00:

                type = USBDEVFS_URB_TYPE_CONTROL;

                break;

            case 0x01:

                type = USBDEVFS_URB_TYPE_ISO;

                break;

            case 0x02:

                break;

            case 0x03:

                type = USBDEVFS_URB_TYPE_INTERRUPT;

                break;

            }

            s->endp_table[(devep & 0xf) - 1].type = type;

            s->endp_table[(devep & 0xf) - 1].halted = 0;

            i += descriptors[i];

        }

    }

    return 0;

}


AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec)

{

    AVStream *fst;

    fst = av_mallocz(sizeof(AVStream));

    if (!fst)

        return NULL;

    fst->priv_data = av_mallocz(sizeof(FeedData));

    memcpy(&fst->codec, codec, sizeof(AVCodecContext));

    stream->streams[stream->nb_streams++] = fst;

    return fst;

}


static av_cold int ljpeg_encode_init(AVCodecContext *avctx)

{

    LJpegEncContext *s = avctx->priv_data;

    if ((avctx->pix_fmt == AV_PIX_FMT_YUV420P ||

         avctx->pix_fmt == AV_PIX_FMT_YUV422P ||

         avctx->pix_fmt == AV_PIX_FMT_YUV444P ||

         avctx->color_range == AVCOL_RANGE_MPEG) &&

        avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {

        av_log(avctx, AV_LOG_ERROR,

               "Limited range YUV is non-standard, set strict_std_compliance to "

               "at least unofficial to use it.\n");

        return AVERROR(EINVAL);

    }

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch));

    if (!s->scratch)

        goto fail;

    ff_idctdsp_init(&s->idsp, avctx);

    ff_init_scantable(s->idsp.idct_permutation, &s->scantable,

                      ff_zigzag_direct);

    ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample);

    ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance,

                                 s->huff_code_dc_luminance,

                                 avpriv_mjpeg_bits_dc_luminance,

                                 avpriv_mjpeg_val_dc);

    ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance,

                                 s->huff_code_dc_chrominance,

                                 avpriv_mjpeg_bits_dc_chrominance,

                                 avpriv_mjpeg_val_dc);

    return 0;

}


void net_host_device_remove(Monitor *mon, int vlan_id, const char *device)

{

    VLANState *vlan;

    VLANClientState *vc;

    vlan = qemu_find_vlan(vlan_id);

    if (!vlan) {

        monitor_printf(mon, "can't find vlan %d\n", vlan_id);

        return;

    }

   for(vc = vlan->first_client; vc != NULL; vc = vc->next)

        if (!strcmp(vc->name, device))

            break;

    if (!vc) {

        monitor_printf(mon, "can't find device %s\n", device);

        return;

    }

    qemu_del_vlan_client(vc);

}


static inline PageDesc *page_find_alloc(target_ulong index)

{

    PageDesc **lp, *p;

#if TARGET_LONG_BITS > 32

    /* Host memory outside guest VM.  For 32-bit targets we have already

       excluded high addresses.  */

    if (index > ((target_ulong)L2_SIZE * L1_SIZE))

        return NULL;

#endif

    lp = &l1_map[index >> L2_BITS];

    p = *lp;

    if (!p) {

        /* allocate if not found */

#if defined(CONFIG_USER_ONLY)

        unsigned long addr;

        size_t len = sizeof(PageDesc) * L2_SIZE;

        /* Don't use qemu_malloc because it may recurse.  */

        p = mmap(0, len, PROT_READ | PROT_WRITE,

                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        *lp = p;

        addr = h2g(p);

        if (addr == (target_ulong)addr) {

            page_set_flags(addr & TARGET_PAGE_MASK,

                           TARGET_PAGE_ALIGN(addr + len),

                           PAGE_RESERVED);

        }

#else

        p = qemu_mallocz(sizeof(PageDesc) * L2_SIZE);

        *lp = p;

#endif

    }

    return p + (index & (L2_SIZE - 1));

}


static int asf_write_trailer(AVFormatContext *s)

{

    ASFContext *asf = s->priv_data;

    int64_t file_size, data_size;

    /* flush the current packet */

    if (asf->pb.buf_ptr > asf->pb.buffer)

        flush_packet(s);

    /* write index */

    data_size = avio_tell(s->pb);

    if ((!asf->is_streamed) && (asf->nb_index_count != 0))

        asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count);

    avio_flush(s->pb);

    if (asf->is_streamed || !s->pb->seekable) {

        put_chunk(s, 0x4524, 0, 0); /* end of stream */

    } else {

        /* rewrite an updated header */

        file_size = avio_tell(s->pb);

        avio_seek(s->pb, 0, SEEK_SET);

        asf_write_header1(s, file_size, data_size - asf->data_offset);

    }

    av_free(asf->index_ptr);

    return 0;

}


static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx,

                                                    const uint8_t *buf,

                                                    int buf_size)

{

    DVBSubContext *ctx = avctx->priv_data;

    DVBSubDisplayDefinition *display_def = ctx->display_definition;

    int dds_version, info_byte;

    if (buf_size < 5)

        return;

    info_byte   = bytestream_get_byte(&buf);

    dds_version = info_byte >> 4;

    if (display_def && display_def->version == dds_version)

        return; // already have this display definition version

    if (!display_def) {

        display_def             = av_mallocz(sizeof(*display_def));

        ctx->display_definition = display_def;

    }

    if (!display_def)

        return;

    display_def->version = dds_version;

    display_def->x       = 0;

    display_def->y       = 0;

    display_def->width   = bytestream_get_be16(&buf) + 1;

    display_def->height  = bytestream_get_be16(&buf) + 1;

    if (buf_size < 13)

        return;

    if (info_byte & 1<<3) { // display_window_flag

        display_def->x = bytestream_get_be16(&buf);

        display_def->y = bytestream_get_be16(&buf);

        display_def->width  = bytestream_get_be16(&buf) - display_def->x + 1;

        display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;

    }

}


static int synchronize_audio(VideoState *is, int nb_samples)

{

    int wanted_nb_samples = nb_samples;

    /* if not master, then we try to remove or add samples to correct the clock */

    if (get_master_sync_type(is) != AV_SYNC_AUDIO_MASTER) {

        double diff, avg_diff;

        int min_nb_samples, max_nb_samples;

        diff = get_audio_clock(is) - get_master_clock(is);

        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {

            is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;

            if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {

                /* not enough measures to have a correct estimate */

                is->audio_diff_avg_count++;

            } else {

                /* estimate the A-V difference */

                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);

                if (fabs(avg_diff) >= is->audio_diff_threshold) {

                    wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);

                    min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));

                    max_nb_samples = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX) / 100));

                    wanted_nb_samples = FFMIN(FFMAX(wanted_nb_samples, min_nb_samples), max_nb_samples);

                }

                av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f %f\n",

                        diff, avg_diff, wanted_nb_samples - nb_samples,

                        is->audio_clock, is->audio_diff_threshold);

            }

        } else {

            /* too big difference : may be initial PTS errors, so

               reset A-V filter */

            is->audio_diff_avg_count = 0;

            is->audio_diff_cum       = 0;

        }

    }

    return wanted_nb_samples;

}


int ff_alloc_packet(AVPacket *avpkt, int size)

{

    if (size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)

        return AVERROR(EINVAL);

    if (avpkt->data) {

        void *destruct = avpkt->destruct;

        if (avpkt->size < size)

            return AVERROR(EINVAL);

        av_init_packet(avpkt);

        avpkt->destruct = destruct;

        avpkt->size = size;

        return 0;

    } else {

        return av_new_packet(avpkt, size);

    }

}


static int ast_write_trailer(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    ASTMuxContext *ast = s->priv_data;

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

    int64_t file_size = avio_tell(pb);

    int64_t samples = (file_size - 64 - (32 * enc->frame_number)) / enc->block_align; /* PCM_S16BE_PLANAR */

    av_log(s, AV_LOG_DEBUG, "total samples: %"PRId64"\n", samples);

    if (s->pb->seekable) {

        /* Number of samples */

        avio_seek(pb, ast->samples, SEEK_SET);

        avio_wb32(pb, samples);

        /* Loopstart if provided */

        if (ast->loopstart > 0) {

        if (ast->loopstart >= samples) {

            av_log(s, AV_LOG_WARNING, "Loopstart value is out of range and will be ignored\n");

            ast->loopstart = -1;

            avio_skip(pb, 4);

        } else

        avio_wb32(pb, ast->loopstart);

        } else

            avio_skip(pb, 4);

        /* Loopend if provided. Otherwise number of samples again */

        if (ast->loopend && ast->loopstart >= 0) {

            if (ast->loopend > samples) {

                av_log(s, AV_LOG_WARNING, "Loopend value is out of range and will be ignored\n");

                ast->loopend = samples;

            }

            avio_wb32(pb, ast->loopend);

        } else {

            avio_wb32(pb, samples);

        }

        /* Size of first block */

        avio_wb32(pb, ast->fbs);

        /* File size minus header */

        avio_seek(pb, ast->size, SEEK_SET);

        avio_wb32(pb, file_size - 64);

        /* Loop flag */

        if (ast->loopstart >= 0) {

            avio_skip(pb, 6);

            avio_wb16(pb, 0xFFFF);

        }

        avio_seek(pb, file_size, SEEK_SET);

        avio_flush(pb);

    }

    return 0;

}


int ff_h264_field_end(H264Context *h, H264SliceContext *sl, int in_setup)

{

    AVCodecContext *const avctx = h->avctx;

    int err = 0;

    h->mb_y = 0;

    if (!in_setup && !h->droppable)

        ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                  h->picture_structure == PICT_BOTTOM_FIELD);

    if (in_setup || !(avctx->active_thread_type & FF_THREAD_FRAME)) {

        if (!h->droppable) {

            err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);

            h->prev_poc_msb = h->poc_msb;

            h->prev_poc_lsb = h->poc_lsb;

        }

        h->prev_frame_num_offset = h->frame_num_offset;

        h->prev_frame_num        = h->frame_num;

    }

    if (avctx->hwaccel) {

        if (avctx->hwaccel->end_frame(avctx) < 0)

            av_log(avctx, AV_LOG_ERROR,

                   "hardware accelerator failed to decode picture\n");

    }

#if CONFIG_ERROR_RESILIENCE

    /*

     * FIXME: Error handling code does not seem to support interlaced

     * when slices span multiple rows

     * The ff_er_add_slice calls don't work right for bottom

     * fields; they cause massive erroneous error concealing

     * Error marking covers both fields (top and bottom).

     * This causes a mismatched s->error_count

     * and a bad error table. Further, the error count goes to

     * INT_MAX when called for bottom field, because mb_y is

     * past end by one (callers fault) and resync_mb_y != 0

     * causes problems for the first MB line, too.

     */

    if (!FIELD_PICTURE(h) && h->enable_er) {

        h264_set_erpic(&sl->er.cur_pic, h->cur_pic_ptr);

        h264_set_erpic(&sl->er.last_pic,

                       sl->ref_count[0] ? sl->ref_list[0][0].parent : NULL);

        h264_set_erpic(&sl->er.next_pic,

                       sl->ref_count[1] ? sl->ref_list[1][0].parent : NULL);

        ff_er_frame_end(&sl->er);

    }

#endif /* CONFIG_ERROR_RESILIENCE */

    emms_c();

    h->current_slice = 0;

    return err;

}


static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)

{

    AlsaData *s  = s1->priv_data;

    AVStream *st = s1->streams[0];

    int res;

    snd_htimestamp_t timestamp;

    snd_pcm_uframes_t ts_delay;

    if (av_new_packet(pkt, s->period_size) < 0) {

        return AVERROR(EIO);

    }

    while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / s->frame_size)) < 0) {

        if (res == -EAGAIN) {

            av_free_packet(pkt);

            return AVERROR(EAGAIN);

        }

        if (ff_alsa_xrun_recover(s1, res) < 0) {

            av_log(s1, AV_LOG_ERROR, "ALSA read error: %s\n",

                   snd_strerror(res));

            av_free_packet(pkt);

            return AVERROR(EIO);

        }

    }

    snd_pcm_htimestamp(s->h, &ts_delay, &timestamp);

    ts_delay += res;

    pkt->pts = timestamp.tv_sec * 1000000LL

               + (timestamp.tv_nsec * st->codec->sample_rate

                  - ts_delay * 1000000000LL + st->codec->sample_rate * 500LL)

               / (st->codec->sample_rate * 1000LL);

    pkt->size = res * s->frame_size;

    return 0;

}


static void RENAME(uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src,

                                      long width, long height,

                                      long lumStride, long chromStride, long srcStride)

{

    long y;

    const long chromWidth= -((-width)>>1);

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

        RENAME(extract_even)(src+1, ydst, width);

        RENAME(extract_even2)(src, udst, vdst, chromWidth);

        src += srcStride;

        ydst+= lumStride;

        udst+= chromStride;

        vdst+= chromStride;

    }

#if COMPILE_TEMPLATE_MMX

    __asm__(

            EMMS"       \n\t"

            SFENCE"     \n\t"

            ::: "memory"

        );

#endif

}


static int mpc8_decode_init(AVCodecContext * avctx)

{

    int i;

    MPCContext *c = avctx->priv_data;

    GetBitContext gb;

    static int vlc_inited = 0;

    if(avctx->extradata_size < 2){

        av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);

        return -1;

    }

    memset(c->oldDSCF, 0, sizeof(c->oldDSCF));

    av_init_random(0xDEADBEEF, &c->rnd);

    dsputil_init(&c->dsp, avctx);

    ff_mpc_init();

    init_get_bits(&gb, avctx->extradata, 16);

    skip_bits(&gb, 3);//sample rate

    c->maxbands = get_bits(&gb, 5) + 1;

    skip_bits(&gb, 4);//channels

    c->MSS = get_bits1(&gb);

    c->frames = 1 << (get_bits(&gb, 3) * 2);

    if(vlc_inited) return 0;

    av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");

    init_vlc(&band_vlc, MPC8_BANDS_BITS, MPC8_BANDS_SIZE,

             mpc8_bands_bits,  1, 1,

             mpc8_bands_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&q1_vlc, MPC8_Q1_BITS, MPC8_Q1_SIZE,

             mpc8_q1_bits,  1, 1,

             mpc8_q1_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&q9up_vlc, MPC8_Q9UP_BITS, MPC8_Q9UP_SIZE,

             mpc8_q9up_bits,  1, 1,

             mpc8_q9up_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&scfi_vlc[0], MPC8_SCFI0_BITS, MPC8_SCFI0_SIZE,

             mpc8_scfi0_bits,  1, 1,

             mpc8_scfi0_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&scfi_vlc[1], MPC8_SCFI1_BITS, MPC8_SCFI1_SIZE,

             mpc8_scfi1_bits,  1, 1,

             mpc8_scfi1_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&dscf_vlc[0], MPC8_DSCF0_BITS, MPC8_DSCF0_SIZE,

             mpc8_dscf0_bits,  1, 1,

             mpc8_dscf0_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc(&dscf_vlc[1], MPC8_DSCF1_BITS, MPC8_DSCF1_SIZE,

             mpc8_dscf1_bits,  1, 1,

             mpc8_dscf1_codes, 1, 1, INIT_VLC_USE_STATIC);

    init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE,

             mpc8_q3_bits,  1, 1,

             mpc8_q3_codes, 1, 1,

             mpc8_q3_syms,  1, 1, INIT_VLC_USE_STATIC);

    init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE,

             mpc8_q4_bits,  1, 1,

             mpc8_q4_codes, 1, 1,

             mpc8_q4_syms,  1, 1, INIT_VLC_USE_STATIC);

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

        init_vlc(&res_vlc[i], MPC8_RES_BITS, MPC8_RES_SIZE,

                 &mpc8_res_bits[i],  1, 1,

                 &mpc8_res_codes[i], 1, 1, INIT_VLC_USE_STATIC);

        init_vlc(&q2_vlc[i], MPC8_Q2_BITS, MPC8_Q2_SIZE,

                 &mpc8_q2_bits[i],  1, 1,

                 &mpc8_q2_codes[i], 1, 1, INIT_VLC_USE_STATIC);

        init_vlc(&quant_vlc[0][i], MPC8_Q5_BITS, MPC8_Q5_SIZE,

                 &mpc8_q5_bits[i],  1, 1,

                 &mpc8_q5_codes[i], 1, 1, INIT_VLC_USE_STATIC);

        init_vlc(&quant_vlc[1][i], MPC8_Q6_BITS, MPC8_Q6_SIZE,

                 &mpc8_q6_bits[i],  1, 1,

                 &mpc8_q6_codes[i], 1, 1, INIT_VLC_USE_STATIC);

        init_vlc(&quant_vlc[2][i], MPC8_Q7_BITS, MPC8_Q7_SIZE,

                 &mpc8_q7_bits[i],  1, 1,

                 &mpc8_q7_codes[i], 1, 1, INIT_VLC_USE_STATIC);

        init_vlc(&quant_vlc[3][i], MPC8_Q8_BITS, MPC8_Q8_SIZE,

                 &mpc8_q8_bits[i],  1, 1,

                 &mpc8_q8_codes[i], 1, 1, INIT_VLC_USE_STATIC);

    }

    vlc_inited = 1;

    return 0;

}


static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,

                      const uint8_t *buf, int count)

{

    BDRVRawState *s = bs->opaque;

    int ret;

    ret = fd_open(bs);

    if (ret < 0)

        return -errno;

    ret = pwrite(s->fd, buf, count, offset);

    if (ret == count)

        goto label__raw_write__success;

    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64

                      "] write failed %d : %d = %s\n",

                      s->fd, bs->filename, offset, buf, count,

                      bs->total_sectors, ret, errno, strerror(errno));

label__raw_write__success:

    return  (ret < 0) ? -errno : ret;

}


void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap)

{

    BdrvDirtyBitmap *bm, *next;

    QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {

        if (bm == bitmap) {

            assert(!bdrv_dirty_bitmap_frozen(bm));

            QLIST_REMOVE(bitmap, list);

            hbitmap_free(bitmap->bitmap);

            g_free(bitmap->name);

            g_free(bitmap);

            return;

        }

    }

}


void memory_region_init_ram(MemoryRegion *mr,

                            Object *owner,

                            const char *name,

                            uint64_t size)

{

    memory_region_init(mr, owner, name, size);

    mr->ram = true;

    mr->terminates = true;

    mr->destructor = memory_region_destructor_ram;

    mr->ram_addr = qemu_ram_alloc(size, mr);

}


int ff_h264_decode_slice_header(H264Context *h, H264Context *h0)

{

    unsigned int first_mb_in_slice;

    unsigned int pps_id;

    int ret;

    unsigned int slice_type, tmp, i, j;

    int last_pic_structure, last_pic_droppable;

    int must_reinit;

    int needs_reinit = 0;

    int field_pic_flag, bottom_field_flag;

    h->qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;

    h->qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;

    first_mb_in_slice = get_ue_golomb_long(&h->gb);

    if (first_mb_in_slice == 0) { // FIXME better field boundary detection

        if (h0->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {

            ff_h264_field_end(h, 1);

        }

        h0->current_slice = 0;

        if (!h0->first_field) {

            if (h->cur_pic_ptr && !h->droppable) {

                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                          h->picture_structure == PICT_BOTTOM_FIELD);

            }

            h->cur_pic_ptr = NULL;

        }

    }

    slice_type = get_ue_golomb_31(&h->gb);

    if (slice_type > 9) {

        av_log(h->avctx, AV_LOG_ERROR,

               "slice type %d too large at %d %d\n",

               slice_type, h->mb_x, h->mb_y);

        return AVERROR_INVALIDDATA;

    }

    if (slice_type > 4) {

        slice_type -= 5;

        h->slice_type_fixed = 1;

    } else

        h->slice_type_fixed = 0;

    slice_type = golomb_to_pict_type[slice_type];

    h->slice_type     = slice_type;

    h->slice_type_nos = slice_type & 3;

    if (h->nal_unit_type  == NAL_IDR_SLICE &&

        h->slice_type_nos != AV_PICTURE_TYPE_I) {

        av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");

        return AVERROR_INVALIDDATA;

    }

    if (

        (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||

        (h->avctx->skip_frame >= AVDISCARD_BIDIR  && h->slice_type_nos == AV_PICTURE_TYPE_B) ||

        (h->avctx->skip_frame >= AVDISCARD_NONINTRA && h->slice_type_nos != AV_PICTURE_TYPE_I) ||

        (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE) ||

         h->avctx->skip_frame >= AVDISCARD_ALL) {

         return SLICE_SKIPED;

     }

    // to make a few old functions happy, it's wrong though

    h->pict_type = h->slice_type;

    pps_id = get_ue_golomb(&h->gb);

    if (pps_id >= MAX_PPS_COUNT) {

        av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", pps_id);

        return AVERROR_INVALIDDATA;

    }

    if (!h0->pps_buffers[pps_id]) {

        av_log(h->avctx, AV_LOG_ERROR,

               "non-existing PPS %u referenced\n",

               pps_id);

        return AVERROR_INVALIDDATA;

    }

    if (h0->au_pps_id >= 0 && pps_id != h0->au_pps_id) {

        av_log(h->avctx, AV_LOG_ERROR,

               "PPS change from %d to %d forbidden\n",

               h0->au_pps_id, pps_id);

        return AVERROR_INVALIDDATA;

    }

    h->pps = *h0->pps_buffers[pps_id];

    if (!h0->sps_buffers[h->pps.sps_id]) {

        av_log(h->avctx, AV_LOG_ERROR,

               "non-existing SPS %u referenced\n",

               h->pps.sps_id);

        return AVERROR_INVALIDDATA;

    }

    if (h->pps.sps_id != h->sps.sps_id ||

        h->pps.sps_id != h->current_sps_id ||

        h0->sps_buffers[h->pps.sps_id]->new) {

        h->sps = *h0->sps_buffers[h->pps.sps_id];

        if (h->mb_width  != h->sps.mb_width ||

            h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) ||

            h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||

            h->cur_chroma_format_idc != h->sps.chroma_format_idc

        )

            needs_reinit = 1;

        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||

            h->chroma_format_idc != h->sps.chroma_format_idc) {

            h->bit_depth_luma    = h->sps.bit_depth_luma;

            h->chroma_format_idc = h->sps.chroma_format_idc;

            needs_reinit         = 1;

        }

        if ((ret = ff_h264_set_parameter_from_sps(h)) < 0)

            return ret;

    }

    h->avctx->profile = ff_h264_get_profile(&h->sps);

    h->avctx->level   = h->sps.level_idc;

    h->avctx->refs    = h->sps.ref_frame_count;

    must_reinit = (h->context_initialized &&

                    (   16*h->sps.mb_width != h->avctx->coded_width

                     || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height

                     || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma

                     || h->cur_chroma_format_idc != h->sps.chroma_format_idc

                     || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)

                     || h->mb_width  != h->sps.mb_width

                     || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag)

                    ));

    if (non_j_pixfmt(h0->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 0)))

        must_reinit = 1;

    h->mb_width  = h->sps.mb_width;

    h->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);

    h->mb_num    = h->mb_width * h->mb_height;

    h->mb_stride = h->mb_width + 1;

    h->b_stride = h->mb_width * 4;

    h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p

    h->width  = 16 * h->mb_width;

    h->height = 16 * h->mb_height;

    ret = init_dimensions(h);

    if (ret < 0)

        return ret;

    if (h->sps.video_signal_type_present_flag) {

        h->avctx->color_range = h->sps.full_range>0 ? AVCOL_RANGE_JPEG

                                                    : AVCOL_RANGE_MPEG;

        if (h->sps.colour_description_present_flag) {

            if (h->avctx->colorspace != h->sps.colorspace)

                needs_reinit = 1;

            h->avctx->color_primaries = h->sps.color_primaries;

            h->avctx->color_trc       = h->sps.color_trc;

            h->avctx->colorspace      = h->sps.colorspace;

        }

    }

    if (h->context_initialized &&

        (must_reinit || needs_reinit)) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "changing width %d -> %d / height %d -> %d on "

                   "slice %d\n",

                   h->width, h->avctx->coded_width,

                   h->height, h->avctx->coded_height,

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

        ff_h264_flush_change(h);

        if ((ret = get_pixel_format(h, 1)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "

               "pix_fmt: %s\n", h->width, h->height, av_get_pix_fmt_name(h->avctx->pix_fmt));

        if ((ret = h264_slice_header_init(h, 1)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (!h->context_initialized) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Cannot (re-)initialize context during parallel decoding.\n");

            return AVERROR_PATCHWELCOME;

        }

        if ((ret = get_pixel_format(h, 1)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        if ((ret = h264_slice_header_init(h, 0)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (h == h0 && h->dequant_coeff_pps != pps_id) {

        h->dequant_coeff_pps = pps_id;

        h264_init_dequant_tables(h);

    }

    h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num);

    h->mb_mbaff        = 0;

    h->mb_aff_frame    = 0;

    last_pic_structure = h0->picture_structure;

    last_pic_droppable = h0->droppable;

    h->droppable       = h->nal_ref_idc == 0;

    if (h->sps.frame_mbs_only_flag) {

        h->picture_structure = PICT_FRAME;

    } else {

        if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {

            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");

            return -1;

        }

        field_pic_flag = get_bits1(&h->gb);

        if (field_pic_flag) {

            bottom_field_flag = get_bits1(&h->gb);

            h->picture_structure = PICT_TOP_FIELD + bottom_field_flag;

        } else {

            h->picture_structure = PICT_FRAME;

            h->mb_aff_frame      = h->sps.mb_aff;

        }

    }

    h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME;

    if (h0->current_slice != 0) {

        if (last_pic_structure != h->picture_structure ||

            last_pic_droppable != h->droppable) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Changing field mode (%d -> %d) between slices is not allowed\n",

                   last_pic_structure, h->picture_structure);

            h->picture_structure = last_pic_structure;

            h->droppable         = last_pic_droppable;

            return AVERROR_INVALIDDATA;

        } else if (!h0->cur_pic_ptr) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "unset cur_pic_ptr on slice %d\n",

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

    } else {

        /* Shorten frame num gaps so we don't have to allocate reference

         * frames just to throw them away */

        if (h->frame_num != h->prev_frame_num) {

            int unwrap_prev_frame_num = h->prev_frame_num;

            int max_frame_num         = 1 << h->sps.log2_max_frame_num;

            if (unwrap_prev_frame_num > h->frame_num)

                unwrap_prev_frame_num -= max_frame_num;

            if ((h->frame_num - unwrap_prev_frame_num) > h->sps.ref_frame_count) {

                unwrap_prev_frame_num = (h->frame_num - h->sps.ref_frame_count) - 1;

                if (unwrap_prev_frame_num < 0)

                    unwrap_prev_frame_num += max_frame_num;

                h->prev_frame_num = unwrap_prev_frame_num;

            }

        }

        /* See if we have a decoded first field looking for a pair...

         * Here, we're using that to see if we should mark previously

         * decode frames as "finished".

         * We have to do that before the "dummy" in-between frame allocation,

         * since that can modify h->cur_pic_ptr. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

            /* Mark old field/frame as completed */

            if (h0->cur_pic_ptr->tf.owner == h0->avctx) {

                ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                          last_pic_structure == PICT_BOTTOM_FIELD);

            }

            /* figure out if we have a complementary field pair */

            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

                /* Previous field is unmatched. Don't display it, but let it

                 * remain for reference if marked as such. */

                if (last_pic_structure != PICT_FRAME) {

                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                              last_pic_structure == PICT_TOP_FIELD);

                }

            } else {

                if (h0->cur_pic_ptr->frame_num != h->frame_num) {

                    /* This and previous field were reference, but had

                     * different frame_nums. Consider this field first in

                     * pair. Throw away previous field except for reference

                     * purposes. */

                    if (last_pic_structure != PICT_FRAME) {

                        ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                                  last_pic_structure == PICT_TOP_FIELD);

                    }

                } else {

                    /* Second field in complementary pair */

                    if (!((last_pic_structure   == PICT_TOP_FIELD &&

                           h->picture_structure == PICT_BOTTOM_FIELD) ||

                          (last_pic_structure   == PICT_BOTTOM_FIELD &&

                           h->picture_structure == PICT_TOP_FIELD))) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "Invalid field mode combination %d/%d\n",

                               last_pic_structure, h->picture_structure);

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_INVALIDDATA;

                    } else if (last_pic_droppable != h->droppable) {

                        avpriv_request_sample(h->avctx,

                                              "Found reference and non-reference fields in the same frame, which");

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_PATCHWELCOME;

                    }

                }

            }

        }

        while (h->frame_num != h->prev_frame_num && !h0->first_field &&

               h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) {

            H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;

            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",

                   h->frame_num, h->prev_frame_num);

            if (!h->sps.gaps_in_frame_num_allowed_flag)

                for(i=0; i<FF_ARRAY_ELEMS(h->last_pocs); i++)

                    h->last_pocs[i] = INT_MIN;

            ret = h264_frame_start(h);

            if (ret < 0) {

                h0->first_field = 0;

                return ret;

            }

            h->prev_frame_num++;

            h->prev_frame_num        %= 1 << h->sps.log2_max_frame_num;

            h->cur_pic_ptr->frame_num = h->prev_frame_num;

            h->cur_pic_ptr->invalid_gap = !h->sps.gaps_in_frame_num_allowed_flag;

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);

            ret = ff_generate_sliding_window_mmcos(h, 1);

            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

                return ret;

            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);

            if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

                return ret;

            /* Error concealment: If a ref is missing, copy the previous ref

             * in its place.

             * FIXME: Avoiding a memcpy would be nice, but ref handling makes

             * many assumptions about there being no actual duplicates.

             * FIXME: This does not copy padding for out-of-frame motion

             * vectors.  Given we are concealing a lost frame, this probably

             * is not noticeable by comparison, but it should be fixed. */

            if (h->short_ref_count) {

                if (prev) {

                    av_image_copy(h->short_ref[0]->f.data,

                                  h->short_ref[0]->f.linesize,

                                  (const uint8_t **)prev->f.data,

                                  prev->f.linesize,

                                  h->avctx->pix_fmt,

                                  h->mb_width  * 16,

                                  h->mb_height * 16);

                    h->short_ref[0]->poc = prev->poc + 2;

                }

                h->short_ref[0]->frame_num = h->prev_frame_num;

            }

        }

        /* See if we have a decoded first field looking for a pair...

         * We're using that to see whether to continue decoding in that

         * frame, or to allocate a new one. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

            /* figure out if we have a complementary field pair */

            if (!FIELD_PICTURE(h) || h->picture_structure == last_pic_structure) {

                /* Previous field is unmatched. Don't display it, but let it

                 * remain for reference if marked as such. */

                h0->cur_pic_ptr = NULL;

                h0->first_field = FIELD_PICTURE(h);

            } else {

                if (h0->cur_pic_ptr->frame_num != h->frame_num) {

                    ff_thread_report_progress(&h0->cur_pic_ptr->tf, INT_MAX,

                                              h0->picture_structure==PICT_BOTTOM_FIELD);

                    /* This and the previous field had different frame_nums.

                     * Consider this field first in pair. Throw away previous

                     * one except for reference purposes. */

                    h0->first_field = 1;

                    h0->cur_pic_ptr = NULL;

                } else {

                    /* Second field in complementary pair */

                    h0->first_field = 0;

                }

            }

        } else {

            /* Frame or first field in a potentially complementary pair */

            h0->first_field = FIELD_PICTURE(h);

        }

        if (!FIELD_PICTURE(h) || h0->first_field) {

            if (h264_frame_start(h) < 0) {

                h0->first_field = 0;

                return AVERROR_INVALIDDATA;

            }

        } else {

            release_unused_pictures(h, 0);

        }

        /* Some macroblocks can be accessed before they're available in case

        * of lost slices, MBAFF or threading. */

        if (FIELD_PICTURE(h)) {

            for(i = (h->picture_structure == PICT_BOTTOM_FIELD); i<h->mb_height; i++)

                memset(h->slice_table + i*h->mb_stride, -1, (h->mb_stride - (i+1==h->mb_height)) * sizeof(*h->slice_table));

        } else {

            memset(h->slice_table, -1,

                (h->mb_height * h->mb_stride - 1) * sizeof(*h->slice_table));

        }

        h0->last_slice_type = -1;

    }

    if (h != h0 && (ret = clone_slice(h, h0)) < 0)

        return ret;

    /* can't be in alloc_tables because linesize isn't known there.

     * FIXME: redo bipred weight to not require extra buffer? */

    for (i = 0; i < h->slice_context_count; i++)

        if (h->thread_context[i]) {

            ret = alloc_scratch_buffers(h->thread_context[i], h->linesize);

            if (ret < 0)

                return ret;

        }

    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup

    av_assert1(h->mb_num == h->mb_width * h->mb_height);

    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||

        first_mb_in_slice >= h->mb_num) {

        av_log(h->avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");

        return AVERROR_INVALIDDATA;

    }

    h->resync_mb_x = h->mb_x =  first_mb_in_slice % h->mb_width;

    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<

                               FIELD_OR_MBAFF_PICTURE(h);

    if (h->picture_structure == PICT_BOTTOM_FIELD)

        h->resync_mb_y = h->mb_y = h->mb_y + 1;

    av_assert1(h->mb_y < h->mb_height);

    if (h->picture_structure == PICT_FRAME) {

        h->curr_pic_num = h->frame_num;

        h->max_pic_num  = 1 << h->sps.log2_max_frame_num;

    } else {

        h->curr_pic_num = 2 * h->frame_num + 1;

        h->max_pic_num  = 1 << (h->sps.log2_max_frame_num + 1);

    }

    if (h->nal_unit_type == NAL_IDR_SLICE)

        get_ue_golomb(&h->gb); /* idr_pic_id */

    if (h->sps.poc_type == 0) {

        h->poc_lsb = get_bits(&h->gb, h->sps.log2_max_poc_lsb);

        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)

            h->delta_poc_bottom = get_se_golomb(&h->gb);

    }

    if (h->sps.poc_type == 1 && !h->sps.delta_pic_order_always_zero_flag) {

        h->delta_poc[0] = get_se_golomb(&h->gb);

        if (h->pps.pic_order_present == 1 && h->picture_structure == PICT_FRAME)

            h->delta_poc[1] = get_se_golomb(&h->gb);

    }

    ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc);

    if (h->pps.redundant_pic_cnt_present)

        h->redundant_pic_count = get_ue_golomb(&h->gb);

    ret = ff_set_ref_count(h);

    if (ret < 0)

        return ret;

    if (slice_type != AV_PICTURE_TYPE_I &&

        (h0->current_slice == 0 ||

         slice_type != h0->last_slice_type ||

         memcmp(h0->last_ref_count, h0->ref_count, sizeof(h0->ref_count)))) {

        ff_h264_fill_default_ref_list(h);

    }

    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(h);

       if (ret < 0) {

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

           return ret;

       }

    }

    if ((h->pps.weighted_pred && h->slice_type_nos == AV_PICTURE_TYPE_P) ||

        (h->pps.weighted_bipred_idc == 1 &&

         h->slice_type_nos == AV_PICTURE_TYPE_B))

        ff_pred_weight_table(h);

    else if (h->pps.weighted_bipred_idc == 2 &&

             h->slice_type_nos == AV_PICTURE_TYPE_B) {

        implicit_weight_table(h, -1);

    } else {

        h->use_weight = 0;

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

            h->luma_weight_flag[i]   = 0;

            h->chroma_weight_flag[i] = 0;

        }

    }

    // If frame-mt is enabled, only update mmco tables for the first slice

    // in a field. Subsequent slices can temporarily clobber h->mmco_index

    // or h->mmco, which will cause ref list mix-ups and decoding errors

    // further down the line. This may break decoding if the first slice is

    // corrupt, thus we only do this if frame-mt is enabled.

    if (h->nal_ref_idc) {

        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,

                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||

                                             h0->current_slice == 0);

        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

            return AVERROR_INVALIDDATA;

    }

    if (FRAME_MBAFF(h)) {

        ff_h264_fill_mbaff_ref_list(h);

        if (h->pps.weighted_bipred_idc == 2 && h->slice_type_nos == AV_PICTURE_TYPE_B) {

            implicit_weight_table(h, 0);

            implicit_weight_table(h, 1);

        }

    }

    if (h->slice_type_nos == AV_PICTURE_TYPE_B && !h->direct_spatial_mv_pred)

        ff_h264_direct_dist_scale_factor(h);

    ff_h264_direct_ref_list_init(h);

    if (h->slice_type_nos != AV_PICTURE_TYPE_I && h->pps.cabac) {

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR, "cabac_init_idc %u overflow\n", tmp);

            return AVERROR_INVALIDDATA;

        }

        h->cabac_init_idc = tmp;

    }

    h->last_qscale_diff = 0;

    tmp = h->pps.init_qp + get_se_golomb(&h->gb);

    if (tmp > 51 + 6 * (h->sps.bit_depth_luma - 8)) {

        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);

        return AVERROR_INVALIDDATA;

    }

    h->qscale       = tmp;

    h->chroma_qp[0] = get_chroma_qp(h, 0, h->qscale);

    h->chroma_qp[1] = get_chroma_qp(h, 1, h->qscale);

    // FIXME qscale / qp ... stuff

    if (h->slice_type == AV_PICTURE_TYPE_SP)

        get_bits1(&h->gb); /* sp_for_switch_flag */

    if (h->slice_type == AV_PICTURE_TYPE_SP ||

        h->slice_type == AV_PICTURE_TYPE_SI)

        get_se_golomb(&h->gb); /* slice_qs_delta */

    h->deblocking_filter     = 1;

    h->slice_alpha_c0_offset = 0;

    h->slice_beta_offset     = 0;

    if (h->pps.deblocking_filter_parameters_present) {

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "deblocking_filter_idc %u out of range\n", tmp);

            return AVERROR_INVALIDDATA;

        }

        h->deblocking_filter = tmp;

        if (h->deblocking_filter < 2)

            h->deblocking_filter ^= 1;  // 1<->0

        if (h->deblocking_filter) {

            h->slice_alpha_c0_offset = get_se_golomb(&h->gb) * 2;

            h->slice_beta_offset     = get_se_golomb(&h->gb) * 2;

            if (h->slice_alpha_c0_offset >  12 ||

                h->slice_alpha_c0_offset < -12 ||

                h->slice_beta_offset >  12     ||

                h->slice_beta_offset < -12) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "deblocking filter parameters %d %d out of range\n",

                       h->slice_alpha_c0_offset, h->slice_beta_offset);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&

         h->nal_unit_type != NAL_IDR_SLICE) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONINTRA &&

         h->slice_type_nos != AV_PICTURE_TYPE_I) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&

         h->slice_type_nos == AV_PICTURE_TYPE_B) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONREF &&

         h->nal_ref_idc == 0))

        h->deblocking_filter = 0;

    if (h->deblocking_filter == 1 && h0->max_contexts > 1) {

        if (h->avctx->flags2 & CODEC_FLAG2_FAST) {

            /* Cheat slightly for speed:

             * Do not bother to deblock across slices. */

            h->deblocking_filter = 2;

        } else {

            h0->max_contexts = 1;

            if (!h0->single_decode_warning) {

                av_log(h->avctx, AV_LOG_INFO,

                       "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");

                h0->single_decode_warning = 1;

            }

            if (h != h0) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "Deblocking switched inside frame.\n");

                return SLICE_SINGLETHREAD;

            }

        }

    }

    h->qp_thresh = 15 -

                   FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) -

                   FFMAX3(0,

                          h->pps.chroma_qp_index_offset[0],

                          h->pps.chroma_qp_index_offset[1]) +

                   6 * (h->sps.bit_depth_luma - 8);

    h0->last_slice_type = slice_type;

    memcpy(h0->last_ref_count, h0->ref_count, sizeof(h0->last_ref_count));

    h->slice_num        = ++h0->current_slice;

    if (h->slice_num)

        h0->slice_row[(h->slice_num-1)&(MAX_SLICES-1)]= h->resync_mb_y;

    if (   h0->slice_row[h->slice_num&(MAX_SLICES-1)] + 3 >= h->resync_mb_y

        && h0->slice_row[h->slice_num&(MAX_SLICES-1)] <= h->resync_mb_y

        && h->slice_num >= MAX_SLICES) {

        //in case of ASO this check needs to be updated depending on how we decide to assign slice numbers in this case

        av_log(h->avctx, AV_LOG_WARNING, "Possibly too many slices (%d >= %d), increase MAX_SLICES and recompile if there are artifacts\n", h->slice_num, MAX_SLICES);

    }

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

        int id_list[16];

        int *ref2frm = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][j];

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

            id_list[i] = 60;

            if (j < h->list_count && i < h->ref_count[j] &&

                h->ref_list[j][i].f.buf[0]) {

                int k;

                AVBuffer *buf = h->ref_list[j][i].f.buf[0]->buffer;

                for (k = 0; k < h->short_ref_count; k++)

                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = k;

                        break;

                    }

                for (k = 0; k < h->long_ref_count; k++)

                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = h->short_ref_count + k;

                        break;

                    }

            }

        }

        ref2frm[0] =

        ref2frm[1] = -1;

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

            ref2frm[i + 2] = 4 * id_list[i] + (h->ref_list[j][i].reference & 3);

        ref2frm[18 + 0] =

        ref2frm[18 + 1] = -1;

        for (i = 16; i < 48; i++)

            ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +

                             (h->ref_list[j][i].reference & 3);

    }

    if (h->ref_count[0]) ff_h264_set_erpic(&h->er.last_pic, &h->ref_list[0][0]);

    if (h->ref_count[1]) ff_h264_set_erpic(&h->er.next_pic, &h->ref_list[1][0]);

    h->er.ref_count = h->ref_count[0];

    h0->au_pps_id = pps_id;

    h->sps.new =

    h0->sps_buffers[h->pps.sps_id]->new = 0;

    h->current_sps_id = h->pps.sps_id;

    if (h->avctx->debug & FF_DEBUG_PICT_INFO) {

        av_log(h->avctx, AV_LOG_DEBUG,

               "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",

               h->slice_num,

               (h->picture_structure == PICT_FRAME ? "F" : h->picture_structure == PICT_TOP_FIELD ? "T" : "B"),

               first_mb_in_slice,

               av_get_picture_type_char(h->slice_type),

               h->slice_type_fixed ? " fix" : "",

               h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",

               pps_id, h->frame_num,

               h->cur_pic_ptr->field_poc[0],

               h->cur_pic_ptr->field_poc[1],

               h->ref_count[0], h->ref_count[1],

               h->qscale,

               h->deblocking_filter,

               h->slice_alpha_c0_offset, h->slice_beta_offset,

               h->use_weight,

               h->use_weight == 1 && h->use_weight_chroma ? "c" : "",

               h->slice_type == AV_PICTURE_TYPE_B ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "");

    }

    return 0;

}


static void virtio_scsi_request_cancelled(SCSIRequest *r)

{

    VirtIOSCSIReq *req = r->hba_private;

    if (!req) {

        return;

    }

    if (req->dev->resetting) {

        req->resp.cmd->response = VIRTIO_SCSI_S_RESET;

    } else {

        req->resp.cmd->response = VIRTIO_SCSI_S_ABORTED;

    }

    virtio_scsi_complete_cmd_req(req);

}


void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome)

{

    const ARMCPRegInfo *ri = rip;

    int target_el;

    if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14

        && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {

        raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));

    }

    if (!ri->accessfn) {

        return;

    }

    switch (ri->accessfn(env, ri)) {

    case CP_ACCESS_OK:

        return;

    case CP_ACCESS_TRAP:

        target_el = exception_target_el(env);

        break;

    case CP_ACCESS_TRAP_EL2:

        /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is

         * a bug in the access function.

         */

        assert(!arm_is_secure(env) && !arm_current_el(env) == 3);

        target_el = 2;

        break;

    case CP_ACCESS_TRAP_EL3:

        target_el = 3;

        break;

    case CP_ACCESS_TRAP_UNCATEGORIZED:

        target_el = exception_target_el(env);

        syndrome = syn_uncategorized();

        break;

    default:

        g_assert_not_reached();

    }

    raise_exception(env, EXCP_UDEF, syndrome, target_el);

}


static void notify_event_cb(void *opaque)

{

    /* No need to do anything; this bottom half is only used to

     * kick the kernel out of ppoll/poll/WaitForMultipleObjects.

     */

}


static int m25p80_init(SSISlave *ss)

{

    DriveInfo *dinfo;

    Flash *s = M25P80(ss);

    M25P80Class *mc = M25P80_GET_CLASS(s);

    s->pi = mc->pi;

    s->size = s->pi->sector_size * s->pi->n_sectors;

    s->dirty_page = -1;

    s->storage = qemu_blockalign(s->bdrv, s->size);

    dinfo = drive_get_next(IF_MTD);

    if (dinfo) {

        DB_PRINT_L(0, "Binding to IF_MTD drive\n");

        s->bdrv = blk_bs(blk_by_legacy_dinfo(dinfo));

        /* FIXME: Move to late init */

        if (bdrv_read(s->bdrv, 0, s->storage, DIV_ROUND_UP(s->size,

                                                    BDRV_SECTOR_SIZE))) {

            fprintf(stderr, "Failed to initialize SPI flash!\n");

            return 1;

        }

    } else {

        DB_PRINT_L(0, "No BDRV - binding to RAM\n");

        memset(s->storage, 0xFF, s->size);

    }

    return 0;

}


static void sdl_mouse_warp(int x, int y, int on)

{

    if (on) {

        if (!guest_cursor)

            sdl_show_cursor();

        if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) {

            SDL_SetCursor(guest_sprite);

            SDL_WarpMouse(x, y);

        }

    } else if (gui_grab)

        sdl_hide_cursor();

    guest_cursor = on;

    guest_x = x, guest_y = y;

}


static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,

    uint64_t offset, void **table, bool read_from_disk)

{

    BDRVQcowState *s = bs->opaque;

    int i;

    int ret;

    int lookup_index;

    uint64_t min_lru_counter = UINT64_MAX;

    int min_lru_index = -1;

    trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache,

                          offset, read_from_disk);

    /* Check if the table is already cached */

    i = lookup_index = (offset / s->cluster_size * 4) % c->size;

    do {

        const Qcow2CachedTable *t = &c->entries[i];

        if (t->offset == offset) {

            goto found;

        }

        if (t->ref == 0 && t->lru_counter < min_lru_counter) {

            min_lru_counter = t->lru_counter;

            min_lru_index = i;

        }

        if (++i == c->size) {

            i = 0;

        }

    } while (i != lookup_index);

    if (min_lru_index == -1) {

        /* This can't happen in current synchronous code, but leave the check

         * here as a reminder for whoever starts using AIO with the cache */

        abort();

    }

    /* Cache miss: write a table back and replace it */

    i = min_lru_index;

    trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(),

                                        c == s->l2_table_cache, i);

    if (i < 0) {

        return i;

    }

    ret = qcow2_cache_entry_flush(bs, c, i);

    if (ret < 0) {

        return ret;

    }

    trace_qcow2_cache_get_read(qemu_coroutine_self(),

                               c == s->l2_table_cache, i);

    c->entries[i].offset = 0;

    if (read_from_disk) {

        if (c == s->l2_table_cache) {

            BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);

        }

        ret = bdrv_pread(bs->file, offset, qcow2_cache_get_table_addr(bs, c, i),

                         s->cluster_size);

        if (ret < 0) {

            return ret;

        }

    }

    c->entries[i].offset = offset;

    /* And return the right table */

found:

    c->entries[i].ref++;

    *table = qcow2_cache_get_table_addr(bs, c, i);

    trace_qcow2_cache_get_done(qemu_coroutine_self(),

                               c == s->l2_table_cache, i);

    return 0;

}


int net_init_socket(QemuOpts *opts,

                    Monitor *mon,

                    const char *name,

                    VLANState *vlan)

{

    if (qemu_opt_get(opts, "fd")) {

        int fd;

        if (qemu_opt_get(opts, "listen") ||

            qemu_opt_get(opts, "connect") ||

            qemu_opt_get(opts, "mcast")) {

            qemu_error("listen=, connect= and mcast= is invalid with fd=\n");

            return -1;

        }

        fd = net_handle_fd_param(mon, qemu_opt_get(opts, "fd"));

        if (fd == -1) {

            return -1;

        }

        if (!net_socket_fd_init(vlan, "socket", name, fd, 1)) {

            close(fd);

            return -1;

        }

    } else if (qemu_opt_get(opts, "listen")) {

        const char *listen;

        if (qemu_opt_get(opts, "fd") ||

            qemu_opt_get(opts, "connect") ||

            qemu_opt_get(opts, "mcast")) {

            qemu_error("fd=, connect= and mcast= is invalid with listen=\n");

            return -1;

        }

        listen = qemu_opt_get(opts, "listen");

        if (net_socket_listen_init(vlan, "socket", name, listen) == -1) {

            return -1;

        }

    } else if (qemu_opt_get(opts, "connect")) {

        const char *connect;

        if (qemu_opt_get(opts, "fd") ||

            qemu_opt_get(opts, "listen") ||

            qemu_opt_get(opts, "mcast")) {

            qemu_error("fd=, listen= and mcast= is invalid with connect=\n");

            return -1;

        }

        connect = qemu_opt_get(opts, "connect");

        if (net_socket_connect_init(vlan, "socket", name, connect) == -1) {

            return -1;

        }

    } else if (qemu_opt_get(opts, "mcast")) {

        const char *mcast;

        if (qemu_opt_get(opts, "fd") ||

            qemu_opt_get(opts, "connect") ||

            qemu_opt_get(opts, "listen")) {

            qemu_error("fd=, connect= and listen= is invalid with mcast=\n");

            return -1;

        }

        mcast = qemu_opt_get(opts, "mcast");

        if (net_socket_mcast_init(vlan, "socket", name, mcast) == -1) {

            return -1;

        }

    } else {

        qemu_error("-socket requires fd=, listen=, connect= or mcast=\n");

        return -1;

    }

    if (vlan) {

        vlan->nb_host_devs++;

    }

    return 0;

}


int ff_init_filters(SwsContext * c)

{

    int i;

    int index;

    int num_ydesc;

    int num_cdesc;

    int num_vdesc = isPlanarYUV(c->dstFormat) && !isGray(c->dstFormat) ? 2 : 1;

    int need_lum_conv = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;

    int need_chr_conv = c->chrToYV12 || c->readChrPlanar;

    int srcIdx, dstIdx;

    int dst_stride = FFALIGN(c->dstW * sizeof(int16_t) + 66, 16);

    uint32_t * pal = usePal(c->srcFormat) ? c->pal_yuv : (uint32_t*)c->input_rgb2yuv_table;

    int res = 0;

    if (c->dstBpc == 16)

        dst_stride <<= 1;

    num_ydesc = need_lum_conv ? 2 : 1;

    num_cdesc = need_chr_conv ? 2 : 1;

    c->numSlice = FFMAX(num_ydesc, num_cdesc) + 2;

    c->numDesc = num_ydesc + num_cdesc + num_vdesc;

    c->descIndex[0] = num_ydesc;

    c->descIndex[1] = num_ydesc + num_cdesc;

    c->desc = av_mallocz_array(sizeof(SwsFilterDescriptor), c->numDesc);

    if (!c->desc)

        return AVERROR(ENOMEM);

    c->slice = av_mallocz_array(sizeof(SwsSlice), c->numSlice);

    res = alloc_slice(&c->slice[0], c->srcFormat, c->srcH, c->chrSrcH, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);

    if (res < 0) goto cleanup;

    for (i = 1; i < c->numSlice-2; ++i) {

        res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize + MAX_LINES_AHEAD, c->vChrFilterSize + MAX_LINES_AHEAD, c->chrSrcHSubSample, c->chrSrcVSubSample, 0);

        if (res < 0) goto cleanup;

        res = alloc_lines(&c->slice[i], FFALIGN(c->srcW*2+78, 16), c->srcW);

        if (res < 0) goto cleanup;

    }

    // horizontal scaler output

    res = alloc_slice(&c->slice[i], c->srcFormat, c->vLumFilterSize + MAX_LINES_AHEAD, c->vChrFilterSize + MAX_LINES_AHEAD, c->chrDstHSubSample, c->chrDstVSubSample, 1);

    if (res < 0) goto cleanup;

    res = alloc_lines(&c->slice[i], dst_stride, c->dstW);

    if (res < 0) goto cleanup;

    fill_ones(&c->slice[i], dst_stride>>1, c->dstBpc == 16);

    // vertical scaler output

    ++i;

    res = alloc_slice(&c->slice[i], c->dstFormat, c->dstH, c->chrDstH, c->chrDstHSubSample, c->chrDstVSubSample, 0);

    if (res < 0) goto cleanup;

    index = 0;

    srcIdx = 0;

    dstIdx = 1;

    if (need_lum_conv) {

        ff_init_desc_fmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);

        c->desc[index].alpha = c->alpPixBuf != 0;

        ++index;

        srcIdx = dstIdx;

    }

    dstIdx = FFMAX(num_ydesc, num_cdesc);

    ff_init_desc_hscale(&c->desc[index], &c->slice[index], &c->slice[dstIdx], c->hLumFilter, c->hLumFilterPos, c->hLumFilterSize, c->lumXInc);

    c->desc[index].alpha = c->alpPixBuf != 0;

    ++index;

    {

        srcIdx = 0;

        dstIdx = 1;

        if (need_chr_conv) {

            ff_init_desc_cfmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);

            ++index;

            srcIdx = dstIdx;

        }

        dstIdx = FFMAX(num_ydesc, num_cdesc);

        if (c->needs_hcscale)

            ff_init_desc_chscale(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], c->hChrFilter, c->hChrFilterPos, c->hChrFilterSize, c->chrXInc);

        else

            ff_init_desc_no_chr(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx]);

    }

    ++index;

    {

        srcIdx = c->numSlice - 2;

        dstIdx = c->numSlice - 1;

        ff_init_vscale(c, c->desc + index, c->slice + srcIdx, c->slice + dstIdx);

    }

    return 0;

cleanup:

    ff_free_filters(c);

    return res;

}


void commit_start(const char *job_id, BlockDriverState *bs,

                  BlockDriverState *base, BlockDriverState *top, int64_t speed,

                  BlockdevOnError on_error, const char *backing_file_str,

                  Error **errp)

{

    CommitBlockJob *s;

    BlockReopenQueue *reopen_queue = NULL;

    int orig_overlay_flags;

    int orig_base_flags;

    BlockDriverState *iter;

    BlockDriverState *overlay_bs;

    Error *local_err = NULL;

    int ret;

    assert(top != bs);

    if (top == base) {

        error_setg(errp, "Invalid files for merge: top and base are the same");

        return;

    }

    overlay_bs = bdrv_find_overlay(bs, top);

    if (overlay_bs == NULL) {

        error_setg(errp, "Could not find overlay image for %s:", top->filename);

        return;

    }

    /* FIXME Use real permissions */

    s = block_job_create(job_id, &commit_job_driver, bs, 0, BLK_PERM_ALL,

                         speed, BLOCK_JOB_DEFAULT, NULL, NULL, errp);

    if (!s) {

        return;

    }

    orig_base_flags    = bdrv_get_flags(base);

    orig_overlay_flags = bdrv_get_flags(overlay_bs);

    /* convert base & overlay_bs to r/w, if necessary */

    if (!(orig_base_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, base, NULL,

                                         orig_base_flags | BDRV_O_RDWR);

    }

    if (!(orig_overlay_flags & BDRV_O_RDWR)) {

        reopen_queue = bdrv_reopen_queue(reopen_queue, overlay_bs, NULL,

                                         orig_overlay_flags | BDRV_O_RDWR);

    }

    if (reopen_queue) {

        bdrv_reopen_multiple(bdrv_get_aio_context(bs), reopen_queue, &local_err);

        if (local_err != NULL) {

            error_propagate(errp, local_err);

            goto fail;

        }

    }

    /* Block all nodes between top and base, because they will

     * disappear from the chain after this operation. */

    assert(bdrv_chain_contains(top, base));

    for (iter = top; iter != backing_bs(base); iter = backing_bs(iter)) {

        /* FIXME Use real permissions */

        block_job_add_bdrv(&s->common, "intermediate node", iter, 0,

                           BLK_PERM_ALL, &error_abort);

    }

    /* overlay_bs must be blocked because it needs to be modified to

     * update the backing image string, but if it's the root node then

     * don't block it again */

    if (bs != overlay_bs) {

        /* FIXME Use real permissions */

        block_job_add_bdrv(&s->common, "overlay of top", overlay_bs, 0,

                           BLK_PERM_ALL, &error_abort);

    }

    /* FIXME Use real permissions */

    s->base = blk_new(0, BLK_PERM_ALL);

    ret = blk_insert_bs(s->base, base, errp);

    if (ret < 0) {

        goto fail;

    }

    /* FIXME Use real permissions */

    s->top = blk_new(0, BLK_PERM_ALL);

    ret = blk_insert_bs(s->top, top, errp);

    if (ret < 0) {

        goto fail;

    }

    s->active = bs;

    s->base_flags          = orig_base_flags;

    s->orig_overlay_flags  = orig_overlay_flags;

    s->backing_file_str = g_strdup(backing_file_str);

    s->on_error = on_error;

    trace_commit_start(bs, base, top, s);

    block_job_start(&s->common);

    return;

fail:

    if (s->base) {

        blk_unref(s->base);

    }

    if (s->top) {

        blk_unref(s->top);

    }

    block_job_unref(&s->common);

}


int load_elf(const char *filename, int64_t virt_to_phys_addend,

             uint64_t *pentry)

{

    int fd, data_order, must_swab, ret;

    uint8_t e_ident[EI_NIDENT];

    fd = open(filename, O_RDONLY | O_BINARY);

    if (fd < 0) {

        perror(filename);

        return -1;

    }

    if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident))

        goto fail;

    if (e_ident[0] != ELFMAG0 ||

        e_ident[1] != ELFMAG1 ||

        e_ident[2] != ELFMAG2 ||

        e_ident[3] != ELFMAG3)

        goto fail;

#ifdef WORDS_BIGENDIAN

    data_order = ELFDATA2MSB;

#else

    data_order = ELFDATA2LSB;

#endif

    must_swab = data_order != e_ident[EI_DATA];

    lseek(fd, 0, SEEK_SET);

    if (e_ident[EI_CLASS] == ELFCLASS64) {

        ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry);

    } else {

        ret = load_elf32(fd, virt_to_phys_addend, must_swab, pentry);

    }

    close(fd);

    return ret;

 fail:

    close(fd);

    return -1;

}


qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,

                    uint64_t mcg_status, uint64_t addr, uint64_t misc)

{

    uint64_t mcg_cap = cenv->mcg_cap;

    uint64_t *banks = cenv->mce_banks;

    /*

     * if MSR_MCG_CTL is not all 1s, the uncorrected error

     * reporting is disabled

     */

    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&

        cenv->mcg_ctl != ~(uint64_t)0) {

        return;

    }

    banks += 4 * bank;

    /*

     * if MSR_MCi_CTL is not all 1s, the uncorrected error

     * reporting is disabled for the bank

     */

    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0) {

        return;

    }

    if (status & MCI_STATUS_UC) {

        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||

            !(cenv->cr[4] & CR4_MCE_MASK)) {

            fprintf(stderr, "injects mce exception while previous "

                    "one is in progress!\n");

            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");

            qemu_system_reset_request();

            return;

        }

        if (banks[1] & MCI_STATUS_VAL) {

            status |= MCI_STATUS_OVER;

        }

        banks[2] = addr;

        banks[3] = misc;

        cenv->mcg_status = mcg_status;

        banks[1] = status;

        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);

    } else if (!(banks[1] & MCI_STATUS_VAL)

               || !(banks[1] & MCI_STATUS_UC)) {

        if (banks[1] & MCI_STATUS_VAL) {

            status |= MCI_STATUS_OVER;

        }

        banks[2] = addr;

        banks[3] = misc;

        banks[1] = status;

    } else {

        banks[1] |= MCI_STATUS_OVER;

    }

}


static USBDevice *usb_msd_init(const char *filename)

{

    static int nr=0;

    char id[8];

    QemuOpts *opts;

    DriveInfo *dinfo;

    USBDevice *dev;

    int fatal_error;

    const char *p1;

    char fmt[32];

    /* parse -usbdevice disk: syntax into drive opts */

    snprintf(id, sizeof(id), "usb%d", nr++);

    opts = qemu_opts_create(&qemu_drive_opts, id, 0);

    p1 = strchr(filename, ':');

    if (p1++) {

        const char *p2;

        if (strstart(filename, "format=", &p2)) {

            int len = MIN(p1 - p2, sizeof(fmt));

            pstrcpy(fmt, len, p2);

            qemu_opt_set(opts, "format", fmt);

        } else if (*filename != ':') {

            printf("unrecognized USB mass-storage option %s\n", filename);

            return NULL;

        }

        filename = p1;

    }

    if (!*filename) {

        printf("block device specification needed\n");

        return NULL;

    }

    qemu_opt_set(opts, "file", filename);

    qemu_opt_set(opts, "if", "none");

    /* create host drive */

    dinfo = drive_init(opts, 0, &fatal_error);

    if (!dinfo) {

        qemu_opts_del(opts);

        return NULL;

    }

    /* create guest device */

    dev = usb_create(NULL /* FIXME */, "usb-storage");

    if (!dev) {

        return NULL;

    }

    qdev_prop_set_drive(&dev->qdev, "drive", dinfo);

    if (qdev_init(&dev->qdev) < 0)

        return NULL;

    return dev;

}


static inline void gen_evmergelo(DisasContext *ctx)

{

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

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

#if defined(TARGET_PPC64)

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);

    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);

    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

#else

    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);

#endif

}


static int64_t cache_seek(URLContext *h, int64_t pos, int whence)

{

    Context *c= h->priv_data;

    if (whence == AVSEEK_SIZE) {

        pos= ffurl_seek(c->inner, pos, whence);

        if(pos <= 0){

            pos= ffurl_seek(c->inner, -1, SEEK_END);

            ffurl_seek(c->inner, c->end, SEEK_SET);

            if(pos <= 0)

                return c->end;

        }

        return pos;

    }

    pos= lseek(c->fd, pos, whence);

    if(pos<0){

        return pos;

    }else if(pos <= c->end){

        c->pos= pos;

        return pos;

    }else{

        lseek(c->fd, c->pos, SEEK_SET);

        return AVERROR(EPIPE);

    }

}