static inline uint16_t vring_avail_flags(VirtQueue *vq)

{

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

    hwaddr pa = offsetof(VRingAvail, flags);

    return virtio_lduw_phys_cached(vq->vdev, &caches->avail, pa);

}


static void ppc_spapr_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    const char *boot_device = machine->boot_order;

    PowerPCCPU *cpu;

    CPUPPCState *env;

    PCIHostState *phb;

    int i;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *rma_region;

    void *rma = NULL;

    hwaddr rma_alloc_size;

    hwaddr node0_size = spapr_node0_size();

    uint32_t initrd_base = 0;

    long kernel_size = 0, initrd_size = 0;

    long load_limit, rtas_limit, fw_size;

    bool kernel_le = false;

    char *filename;

    msi_supported = true;

    spapr = g_malloc0(sizeof(*spapr));

    QLIST_INIT(&spapr->phbs);

    cpu_ppc_hypercall = emulate_spapr_hypercall;

    /* Allocate RMA if necessary */

    rma_alloc_size = kvmppc_alloc_rma(&rma);

    if (rma_alloc_size == -1) {

        hw_error("qemu: Unable to create RMA\n");

        exit(1);

    }

    if (rma_alloc_size && (rma_alloc_size < node0_size)) {

        spapr->rma_size = rma_alloc_size;

    } else {

        spapr->rma_size = node0_size;

        /* With KVM, we don't actually know whether KVM supports an

         * unbounded RMA (PR KVM) or is limited by the hash table size

         * (HV KVM using VRMA), so we always assume the latter

         *

         * In that case, we also limit the initial allocations for RTAS

         * etc... to 256M since we have no way to know what the VRMA size

         * is going to be as it depends on the size of the hash table

         * isn't determined yet.

         */

        if (kvm_enabled()) {

            spapr->vrma_adjust = 1;

            spapr->rma_size = MIN(spapr->rma_size, 0x10000000);

        }

    }

    if (spapr->rma_size > node0_size) {

        fprintf(stderr, "Error: Numa node 0 has to span the RMA (%#08"HWADDR_PRIx")\n",

                spapr->rma_size);

        exit(1);

    }

    /* We place the device tree and RTAS just below either the top of the RMA,

     * or just below 2GB, whichever is lowere, so that it can be

     * processed with 32-bit real mode code if necessary */

    rtas_limit = MIN(spapr->rma_size, 0x80000000);

    spapr->rtas_addr = rtas_limit - RTAS_MAX_SIZE;

    spapr->fdt_addr = spapr->rtas_addr - FDT_MAX_SIZE;

    load_limit = spapr->fdt_addr - FW_OVERHEAD;

    /* We aim for a hash table of size 1/128 the size of RAM.  The

     * normal rule of thumb is 1/64 the size of RAM, but that's much

     * more than needed for the Linux guests we support. */

    spapr->htab_shift = 18; /* Minimum architected size */

    while (spapr->htab_shift <= 46) {

        if ((1ULL << (spapr->htab_shift + 7)) >= ram_size) {

            break;

        }

        spapr->htab_shift++;

    }

    /* Set up Interrupt Controller before we create the VCPUs */

    spapr->icp = xics_system_init(smp_cpus * kvmppc_smt_threads() / smp_threads,

                                  XICS_IRQS);

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = kvm_enabled() ? "host" : "POWER7";

    }

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

        cpu = cpu_ppc_init(cpu_model);

        if (cpu == NULL) {

            fprintf(stderr, "Unable to find PowerPC CPU definition\n");

            exit(1);

        }

        env = &cpu->env;

        /* Set time-base frequency to 512 MHz */

        cpu_ppc_tb_init(env, TIMEBASE_FREQ);

        /* PAPR always has exception vectors in RAM not ROM. To ensure this,

         * MSR[IP] should never be set.

         */

        env->msr_mask &= ~(1 << 6);

        /* Tell KVM that we're in PAPR mode */

        if (kvm_enabled()) {

            kvmppc_set_papr(cpu);

        }

        if (cpu->max_compat) {

            if (ppc_set_compat(cpu, cpu->max_compat) < 0) {

                exit(1);

            }

        }

        xics_cpu_setup(spapr->icp, cpu);

        qemu_register_reset(spapr_cpu_reset, cpu);

    }

    /* allocate RAM */

    spapr->ram_limit = ram_size;

    memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",

                                         spapr->ram_limit);

    memory_region_add_subregion(sysmem, 0, ram);

    if (rma_alloc_size && rma) {

        rma_region = g_new(MemoryRegion, 1);

        memory_region_init_ram_ptr(rma_region, NULL, "ppc_spapr.rma",

                                   rma_alloc_size, rma);

        vmstate_register_ram_global(rma_region);

        memory_region_add_subregion(sysmem, 0, rma_region);

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");

    spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,

                                           rtas_limit - spapr->rtas_addr);

    if (spapr->rtas_size < 0) {

        hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

        exit(1);

    }

    if (spapr->rtas_size > RTAS_MAX_SIZE) {

        hw_error("RTAS too big ! 0x%lx bytes (max is 0x%x)\n",

                 spapr->rtas_size, RTAS_MAX_SIZE);

        exit(1);

    }

    g_free(filename);

    /* Set up EPOW events infrastructure */

    spapr_events_init(spapr);

    /* Set up VIO bus */

    spapr->vio_bus = spapr_vio_bus_init();

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

        if (serial_hds[i]) {

            spapr_vty_create(spapr->vio_bus, serial_hds[i]);

        }

    }

    /* We always have at least the nvram device on VIO */

    spapr_create_nvram(spapr);

    /* Set up PCI */

    spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW);

    spapr_pci_rtas_init();

    phb = spapr_create_phb(spapr, 0);

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

        NICInfo *nd = &nd_table[i];

        if (!nd->model) {

            nd->model = g_strdup("ibmveth");

        }

        if (strcmp(nd->model, "ibmveth") == 0) {

            spapr_vlan_create(spapr->vio_bus, nd);

        } else {

            pci_nic_init_nofail(&nd_table[i], phb->bus, nd->model, NULL);

        }

    }

    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {

        spapr_vscsi_create(spapr->vio_bus);

    }

    /* Graphics */

    if (spapr_vga_init(phb->bus)) {

        spapr->has_graphics = true;

    }

    if (usb_enabled(spapr->has_graphics)) {

        pci_create_simple(phb->bus, -1, "pci-ohci");

        if (spapr->has_graphics) {

            usbdevice_create("keyboard");

            usbdevice_create("mouse");

        }

    }

    if (spapr->rma_size < (MIN_RMA_SLOF << 20)) {

        fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "

                "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);

        exit(1);

    }

    if (kernel_filename) {

        uint64_t lowaddr = 0;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,

                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);

        if (kernel_size == ELF_LOAD_WRONG_ENDIAN) {

            kernel_size = load_elf(kernel_filename,

                                   translate_kernel_address, NULL,

                                   NULL, &lowaddr, NULL, 0, ELF_MACHINE, 0);

            kernel_le = kernel_size > 0;

        }

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: error loading %s: %s\n",

                    kernel_filename, load_elf_strerror(kernel_size));

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            /* Try to locate the initrd in the gap between the kernel

             * and the firmware. Add a bit of space just in case

             */

            initrd_base = (KERNEL_LOAD_ADDR + kernel_size + 0x1ffff) & ~0xffff;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              load_limit - initrd_base);

            if (initrd_size < 0) {

                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",

                        initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

    }

    if (bios_name == NULL) {

        bios_name = FW_FILE_NAME;

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);

    if (fw_size < 0) {

        hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

        exit(1);

    }

    g_free(filename);

    spapr->entry_point = 0x100;

    vmstate_register(NULL, 0, &vmstate_spapr, spapr);

    register_savevm_live(NULL, "spapr/htab", -1, 1,

                         &savevm_htab_handlers, spapr);

    /* Prepare the device tree */

    spapr->fdt_skel = spapr_create_fdt_skel(initrd_base, initrd_size,

                                            kernel_size, kernel_le,

                                            boot_device, kernel_cmdline,

                                            spapr->epow_irq);

    assert(spapr->fdt_skel != NULL);

}


static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    TTAContext *c = s->priv_data;
    AVStream *st;
    int i, channels, bps, samplerate, datalen, framelen, start;
    start = url_ftell(&s->pb);
    if (get_le32(&s->pb) != ff_get_fourcc("TTA1"))
        return -1; // not tta file
    url_fskip(&s->pb, 2); // FIXME: flags
    channels = get_le16(&s->pb);
    bps = get_le16(&s->pb);
    samplerate = get_le32(&s->pb);
    datalen = get_le32(&s->pb);
    url_fskip(&s->pb, 4); // header crc
    framelen = 1.04489795918367346939 * samplerate;
    c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0);
    c->currentframe = 0;
    c->seektable = av_mallocz(sizeof(uint32_t)*c->totalframes);
    if (!c->seektable)
        return AVERROR_NOMEM;
    for (i = 0; i < c->totalframes; i++)
            c->seektable[i] = get_le32(&s->pb);
    url_fskip(&s->pb, 4); // seektable crc
    st = av_new_stream(s, 0);
//    av_set_pts_info(st, 32, 1, 1000);
    if (!st)
        return AVERROR_NOMEM;
    st->codec->codec_type = CODEC_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_TTA;
    st->codec->channels = channels;
    st->codec->sample_rate = samplerate;
    st->codec->bits_per_sample = bps;
    st->codec->extradata_size = url_ftell(&s->pb) - start;
    if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
        //this check is redundant as get_buffer should fail
        av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
    st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
    url_fseek(&s->pb, start, SEEK_SET); // or SEEK_CUR and -size ? :)
    get_buffer(&s->pb, st->codec->extradata, st->codec->extradata_size);
    return 0;


void kvm_flush_coalesced_mmio_buffer(void)

{

#ifdef KVM_CAP_COALESCED_MMIO

    KVMState *s = kvm_state;

    if (s->coalesced_mmio_ring) {

        struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;

        while (ring->first != ring->last) {

            struct kvm_coalesced_mmio *ent;

            ent = &ring->coalesced_mmio[ring->first];

            cpu_physical_memory_write(ent->phys_addr, ent->data, ent->len);

            smp_wmb();

            ring->first = (ring->first + 1) % KVM_COALESCED_MMIO_MAX;

        }

    }

#endif

}


void in_asm_used_var_warning_killer()

{

 volatile int i= yCoeff+vrCoeff+ubCoeff+vgCoeff+ugCoeff+bF8+bFC+w400+w80+w10+

 bm00001111+bm00000111+bm11111000+b16Mask+g16Mask+r16Mask+b15Mask+g15Mask+r15Mask+temp0+asm_yalpha1+ asm_uvalpha1+

 M24A+M24B+M24C+w02 + funnyYCode[0]+ funnyUVCode[0]+b5Dither+g5Dither+r5Dither+g6Dither+dither4[0]+dither8[0];

 if(i) i=0;

}


static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block)

{

    int i;

    int dc = block[0];

    const uint8_t *cm;

    dc = (17 * dc +  4) >> 3;

    dc = (12 * dc + 64) >> 7;

    cm = ff_cropTbl + MAX_NEG_CROP + dc;

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

        dest[0] = cm[dest[0]];

        dest[1] = cm[dest[1]];

        dest[2] = cm[dest[2]];

        dest[3] = cm[dest[3]];

        dest += linesize;

    }

}


static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,

                            qxl_async_io async)

{

    static const int regions[] = {

        QXL_RAM_RANGE_INDEX,

        QXL_VRAM_RANGE_INDEX,

        QXL_VRAM64_RANGE_INDEX,

    };

    uint64_t guest_start;

    uint64_t guest_end;

    int pci_region;

    pcibus_t pci_start;

    pcibus_t pci_end;

    intptr_t virt_start;

    QXLDevMemSlot memslot;

    int i;

    guest_start = le64_to_cpu(d->guest_slots[slot_id].slot.mem_start);

    guest_end   = le64_to_cpu(d->guest_slots[slot_id].slot.mem_end);

    trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);

    PANIC_ON(slot_id >= NUM_MEMSLOTS);

    PANIC_ON(guest_start > guest_end);

    for (i = 0; i < ARRAY_SIZE(regions); i++) {

        pci_region = regions[i];

        pci_start = d->pci.io_regions[pci_region].addr;

        pci_end = pci_start + d->pci.io_regions[pci_region].size;

        /* mapped? */

        if (pci_start == -1) {

            continue;

        }

        /* start address in range ? */

        if (guest_start < pci_start || guest_start > pci_end) {

            continue;

        }

        /* end address in range ? */

        if (guest_end > pci_end) {

            continue;

        }

        /* passed */

        break;

    }

    PANIC_ON(i == ARRAY_SIZE(regions)); /* finished loop without match */

    switch (pci_region) {

    case QXL_RAM_RANGE_INDEX:

        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);

        break;

    case QXL_VRAM_RANGE_INDEX:

    case 4 /* vram 64bit */:

        virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);

        break;

    default:

        /* should not happen */

        abort();

    }

    memslot.slot_id = slot_id;

    memslot.slot_group_id = MEMSLOT_GROUP_GUEST; /* guest group */

    memslot.virt_start = virt_start + (guest_start - pci_start);

    memslot.virt_end   = virt_start + (guest_end   - pci_start);

    memslot.addr_delta = memslot.virt_start - delta;

    memslot.generation = d->rom->slot_generation = 0;

    qxl_rom_set_dirty(d);

    qemu_spice_add_memslot(&d->ssd, &memslot, async);

    d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;

    d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;

    d->guest_slots[slot_id].delta = delta;

    d->guest_slots[slot_id].active = 1;

}


static int nbd_negotiate_handle_info(NBDClient *client, uint16_t myflags,

                                     Error **errp)

{

    int rc;

    char name[NBD_MAX_NAME_SIZE + 1];

    NBDExport *exp;

    uint16_t requests;

    uint16_t request;

    uint32_t namelen;

    bool sendname = false;

    bool blocksize = false;

    uint32_t sizes[3];

    char buf[sizeof(uint64_t) + sizeof(uint16_t)];

    const char *msg;

    /* Client sends:

        4 bytes: L, name length (can be 0)

        L bytes: export name

        2 bytes: N, number of requests (can be 0)

        N * 2 bytes: N requests

    */

    if (client->optlen < sizeof(namelen) + sizeof(requests)) {

        msg = "overall request too short";

        goto invalid;

    }

    if (nbd_read(client->ioc, &namelen, sizeof(namelen), errp) < 0) {

        return -EIO;

    }

    be32_to_cpus(&namelen);

    client->optlen -= sizeof(namelen);

    if (namelen > client->optlen - sizeof(requests) ||

        (client->optlen - namelen) % 2)

    {

        msg = "name length is incorrect";

        goto invalid;

    }

    if (namelen >= sizeof(name)) {

        msg = "name too long for qemu";

        goto invalid;

    }

    if (nbd_read(client->ioc, name, namelen, errp) < 0) {

        return -EIO;

    }

    name[namelen] = '\0';

    client->optlen -= namelen;

    trace_nbd_negotiate_handle_export_name_request(name);

    if (nbd_read(client->ioc, &requests, sizeof(requests), errp) < 0) {

        return -EIO;

    }

    be16_to_cpus(&requests);

    client->optlen -= sizeof(requests);

    trace_nbd_negotiate_handle_info_requests(requests);

    if (requests != client->optlen / sizeof(request)) {

        msg = "incorrect number of  requests for overall length";

        goto invalid;

    }

    while (requests--) {

        if (nbd_read(client->ioc, &request, sizeof(request), errp) < 0) {

            return -EIO;

        }

        be16_to_cpus(&request);

        client->optlen -= sizeof(request);

        trace_nbd_negotiate_handle_info_request(request,

                                                nbd_info_lookup(request));

        /* We care about NBD_INFO_NAME and NBD_INFO_BLOCK_SIZE;

         * everything else is either a request we don't know or

         * something we send regardless of request */

        switch (request) {

        case NBD_INFO_NAME:

            sendname = true;

            break;

        case NBD_INFO_BLOCK_SIZE:

            blocksize = true;

            break;

        }

    }

    assert(client->optlen == 0);

    exp = nbd_export_find(name);

    if (!exp) {

        return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_UNKNOWN,

                                          errp, "export '%s' not present",

                                          name);

    }

    /* Don't bother sending NBD_INFO_NAME unless client requested it */

    if (sendname) {

        rc = nbd_negotiate_send_info(client, NBD_INFO_NAME, namelen, name,

                                     errp);

        if (rc < 0) {

            return rc;

        }

    }

    /* Send NBD_INFO_DESCRIPTION only if available, regardless of

     * client request */

    if (exp->description) {

        size_t len = strlen(exp->description);

        rc = nbd_negotiate_send_info(client, NBD_INFO_DESCRIPTION,

                                     len, exp->description, errp);

        if (rc < 0) {

            return rc;

        }

    }

    /* Send NBD_INFO_BLOCK_SIZE always, but tweak the minimum size

     * according to whether the client requested it, and according to

     * whether this is OPT_INFO or OPT_GO. */

    /* minimum - 1 for back-compat, or 512 if client is new enough.

     * TODO: consult blk_bs(blk)->bl.request_alignment? */

    sizes[0] =

            (client->opt == NBD_OPT_INFO || blocksize) ? BDRV_SECTOR_SIZE : 1;

    /* preferred - Hard-code to 4096 for now.

     * TODO: is blk_bs(blk)->bl.opt_transfer appropriate? */

    sizes[1] = 4096;

    /* maximum - At most 32M, but smaller as appropriate. */

    sizes[2] = MIN(blk_get_max_transfer(exp->blk), NBD_MAX_BUFFER_SIZE);

    trace_nbd_negotiate_handle_info_block_size(sizes[0], sizes[1], sizes[2]);

    cpu_to_be32s(&sizes[0]);

    cpu_to_be32s(&sizes[1]);

    cpu_to_be32s(&sizes[2]);

    rc = nbd_negotiate_send_info(client, NBD_INFO_BLOCK_SIZE,

                                 sizeof(sizes), sizes, errp);

    if (rc < 0) {

        return rc;

    }

    /* Send NBD_INFO_EXPORT always */

    trace_nbd_negotiate_new_style_size_flags(exp->size,

                                             exp->nbdflags | myflags);

    stq_be_p(buf, exp->size);

    stw_be_p(buf + 8, exp->nbdflags | myflags);

    rc = nbd_negotiate_send_info(client, NBD_INFO_EXPORT,

                                 sizeof(buf), buf, errp);

    if (rc < 0) {

        return rc;

    }

    /* If the client is just asking for NBD_OPT_INFO, but forgot to

     * request block sizes, return an error.

     * TODO: consult blk_bs(blk)->request_align, and only error if it

     * is not 1? */

    if (client->opt == NBD_OPT_INFO && !blocksize) {

        return nbd_negotiate_send_rep_err(client,

                                          NBD_REP_ERR_BLOCK_SIZE_REQD,

                                          errp,

                                          "request NBD_INFO_BLOCK_SIZE to "

                                          "use this export");

    }

    /* Final reply */

    rc = nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);

    if (rc < 0) {

        return rc;

    }

    if (client->opt == NBD_OPT_GO) {

        client->exp = exp;

        QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);

        nbd_export_get(client->exp);

        rc = 1;

    }

    return rc;

 invalid:

    if (nbd_drop(client->ioc, client->optlen, errp) < 0) {

        return -EIO;

    }

    return nbd_negotiate_send_rep_err(client, NBD_REP_ERR_INVALID,

                                      errp, "%s", msg);

}


static void qemu_rdma_init_one_block(void *host_addr,

    ram_addr_t block_offset, ram_addr_t length, void *opaque)

{

    __qemu_rdma_add_block(opaque, host_addr, block_offset, length);

}


static int qsv_decode(AVCodecContext *avctx, QSVContext *q,

                      AVFrame *frame, int *got_frame,

                      AVPacket *avpkt)

{

    QSVFrame *out_frame;

    mfxFrameSurface1 *insurf;

    mfxFrameSurface1 *outsurf;

    mfxSyncPoint *sync;

    mfxBitstream bs = { { { 0 } } };

    int ret;

    if (avpkt->size) {

        bs.Data       = avpkt->data;

        bs.DataLength = avpkt->size;

        bs.MaxLength  = bs.DataLength;

        bs.TimeStamp  = avpkt->pts;

    }

    sync = av_mallocz(sizeof(*sync));

    if (!sync) {

        av_freep(&sync);

        return AVERROR(ENOMEM);

    }

    do {

        ret = get_surface(avctx, q, &insurf);

        if (ret < 0)

            return ret;

        ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL,

                                              insurf, &outsurf, sync);

        if (ret == MFX_WRN_DEVICE_BUSY)

            av_usleep(500);

    } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE);

    if (ret != MFX_ERR_NONE &&

        ret != MFX_ERR_MORE_DATA &&

        ret != MFX_WRN_VIDEO_PARAM_CHANGED &&

        ret != MFX_ERR_MORE_SURFACE) {

        av_log(avctx, AV_LOG_ERROR, "Error during QSV decoding.\n");

        av_freep(&sync);

        return ff_qsv_error(ret);

    }

    /* make sure we do not enter an infinite loop if the SDK

     * did not consume any data and did not return anything */

    if (!*sync && !bs.DataOffset) {

        av_log(avctx, AV_LOG_WARNING, "A decode call did not consume any data\n");

        bs.DataOffset = avpkt->size;

    }

    if (*sync) {

        QSVFrame *out_frame = find_frame(q, outsurf);

        if (!out_frame) {

            av_log(avctx, AV_LOG_ERROR,

                   "The returned surface does not correspond to any frame\n");

            av_freep(&sync);

            return AVERROR_BUG;

        }

        out_frame->queued = 1;

        av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL);

        av_fifo_generic_write(q->async_fifo, &sync,      sizeof(sync),      NULL);

    } else {

        av_freep(&sync);

    }

    if (!av_fifo_space(q->async_fifo) ||

        (!avpkt->size && av_fifo_size(q->async_fifo))) {

        AVFrame *src_frame;

        av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL);

        av_fifo_generic_read(q->async_fifo, &sync,      sizeof(sync),      NULL);

        out_frame->queued = 0;

        do {

            ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000);

        } while (ret == MFX_WRN_IN_EXECUTION);

        av_freep(&sync);

        src_frame = out_frame->frame;

        ret = av_frame_ref(frame, src_frame);

        if (ret < 0)

            return ret;

        outsurf = out_frame->surface;

#if FF_API_PKT_PTS

FF_DISABLE_DEPRECATION_WARNINGS

        frame->pkt_pts = outsurf->Data.TimeStamp;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

        frame->pts = outsurf->Data.TimeStamp;

        frame->repeat_pict =

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 :

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 :

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0;

        frame->top_field_first =

            outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF;

        frame->interlaced_frame =

            !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE);

        *got_frame = 1;

    }

    return bs.DataOffset;

}


static int cmp(const void *a, const void *b)

{

    const double va = *(const double *)a, vb = *(const double *)b;

    return va < vb ? -1 : ( va > vb ? 1 : 0 );

}


static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,

                          int num_ports, dma_addr_t localmem_base,

                          char *masterbus, uint32_t firstport,

                          AddressSpace *as, Error **errp)

{

    Error *err = NULL;

    int i;

    ohci->as = as;

    if (usb_frame_time == 0) {

#ifdef OHCI_TIME_WARP

        usb_frame_time = get_ticks_per_sec();

        usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000);

#else

        usb_frame_time = muldiv64(1, get_ticks_per_sec(), 1000);

        if (get_ticks_per_sec() >= USB_HZ) {

            usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ);

        } else {

            usb_bit_time = 1;

        }

#endif

        trace_usb_ohci_init_time(usb_frame_time, usb_bit_time);

    }

    ohci->num_ports = num_ports;

    if (masterbus) {

        USBPort *ports[OHCI_MAX_PORTS];

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

            ports[i] = &ohci->rhport[i].port;

        }

        usb_register_companion(masterbus, ports, num_ports,

                               firstport, ohci, &ohci_port_ops,

                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL,

                               &err);

        if (err) {

            error_propagate(errp, err);

            return;

        }

    } else {

        usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);

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

            usb_register_port(&ohci->bus, &ohci->rhport[i].port,

                              ohci, i, &ohci_port_ops,

                              USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);

        }

    }

    memory_region_init_io(&ohci->mem, OBJECT(dev), &ohci_mem_ops,

                          ohci, "ohci", 256);

    ohci->localmem_base = localmem_base;

    ohci->name = object_get_typename(OBJECT(dev));

    usb_packet_init(&ohci->usb_packet);

    ohci->async_td = 0;

    qemu_register_reset(ohci_reset, ohci);

}


static void read_len_table(uint8_t *dst, GetBitContext *gb){

    int i, val, repeat;

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

        repeat= get_bits(gb, 3);

        val   = get_bits(gb, 5);

        if(repeat==0)

            repeat= get_bits(gb, 8);

//printf("%d %d\n", val, repeat);

        while (repeat--)

            dst[i++] = val;

    }

}


static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,

                     const uint8_t **poutbuf, int *poutbuf_size,

                     const uint8_t *buf, int buf_size)

{

    DCAParseContext *pc1 = s->priv_data;

    ParseContext *pc = &pc1->pc;

    int next, duration, sample_rate;

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {

        next = buf_size;

    } else {

        next = dca_find_frame_end(pc1, buf, buf_size);

        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {

            *poutbuf      = NULL;

            *poutbuf_size = 0;

            return buf_size;

        }

    }

    /* read the duration and sample rate from the frame header */

    if (!dca_parse_params(buf, buf_size, &duration, &sample_rate, &pc1->framesize)) {

        s->duration        = duration;

        avctx->sample_rate = sample_rate;

    } else

        s->duration = 0;

    *poutbuf      = buf;

    *poutbuf_size = buf_size;

    return next;

}


void error_setg(Error **errp, const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    error_setv(errp, ERROR_CLASS_GENERIC_ERROR, fmt, ap);

    va_end(ap);

}


static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)

{

    *ACPI_BUILD_PTR(start, size, acpi_pci32_start[0], uint32_t) =

        cpu_to_le32(pci->w32.begin);

    *ACPI_BUILD_PTR(start, size, acpi_pci32_end[0], uint32_t) =

        cpu_to_le32(pci->w32.end - 1);

    if (pci->w64.end || pci->w64.begin) {

        *ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 1;

        *ACPI_BUILD_PTR(start, size, acpi_pci64_start[0], uint64_t) =

            cpu_to_le64(pci->w64.begin);

        *ACPI_BUILD_PTR(start, size, acpi_pci64_end[0], uint64_t) =

            cpu_to_le64(pci->w64.end - 1);

        *ACPI_BUILD_PTR(start, size, acpi_pci64_length[0], uint64_t) =

            cpu_to_le64(pci->w64.end - pci->w64.begin);

    } else {

        *ACPI_BUILD_PTR(start, size, acpi_pci64_valid[0], uint8_t) = 0;

    }

}


static int decode_header(EXRContext *s)

{

    int magic_number, version, i, flags, sar = 0;

    int layer_match = 0;

    s->current_channel_offset = 0;

    s->xmin               = ~0;

    s->xmax               = ~0;

    s->ymin               = ~0;

    s->ymax               = ~0;

    s->xdelta             = ~0;

    s->ydelta             = ~0;

    s->channel_offsets[0] = -1;

    s->channel_offsets[1] = -1;

    s->channel_offsets[2] = -1;

    s->channel_offsets[3] = -1;

    s->pixel_type         = EXR_UNKNOWN;

    s->compression        = EXR_UNKN;

    s->nb_channels        = 0;

    s->w                  = 0;

    s->h                  = 0;

    s->tile_attr.xSize    = -1;

    s->tile_attr.ySize    = -1;

    s->is_tile            = 0;

    s->is_luma            = 0;

    if (bytestream2_get_bytes_left(&s->gb) < 10) {

        av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n");

        return AVERROR_INVALIDDATA;

    }

    magic_number = bytestream2_get_le32(&s->gb);

    if (magic_number != 20000630) {

        /* As per documentation of OpenEXR, it is supposed to be

         * int 20000630 little-endian */

        av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number);

        return AVERROR_INVALIDDATA;

    }

    version = bytestream2_get_byte(&s->gb);

    if (version != 2) {

        avpriv_report_missing_feature(s->avctx, "Version %d", version);

        return AVERROR_PATCHWELCOME;

    }

    flags = bytestream2_get_le24(&s->gb);

    if (flags == 0x00)

        s->is_tile = 0;

    else if (flags & 0x02)

        s->is_tile = 1;

    else{

        avpriv_report_missing_feature(s->avctx, "flags %d", flags);

        return AVERROR_PATCHWELCOME;

    }

    // Parse the header

    while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) {

        int var_size;

        if ((var_size = check_header_variable(s, "channels",

                                              "chlist", 38)) >= 0) {

            GetByteContext ch_gb;

            if (!var_size)

                return AVERROR_INVALIDDATA;

            bytestream2_init(&ch_gb, s->gb.buffer, var_size);

            while (bytestream2_get_bytes_left(&ch_gb) >= 19) {

                EXRChannel *channel;

                enum ExrPixelType current_pixel_type;

                int channel_index = -1;

                int xsub, ysub;

                if (strcmp(s->layer, "") != 0) {

                    if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) {

                        layer_match = 1;

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel match layer : %s.\n", ch_gb.buffer);

                        ch_gb.buffer += strlen(s->layer);

                        if (*ch_gb.buffer == '.')

                            ch_gb.buffer++;         /* skip dot if not given */

                    } else {

                        av_log(s->avctx, AV_LOG_INFO,

                               "Channel doesn't match layer : %s.\n", ch_gb.buffer);

                    }

                } else {

                    layer_match = 1;

                }

                if (layer_match) { /* only search channel if the layer match is valid */

                    if (!strcmp(ch_gb.buffer, "R") ||

                        !strcmp(ch_gb.buffer, "X") ||

                        !strcmp(ch_gb.buffer, "U")) {

                        channel_index = 0;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "G") ||

                               !strcmp(ch_gb.buffer, "V")) {

                        channel_index = 1;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "Y")) {

                        channel_index = 1;

                        s->is_luma = 1;

                    } else if (!strcmp(ch_gb.buffer, "B") ||

                               !strcmp(ch_gb.buffer, "Z") ||

                               !strcmp(ch_gb.buffer, "W")){

                               channel_index = 2;

                        s->is_luma = 0;

                    } else if (!strcmp(ch_gb.buffer, "A")) {

                        channel_index = 3;

                    } else {

                        av_log(s->avctx, AV_LOG_WARNING,

                               "Unsupported channel %.256s.\n", ch_gb.buffer);

                    }

                }

                /* skip until you get a 0 */

                while (bytestream2_get_bytes_left(&ch_gb) > 0 &&

                       bytestream2_get_byte(&ch_gb))

                    continue;

                if (bytestream2_get_bytes_left(&ch_gb) < 4) {

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

                    return AVERROR_INVALIDDATA;

                }

                current_pixel_type = bytestream2_get_le32(&ch_gb);

                if (current_pixel_type >= EXR_UNKNOWN) {

                    avpriv_report_missing_feature(s->avctx, "Pixel type %d",

                                                  current_pixel_type);

                    return AVERROR_PATCHWELCOME;

                }

                bytestream2_skip(&ch_gb, 4);

                xsub = bytestream2_get_le32(&ch_gb);

                ysub = bytestream2_get_le32(&ch_gb);

                if (xsub != 1 || ysub != 1) {

                    avpriv_report_missing_feature(s->avctx,

                                                  "Subsampling %dx%d",

                                                  xsub, ysub);

                    return AVERROR_PATCHWELCOME;

                }

                if (s->channel_offsets[channel_index] == -1){/* channel have not been previously assign */

                    if (channel_index >= 0) {

                        if (s->pixel_type != EXR_UNKNOWN &&

                            s->pixel_type != current_pixel_type) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "RGB channels not of the same depth.\n");

                            return AVERROR_INVALIDDATA;

                        }

                        s->pixel_type                     = current_pixel_type;

                        s->channel_offsets[channel_index] = s->current_channel_offset;

                    }

                }

                s->channels = av_realloc(s->channels,

                                         ++s->nb_channels * sizeof(EXRChannel));

                if (!s->channels)

                    return AVERROR(ENOMEM);

                channel             = &s->channels[s->nb_channels - 1];

                channel->pixel_type = current_pixel_type;

                channel->xsub       = xsub;

                channel->ysub       = ysub;

                s->current_channel_offset += 1 << current_pixel_type;

            }

            /* Check if all channels are set with an offset or if the channels

             * are causing an overflow  */

            if (!s->is_luma){/* if we expected to have at least 3 channels */

                if (FFMIN3(s->channel_offsets[0],

                           s->channel_offsets[1],

                           s->channel_offsets[2]) < 0) {

                    if (s->channel_offsets[0] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n");

                    if (s->channel_offsets[1] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n");

                    if (s->channel_offsets[2] < 0)

                        av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n");

                    return AVERROR_INVALIDDATA;

                }

            }

            // skip one last byte and update main gb

            s->gb.buffer = ch_gb.buffer + 1;

            continue;

        } else if ((var_size = check_header_variable(s, "dataWindow", "box2i",

                                                     31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;

            s->xmin   = bytestream2_get_le32(&s->gb);

            s->ymin   = bytestream2_get_le32(&s->gb);

            s->xmax   = bytestream2_get_le32(&s->gb);

            s->ymax   = bytestream2_get_le32(&s->gb);

            s->xdelta = (s->xmax - s->xmin) + 1;

            s->ydelta = (s->ymax - s->ymin) + 1;

            continue;

        } else if ((var_size = check_header_variable(s, "displayWindow",

                                                     "box2i", 34)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;

            bytestream2_skip(&s->gb, 8);

            s->w = bytestream2_get_le32(&s->gb) + 1;

            s->h = bytestream2_get_le32(&s->gb) + 1;

            continue;

        } else if ((var_size = check_header_variable(s, "lineOrder",

                                                     "lineOrder", 25)) >= 0) {

            int line_order;

            if (!var_size)

                return AVERROR_INVALIDDATA;

            line_order = bytestream2_get_byte(&s->gb);

            av_log(s->avctx, AV_LOG_DEBUG, "line order: %d.\n", line_order);

            if (line_order > 2) {

                av_log(s->avctx, AV_LOG_ERROR, "Unknown line order.\n");

                return AVERROR_INVALIDDATA;

            }

            continue;

        } else if ((var_size = check_header_variable(s, "pixelAspectRatio",

                                                     "float", 31)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;

            sar = bytestream2_get_le32(&s->gb);

            continue;

        } else if ((var_size = check_header_variable(s, "compression",

                                                     "compression", 29)) >= 0) {

            if (!var_size)

                return AVERROR_INVALIDDATA;

            if (s->compression == EXR_UNKN)

                s->compression = bytestream2_get_byte(&s->gb);

            else

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found more than one compression attribute.\n");

            continue;

        } else if ((var_size = check_header_variable(s, "tiles",

                                                     "tiledesc", 22)) >= 0) {

            char tileLevel;

            if (!s->is_tile)

                av_log(s->avctx, AV_LOG_WARNING,

                       "Found tile attribute and scanline flags. Exr will be interpreted as scanline.\n");

            s->tile_attr.xSize = bytestream2_get_le32(&s->gb);

            s->tile_attr.ySize = bytestream2_get_le32(&s->gb);

            tileLevel = bytestream2_get_byte(&s->gb);

            s->tile_attr.level_mode = tileLevel & 0x0f;

            s->tile_attr.level_round = (tileLevel >> 4) & 0x0f;

            if (s->tile_attr.level_mode >= EXR_TILE_LEVEL_UNKNOWN){

                avpriv_report_missing_feature(s->avctx, "Tile level mode %d",

                                              s->tile_attr.level_mode);

                return AVERROR_PATCHWELCOME;

            }

            if (s->tile_attr.level_round >= EXR_TILE_ROUND_UNKNOWN) {

                avpriv_report_missing_feature(s->avctx, "Tile level round %d",

                                              s->tile_attr.level_round);

                return AVERROR_PATCHWELCOME;

            }

            continue;

        }

        // Check if there are enough bytes for a header

        if (bytestream2_get_bytes_left(&s->gb) <= 9) {

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

            return AVERROR_INVALIDDATA;

        }

        // Process unknown variables

        for (i = 0; i < 2; i++) // value_name and value_type

            while (bytestream2_get_byte(&s->gb) != 0);

        // Skip variable length

        bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb));

    }

    ff_set_sar(s->avctx, av_d2q(av_int2float(sar), 255));

    if (s->compression == EXR_UNKN) {

        av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->is_tile) {

        if (s->tile_attr.xSize < 1 || s->tile_attr.ySize < 1) {

            av_log(s->avctx, AV_LOG_ERROR, "Invalid tile attribute.\n");

            return AVERROR_INVALIDDATA;

        }

    }

    if (bytestream2_get_bytes_left(&s->gb) <= 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n");

        return AVERROR_INVALIDDATA;

    }

    // aaand we are done

    bytestream2_skip(&s->gb, 1);

    return 0;

}


static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int output_size)

{

    PutBitContext pb;

    int i, j, band, block, best_idx, power_idx = 0;

    float power_val, coeff, coeff_sum;

    float pows[NELLY_FILL_LEN];

    int bits[NELLY_BUF_LEN], idx_table[NELLY_BANDS];

    float cand[NELLY_BANDS];

    apply_mdct(s);

    init_put_bits(&pb, output, output_size * 8);

    i = 0;

    for (band = 0; band < NELLY_BANDS; band++) {

        coeff_sum = 0;

        for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {

            coeff_sum += s->mdct_out[i                ] * s->mdct_out[i                ]

                       + s->mdct_out[i + NELLY_BUF_LEN] * s->mdct_out[i + NELLY_BUF_LEN];

        }

        cand[band] =

            log(FFMAX(1.0, coeff_sum / (ff_nelly_band_sizes_table[band] << 7))) * 1024.0 / M_LN2;

    }

    if (s->avctx->trellis) {

        get_exponent_dynamic(s, cand, idx_table);

    } else {

        get_exponent_greedy(s, cand, idx_table);

    }

    i = 0;

    for (band = 0; band < NELLY_BANDS; band++) {

        if (band) {

            power_idx += ff_nelly_delta_table[idx_table[band]];

            put_bits(&pb, 5, idx_table[band]);

        } else {

            power_idx = ff_nelly_init_table[idx_table[0]];

            put_bits(&pb, 6, idx_table[0]);

        }

        power_val = pow_table[power_idx & 0x7FF] / (1 << ((power_idx >> 11) + POW_TABLE_OFFSET));

        for (j = 0; j < ff_nelly_band_sizes_table[band]; i++, j++) {

            s->mdct_out[i] *= power_val;

            s->mdct_out[i + NELLY_BUF_LEN] *= power_val;

            pows[i] = power_idx;

        }

    }

    ff_nelly_get_sample_bits(pows, bits);

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

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

            if (bits[i] > 0) {

                const float *table = ff_nelly_dequantization_table + (1 << bits[i]) - 1;

                coeff = s->mdct_out[block * NELLY_BUF_LEN + i];

                best_idx =

                    quant_lut[av_clip (

                            coeff * quant_lut_mul[bits[i]] + quant_lut_add[bits[i]],

                            quant_lut_offset[bits[i]],

                            quant_lut_offset[bits[i]+1] - 1

                            )];

                if (fabs(coeff - table[best_idx]) > fabs(coeff - table[best_idx + 1]))

                    best_idx++;

                put_bits(&pb, bits[i], best_idx);

            }

        }

        if (!block)

            put_bits(&pb, NELLY_HEADER_BITS + NELLY_DETAIL_BITS - put_bits_count(&pb), 0);

    }

    flush_put_bits(&pb);

    memset(put_bits_ptr(&pb), 0, output + output_size - put_bits_ptr(&pb));

}


hwaddr uc32_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)

{

    UniCore32CPU *cpu = UNICORE32_CPU(cs);

    cpu_abort(CPU(cpu), "%s not supported yet\n", __func__);

    return addr;

}


static char *SocketAddress_to_str(const char *prefix, SocketAddress *addr,

                                  bool is_listen, bool is_telnet)

{

    switch (addr->type) {

    case SOCKET_ADDRESS_KIND_INET:

        return g_strdup_printf("%s%s:%s:%s%s", prefix,

                               is_telnet ? "telnet" : "tcp",

                               addr->u.inet.data->host,

                               addr->u.inet.data->port,

                               is_listen ? ",server" : "");

        break;

    case SOCKET_ADDRESS_KIND_UNIX:

        return g_strdup_printf("%sunix:%s%s", prefix,

                               addr->u.q_unix.data->path,

                               is_listen ? ",server" : "");

        break;

    case SOCKET_ADDRESS_KIND_FD:

        return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.data->str,

                               is_listen ? ",server" : "");

        break;

    default:

        abort();

    }

}


static void dnxhd_decode_dct_block_10(const DNXHDContext *ctx,

                                      RowContext *row, int n)

{

    dnxhd_decode_dct_block(ctx, row, n, 6, 8, 4);

}


static void opt_qsquish(const char *arg)

{

    video_qsquish = atof(arg);

    if (video_qsquish < 0.0 ||

        video_qsquish > 99.0) {

        fprintf(stderr, "qsquish must be >= 0.0 and <= 99.0\n");

        exit(1);

    }

}


static int create_vorbis_context(vorbis_enc_context *venc,

                                 AVCodecContext *avctx)

{

    vorbis_enc_floor   *fc;

    vorbis_enc_residue *rc;

    vorbis_enc_mapping *mc;

    int i, book, ret;

    venc->channels    = avctx->channels;

    venc->sample_rate = avctx->sample_rate;

    venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;

    venc->ncodebooks = FF_ARRAY_ELEMS(cvectors);

    venc->codebooks  = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks);

    if (!venc->codebooks)

        return AVERROR(ENOMEM);

    // codebook 0..14 - floor1 book, values 0..255

    // codebook 15 residue masterbook

    // codebook 16..29 residue

    for (book = 0; book < venc->ncodebooks; book++) {

        vorbis_enc_codebook *cb = &venc->codebooks[book];

        int vals;

        cb->ndimensions = cvectors[book].dim;

        cb->nentries    = cvectors[book].real_len;

        cb->min         = cvectors[book].min;

        cb->delta       = cvectors[book].delta;

        cb->lookup      = cvectors[book].lookup;

        cb->seq_p       = 0;

        cb->lens      = av_malloc_array(cb->nentries, sizeof(uint8_t));

        cb->codewords = av_malloc_array(cb->nentries, sizeof(uint32_t));

        if (!cb->lens || !cb->codewords)

            return AVERROR(ENOMEM);

        memcpy(cb->lens, cvectors[book].clens, cvectors[book].len);

        memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len);

        if (cb->lookup) {

            vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries);

            cb->quantlist = av_malloc_array(vals, sizeof(int));

            if (!cb->quantlist)

                return AVERROR(ENOMEM);

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

                cb->quantlist[i] = cvectors[book].quant[i];

        } else {

            cb->quantlist = NULL;

        }

        if ((ret = ready_codebook(cb)) < 0)

            return ret;

    }

    venc->nfloors = 1;

    venc->floors  = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors);

    if (!venc->floors)

        return AVERROR(ENOMEM);

    // just 1 floor

    fc = &venc->floors[0];

    fc->partitions         = NUM_FLOOR_PARTITIONS;

    fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions);

    if (!fc->partition_to_class)

        return AVERROR(ENOMEM);

    fc->nclasses           = 0;

    for (i = 0; i < fc->partitions; i++) {

        static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4};

        fc->partition_to_class[i] = a[i];

        fc->nclasses = FFMAX(fc->nclasses, fc->partition_to_class[i]);

    }

    fc->nclasses++;

    fc->classes = av_malloc_array(fc->nclasses, sizeof(vorbis_enc_floor_class));

    if (!fc->classes)

        return AVERROR(ENOMEM);

    for (i = 0; i < fc->nclasses; i++) {

        vorbis_enc_floor_class * c = &fc->classes[i];

        int j, books;

        c->dim        = floor_classes[i].dim;

        c->subclass   = floor_classes[i].subclass;

        c->masterbook = floor_classes[i].masterbook;

        books         = (1 << c->subclass);

        c->books      = av_malloc_array(books, sizeof(int));

        if (!c->books)

            return AVERROR(ENOMEM);

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

            c->books[j] = floor_classes[i].nbooks[j];

    }

    fc->multiplier = 2;

    fc->rangebits  = venc->log2_blocksize[0] - 1;

    fc->values = 2;

    for (i = 0; i < fc->partitions; i++)

        fc->values += fc->classes[fc->partition_to_class[i]].dim;

    fc->list = av_malloc_array(fc->values, sizeof(vorbis_floor1_entry));

    if (!fc->list)

        return AVERROR(ENOMEM);

    fc->list[0].x = 0;

    fc->list[1].x = 1 << fc->rangebits;

    for (i = 2; i < fc->values; i++) {

        static const int a[] = {

             93, 23,372,  6, 46,186,750, 14, 33, 65,

            130,260,556,  3, 10, 18, 28, 39, 55, 79,

            111,158,220,312,464,650,850

        };

        fc->list[i].x = a[i - 2];

    }

    if (ff_vorbis_ready_floor1_list(avctx, fc->list, fc->values))

        return AVERROR_BUG;

    venc->nresidues = 1;

    venc->residues  = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues);

    if (!venc->residues)

        return AVERROR(ENOMEM);

    // single residue

    rc = &venc->residues[0];

    rc->type            = 2;

    rc->begin           = 0;

    rc->end             = 1600;

    rc->partition_size  = 32;

    rc->classifications = 10;

    rc->classbook       = 15;

    rc->books           = av_malloc(sizeof(*rc->books) * rc->classifications);

    if (!rc->books)

        return AVERROR(ENOMEM);

    {

        static const int8_t a[10][8] = {

            { -1, -1, -1, -1, -1, -1, -1, -1, },

            { -1, -1, 16, -1, -1, -1, -1, -1, },

            { -1, -1, 17, -1, -1, -1, -1, -1, },

            { -1, -1, 18, -1, -1, -1, -1, -1, },

            { -1, -1, 19, -1, -1, -1, -1, -1, },

            { -1, -1, 20, -1, -1, -1, -1, -1, },

            { -1, -1, 21, -1, -1, -1, -1, -1, },

            { 22, 23, -1, -1, -1, -1, -1, -1, },

            { 24, 25, -1, -1, -1, -1, -1, -1, },

            { 26, 27, 28, -1, -1, -1, -1, -1, },

        };

        memcpy(rc->books, a, sizeof a);

    }

    if ((ret = ready_residue(rc, venc)) < 0)

        return ret;

    venc->nmappings = 1;

    venc->mappings  = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings);

    if (!venc->mappings)

        return AVERROR(ENOMEM);

    // single mapping

    mc = &venc->mappings[0];

    mc->submaps = 1;

    mc->mux     = av_malloc(sizeof(int) * venc->channels);

    if (!mc->mux)

        return AVERROR(ENOMEM);

    for (i = 0; i < venc->channels; i++)

        mc->mux[i] = 0;

    mc->floor   = av_malloc(sizeof(int) * mc->submaps);

    mc->residue = av_malloc(sizeof(int) * mc->submaps);

    if (!mc->floor || !mc->residue)

        return AVERROR(ENOMEM);

    for (i = 0; i < mc->submaps; i++) {

        mc->floor[i]   = 0;

        mc->residue[i] = 0;

    }

    mc->coupling_steps = venc->channels == 2 ? 1 : 0;

    mc->magnitude      = av_malloc(sizeof(int) * mc->coupling_steps);

    mc->angle          = av_malloc(sizeof(int) * mc->coupling_steps);

    if (!mc->magnitude || !mc->angle)

        return AVERROR(ENOMEM);

    if (mc->coupling_steps) {

        mc->magnitude[0] = 0;

        mc->angle[0]     = 1;

    }

    venc->nmodes = 1;

    venc->modes  = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes);

    if (!venc->modes)

        return AVERROR(ENOMEM);

    // single mode

    venc->modes[0].blockflag = 0;

    venc->modes[0].mapping   = 0;

    venc->have_saved = 0;

    venc->saved      = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);

    venc->samples    = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]));

    venc->floor      = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);

    venc->coeffs     = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);

    venc->scratch    = av_malloc_array(sizeof(float) * venc->channels, (1 << venc->log2_blocksize[1]) / 2);

    if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs || !venc->scratch)

        return AVERROR(ENOMEM);

    if ((ret = dsp_init(avctx, venc)) < 0)

        return ret;

    return 0;

}


static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)

{

    MpegEncContext *s= &s1->mpeg_enc_ctx;

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

    s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);

    if(!s->pict_type && s1->mpeg_enc_ctx_allocated){

        av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n");

        if(s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1]==15){

            if(s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)

                s->pict_type= FF_I_TYPE;

            else

                s->pict_type= FF_P_TYPE;

        }else

            s->pict_type= FF_B_TYPE;

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

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

    }

    s->intra_dc_precision = get_bits(&s->gb, 2);

    s->picture_structure = get_bits(&s->gb, 2);

    s->top_field_first = get_bits1(&s->gb);

    s->frame_pred_frame_dct = get_bits1(&s->gb);

    s->concealment_motion_vectors = get_bits1(&s->gb);

    s->q_scale_type = get_bits1(&s->gb);

    s->intra_vlc_format = get_bits1(&s->gb);

    s->alternate_scan = get_bits1(&s->gb);

    s->repeat_first_field = get_bits1(&s->gb);

    s->chroma_420_type = get_bits1(&s->gb);

    s->progressive_frame = get_bits1(&s->gb);

    if(s->progressive_sequence && !s->progressive_frame){

        s->progressive_frame= 1;

        av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");

    }

    if(s->picture_structure==0 || (s->progressive_frame && s->picture_structure!=PICT_FRAME)){

        av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);

        s->picture_structure= PICT_FRAME;

    }

    if(s->progressive_frame && !s->frame_pred_frame_dct){

        av_log(s->avctx, AV_LOG_ERROR, "invalid frame_pred_frame_dct\n");

        s->frame_pred_frame_dct= 1;

    }

    if(s->picture_structure == PICT_FRAME){

        s->first_field=0;

        s->v_edge_pos= 16*s->mb_height;

    }else{

        s->first_field ^= 1;

        s->v_edge_pos=  8*s->mb_height;

        memset(s->mbskip_table, 0, s->mb_stride*s->mb_height);

    }

    if(s->alternate_scan){

        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_alternate_vertical_scan);

        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_alternate_vertical_scan);

    }else{

        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_zigzag_direct);

        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_zigzag_direct);

    }

    /* composite display not parsed */

    dprintf(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);

    dprintf(s->avctx, "picture_structure=%d\n", s->picture_structure);

    dprintf(s->avctx, "top field first=%d\n", s->top_field_first);

    dprintf(s->avctx, "repeat first field=%d\n", s->repeat_first_field);

    dprintf(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);

    dprintf(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);

    dprintf(s->avctx, "alternate_scan=%d\n", s->alternate_scan);

    dprintf(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);

    dprintf(s->avctx, "progressive_frame=%d\n", s->progressive_frame);

}


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

{

    /* TODO:

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

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

     */

    EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;

    uint16_t rfd_status = 0xa000;

    static const uint8_t broadcast_macaddr[6] =

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

    /* TODO: check multiple IA bit. */

    if (s->configuration[20] & BIT(6)) {

        missing("Multiple IA bit");

        return -1;

    }

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

        /* CSMA is disabled. */

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

        return -1;

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

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

         * Short frame is discarded */

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

        s->statistics.rx_short_frame_errors++;

#if 0

        return -1;

#endif

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

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

         * Long frames are discarded. */

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

        return -1;

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

        /* Frame matches individual address. */

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

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

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

        /* Broadcast frame. */

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

        rfd_status |= 0x0002;

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

        /* Multicast frame. */

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

        if (s->configuration[21] & BIT(3)) {

          /* Multicast all bit is set, receive all multicast frames. */

        } else {

          unsigned mcast_idx = compute_mcast_idx(buf);

          assert(mcast_idx < 64);

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

            /* Multicast frame is allowed in hash table. */

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

              /* Promiscuous: receive all. */

              rfd_status |= 0x0004;

          } else {

              TRACE(RXTX, logout("%p multicast ignored\n", s));

              return -1;

          }

        }

        /* TODO: Next not for promiscuous mode? */

        rfd_status |= 0x0002;

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

        /* Promiscuous: receive all. */

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

        rfd_status |= 0x0004;

    } else {

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

              nic_dump(buf, size)));

        return size;

    }

    if (get_ru_state(s) != ru_ready) {

        /* No resources available. */

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

        /* TODO: RNR interrupt only at first failed frame? */

        eepro100_rnr_interrupt(s);

        s->statistics.rx_resource_errors++;

#if 0

        assert(!"no resources");

#endif

        return -1;

    }

    /* !!! */

    eepro100_rx_t rx;

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

                             offsetof(eepro100_rx_t, packet));

    uint16_t rfd_command = le16_to_cpu(rx.command);

    uint16_t rfd_size = le16_to_cpu(rx.size);

    if (size > rfd_size) {

        logout("Receive buffer (%" PRId16 " bytes) too small for data "

            "(%zu bytes); data truncated\n", rfd_size, size);

        size = rfd_size;

    }

    if (size < 64) {

        rfd_status |= 0x0080;

    }

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

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

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

             rfd_status);

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

    /* Early receive interrupt not supported. */

#if 0

    eepro100_er_interrupt(s);

#endif

    /* Receive CRC Transfer not supported. */

    if (s->configuration[18] & BIT(2)) {

        missing("Receive CRC Transfer");

        return -1;

    }

    /* TODO: check stripping enable bit. */

#if 0

    assert(!(s->configuration[17] & BIT(0)));

#endif

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

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

    s->statistics.rx_good_frames++;

    eepro100_fr_interrupt(s);

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

    if (rfd_command & COMMAND_EL) {

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

        logout("receive: Running out of frames\n");

        set_ru_state(s, ru_suspended);

    }

    if (rfd_command & COMMAND_S) {

        /* S bit is set. */

        set_ru_state(s, ru_suspended);

    }

    return size;

}


static int mov_write_mdia_tag(AVIOContext *pb, MOVMuxContext *mov,

                              MOVTrack *track)

{

    int64_t pos = avio_tell(pb);

    avio_wb32(pb, 0); /* size */

    ffio_wfourcc(pb, "mdia");

    mov_write_mdhd_tag(pb, mov, track);

    mov_write_hdlr_tag(pb, track);

    mov_write_minf_tag(pb, track);

    return update_size(pb, pos);

}


int ff_h264_decode_sei(H264Context *h){

    while (get_bits_left(&h->gb) > 16) {

        int size, type;

        type=0;

        do{

            if (get_bits_left(&h->gb) < 8)

                return AVERROR_INVALIDDATA;

            type+= show_bits(&h->gb, 8);

        }while(get_bits(&h->gb, 8) == 255);

        size=0;

        do{

            if (get_bits_left(&h->gb) < 8)

                return AVERROR_INVALIDDATA;

            size+= show_bits(&h->gb, 8);

        }while(get_bits(&h->gb, 8) == 255);

        if(h->avctx->debug&FF_DEBUG_STARTCODE)

            av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size);

        switch(type){

        case SEI_TYPE_PIC_TIMING: // Picture timing SEI

            if(decode_picture_timing(h) < 0)

                return -1;

            break;

        case SEI_TYPE_USER_DATA_ITU_T_T35:

            if(decode_user_data_itu_t_t35(h, size) < 0)

                return -1;

            break;

        case SEI_TYPE_USER_DATA_UNREGISTERED:

            if(decode_unregistered_user_data(h, size) < 0)

                return -1;

            break;

        case SEI_TYPE_RECOVERY_POINT:

            if(decode_recovery_point(h) < 0)

                return -1;

            break;

        case SEI_BUFFERING_PERIOD:

            if(decode_buffering_period(h) < 0)

                return -1;

            break;

        case SEI_TYPE_FRAME_PACKING:

            if(decode_frame_packing(h, size) < 0)

                return -1;

        default:

            skip_bits(&h->gb, 8*size);

        }

        //FIXME check bits here

        align_get_bits(&h->gb);

    }

    return 0;

}


static int mpeg_decode_postinit(AVCodecContext *avctx)

{

    Mpeg1Context *s1  = avctx->priv_data;

    MpegEncContext *s = &s1->mpeg_enc_ctx;

    uint8_t old_permutation[64];

    int ret;

    if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {

        // MPEG-1 aspect

        avctx->sample_aspect_ratio = av_d2q(1.0 / ff_mpeg1_aspect[s->aspect_ratio_info], 255);

    } else { // MPEG-2

        // MPEG-2 aspect

        if (s->aspect_ratio_info > 1) {

            AVRational dar =

                av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],

                                  (AVRational) { s1->pan_scan.width,

                                                 s1->pan_scan.height }),

                         (AVRational) { s->width, s->height });

            /* We ignore the spec here and guess a bit as reality does not

             * match the spec, see for example res_change_ffmpeg_aspect.ts

             * and sequence-display-aspect.mpg.

             * issue1613, 621, 562 */

            if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||

                (av_cmp_q(dar, (AVRational) { 4, 3 }) &&

                 av_cmp_q(dar, (AVRational) { 16, 9 }))) {

                s->avctx->sample_aspect_ratio =

                    av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],

                             (AVRational) { s->width, s->height });

            } else {

                s->avctx->sample_aspect_ratio =

                    av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],

                             (AVRational) { s1->pan_scan.width, s1->pan_scan.height });

// issue1613 4/3 16/9 -> 16/9

// res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3

// widescreen-issue562.mpg 4/3 16/9 -> 16/9

//                s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});

                av_dlog(avctx, "A %d/%d\n",

                        ff_mpeg2_aspect[s->aspect_ratio_info].num,

                        ff_mpeg2_aspect[s->aspect_ratio_info].den);

                av_dlog(avctx, "B %d/%d\n", s->avctx->sample_aspect_ratio.num,

                        s->avctx->sample_aspect_ratio.den);

            }

        } else {

            s->avctx->sample_aspect_ratio =

                ff_mpeg2_aspect[s->aspect_ratio_info];

        }

    } // MPEG-2

    ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);

    if ((s1->mpeg_enc_ctx_allocated == 0)                   ||

        avctx->coded_width       != s->width                ||

        avctx->coded_height      != s->height               ||

        s1->save_width           != s->width                ||

        s1->save_height          != s->height               ||

        s1->save_aspect_info     != s->aspect_ratio_info    ||

        (s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||

        0) {

        if (s1->mpeg_enc_ctx_allocated) {

            ParseContext pc = s->parse_context;

            s->parse_context.buffer = 0;

            ff_mpv_common_end(s);

            s->parse_context = pc;

            s1->mpeg_enc_ctx_allocated = 0;

        }

        ret = ff_set_dimensions(avctx, s->width, s->height);

        if (ret < 0)

            return ret;

        if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate) {

            avctx->rc_max_rate = s->bit_rate;

        } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&

                   (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) {

            avctx->bit_rate = s->bit_rate;

        }

        s1->save_aspect_info     = s->aspect_ratio_info;

        s1->save_width           = s->width;

        s1->save_height          = s->height;

        s1->save_progressive_seq = s->progressive_sequence;

        /* low_delay may be forced, in this case we will have B-frames

         * that behave like P-frames. */

        avctx->has_b_frames = !s->low_delay;

        if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {

            // MPEG-1 fps

            avctx->framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];

            avctx->ticks_per_frame     = 1;

        } else { // MPEG-2

            // MPEG-2 fps

            av_reduce(&s->avctx->framerate.num,

                      &s->avctx->framerate.den,

                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num,

                      ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,

                      1 << 30);

            avctx->ticks_per_frame = 2;

        } // MPEG-2

        avctx->pix_fmt = mpeg_get_pixelformat(avctx);

        setup_hwaccel_for_pixfmt(avctx);

        /* Quantization matrices may need reordering

         * if DCT permutation is changed. */

        memcpy(old_permutation, s->idsp.idct_permutation, 64 * sizeof(uint8_t));

        ff_mpv_idct_init(s);

        if ((ret = ff_mpv_common_init(s)) < 0)

            return ret;

        quant_matrix_rebuild(s->intra_matrix,        old_permutation, s->idsp.idct_permutation);

        quant_matrix_rebuild(s->inter_matrix,        old_permutation, s->idsp.idct_permutation);

        quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->idsp.idct_permutation);

        quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->idsp.idct_permutation);

        s1->mpeg_enc_ctx_allocated = 1;

    }

    return 0;

}


static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)

{

    MXFContext *mxf = arg;

    int item_num = avio_rb32(pb);

    int item_len = avio_rb32(pb);

    if (item_len != 18) {

        avpriv_request_sample(pb, "Primer pack item length %d", item_len);

        return AVERROR_PATCHWELCOME;

    }

    if (item_num > 65536) {

        av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);

        return AVERROR_INVALIDDATA;

    }

    mxf->local_tags = av_calloc(item_num, item_len);

    if (!mxf->local_tags)

        return AVERROR(ENOMEM);

    mxf->local_tags_count = item_num;

    avio_read(pb, mxf->local_tags, item_num*item_len);

    return 0;

}


void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,

                        uint64_t mcg_status, uint64_t addr, uint64_t misc,

                        int abort_on_error)

{

#ifdef KVM_CAP_MCE

    struct kvm_x86_mce mce = {

        .bank = bank,

        .status = status,

        .mcg_status = mcg_status,

        .addr = addr,

        .misc = misc,

    };

    struct kvm_x86_mce_data data = {

            .env = cenv,

            .mce = &mce,

    };

    if (!cenv->mcg_cap) {

        fprintf(stderr, "MCE support is not enabled!\n");

        return;

    }

    run_on_cpu(cenv, kvm_do_inject_x86_mce, &data);

#else

    if (abort_on_error)

        abort();

#endif

}


static inline void RENAME(yuv2bgr24_2)(SwsContext *c, const uint16_t *buf0,

                                       const uint16_t *buf1, const uint16_t *ubuf0,

                                       const uint16_t *ubuf1, const uint16_t *vbuf0,

                                       const uint16_t *vbuf1, const uint16_t *abuf0,

                                       const uint16_t *abuf1, uint8_t *dest,

                                       int dstW, int yalpha, int uvalpha, int y)

{

    x86_reg uv_off = c->uv_off << 1;

    //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(

    __asm__ volatile(

        "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

        "mov        %4, %%"REG_b"               \n\t"

        "push %%"REG_BP"                        \n\t"

        YSCALEYUV2RGB(%%REGBP, %5, %6)

        "pxor    %%mm7, %%mm7                   \n\t"

        WRITEBGR24(%%REGb, 8280(%5), %%REGBP)

        "pop %%"REG_BP"                         \n\t"

        "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

        :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

           "a" (&c->redDither), "m"(uv_off)

    );

}


static int usb_xhci_initfn(struct PCIDevice *dev)

{

    int i, ret;

    XHCIState *xhci = DO_UPCAST(XHCIState, pci_dev, dev);

    xhci->pci_dev.config[PCI_CLASS_PROG] = 0x30;    /* xHCI */

    xhci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */

    xhci->pci_dev.config[PCI_CACHE_LINE_SIZE] = 0x10;

    xhci->pci_dev.config[0x60] = 0x30; /* release number */

    usb_xhci_init(xhci, &dev->qdev);

    if (xhci->numintrs > MAXINTRS) {

        xhci->numintrs = MAXINTRS;

    if (xhci->numintrs < 1) {

        xhci->numintrs = 1;

    if (xhci->numslots > MAXSLOTS) {

        xhci->numslots = MAXSLOTS;

    if (xhci->numslots < 1) {

        xhci->numslots = 1;

    xhci->mfwrap_timer = qemu_new_timer_ns(vm_clock, xhci_mfwrap_timer, xhci);

    xhci->irq = xhci->pci_dev.irq[0];

    memory_region_init(&xhci->mem, "xhci", LEN_REGS);

    memory_region_init_io(&xhci->mem_cap, &xhci_cap_ops, xhci,

                          "capabilities", LEN_CAP);

    memory_region_init_io(&xhci->mem_oper, &xhci_oper_ops, xhci,

                          "operational", 0x400);

    memory_region_init_io(&xhci->mem_runtime, &xhci_runtime_ops, xhci,

                          "runtime", LEN_RUNTIME);

    memory_region_init_io(&xhci->mem_doorbell, &xhci_doorbell_ops, xhci,

                          "doorbell", LEN_DOORBELL);

    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap);

    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper);

    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime);

    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell);

    for (i = 0; i < xhci->numports; i++) {

        XHCIPort *port = &xhci->ports[i];

        uint32_t offset = OFF_OPER + 0x400 + 0x10 * i;

        port->xhci = xhci;

        memory_region_init_io(&port->mem, &xhci_port_ops, port,

                              port->name, 0x10);

        memory_region_add_subregion(&xhci->mem, offset, &port->mem);

    pci_register_bar(&xhci->pci_dev, 0,

                     PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,

                     &xhci->mem);

    ret = pcie_endpoint_cap_init(&xhci->pci_dev, 0xa0);

    assert(ret >= 0);

    if (xhci->flags & (1 << XHCI_FLAG_USE_MSI)) {

        msi_init(&xhci->pci_dev, 0x70, xhci->numintrs, true, false);

    if (xhci->flags & (1 << XHCI_FLAG_USE_MSI_X)) {

        msix_init(&xhci->pci_dev, xhci->numintrs,

                  &xhci->mem, 0, OFF_MSIX_TABLE,

                  &xhci->mem, 0, OFF_MSIX_PBA,

                  0x90);

    return 0;


int avformat_network_init(void)

{

#if CONFIG_NETWORK

    int ret;

    ff_network_inited_globally = 1;

    if ((ret = ff_network_init()) < 0)

        return ret;

    ff_tls_init();

#endif

    return 0;

}


GList *range_list_insert(GList *list, Range *data)

{

    GList *l, *next = NULL;

    Range *r, *nextr;

    if (!list) {

        list = g_list_insert_sorted(list, data, range_compare);

        return list;

    }

    nextr = data;

    l = list;

    while (l && l != next && nextr) {

        r = l->data;

        if (ranges_can_merge(r, nextr)) {

            range_merge(r, nextr);

            l = g_list_remove_link(l, next);

            next = g_list_next(l);

            if (next) {

                nextr = next->data;

            } else {

                nextr = NULL;

            }

        } else {

            l = g_list_next(l);

        }

    }

    if (!l) {

        list = g_list_insert_sorted(list, data, range_compare);

    }

    return list;

}


static int sab_diamond_search(MpegEncContext * s, int *best, int dmin,

                                       int src_index, int ref_index, int const penalty_factor,

                                       int size, int h, int flags)

{

    MotionEstContext * const c= &s->me;

    me_cmp_func cmpf, chroma_cmpf;

    Minima minima[MAX_SAB_SIZE];

    const int minima_count= FFABS(c->dia_size);

    int i, j;

    LOAD_COMMON

    LOAD_COMMON2

    int map_generation= c->map_generation;

    cmpf= s->dsp.me_cmp[size];

    chroma_cmpf= s->dsp.me_cmp[size+1];

    for(j=i=0; i<ME_MAP_SIZE; i++){

        uint32_t key= map[i];

        key += (1<<(ME_MAP_MV_BITS-1)) + (1<<(2*ME_MAP_MV_BITS-1));

        if((key&((-1)<<(2*ME_MAP_MV_BITS))) != map_generation) continue;

        assert(j<MAX_SAB_SIZE); //max j = number of predictors

        minima[j].height= score_map[i];

        minima[j].x= key & ((1<<ME_MAP_MV_BITS)-1); key>>=ME_MAP_MV_BITS;

        minima[j].y= key & ((1<<ME_MAP_MV_BITS)-1);

        minima[j].x-= (1<<(ME_MAP_MV_BITS-1));

        minima[j].y-= (1<<(ME_MAP_MV_BITS-1));

        minima[j].checked=0;

        if(minima[j].x || minima[j].y)

            minima[j].height+= (mv_penalty[((minima[j].x)<<shift)-pred_x] + mv_penalty[((minima[j].y)<<shift)-pred_y])*penalty_factor;

        j++;

    }

    qsort(minima, j, sizeof(Minima), minima_cmp);

    for(; j<minima_count; j++){

        minima[j].height=256*256*256*64;

        minima[j].checked=0;

        minima[j].x= minima[j].y=0;

    }

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

        const int x= minima[i].x;

        const int y= minima[i].y;

        int d;

        if(minima[i].checked) continue;

        if(   x >= xmax || x <= xmin

           || y >= ymax || y <= ymin)

           continue;

        SAB_CHECK_MV(x-1, y)

        SAB_CHECK_MV(x+1, y)

        SAB_CHECK_MV(x  , y-1)

        SAB_CHECK_MV(x  , y+1)

        minima[i].checked= 1;

    }

    best[0]= minima[0].x;

    best[1]= minima[0].y;

    dmin= minima[0].height;

    if(   best[0] < xmax && best[0] > xmin

       && best[1] < ymax && best[1] > ymin){

        int d;

        //ensure that the refernece samples for hpel refinement are in the map

        CHECK_MV(best[0]-1, best[1])

        CHECK_MV(best[0]+1, best[1])

        CHECK_MV(best[0], best[1]-1)

        CHECK_MV(best[0], best[1]+1)

    }

    return dmin;

}


static void close_guest_eventfds(IVShmemState *s, int posn)

{

    int i, guest_curr_max;

    if (!ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {

    guest_curr_max = s->peers[posn].nb_eventfds;

    memory_region_transaction_begin();

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

        ivshmem_del_eventfd(s, posn, i);

    memory_region_transaction_commit();

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

        event_notifier_cleanup(&s->peers[posn].eventfds[i]);

    g_free(s->peers[posn].eventfds);

    s->peers[posn].nb_eventfds = 0;


static int tiff_decode_tag(TiffContext *s, const uint8_t *start,

                           const uint8_t *buf, const uint8_t *end_buf)

{

    unsigned tag, type, count, off, value = 0;

    int i;

    uint32_t *pal;

    const uint8_t *rp, *gp, *bp;

    if (end_buf - buf < 12)

        return AVERROR_INVALIDDATA;

    tag   = tget_short(&buf, s->le);

    type  = tget_short(&buf, s->le);

    count = tget_long(&buf, s->le);

    off   = tget_long(&buf, s->le);

    if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {

        av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",

               type);

        return 0;

    }

    if (count == 1) {

        switch (type) {

        case TIFF_BYTE:

        case TIFF_SHORT:

            buf  -= 4;

            value = tget(&buf, type, s->le);

            buf   = NULL;

            break;

        case TIFF_LONG:

            value = off;

            buf   = NULL;

            break;

        case TIFF_STRING:

            if (count <= 4) {

                buf -= 4;

                break;

            }

        default:

            value = UINT_MAX;

            buf   = start + off;

        }

    } else {

        if (count <= 4 && type_sizes[type] * count <= 4)

            buf -= 4;

        else

            buf = start + off;

    }

    if (buf && (buf < start || buf > end_buf)) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Tag referencing position outside the image\n");

        return AVERROR_INVALIDDATA;

    }

    switch (tag) {

    case TIFF_WIDTH:

        s->width = value;

        break;

    case TIFF_HEIGHT:

        s->height = value;

        break;

    case TIFF_BPP:

        s->bppcount = count;

        if (count > 4) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "This format is not supported (bpp=%d, %d components)\n",

                   s->bpp, count);

            return AVERROR_INVALIDDATA;

        }

        if (count == 1)

            s->bpp = value;

        else {

            switch (type) {

            case TIFF_BYTE:

                s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) +

                         ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);

                break;

            case TIFF_SHORT:

            case TIFF_LONG:

                s->bpp = 0;

                for (i = 0; i < count && buf < end_buf; i++)

                    s->bpp += tget(&buf, type, s->le);

                break;

            default:

                s->bpp = -1;

            }

        }

        break;

    case TIFF_SAMPLES_PER_PIXEL:

        if (count != 1) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Samples per pixel requires a single value, many provided\n");

            return AVERROR_INVALIDDATA;

        }

        if (s->bppcount == 1)

            s->bpp *= value;

        s->bppcount = value;

        break;

    case TIFF_COMPR:

        s->compr     = value;

        s->predictor = 0;

        switch (s->compr) {

        case TIFF_RAW:

        case TIFF_PACKBITS:

        case TIFF_LZW:

        case TIFF_CCITT_RLE:

            break;

        case TIFF_G3:

        case TIFF_G4:

            s->fax_opts = 0;

            break;

        case TIFF_DEFLATE:

        case TIFF_ADOBE_DEFLATE:

#if CONFIG_ZLIB

            break;

#else

            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");

            return AVERROR(ENOSYS);

#endif

        case TIFF_JPEG:

        case TIFF_NEWJPEG:

            avpriv_report_missing_feature(s->avctx, "JPEG compression");

            return AVERROR_PATCHWELCOME;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",

                   s->compr);

            return AVERROR_INVALIDDATA;

        }

        break;

    case TIFF_ROWSPERSTRIP:

        if (type == TIFF_LONG && value == UINT_MAX)

            value = s->avctx->height;

        if (value < 1) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Incorrect value of rows per strip\n");

            return AVERROR_INVALIDDATA;

        }

        s->rps = value;

        break;

    case TIFF_STRIP_OFFS:

        if (count == 1) {

            s->stripdata = NULL;

            s->stripoff  = value;

        } else

            s->stripdata = start + off;

        s->strips = count;

        if (s->strips == 1)

            s->rps = s->height;

        s->sot = type;

        if (s->stripdata > end_buf) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Tag referencing position outside the image\n");

            return AVERROR_INVALIDDATA;

        }

        break;

    case TIFF_STRIP_SIZE:

        if (count == 1) {

            s->stripsizes = NULL;

            s->stripsize  = value;

            s->strips     = 1;

        } else {

            s->stripsizes = start + off;

        }

        s->strips = count;

        s->sstype = type;

        if (s->stripsizes > end_buf) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Tag referencing position outside the image\n");

            return AVERROR_INVALIDDATA;

        }

        break;

    case TIFF_PREDICTOR:

        s->predictor = value;

        break;

    case TIFF_INVERT:

        switch (value) {

        case 0:

            s->invert = 1;

            break;

        case 1:

            s->invert = 0;

            break;

        case 2:

        case 3:

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n",

                   value);

            return AVERROR_INVALIDDATA;

        }

        break;

    case TIFF_FILL_ORDER:

        if (value < 1 || value > 2) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "Unknown FillOrder value %d, trying default one\n", value);

            value = 1;

        }

        s->fill_order = value - 1;

        break;

    case TIFF_PAL:

        pal = (uint32_t *) s->palette;

        off = type_sizes[type];

        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)

            return AVERROR_INVALIDDATA;

        rp  = buf;

        gp  = buf + count / 3 * off;

        bp  = buf + count / 3 * off * 2;

        off = (type_sizes[type] - 1) << 3;

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

            uint32_t p = 0xFF000000;

            p |= (tget(&rp, type, s->le) >> off) << 16;

            p |= (tget(&gp, type, s->le) >> off) << 8;

            p |=  tget(&bp, type, s->le) >> off;

            pal[i] = p;

        }

        s->palette_is_set = 1;

        break;

    case TIFF_PLANAR:

        if (value == 2) {

            avpriv_report_missing_feature(s->avctx, "Planar format");

            return AVERROR_PATCHWELCOME;

        }

        break;

    case TIFF_T4OPTIONS:

        if (s->compr == TIFF_G3)

            s->fax_opts = value;

        break;

    case TIFF_T6OPTIONS:

        if (s->compr == TIFF_G4)

            s->fax_opts = value;

        break;

    default:

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

            av_log(s->avctx, AV_LOG_ERROR,

                   "Unknown or unsupported tag %d/0X%0X\n",

                   tag, tag);

            return AVERROR_INVALIDDATA;

        }

    }

    return 0;

}


static int read_packet(AVFormatContext *s,

                           AVPacket *pkt)

{

    MmDemuxContext *mm = s->priv_data;

    AVIOContext *pb = s->pb;

    unsigned char preamble[MM_PREAMBLE_SIZE];

    unsigned int type, length;

    while(1) {

        if (avio_read(pb, preamble, MM_PREAMBLE_SIZE) != MM_PREAMBLE_SIZE) {

            return AVERROR(EIO);

        }

        type = AV_RL16(&preamble[0]);

        length = AV_RL16(&preamble[2]);

        switch(type) {

        case MM_TYPE_PALETTE :

        case MM_TYPE_INTER :

        case MM_TYPE_INTRA :

        case MM_TYPE_INTRA_HH :

        case MM_TYPE_INTER_HH :

        case MM_TYPE_INTRA_HHV :

        case MM_TYPE_INTER_HHV :

            /* output preamble + data */

            if (av_new_packet(pkt, length + MM_PREAMBLE_SIZE))

                return AVERROR(ENOMEM);

            memcpy(pkt->data, preamble, MM_PREAMBLE_SIZE);

            if (avio_read(pb, pkt->data + MM_PREAMBLE_SIZE, length) != length)

                return AVERROR(EIO);

            pkt->size = length + MM_PREAMBLE_SIZE;

            pkt->stream_index = 0;

            pkt->pts = mm->video_pts;

            if (type!=MM_TYPE_PALETTE)

                mm->video_pts++;

            return 0;

        case MM_TYPE_AUDIO :

            if (av_get_packet(s->pb, pkt, length)<0)

                return AVERROR(ENOMEM);

            pkt->size = length;

            pkt->stream_index = 1;

            pkt->pts = mm->audio_pts++;

            return 0;

        default :

            av_log(s, AV_LOG_INFO, "unknown chunk type 0x%x\n", type);

            avio_skip(pb, length);

        }

    }

}


static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path,

                              const char *name, V9fsPath *target)

{

    char buffer[PATH_MAX];

    struct file_handle *fh;

    int dirfd, ret, mnt_id;

    struct handle_data *data = (struct handle_data *)ctx->private;

    /* "." and ".." are not allowed */

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

        errno = EINVAL;

        return -1;

    }

    if (dir_path) {

        dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH);

    } else {

        /* relative to export root */

        dirfd = open(rpath(ctx, ".", buffer), O_DIRECTORY);

    }

    if (dirfd < 0) {

        return dirfd;

    }

    fh = g_malloc(sizeof(struct file_handle) + data->handle_bytes);

    fh->handle_bytes = data->handle_bytes;

    /* add a "./" at the beginning of the path */

    snprintf(buffer, PATH_MAX, "./%s", name);

    /* flag = 0 imply don't follow symlink */

    ret = name_to_handle(dirfd, buffer, fh, &mnt_id, 0);

    if (!ret) {

        target->data = (char *)fh;

        target->size = sizeof(struct file_handle) + data->handle_bytes;

    } else {

        g_free(fh);

    }

    close(dirfd);

    return ret;

}


static int qio_dns_resolver_lookup_sync_inet(QIODNSResolver *resolver,

                                             SocketAddress *addr,

                                             size_t *naddrs,

                                             SocketAddress ***addrs,

                                             Error **errp)

{

    struct addrinfo ai, *res, *e;

    InetSocketAddress *iaddr = addr->u.inet.data;

    char port[33];

    char uaddr[INET6_ADDRSTRLEN + 1];

    char uport[33];

    int rc;

    Error *err = NULL;

    size_t i;

    *naddrs = 0;

    *addrs = NULL;

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

    ai.ai_flags = AI_PASSIVE;

    if (iaddr->has_numeric && iaddr->numeric) {

        ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;

    }

    ai.ai_family = inet_ai_family_from_address(iaddr, &err);

    ai.ai_socktype = SOCK_STREAM;

    if (err) {

        error_propagate(errp, err);

        return -1;

    }

    if (iaddr->host == NULL) {

        error_setg(errp, "host not specified");

        return -1;

    }

    if (iaddr->port != NULL) {

        pstrcpy(port, sizeof(port), iaddr->port);

    } else {

        port[0] = '\0';

    }

    rc = getaddrinfo(strlen(iaddr->host) ? iaddr->host : NULL,

                     strlen(port) ? port : NULL, &ai, &res);

    if (rc != 0) {

        error_setg(errp, "address resolution failed for %s:%s: %s",

                   iaddr->host, port, gai_strerror(rc));

        return -1;

    }

    for (e = res; e != NULL; e = e->ai_next) {

        (*naddrs)++;

    }

    *addrs = g_new0(SocketAddress *, *naddrs);

    /* create socket + bind */

    for (i = 0, e = res; e != NULL; i++, e = e->ai_next) {

        SocketAddress *newaddr = g_new0(SocketAddress, 1);

        InetSocketAddress *newiaddr = g_new0(InetSocketAddress, 1);

        newaddr->u.inet.data = newiaddr;

        newaddr->type = SOCKET_ADDRESS_KIND_INET;

        getnameinfo((struct sockaddr *)e->ai_addr, e->ai_addrlen,

                    uaddr, INET6_ADDRSTRLEN, uport, 32,

                    NI_NUMERICHOST | NI_NUMERICSERV);

        *newiaddr = (InetSocketAddress){

            .host = g_strdup(uaddr),

            .port = g_strdup(uport),

            .has_numeric = true,

            .numeric = true,

            .has_to = iaddr->has_to,

            .to = iaddr->to,

            .has_ipv4 = false,

            .has_ipv6 = false,

        };

        (*addrs)[i] = newaddr;

    }

    freeaddrinfo(res);

    return 0;

}


void acpi_build(AcpiBuildTables *tables, MachineState *machine)

{

    PCMachineState *pcms = PC_MACHINE(machine);

    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);

    GArray *table_offsets;

    unsigned facs, dsdt, rsdt, fadt;

    AcpiPmInfo pm;

    AcpiMiscInfo misc;

    AcpiMcfgInfo mcfg;

    Range pci_hole, pci_hole64;

    uint8_t *u;

    size_t aml_len = 0;

    GArray *tables_blob = tables->table_data;

    AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };

    Object *vmgenid_dev;

    acpi_get_pm_info(&pm);

    acpi_get_misc_info(&misc);

    acpi_get_pci_holes(&pci_hole, &pci_hole64);

    acpi_get_slic_oem(&slic_oem);

    table_offsets = g_array_new(false, true /* clear */,

                                        sizeof(uint32_t));

    ACPI_BUILD_DPRINTF("init ACPI tables\n");

    bios_linker_loader_alloc(tables->linker,

                             ACPI_BUILD_TABLE_FILE, tables_blob,

                             64 /* Ensure FACS is aligned */,

                             false /* high memory */);

    /*

     * FACS is pointed to by FADT.

     * We place it first since it's the only table that has alignment

     * requirements.

     */

    facs = tables_blob->len;

    build_facs(tables_blob, tables->linker);

    /* DSDT is pointed to by FADT */

    dsdt = tables_blob->len;

    build_dsdt(tables_blob, tables->linker, &pm, &misc,

               &pci_hole, &pci_hole64, machine);

    /* Count the size of the DSDT and SSDT, we will need it for legacy

     * sizing of ACPI tables.

     */

    aml_len += tables_blob->len - dsdt;

    /* ACPI tables pointed to by RSDT */

    fadt = tables_blob->len;

    acpi_add_table(table_offsets, tables_blob);

    build_fadt(tables_blob, tables->linker, &pm, facs, dsdt,

               slic_oem.id, slic_oem.table_id);

    aml_len += tables_blob->len - fadt;

    acpi_add_table(table_offsets, tables_blob);

    build_madt(tables_blob, tables->linker, pcms);

    vmgenid_dev = find_vmgenid_dev();

    if (vmgenid_dev) {

        acpi_add_table(table_offsets, tables_blob);

        vmgenid_build_acpi(VMGENID(vmgenid_dev), tables_blob,

                           tables->vmgenid, tables->linker);

    }

    if (misc.has_hpet) {

        acpi_add_table(table_offsets, tables_blob);

        build_hpet(tables_blob, tables->linker);

    }

    if (misc.tpm_version != TPM_VERSION_UNSPEC) {

        acpi_add_table(table_offsets, tables_blob);

        build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);

        if (misc.tpm_version == TPM_VERSION_2_0) {

            acpi_add_table(table_offsets, tables_blob);

            build_tpm2(tables_blob, tables->linker);

        }

    }

    if (pcms->numa_nodes) {

        acpi_add_table(table_offsets, tables_blob);

        build_srat(tables_blob, tables->linker, machine);

        if (have_numa_distance) {

            acpi_add_table(table_offsets, tables_blob);

            build_slit(tables_blob, tables->linker);

        }

    }

    if (acpi_get_mcfg(&mcfg)) {

        acpi_add_table(table_offsets, tables_blob);

        build_mcfg_q35(tables_blob, tables->linker, &mcfg);

    }

    if (x86_iommu_get_default()) {

        IommuType IOMMUType = x86_iommu_get_type();

        if (IOMMUType == TYPE_AMD) {

            acpi_add_table(table_offsets, tables_blob);

            build_amd_iommu(tables_blob, tables->linker);

        } else if (IOMMUType == TYPE_INTEL) {

            acpi_add_table(table_offsets, tables_blob);

            build_dmar_q35(tables_blob, tables->linker);

        }

    }

    if (pcms->acpi_nvdimm_state.is_enabled) {

        nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,

                          &pcms->acpi_nvdimm_state, machine->ram_slots);

    }

    /* Add tables supplied by user (if any) */

    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {

        unsigned len = acpi_table_len(u);

        acpi_add_table(table_offsets, tables_blob);

        g_array_append_vals(tables_blob, u, len);

    }

    /* RSDT is pointed to by RSDP */

    rsdt = tables_blob->len;

    build_rsdt(tables_blob, tables->linker, table_offsets,

               slic_oem.id, slic_oem.table_id);

    /* RSDP is in FSEG memory, so allocate it separately */

    build_rsdp(tables->rsdp, tables->linker, rsdt);

    /* We'll expose it all to Guest so we want to reduce

     * chance of size changes.

     *

     * We used to align the tables to 4k, but of course this would

     * too simple to be enough.  4k turned out to be too small an

     * alignment very soon, and in fact it is almost impossible to

     * keep the table size stable for all (max_cpus, max_memory_slots)

     * combinations.  So the table size is always 64k for pc-i440fx-2.1

     * and we give an error if the table grows beyond that limit.

     *

     * We still have the problem of migrating from "-M pc-i440fx-2.0".  For

     * that, we exploit the fact that QEMU 2.1 generates _smaller_ tables

     * than 2.0 and we can always pad the smaller tables with zeros.  We can

     * then use the exact size of the 2.0 tables.

     *

     * All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration.

     */

    if (pcmc->legacy_acpi_table_size) {

        /* Subtracting aml_len gives the size of fixed tables.  Then add the

         * size of the PIIX4 DSDT/SSDT in QEMU 2.0.

         */

        int legacy_aml_len =

            pcmc->legacy_acpi_table_size +

            ACPI_BUILD_LEGACY_CPU_AML_SIZE * pcms->apic_id_limit;

        int legacy_table_size =

            ROUND_UP(tables_blob->len - aml_len + legacy_aml_len,

                     ACPI_BUILD_ALIGN_SIZE);

        if (tables_blob->len > legacy_table_size) {

            /* Should happen only with PCI bridges and -M pc-i440fx-2.0.  */

            error_report("Warning: migration may not work.");

        }

        g_array_set_size(tables_blob, legacy_table_size);

    } else {

        /* Make sure we have a buffer in case we need to resize the tables. */

        if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {

            /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots.  */

            error_report("Warning: ACPI tables are larger than 64k.");

            error_report("Warning: migration may not work.");

            error_report("Warning: please remove CPUs, NUMA nodes, "

                         "memory slots or PCI bridges.");

        }

        acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);

    }

    acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);

    /* Cleanup memory that's no longer used. */

    g_array_free(table_offsets, true);

}