static void pc_q35_init(MachineState *machine)
{
    PCMachineState *pc_machine = PC_MACHINE(machine);
    ram_addr_t below_4g_mem_size, above_4g_mem_size;
    Q35PCIHost *q35_host;
    PCIHostState *phb;
    PCIBus *host_bus;
    PCIDevice *lpc;
    BusState *idebus[MAX_SATA_PORTS];
    ISADevice *rtc_state;
    ISADevice *floppy;
    MemoryRegion *pci_memory;
    MemoryRegion *rom_memory;
    MemoryRegion *ram_memory;
    GSIState *gsi_state;
    ISABus *isa_bus;
    int pci_enabled = 1;
    qemu_irq *cpu_irq;
    qemu_irq *gsi;
    qemu_irq *i8259;
    int i;
    ICH9LPCState *ich9_lpc;
    PCIDevice *ahci;
    DeviceState *icc_bridge;
    PcGuestInfo *guest_info;
    ram_addr_t lowmem;
    /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
     * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
     * also known as MMCFG).
     * If it doesn't, we need to split it in chunks below and above 4G.
     * In any case, try to make sure that guest addresses aligned at
     * 1G boundaries get mapped to host addresses aligned at 1G boundaries.
     * For old machine types, use whatever split we used historically to avoid
     * breaking migration.
    if (machine->ram_size >= 0xb0000000) {
        lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;
    } else {
        lowmem = 0xb0000000;
    }
    /* Handle the machine opt max-ram-below-4g.  It is basically doing
     * min(qemu limit, user limit).
    if (lowmem > pc_machine->max_ram_below_4g) {
        lowmem = pc_machine->max_ram_below_4g;
        if (machine->ram_size - lowmem > lowmem &&
            lowmem & ((1ULL << 30) - 1)) {
            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64
                         ") not a multiple of 1G; possible bad performance.",
                         pc_machine->max_ram_below_4g);
        }
    }
    if (machine->ram_size >= lowmem) {
        above_4g_mem_size = machine->ram_size - lowmem;
        below_4g_mem_size = lowmem;
    } else {
        above_4g_mem_size = 0;
        below_4g_mem_size = machine->ram_size;
    }
    if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size,
                                      &ram_memory) != 0) {
        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
        exit(1);
    }
    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
    object_property_add_child(qdev_get_machine(), "icc-bridge",
                              OBJECT(icc_bridge), NULL);
    pc_cpus_init(machine->cpu_model, icc_bridge);
    pc_acpi_init("q35-acpi-dsdt.aml");
    kvmclock_create();
    /* pci enabled */
    if (pci_enabled) {
        pci_memory = g_new(MemoryRegion, 1);
        memory_region_init(pci_memory, NULL, "pci", UINT64_MAX);
        rom_memory = pci_memory;
    } else {
        pci_memory = NULL;
        rom_memory = get_system_memory();
    }
    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
    guest_info->has_pci_info = has_pci_info;
    guest_info->isapc_ram_fw = false;
    guest_info->has_acpi_build = has_acpi_build;
    guest_info->has_reserved_memory = has_reserved_memory;
    if (smbios_defaults) {
        MachineClass *mc = MACHINE_GET_CLASS(machine);
        /* These values are guest ABI, do not change */
        smbios_set_defaults("QEMU", "Standard PC (Q35 + ICH9, 2009)",
                            mc->name, smbios_legacy_mode);
    }
    /* allocate ram and load rom/bios */
    if (!xen_enabled()) {
        pc_memory_init(machine, get_system_memory(),
                       below_4g_mem_size, above_4g_mem_size,
                       rom_memory, &ram_memory, guest_info);
    }
    /* irq lines */
    gsi_state = g_malloc0(sizeof(*gsi_state));
    if (kvm_irqchip_in_kernel()) {
        kvm_pc_setup_irq_routing(pci_enabled);
        gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,
                                 GSI_NUM_PINS);
    } else {
        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
    }
    /* create pci host bus */
    q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE));
    object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL);
    q35_host->mch.ram_memory = ram_memory;
    q35_host->mch.pci_address_space = pci_memory;
    q35_host->mch.system_memory = get_system_memory();
    q35_host->mch.address_space_io = get_system_io();
    q35_host->mch.below_4g_mem_size = below_4g_mem_size;
    q35_host->mch.above_4g_mem_size = above_4g_mem_size;
    q35_host->mch.guest_info = guest_info;
    /* pci */
    qdev_init_nofail(DEVICE(q35_host));
    phb = PCI_HOST_BRIDGE(q35_host);
    host_bus = phb->bus;
    /* create ISA bus */
    lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,
                                          ICH9_LPC_FUNC), true,
                                          TYPE_ICH9_LPC_DEVICE);
    object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
                             TYPE_HOTPLUG_HANDLER,
                             (Object **)&pc_machine->acpi_dev,
                             object_property_allow_set_link,
                             OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
    object_property_set_link(OBJECT(machine), OBJECT(lpc),
                             PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
    ich9_lpc = ICH9_LPC_DEVICE(lpc);
    ich9_lpc->pic = gsi;
    ich9_lpc->ioapic = gsi_state->ioapic_irq;
    pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc,
                 ICH9_LPC_NB_PIRQS);
    pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);
    isa_bus = ich9_lpc->isa_bus;
    /*end early*/
    isa_bus_irqs(isa_bus, gsi);
    if (kvm_irqchip_in_kernel()) {
        i8259 = kvm_i8259_init(isa_bus);
    } else if (xen_enabled()) {
        i8259 = xen_interrupt_controller_init();
    } else {
        cpu_irq = pc_allocate_cpu_irq();
        i8259 = i8259_init(isa_bus, cpu_irq[0]);
    }
    for (i = 0; i < ISA_NUM_IRQS; i++) {
        gsi_state->i8259_irq[i] = i8259[i];
    }
    if (pci_enabled) {
        ioapic_init_gsi(gsi_state, NULL);
    }
    qdev_init_nofail(icc_bridge);
    pc_register_ferr_irq(gsi[13]);
    /* init basic PC hardware */
    pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false, 0xff0104);
    /* connect pm stuff to lpc */
    ich9_lpc_pm_init(lpc);
    /* ahci and SATA device, for q35 1 ahci controller is built-in */
    ahci = pci_create_simple_multifunction(host_bus,
                                           PCI_DEVFN(ICH9_SATA1_DEV,
                                                     ICH9_SATA1_FUNC),
                                           true, "ich9-ahci");
    idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");
    idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");
    if (usb_enabled(false)) {
        /* Should we create 6 UHCI according to ich9 spec? */
        ehci_create_ich9_with_companions(host_bus, 0x1d);
    }
    /* TODO: Populate SPD eeprom data.  */
    smbus_eeprom_init(ich9_smb_init(host_bus,
                                    PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),
                                    0xb100),
                      8, NULL, 0);
    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
                 floppy, idebus[0], idebus[1], rtc_state);
    /* the rest devices to which pci devfn is automatically assigned */
    pc_vga_init(isa_bus, host_bus);
    pc_nic_init(isa_bus, host_bus);
    if (pci_enabled) {
        pc_pci_device_init(host_bus);
    }
}


static int vpc_open(BlockDriverState *bs, QDict *options, int flags,

                    Error **errp)

{

    BDRVVPCState *s = bs->opaque;

    int i;

    VHDFooter *footer;

    VHDDynDiskHeader *dyndisk_header;

    uint8_t buf[HEADER_SIZE];

    uint32_t checksum;

    int disk_type = VHD_DYNAMIC;

    int ret;

    ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);

    if (ret < 0) {

        goto fail;

    }

    footer = (VHDFooter *) s->footer_buf;

    if (strncmp(footer->creator, "conectix", 8)) {

        int64_t offset = bdrv_getlength(bs->file);

        if (offset < 0) {

            ret = offset;

            goto fail;

        } else if (offset < HEADER_SIZE) {

            ret = -EINVAL;

            goto fail;

        }

        /* If a fixed disk, the footer is found only at the end of the file */

        ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,

                         HEADER_SIZE);

        if (ret < 0) {

            goto fail;

        }

        if (strncmp(footer->creator, "conectix", 8)) {

            error_setg(errp, "invalid VPC image");

            ret = -EINVAL;

            goto fail;

        }

        disk_type = VHD_FIXED;

    }

    checksum = be32_to_cpu(footer->checksum);

    footer->checksum = 0;

    if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)

        fprintf(stderr, "block-vpc: The header checksum of '%s' is "

            "incorrect.\n", bs->filename);

    /* Write 'checksum' back to footer, or else will leave it with zero. */

    footer->checksum = be32_to_cpu(checksum);

    // The visible size of a image in Virtual PC depends on the geometry

    // rather than on the size stored in the footer (the size in the footer

    // is too large usually)

    bs->total_sectors = (int64_t)

        be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;

    /* images created with disk2vhd report a far higher virtual size

     * than expected with the cyls * heads * sectors_per_cyl formula.

     * use the footer->size instead if the image was created with

     * disk2vhd.

     */

    if (!strncmp(footer->creator_app, "d2v", 4)) {

        bs->total_sectors = be64_to_cpu(footer->size) / BDRV_SECTOR_SIZE;

    }

    /* Allow a maximum disk size of approximately 2 TB */

    if (bs->total_sectors >= 65535LL * 255 * 255) {

        ret = -EFBIG;

        goto fail;

    }

    if (disk_type == VHD_DYNAMIC) {

        ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,

                         HEADER_SIZE);

        if (ret < 0) {

            goto fail;

        }

        dyndisk_header = (VHDDynDiskHeader *) buf;

        if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {

            ret = -EINVAL;

            goto fail;

        }

        s->block_size = be32_to_cpu(dyndisk_header->block_size);

        s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;

        s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);

        s->pagetable = g_malloc(s->max_table_entries * 4);

        s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);

        ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,

                         s->max_table_entries * 4);

        if (ret < 0) {

            goto fail;

        }

        s->free_data_block_offset =

            (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;

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

            be32_to_cpus(&s->pagetable[i]);

            if (s->pagetable[i] != 0xFFFFFFFF) {

                int64_t next = (512 * (int64_t) s->pagetable[i]) +

                    s->bitmap_size + s->block_size;

                if (next > s->free_data_block_offset) {

                    s->free_data_block_offset = next;

                }

            }

        }

        if (s->free_data_block_offset > bdrv_getlength(bs->file)) {

            error_setg(errp, "block-vpc: free_data_block_offset points after "

                             "the end of file. The image has been truncated.");

            ret = -EINVAL;

            goto fail;

        }

        s->last_bitmap_offset = (int64_t) -1;

#ifdef CACHE

        s->pageentry_u8 = g_malloc(512);

        s->pageentry_u32 = s->pageentry_u8;

        s->pageentry_u16 = s->pageentry_u8;

        s->last_pagetable = -1;

#endif

    }

    qemu_co_mutex_init(&s->lock);

    /* Disable migration when VHD images are used */

    error_set(&s->migration_blocker,

              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,

              "vpc", bs->device_name, "live migration");

    migrate_add_blocker(s->migration_blocker);

    return 0;

fail:

    g_free(s->pagetable);

#ifdef CACHE

    g_free(s->pageentry_u8);

#endif

    return ret;

}


void helper_done(CPUSPARCState *env)

{

    trap_state *tsptr = cpu_tsptr(env);

    env->pc = tsptr->tnpc;

    env->npc = tsptr->tnpc + 4;

    cpu_put_ccr(env, tsptr->tstate >> 32);

    env->asi = (tsptr->tstate >> 24) & 0xff;

    cpu_change_pstate(env, (tsptr->tstate >> 8) & 0xf3f);

    cpu_put_cwp64(env, tsptr->tstate & 0xff);

    if (cpu_has_hypervisor(env)) {

        uint32_t new_gl = (tsptr->tstate >> 40) & 7;

        env->hpstate = env->htstate[env->tl];

        cpu_gl_switch_gregs(env, new_gl);

        env->gl = new_gl;

    }

    env->tl--;

    trace_win_helper_done(env->tl);

#if !defined(CONFIG_USER_ONLY)

    if (cpu_interrupts_enabled(env)) {

        cpu_check_irqs(env);

    }

#endif

}


void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,

                                 DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)

#else

static void host_alarm_handler(int host_signum)

#endif

{

#if 0

#define DISP_FREQ 1000

    {

        static int64_t delta_min = INT64_MAX;

        static int64_t delta_max, delta_cum, last_clock, delta, ti;

        static int count;

        ti = qemu_get_clock(vm_clock);

        if (last_clock != 0) {

            delta = ti - last_clock;

            if (delta < delta_min)

                delta_min = delta;

            if (delta > delta_max)

                delta_max = delta;

            delta_cum += delta;

            if (++count == DISP_FREQ) {

                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",

                       muldiv64(delta_min, 1000000, ticks_per_sec),

                       muldiv64(delta_max, 1000000, ticks_per_sec),

                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),

                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));

                count = 0;

                delta_min = INT64_MAX;

                delta_max = 0;

                delta_cum = 0;

            }

        }

        last_clock = ti;

    }

#endif

    if (alarm_has_dynticks(alarm_timer) ||

        qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],

                           qemu_get_clock(vm_clock)) ||

        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],

                           qemu_get_clock(rt_clock))) {

#ifdef _WIN32

        struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;

        SetEvent(data->host_alarm);

#endif

        CPUState *env = next_cpu;

        /* stop the currently executing cpu because a timer occured */

        cpu_interrupt(env, CPU_INTERRUPT_EXIT);

#ifdef USE_KQEMU

        if (env->kqemu_enabled) {

            kqemu_cpu_interrupt(env);

        }

#endif

        event_pending = 1;

    }

}


static void tqi_calculate_qtable(TqiContext *t, int quant)

{

    const int qscale = (215 - 2*quant)*5;

    int i;

    t->intra_matrix[0] = (ff_inv_aanscales[0] * ff_mpeg1_default_intra_matrix[0]) >> 11;

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

        t->intra_matrix[i] = (ff_inv_aanscales[i] * ff_mpeg1_default_intra_matrix[i] * qscale + 32) >> 14;

}


static void free_input_threads(void)

{

    int i;

    if (nb_input_files == 1)

        return;

    transcoding_finished = 1;

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

        InputFile *f = input_files[i];

        AVPacket pkt;

        if (f->joined)

            continue;

        pthread_mutex_lock(&f->fifo_lock);

        while (av_fifo_size(f->fifo)) {

            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);

            av_free_packet(&pkt);

        }

        pthread_cond_signal(&f->fifo_cond);

        pthread_mutex_unlock(&f->fifo_lock);

        pthread_join(f->thread, NULL);

        f->joined = 1;

        while (av_fifo_size(f->fifo)) {

            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);

            av_free_packet(&pkt);

        }

        av_fifo_free(f->fifo);

    }

}


static void tcp_chr_disconnect(CharDriverState *chr)

{

    TCPCharDriver *s = chr->opaque;

    if (!s->connected) {

        return;

    }

    s->connected = 0;

    if (s->listen_ioc) {

        s->listen_tag = qio_channel_add_watch(

            QIO_CHANNEL(s->listen_ioc), G_IO_IN, tcp_chr_accept, chr, NULL);

    }

    tcp_set_msgfds(chr, NULL, 0);

    remove_fd_in_watch(chr);

    object_unref(OBJECT(s->sioc));

    s->sioc = NULL;

    object_unref(OBJECT(s->ioc));

    s->ioc = NULL;

    g_free(chr->filename);

    chr->filename = SocketAddress_to_str("disconnected:", s->addr,

                                         s->is_listen, s->is_telnet);

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);

    if (s->reconnect_time) {

        qemu_chr_socket_restart_timer(chr);

    }

}


static inline void menelaus_rtc_stop(MenelausState *s)

{

    qemu_del_timer(s->rtc.hz_tm);

    s->rtc.next -= qemu_get_clock(rt_clock);

    if (s->rtc.next < 1)

        s->rtc.next = 1;

}


int ide_get_geometry(BusState *bus, int unit,

                     int16_t *cyls, int8_t *heads, int8_t *secs)

{

    IDEState *s = &DO_UPCAST(IDEBus, qbus, bus)->ifs[unit];

    if (s->drive_kind != IDE_HD || !s->bs) {

        return -1;

    }

    *cyls = s->cylinders;

    *heads = s->heads;

    *secs = s->sectors;

    return 0;

}


static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block,

                              uint8_t *dst, int linesize, int skip_block, int apply_filter, int cbp_top, int cbp_left)

{

    MpegEncContext *s = &v->s;

    GetBitContext *gb = &s->gb;

    int i, j;

    int subblkpat = 0;

    int scale, off, idx, last, skip, value;

    int ttblk = ttmb & 7;

    int pat = 0;

    if(ttmb == -1) {

        ttblk = ff_vc1_ttblk_to_tt[v->tt_index][get_vlc2(gb, ff_vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];

    }

    if(ttblk == TT_4X4) {

        subblkpat = ~(get_vlc2(gb, ff_vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);

    }

    if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) {

        subblkpat = decode012(gb);

        if(subblkpat) subblkpat ^= 3; //swap decoded pattern bits

        if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;

        if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;

    }

    scale = 2 * mquant + ((v->pq == mquant) ? v->halfpq : 0);

    // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT

    if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {

        subblkpat = 2 - (ttblk == TT_8X4_TOP);

        ttblk = TT_8X4;

    }

    if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {

        subblkpat = 2 - (ttblk == TT_4X8_LEFT);

        ttblk = TT_4X8;

    }

    switch(ttblk) {

    case TT_8X8:

        pat = 0xF;

        i = 0;

        last = 0;

        while (!last) {

            vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);

            i += skip;

            if(i > 63)

                break;

            idx = wmv1_scantable[0][i++];

            block[idx] = value * scale;

            if(!v->pquantizer)

                block[idx] += (block[idx] < 0) ? -mquant : mquant;

        }

        if(!skip_block){

            s->dsp.vc1_inv_trans_8x8(block);

            s->dsp.add_pixels_clamped(block, dst, linesize);

            if(apply_filter && cbp_top  & 0xC)

                vc1_loop_filter(dst, 1, linesize, 8, mquant);

            if(apply_filter && cbp_left & 0xA)

                vc1_loop_filter(dst, linesize, 1, 8, mquant);

        }

        break;

    case TT_4X4:

        pat = ~subblkpat & 0xF;

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

            last = subblkpat & (1 << (3 - j));

            i = 0;

            off = (j & 1) * 4 + (j & 2) * 16;

            while (!last) {

                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);

                i += skip;

                if(i > 15)

                    break;

                idx = ff_vc1_simple_progressive_4x4_zz[i++];

                block[idx + off] = value * scale;

                if(!v->pquantizer)

                    block[idx + off] += (block[idx + off] < 0) ? -mquant : mquant;

            }

            if(!(subblkpat & (1 << (3 - j))) && !skip_block){

                s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off);

                if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2)))))

                    vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant);

                if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1)))))

                    vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant);

            }

        }

        break;

    case TT_8X4:

        pat = ~((subblkpat & 2)*6 + (subblkpat & 1)*3) & 0xF;

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

            last = subblkpat & (1 << (1 - j));

            i = 0;

            off = j * 32;

            while (!last) {

                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);

                i += skip;

                if(i > 31)

                    break;

                idx = v->zz_8x4[i++]+off;

                block[idx] = value * scale;

                if(!v->pquantizer)

                    block[idx] += (block[idx] < 0) ? -mquant : mquant;

            }

            if(!(subblkpat & (1 << (1 - j))) && !skip_block){

                s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off);

                if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC))

                    vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant);

                if(apply_filter && cbp_left & (2 << j))

                    vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant);

            }

        }

        break;

    case TT_4X8:

        pat = ~(subblkpat*5) & 0xF;

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

            last = subblkpat & (1 << (1 - j));

            i = 0;

            off = j * 4;

            while (!last) {

                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);

                i += skip;

                if(i > 31)

                    break;

                idx = v->zz_4x8[i++]+off;

                block[idx] = value * scale;

                if(!v->pquantizer)

                    block[idx] += (block[idx] < 0) ? -mquant : mquant;

            }

            if(!(subblkpat & (1 << (1 - j))) && !skip_block){

                s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);

                if(apply_filter && cbp_top & (2 << j))

                    vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant);

                if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA))

                    vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant);

            }

        }

        break;

    }

    return pat;

}


static void gen_dcread(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    TCGv EA, val;

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_set_access_type(ctx, ACCESS_CACHE);

    EA = tcg_temp_new();

    gen_addr_reg_index(ctx, EA);

    val = tcg_temp_new();

    gen_qemu_ld32u(ctx, val, EA);

    tcg_temp_free(val);

    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);

    tcg_temp_free(EA);

#endif

}


uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,

                                               uint64_t offset,

                                               int compressed_size)

{

    BDRVQcowState *s = bs->opaque;

    int l2_index, ret;

    uint64_t *l2_table;

    int64_t cluster_offset;

    int nb_csectors;

    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);

    if (ret < 0) {

        return 0;

    }

    cluster_offset = be64_to_cpu(l2_table[l2_index]);

    if (cluster_offset & QCOW_OFLAG_COPIED) {

        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

        return 0;

    }

    if (cluster_offset)

        qcow2_free_any_clusters(bs, cluster_offset, 1);

    cluster_offset = qcow2_alloc_bytes(bs, compressed_size);

    if (cluster_offset < 0) {

        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

        return 0;

    }

    nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -

                  (cluster_offset >> 9);

    cluster_offset |= QCOW_OFLAG_COMPRESSED |

                      ((uint64_t)nb_csectors << s->csize_shift);

    /* update L2 table */

    /* compressed clusters never have the copied flag */

    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);

    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);

    l2_table[l2_index] = cpu_to_be64(cluster_offset);

    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

    if (ret < 0) {

        return 0;

    }

    return cluster_offset;

}


static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id)

{

    int max_frames, first_frames = 0, frames;

    uint8_t *buf, *buf2, *end;

    AC3HeaderInfo hdr;

    GetBitContext gbc;

    enum AVCodecID codec_id = AV_CODEC_ID_AC3;

    max_frames = 0;

    buf = p->buf;

    end = buf + p->buf_size;

    for(; buf < end; buf++) {

        if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77)

                        && !(buf[0] == 0x77 && buf[1] == 0x0B) )

            continue;

        buf2 = buf;

        for(frames = 0; buf2 < end; frames++) {

            uint8_t buf3[4096];

            int i;

            if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8))

                buf2+=16;

            if (buf[0] == 0x77 && buf[1] == 0x0B) {

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

                    buf3[i  ] = buf[i+1];

                    buf3[i+1] = buf[i  ];

                }

                init_get_bits(&gbc, buf3, 54);

            }else

                init_get_bits(&gbc, buf2, 54);

            if(avpriv_ac3_parse_header(&gbc, &hdr) < 0)

                break;

            if(buf2 + hdr.frame_size > end)

                break;

            if (buf[0] == 0x77 && buf[1] == 0x0B) {

                av_assert0(hdr.frame_size <= sizeof(buf3));

                for(; i<hdr.frame_size; i+=2) {

                    buf3[i  ] = buf[i+1];

                    buf3[i+1] = buf[i  ];

                }

            }

            if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, gbc.buffer + 2, hdr.frame_size - 2))

                break;

            if (hdr.bitstream_id > 10)

                codec_id = AV_CODEC_ID_EAC3;

            buf2 += hdr.frame_size;

        }

        max_frames = FFMAX(max_frames, frames);

        if(buf == p->buf)

            first_frames = frames;

    }

    if(codec_id != expected_codec_id) return 0;

    // keep this in sync with mp3 probe, both need to avoid

    // issues with MPEG-files!

    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;

    else if(max_frames>200)return AVPROBE_SCORE_MAX/2;

    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;

    else if(max_frames>=1) return 1;

    else                   return 0;

}


static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb){

    ASFContext *asf = s->priv_data;

    int rsize = 1;

    int num = avio_r8(pb);

    int64_t ts0, ts1;

    asf->packet_segments--;

    asf->packet_key_frame = num >> 7;

    asf->stream_index = asf->asfid2avid[num & 0x7f];

    // sequence should be ignored!

    DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0);

    DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0);

    DO_2BITS(asf->packet_property, asf->packet_replic_size, 0);

//printf("key:%d stream:%d seq:%d offset:%d replic_size:%d\n", asf->packet_key_frame, asf->stream_index, asf->packet_seq, //asf->packet_frag_offset, asf->packet_replic_size);

    if (asf->packet_replic_size >= 8) {

        asf->packet_obj_size = avio_rl32(pb);

        if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){

            av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");

        asf->packet_frag_timestamp = avio_rl32(pb); // timestamp

        if(asf->packet_replic_size >= 8+38+4){

//            for(i=0; i<asf->packet_replic_size-8; i++)

//                av_log(s, AV_LOG_DEBUG, "%02X ",avio_r8(pb));

//            av_log(s, AV_LOG_DEBUG, "\n");

            avio_skip(pb, 10);

            ts0= avio_rl64(pb);

            ts1= avio_rl64(pb);

            avio_skip(pb, 12);

            avio_rl32(pb);

            avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);

            if(ts0!= -1) asf->packet_frag_timestamp= ts0/10000;

            else         asf->packet_frag_timestamp= AV_NOPTS_VALUE;

        }else

            avio_skip(pb, asf->packet_replic_size - 8);

        rsize += asf->packet_replic_size; // FIXME - check validity

    } else if (asf->packet_replic_size==1){

        // multipacket - frag_offset is beginning timestamp

        asf->packet_time_start = asf->packet_frag_offset;

        asf->packet_frag_offset = 0;

        asf->packet_frag_timestamp = asf->packet_timestamp;

        asf->packet_time_delta = avio_r8(pb);

        rsize++;

    }else if(asf->packet_replic_size!=0){

        av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", asf->packet_replic_size);

    if (asf->packet_flags & 0x01) {

        DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal

        if(asf->packet_frag_size > asf->packet_size_left - rsize){

            if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) {

                av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", asf->packet_size_left, rsize);

            } else {

                int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);

                asf->packet_size_left += diff;

                asf->packet_padsize   -= diff;

        //printf("Fragsize %d\n", asf->packet_frag_size);

    } else {

        asf->packet_frag_size = asf->packet_size_left - rsize;

        //printf("Using rest  %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize);

    if (asf->packet_replic_size == 1) {

        asf->packet_multi_size = asf->packet_frag_size;

        if (asf->packet_multi_size > asf->packet_size_left)

    asf->packet_size_left -= rsize;

    //printf("___objsize____  %d   %d    rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize);

    return 0;


static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y)

{

    YuvPixel p;

    const int y0 = y * mp->avctx->width;

    int w, i, x = 0;

    p = mp->vpt[y];

    if (mp->changes_map[y0 + x] == 0) {

        memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale));

        ++x;

    }

    while (x < mp->avctx->width) {

        w = mp->changes_map[y0 + x];

        if (w != 0) {

            if ((y & 3) == 0) {

                if (mp->changes_map[y0 + x + mp->avctx->width] < w ||

                    mp->changes_map[y0 + x + mp->avctx->width * 2] < w ||

                    mp->changes_map[y0 + x + mp->avctx->width * 3] < w) {

                    for (i = (x + 3) & ~3; i < x + w; i += 4) {

                        mp->hpt[((y / 4) * mp->avctx->width + i) / 4] = mp_get_yuv_from_rgb(mp, i, y);

                    }

                }

            }

            x += w;

            memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale));

            p = mp_get_yuv_from_rgb(mp, x - 1, y);

        } else {

            p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb));

            if ((x & 3) == 0) {

                if ((y & 3) == 0) {

                    p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb));

                    p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb));

                    mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p;

                } else {

                    p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v;

                    p.u = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].u;

                }

            }

            mp_set_rgb_from_yuv(mp, x, y, &p);

            ++x;

        }

    }

}


int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)

{

    uint64_t *copy;

    copy = g_malloc(sizeof(value));

    *copy = cpu_to_le64(value);

    return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));

}


void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)

{

    const char *codec_type;

    const char *codec_name;

    const char *profile = NULL;

    const AVCodec *p;

    int64_t bitrate;

    int new_line = 0;

    AVRational display_aspect_ratio;

    const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", ";

    if (!buf || buf_size <= 0)

        return;

    codec_type = av_get_media_type_string(enc->codec_type);

    codec_name = avcodec_get_name(enc->codec_id);

    if (enc->profile != FF_PROFILE_UNKNOWN) {

        if (enc->codec)

            p = enc->codec;

        else

            p = encode ? avcodec_find_encoder(enc->codec_id) :

                        avcodec_find_decoder(enc->codec_id);

        if (p)

            profile = av_get_profile_name(p, enc->profile);

    }

    snprintf(buf, buf_size, "%s: %s", codec_type ? codec_type : "unknown",

             codec_name);

    buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */

    if (enc->codec && strcmp(enc->codec->name, codec_name))

        snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", enc->codec->name);

    if (profile)

        snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile);

    if (   enc->codec_type == AVMEDIA_TYPE_VIDEO

        && av_log_get_level() >= AV_LOG_VERBOSE

        && enc->refs)

        snprintf(buf + strlen(buf), buf_size - strlen(buf),

                 ", %d reference frame%s",

                 enc->refs, enc->refs > 1 ? "s" : "");

    if (enc->codec_tag) {

        char tag_buf[32];

        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag);

        snprintf(buf + strlen(buf), buf_size - strlen(buf),

                 " (%s / 0x%04X)", tag_buf, enc->codec_tag);

    }

    switch (enc->codec_type) {

    case AVMEDIA_TYPE_VIDEO:

        {

            char detail[256] = "(";

            av_strlcat(buf, separator, buf_size);

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                 "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" :

                     av_get_pix_fmt_name(enc->pix_fmt));

            if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE &&

                enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth)

                av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample);

            if (enc->color_range != AVCOL_RANGE_UNSPECIFIED)

                av_strlcatf(detail, sizeof(detail), "%s, ",

                            av_color_range_name(enc->color_range));

            if (enc->colorspace != AVCOL_SPC_UNSPECIFIED ||

                enc->color_primaries != AVCOL_PRI_UNSPECIFIED ||

                enc->color_trc != AVCOL_TRC_UNSPECIFIED) {

                if (enc->colorspace != (int)enc->color_primaries ||

                    enc->colorspace != (int)enc->color_trc) {

                    new_line = 1;

                    av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ",

                                av_color_space_name(enc->colorspace),

                                av_color_primaries_name(enc->color_primaries),

                                av_color_transfer_name(enc->color_trc));

                } else

                    av_strlcatf(detail, sizeof(detail), "%s, ",

                                av_get_colorspace_name(enc->colorspace));

            }

            if (av_log_get_level() >= AV_LOG_DEBUG &&

                enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)

                av_strlcatf(detail, sizeof(detail), "%s, ",

                            av_chroma_location_name(enc->chroma_sample_location));

            if (strlen(detail) > 1) {

                detail[strlen(detail) - 2] = 0;

                av_strlcatf(buf, buf_size, "%s)", detail);

            }

        }

        if (enc->width) {

            av_strlcat(buf, new_line ? separator : ", ", buf_size);

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     "%dx%d",

                     enc->width, enc->height);

            if (av_log_get_level() >= AV_LOG_VERBOSE &&

                (enc->width != enc->coded_width ||

                 enc->height != enc->coded_height))

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         " (%dx%d)", enc->coded_width, enc->coded_height);

            if (enc->sample_aspect_ratio.num) {

                av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,

                          enc->width * enc->sample_aspect_ratio.num,

                          enc->height * enc->sample_aspect_ratio.den,

                          1024 * 1024);

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         " [SAR %d:%d DAR %d:%d]",

                         enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den,

                         display_aspect_ratio.num, display_aspect_ratio.den);

            }

            if (av_log_get_level() >= AV_LOG_DEBUG) {

                int g = av_gcd(enc->time_base.num, enc->time_base.den);

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         ", %d/%d",

                         enc->time_base.num / g, enc->time_base.den / g);

            }

        }

        if (encode) {

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     ", q=%d-%d", enc->qmin, enc->qmax);

        } else {

            if (enc->properties & FF_CODEC_PROPERTY_CLOSED_CAPTIONS)

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         ", Closed Captions");

            if (enc->properties & FF_CODEC_PROPERTY_LOSSLESS)

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         ", lossless");

        }

        break;

    case AVMEDIA_TYPE_AUDIO:

        av_strlcat(buf, separator, buf_size);

        if (enc->sample_rate) {

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     "%d Hz, ", enc->sample_rate);

        }

        av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout);

        if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) {

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     ", %s", av_get_sample_fmt_name(enc->sample_fmt));

        }

        if (   enc->bits_per_raw_sample > 0

            && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8)

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     " (%d bit)", enc->bits_per_raw_sample);

        break;

    case AVMEDIA_TYPE_DATA:

        if (av_log_get_level() >= AV_LOG_DEBUG) {

            int g = av_gcd(enc->time_base.num, enc->time_base.den);

            if (g)

                snprintf(buf + strlen(buf), buf_size - strlen(buf),

                         ", %d/%d",

                         enc->time_base.num / g, enc->time_base.den / g);

        }

        break;

    case AVMEDIA_TYPE_SUBTITLE:

        if (enc->width)

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     ", %dx%d", enc->width, enc->height);

        break;

    default:

        return;

    }

    if (encode) {

        if (enc->flags & AV_CODEC_FLAG_PASS1)

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     ", pass 1");

        if (enc->flags & AV_CODEC_FLAG_PASS2)

            snprintf(buf + strlen(buf), buf_size - strlen(buf),

                     ", pass 2");

    }

    bitrate = get_bit_rate(enc);

    if (bitrate != 0) {

        snprintf(buf + strlen(buf), buf_size - strlen(buf),

                 ", %"PRId64" kb/s", bitrate / 1000);

    } else if (enc->rc_max_rate > 0) {

        snprintf(buf + strlen(buf), buf_size - strlen(buf),

                 ", max. %"PRId64" kb/s", (int64_t)enc->rc_max_rate / 1000);

    }

}


static uint16_t nvme_del_sq(NvmeCtrl *n, NvmeCmd *cmd)

{

    NvmeDeleteQ *c = (NvmeDeleteQ *)cmd;

    NvmeRequest *req, *next;

    NvmeSQueue *sq;

    NvmeCQueue *cq;

    uint16_t qid = le16_to_cpu(c->qid);

    if (!qid || nvme_check_sqid(n, qid)) {

        return NVME_INVALID_QID | NVME_DNR;

    }

    sq = n->sq[qid];

    while (!QTAILQ_EMPTY(&sq->out_req_list)) {

        req = QTAILQ_FIRST(&sq->out_req_list);

        assert(req->aiocb);

        bdrv_aio_cancel(req->aiocb);

    }

    if (!nvme_check_cqid(n, sq->cqid)) {

        cq = n->cq[sq->cqid];

        QTAILQ_REMOVE(&cq->sq_list, sq, entry);

        nvme_post_cqes(cq);

        QTAILQ_FOREACH_SAFE(req, &cq->req_list, entry, next) {

            if (req->sq == sq) {

                QTAILQ_REMOVE(&cq->req_list, req, entry);

                QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);

            }

        }

    }

    nvme_free_sq(sq, n);

    return NVME_SUCCESS;

}


static void qmp_query_auth(VncDisplay *vd, VncInfo2 *info)

{

    switch (vd->auth) {

    case VNC_AUTH_VNC:

        info->auth = VNC_PRIMARY_AUTH_VNC;

        break;

    case VNC_AUTH_RA2:

        info->auth = VNC_PRIMARY_AUTH_RA2;

        break;

    case VNC_AUTH_RA2NE:

        info->auth = VNC_PRIMARY_AUTH_RA2NE;

        break;

    case VNC_AUTH_TIGHT:

        info->auth = VNC_PRIMARY_AUTH_TIGHT;

        break;

    case VNC_AUTH_ULTRA:

        info->auth = VNC_PRIMARY_AUTH_ULTRA;

        break;

    case VNC_AUTH_TLS:

        info->auth = VNC_PRIMARY_AUTH_TLS;

        break;

    case VNC_AUTH_VENCRYPT:

        info->auth = VNC_PRIMARY_AUTH_VENCRYPT;

        info->has_vencrypt = true;

        switch (vd->subauth) {

        case VNC_AUTH_VENCRYPT_PLAIN:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_PLAIN;

            break;

        case VNC_AUTH_VENCRYPT_TLSNONE:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_NONE;

            break;

        case VNC_AUTH_VENCRYPT_TLSVNC:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_VNC;

            break;

        case VNC_AUTH_VENCRYPT_TLSPLAIN:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_PLAIN;

            break;

        case VNC_AUTH_VENCRYPT_X509NONE:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_NONE;

            break;

        case VNC_AUTH_VENCRYPT_X509VNC:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_VNC;

            break;

        case VNC_AUTH_VENCRYPT_X509PLAIN:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_PLAIN;

            break;

        case VNC_AUTH_VENCRYPT_TLSSASL:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_TLS_SASL;

            break;

        case VNC_AUTH_VENCRYPT_X509SASL:

            info->vencrypt = VNC_VENCRYPT_SUB_AUTH_X509_SASL;

            break;

        default:

            info->has_vencrypt = false;

            break;

        }

        break;

    case VNC_AUTH_SASL:

        info->auth = VNC_PRIMARY_AUTH_SASL;

        break;

    case VNC_AUTH_NONE:

    default:

        info->auth = VNC_PRIMARY_AUTH_NONE;

        break;

    }

}


static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)

{

    TCGv_i32 r_src1, r_src2;

    TCGv_i64 r_temp, r_temp2;

    r_src1 = tcg_temp_new_i32();

    r_src2 = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(r_src1, src1);

    tcg_gen_trunc_tl_i32(r_src2, src2);

    r_temp = tcg_temp_new_i64();

    r_temp2 = tcg_temp_new_i64();

    if (sign_ext) {

        tcg_gen_ext_i32_i64(r_temp, r_src2);

        tcg_gen_ext_i32_i64(r_temp2, r_src1);

    } else {

        tcg_gen_extu_i32_i64(r_temp, r_src2);

        tcg_gen_extu_i32_i64(r_temp2, r_src1);

    }

    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);

    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);

    tcg_temp_free_i64(r_temp);

    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);

    tcg_gen_trunc_i64_tl(dst, r_temp2);

    tcg_temp_free_i64(r_temp2);

    tcg_temp_free_i32(r_src1);

    tcg_temp_free_i32(r_src2);

}


AioContext *aio_context_new(void)

{

    return (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));

}


static int check_refcounts_l1(BlockDriverState *bs,

                              BdrvCheckResult *res,

                              uint16_t *refcount_table,

                              int refcount_table_size,

                              int64_t l1_table_offset, int l1_size,

                              int flags)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l1_table, l2_offset, l1_size2;

    int i, ret;

    l1_size2 = l1_size * sizeof(uint64_t);

    /* Mark L1 table as used */

    inc_refcounts(bs, res, refcount_table, refcount_table_size,

        l1_table_offset, l1_size2);

    /* Read L1 table entries from disk */

    if (l1_size2 == 0) {

        l1_table = NULL;

    } else {

        l1_table = g_try_malloc(l1_size2);

        if (l1_table == NULL) {

            ret = -ENOMEM;

            goto fail;

        }

        if (bdrv_pread(bs->file, l1_table_offset,

                       l1_table, l1_size2) != l1_size2)

            goto fail;

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

            be64_to_cpus(&l1_table[i]);

    }

    /* Do the actual checks */

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

        l2_offset = l1_table[i];

        if (l2_offset) {

            /* Mark L2 table as used */

            l2_offset &= L1E_OFFSET_MASK;

            inc_refcounts(bs, res, refcount_table, refcount_table_size,

                l2_offset, s->cluster_size);

            /* L2 tables are cluster aligned */

            if (offset_into_cluster(s, l2_offset)) {

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

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

                res->corruptions++;

            }

            /* Process and check L2 entries */

            ret = check_refcounts_l2(bs, res, refcount_table,

                                     refcount_table_size, l2_offset, flags);

            if (ret < 0) {

                goto fail;

            }

        }

    }

    g_free(l1_table);

    return 0;

fail:

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

    res->check_errors++;

    g_free(l1_table);

    return -EIO;

}


void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params)

{

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    PCIBus *pci_bus;

    CPUPPCState *env = NULL;

    uint64_t elf_entry;

    uint64_t elf_lowaddr;

    hwaddr entry=0;

    hwaddr loadaddr=UIMAGE_LOAD_BASE;

    target_long kernel_size=0;

    target_ulong dt_base = 0;

    target_ulong initrd_base = 0;

    target_long initrd_size = 0;

    target_ulong cur_base = 0;

    int i;

    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};

    qemu_irq **irqs, *mpic;

    DeviceState *dev;

    CPUPPCState *firstenv = NULL;

    MemoryRegion *ccsr_addr_space;

    SysBusDevice *s;

    PPCE500CCSRState *ccsr;

    /* Setup CPUs */

    if (args->cpu_model == NULL) {

        args->cpu_model = "e500v2_v30";

    }

    irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));

    irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);

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

        PowerPCCPU *cpu;

        CPUState *cs;

        qemu_irq *input;

        cpu = cpu_ppc_init(args->cpu_model);

        if (cpu == NULL) {

            fprintf(stderr, "Unable to initialize CPU!\n");

            exit(1);

        }

        env = &cpu->env;

        cs = CPU(cpu);

        if (!firstenv) {

            firstenv = env;

        }

        irqs[i] = irqs[0] + (i * OPENPIC_OUTPUT_NB);

        input = (qemu_irq *)env->irq_inputs;

        irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT];

        irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT];

        env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i;

        env->mpic_iack = MPC8544_CCSRBAR_BASE +

                         MPC8544_MPIC_REGS_OFFSET + 0xa0;

        ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500);

        /* Register reset handler */

        if (!i) {

            /* Primary CPU */

            struct boot_info *boot_info;

            boot_info = g_malloc0(sizeof(struct boot_info));

            qemu_register_reset(ppce500_cpu_reset, cpu);

            env->load_info = boot_info;

        } else {

            /* Secondary CPUs */

            qemu_register_reset(ppce500_cpu_reset_sec, cpu);

        }

    }

    env = firstenv;

    /* Fixup Memory size on a alignment boundary */

    ram_size &= ~(RAM_SIZES_ALIGN - 1);

    args->ram_size = ram_size;

    /* Register Memory */

    memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(address_space_mem, 0, ram);

    dev = qdev_create(NULL, "e500-ccsr");

    object_property_add_child(qdev_get_machine(), "e500-ccsr",

                              OBJECT(dev), NULL);

    qdev_init_nofail(dev);

    ccsr = CCSR(dev);

    ccsr_addr_space = &ccsr->ccsr_space;

    memory_region_add_subregion(address_space_mem, MPC8544_CCSRBAR_BASE,

                                ccsr_addr_space);

    mpic = ppce500_init_mpic(params, ccsr_addr_space, irqs);

    /* Serial */

    if (serial_hds[0]) {

        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL0_REGS_OFFSET,

                       0, mpic[42], 399193,

                       serial_hds[0], DEVICE_BIG_ENDIAN);

    }

    if (serial_hds[1]) {

        serial_mm_init(ccsr_addr_space, MPC8544_SERIAL1_REGS_OFFSET,

                       0, mpic[42], 399193,

                       serial_hds[1], DEVICE_BIG_ENDIAN);

    }

    /* General Utility device */

    dev = qdev_create(NULL, "mpc8544-guts");

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    memory_region_add_subregion(ccsr_addr_space, MPC8544_UTIL_OFFSET,

                                sysbus_mmio_get_region(s, 0));

    /* PCI */

    dev = qdev_create(NULL, "e500-pcihost");

    qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    sysbus_connect_irq(s, 0, mpic[pci_irq_nrs[0]]);

    sysbus_connect_irq(s, 1, mpic[pci_irq_nrs[1]]);

    sysbus_connect_irq(s, 2, mpic[pci_irq_nrs[2]]);

    sysbus_connect_irq(s, 3, mpic[pci_irq_nrs[3]]);

    memory_region_add_subregion(ccsr_addr_space, MPC8544_PCI_REGS_OFFSET,

                                sysbus_mmio_get_region(s, 0));

    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");

    if (!pci_bus)

        printf("couldn't create PCI controller!\n");

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, MPC8544_PCI_IO);

    if (pci_bus) {

        /* Register network interfaces. */

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

            pci_nic_init_nofail(&nd_table[i], pci_bus, "virtio", NULL);

        }

    }

    /* Register spinning region */

    sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);

    /* Load kernel. */

    if (args->kernel_filename) {

        kernel_size = load_uimage(args->kernel_filename, &entry,

                                  &loadaddr, NULL);

        if (kernel_size < 0) {

            kernel_size = load_elf(args->kernel_filename, NULL, NULL,

                                   &elf_entry, &elf_lowaddr, NULL, 1,

                                   ELF_MACHINE, 0);

            entry = elf_entry;

            loadaddr = elf_lowaddr;

        }

        /* XXX try again as binary */

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    args->kernel_filename);

            exit(1);

        }

        cur_base = loadaddr + kernel_size;

        /* Reserve space for dtb */

        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;

        cur_base += DTB_MAX_SIZE;

    }

    /* Load initrd. */

    if (args->initrd_filename) {

        initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;

        initrd_size = load_image_targphys(args->initrd_filename, initrd_base,

                                          ram_size - initrd_base);

        if (initrd_size < 0) {

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

                    args->initrd_filename);

            exit(1);

        }

        cur_base = initrd_base + initrd_size;

    }

    /* If we're loading a kernel directly, we must load the device tree too. */

    if (args->kernel_filename) {

        struct boot_info *boot_info;

        int dt_size;

        dt_size = ppce500_load_device_tree(env, args, params, dt_base,

                                           initrd_base, initrd_size);

        if (dt_size < 0) {

            fprintf(stderr, "couldn't load device tree\n");

            exit(1);

        }

        assert(dt_size < DTB_MAX_SIZE);

        boot_info = env->load_info;

        boot_info->entry = entry;

        boot_info->dt_base = dt_base;

        boot_info->dt_size = dt_size;

    }

    if (kvm_enabled()) {

        kvmppc_init();

    }

}


static int write_f(BlockBackend *blk, int argc, char **argv)

{

    struct timeval t1, t2;

    int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0;

    int cflag = 0;

    int c, cnt;

    char *buf = NULL;

    int64_t offset;

    int count;

    /* Some compilers get confused and warn if this is not initialized.  */

    int total = 0;

    int pattern = 0xcd;

    while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) {

        switch (c) {

        case 'b':

            bflag = 1;

            break;

        case 'c':

            cflag = 1;

            break;

        case 'C':

            Cflag = 1;

            break;

        case 'p':

            pflag = 1;

            break;

        case 'P':

            Pflag = 1;

            pattern = parse_pattern(optarg);

            if (pattern < 0) {

                return 0;

            }

            break;

        case 'q':

            qflag = 1;

            break;

        case 'z':

            zflag = 1;

            break;

        default:

            return qemuio_command_usage(&write_cmd);

        }

    }

    if (optind != argc - 2) {

        return qemuio_command_usage(&write_cmd);

    }

    if (bflag + pflag + zflag > 1) {

        printf("-b, -p, or -z cannot be specified at the same time\n");

        return 0;

    }

    if (zflag && Pflag) {

        printf("-z and -P cannot be specified at the same time\n");

        return 0;

    }

    offset = cvtnum(argv[optind]);

    if (offset < 0) {

        printf("non-numeric length argument -- %s\n", argv[optind]);

        return 0;

    }

    optind++;

    count = cvtnum(argv[optind]);

    if (count < 0) {

        printf("non-numeric length argument -- %s\n", argv[optind]);

        return 0;

    }

    if (!pflag) {

        if (offset & 0x1ff) {

            printf("offset %" PRId64 " is not sector aligned\n",

                   offset);

            return 0;

        }

        if (count & 0x1ff) {

            printf("count %d is not sector aligned\n",

                   count);

            return 0;

        }

    }

    if (!zflag) {

        buf = qemu_io_alloc(blk, count, pattern);

    }

    gettimeofday(&t1, NULL);

    if (pflag) {

        cnt = do_pwrite(blk, buf, offset, count, &total);

    } else if (bflag) {

        cnt = do_save_vmstate(blk, buf, offset, count, &total);

    } else if (zflag) {

        cnt = do_co_write_zeroes(blk, offset, count, &total);

    } else if (cflag) {

        cnt = do_write_compressed(blk, buf, offset, count, &total);

    } else {

        cnt = do_write(blk, buf, offset, count, &total);

    }

    gettimeofday(&t2, NULL);

    if (cnt < 0) {

        printf("write failed: %s\n", strerror(-cnt));

        goto out;

    }

    if (qflag) {

        goto out;

    }

    /* Finally, report back -- -C gives a parsable format */

    t2 = tsub(t2, t1);

    print_report("wrote", &t2, offset, count, total, cnt, Cflag);

out:

    if (!zflag) {

        qemu_io_free(buf);

    }

    return 0;

}


static int lance_init(SysBusDevice *dev)

{

    SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);

    PCNetState *s = &d->state;

    memory_region_init_io(&s->mmio, &lance_mem_ops, s, "lance-mmio", 4);

    qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);

    sysbus_init_mmio_region(dev, &s->mmio);

    sysbus_init_irq(dev, &s->irq);

    s->phys_mem_read = ledma_memory_read;

    s->phys_mem_write = ledma_memory_write;

    return pcnet_common_init(&dev->qdev, s, &net_lance_info);

}


static int decode_slice_header(H264Context *h, H264Context *h0)

{

    unsigned int first_mb_in_slice;

    unsigned int pps_id;

    int ret;

    unsigned int slice_type, tmp, i, j;

    int default_ref_list_done = 0;

    int last_pic_structure, last_pic_droppable;

    int needs_reinit = 0;

    int field_pic_flag, bottom_field_flag;

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

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

    first_mb_in_slice = get_ue_golomb(&h->gb);

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

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

            field_end(h, 1);

        }

        h0->current_slice = 0;

        if (!h0->first_field) {

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

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

                                          h->picture_structure == PICT_BOTTOM_FIELD);

            }

            h->cur_pic_ptr = NULL;

        }

    }

    slice_type = get_ue_golomb_31(&h->gb);

    if (slice_type > 9) {

        av_log(h->avctx, AV_LOG_ERROR,

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

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

        return AVERROR_INVALIDDATA;

    }

    if (slice_type > 4) {

        slice_type -= 5;

        h->slice_type_fixed = 1;

    } else

        h->slice_type_fixed = 0;

    slice_type = golomb_to_pict_type[slice_type];

    if (slice_type == AV_PICTURE_TYPE_I ||

        (h0->current_slice != 0 && slice_type == h0->last_slice_type)) {

        default_ref_list_done = 1;

    }

    h->slice_type     = slice_type;

    h->slice_type_nos = slice_type & 3;

    if (h->nal_unit_type  == NAL_IDR_SLICE &&

        h->slice_type_nos != AV_PICTURE_TYPE_I) {

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

        return AVERROR_INVALIDDATA;

    }

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

    h->pict_type = h->slice_type;

    pps_id = get_ue_golomb(&h->gb);

    if (pps_id >= MAX_PPS_COUNT) {

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

        return AVERROR_INVALIDDATA;

    }

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

        av_log(h->avctx, AV_LOG_ERROR,

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

               pps_id);

        return AVERROR_INVALIDDATA;

    }

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

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

        av_log(h->avctx, AV_LOG_ERROR,

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

               h->pps.sps_id);

        return AVERROR_INVALIDDATA;

    }

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

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

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

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

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

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

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

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

            needs_reinit         = 1;

        }

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

            return ret;

    }

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

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

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

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

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

        needs_reinit = 1;

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

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

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

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

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

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

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

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

    ret = init_dimensions(h);

    if (ret < 0)

        return ret;

    if (h->sps.video_signal_type_present_flag) {

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

                                                  : AVCOL_RANGE_MPEG;

        if (h->sps.colour_description_present_flag) {

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

                needs_reinit = 1;

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

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

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

        }

    }

    if (h->context_initialized &&

        (h->width  != h->avctx->coded_width   ||

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

         needs_reinit)) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

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

                   "slice %d\n",

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

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

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

        flush_change(h);

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

            return ret;

        h->avctx->pix_fmt = ret;

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

               "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt);

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

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (!h->context_initialized) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

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

            return AVERROR_PATCHWELCOME;

        }

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

            return ret;

        h->avctx->pix_fmt = ret;

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

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

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

        h->dequant_coeff_pps = pps_id;

        init_dequant_tables(h);

    }

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

    h->mb_mbaff        = 0;

    h->mb_aff_frame    = 0;

    last_pic_structure = h0->picture_structure;

    last_pic_droppable = h0->droppable;

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

    if (h->sps.frame_mbs_only_flag) {

        h->picture_structure = PICT_FRAME;

    } else {

        field_pic_flag = get_bits1(&h->gb);

        if (field_pic_flag) {

            bottom_field_flag = get_bits1(&h->gb);

            h->picture_structure = PICT_TOP_FIELD + bottom_field_flag;

        } else {

            h->picture_structure = PICT_FRAME;

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

        }

    }

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

    if (h0->current_slice != 0) {

        if (last_pic_structure != h->picture_structure ||

            last_pic_droppable != h->droppable) {

            av_log(h->avctx, AV_LOG_ERROR,

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

                   last_pic_structure, h->picture_structure);

            h->picture_structure = last_pic_structure;

            h->droppable         = last_pic_droppable;

            return AVERROR_INVALIDDATA;

        } else if (!h0->cur_pic_ptr) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "unset cur_pic_ptr on slice %d\n",

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

    } else {

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

         * frames just to throw them away */

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

            int unwrap_prev_frame_num = h->prev_frame_num;

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

            if (unwrap_prev_frame_num > h->frame_num)

                unwrap_prev_frame_num -= max_frame_num;

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

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

                if (unwrap_prev_frame_num < 0)

                    unwrap_prev_frame_num += max_frame_num;

                h->prev_frame_num = unwrap_prev_frame_num;

            }

        }

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

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

         * decode frames as "finished".

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

         * since that can modify s->current_picture_ptr. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

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

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

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

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

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

                 * remain for reference if marked as such. */

                if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {

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

                                              last_pic_structure == PICT_TOP_FIELD);

                }

            } else {

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

                    /* This and previous field were reference, but had

                     * different frame_nums. Consider this field first in

                     * pair. Throw away previous field except for reference

                     * purposes. */

                    if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {

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

                                                  last_pic_structure == PICT_TOP_FIELD);

                    }

                } else {

                    /* Second field in complementary pair */

                    if (!((last_pic_structure   == PICT_TOP_FIELD &&

                           h->picture_structure == PICT_BOTTOM_FIELD) ||

                          (last_pic_structure   == PICT_BOTTOM_FIELD &&

                           h->picture_structure == PICT_TOP_FIELD))) {

                        av_log(h->avctx, AV_LOG_ERROR,

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

                               last_pic_structure, h->picture_structure);

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_INVALIDDATA;

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

                        avpriv_request_sample(h->avctx,

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

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_PATCHWELCOME;

                    }

                }

            }

        }

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

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

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

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

                   h->frame_num, h->prev_frame_num);

            ret = h264_frame_start(h);

            if (ret < 0) {

                h0->first_field = 0;

                return ret;

            }

            h->prev_frame_num++;

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

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

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

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

            ret = ff_generate_sliding_window_mmcos(h, 1);

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

                return ret;

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

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

                return ret;

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

             * in its place.

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

             * many assumptions about there being no actual duplicates.

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

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

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

            if (h->short_ref_count) {

                if (prev) {

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

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

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

                                  prev->f.linesize,

                                  h->avctx->pix_fmt,

                                  h->mb_width  * 16,

                                  h->mb_height * 16);

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

                }

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

            }

        }

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

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

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

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

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

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

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

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

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

                 * remain for reference if marked as such. */

                h0->cur_pic_ptr = NULL;

                h0->first_field = FIELD_PICTURE(h);

            } else {

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

                    /* This and the previous field had different frame_nums.

                     * Consider this field first in pair. Throw away previous

                     * one except for reference purposes. */

                    h0->first_field = 1;

                    h0->cur_pic_ptr = NULL;

                } else {

                    /* Second field in complementary pair */

                    h0->first_field = 0;

                }

            }

        } else {

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

            h0->first_field = FIELD_PICTURE(h);

        }

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

            if (h264_frame_start(h) < 0) {

                h0->first_field = 0;

                return AVERROR_INVALIDDATA;

            }

        } else {

            release_unused_pictures(h, 0);

        }

    }

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

        return ret;

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

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

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

        first_mb_in_slice >= h->mb_num) {

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

        return AVERROR_INVALIDDATA;

    }

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

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

                               FIELD_OR_MBAFF_PICTURE(h);

    if (h->picture_structure == PICT_BOTTOM_FIELD)

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

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

    if (h->picture_structure == PICT_FRAME) {

        h->curr_pic_num = h->frame_num;

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

    } else {

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

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

    }

    if (h->nal_unit_type == NAL_IDR_SLICE)

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

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

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

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

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

    }

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

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

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

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

    }

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

    if (h->pps.redundant_pic_cnt_present)

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

    ret = ff_set_ref_count(h);

    if (ret < 0)

        return ret;

    else if (ret == 1)

        default_ref_list_done = 0;

    if (!default_ref_list_done)

        ff_h264_fill_default_ref_list(h);

    if (h->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(h);

       if (ret < 0) {

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

           return ret;

       }

    }

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

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

         h->slice_type_nos == AV_PICTURE_TYPE_B))

        ff_pred_weight_table(h);

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

             h->slice_type_nos == AV_PICTURE_TYPE_B) {

        implicit_weight_table(h, -1);

    } else {

        h->use_weight = 0;

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

            h->luma_weight_flag[i]   = 0;

            h->chroma_weight_flag[i] = 0;

        }

    }

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

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

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

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

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

    if (h->nal_ref_idc) {

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

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

                                             h0->current_slice == 0);

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

            return AVERROR_INVALIDDATA;

    }

    if (FRAME_MBAFF(h)) {

        ff_h264_fill_mbaff_ref_list(h);

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

            implicit_weight_table(h, 0);

            implicit_weight_table(h, 1);

        }

    }

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

        ff_h264_direct_dist_scale_factor(h);

    ff_h264_direct_ref_list_init(h);

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

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

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

            return AVERROR_INVALIDDATA;

        }

        h->cabac_init_idc = tmp;

    }

    h->last_qscale_diff = 0;

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

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

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

        return AVERROR_INVALIDDATA;

    }

    h->qscale       = tmp;

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

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

    // FIXME qscale / qp ... stuff

    if (h->slice_type == AV_PICTURE_TYPE_SP)

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

    if (h->slice_type == AV_PICTURE_TYPE_SP ||

        h->slice_type == AV_PICTURE_TYPE_SI)

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

    h->deblocking_filter     = 1;

    h->slice_alpha_c0_offset = 52;

    h->slice_beta_offset     = 52;

    if (h->pps.deblocking_filter_parameters_present) {

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR,

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

            return AVERROR_INVALIDDATA;

        }

        h->deblocking_filter = tmp;

        if (h->deblocking_filter < 2)

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

        if (h->deblocking_filter) {

            h->slice_alpha_c0_offset += get_se_golomb(&h->gb) << 1;

            h->slice_beta_offset     += get_se_golomb(&h->gb) << 1;

            if (h->slice_alpha_c0_offset > 104U ||

                h->slice_beta_offset     > 104U) {

                av_log(h->avctx, AV_LOG_ERROR,

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

                       h->slice_alpha_c0_offset, h->slice_beta_offset);

                return AVERROR_INVALIDDATA;

            }

        }

    }

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

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

         h->slice_type_nos != AV_PICTURE_TYPE_I) ||

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

         h->slice_type_nos == AV_PICTURE_TYPE_B) ||

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

         h->nal_ref_idc == 0))

        h->deblocking_filter = 0;

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

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

            /* Cheat slightly for speed:

             * Do not bother to deblock across slices. */

            h->deblocking_filter = 2;

        } else {

            h0->max_contexts = 1;

            if (!h0->single_decode_warning) {

                av_log(h->avctx, AV_LOG_INFO,

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

                h0->single_decode_warning = 1;

            }

            if (h != h0) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "Deblocking switched inside frame.\n");

                return 1;

            }

        }

    }

    h->qp_thresh = 15 + 52 -

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

                   FFMAX3(0,

                          h->pps.chroma_qp_index_offset[0],

                          h->pps.chroma_qp_index_offset[1]) +

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

    h0->last_slice_type = slice_type;

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

    if (h->slice_num >= MAX_SLICES) {

        av_log(h->avctx, AV_LOG_ERROR,

               "Too many slices, increase MAX_SLICES and recompile\n");

    }

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

        int id_list[16];

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

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

            id_list[i] = 60;

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

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

                int k;

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

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

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

                        id_list[i] = k;

                        break;

                    }

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

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

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

                        break;

                    }

            }

        }

        ref2frm[0] =

        ref2frm[1] = -1;

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

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

        ref2frm[18 + 0] =

        ref2frm[18 + 1] = -1;

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

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

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

    }

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

        av_log(h->avctx, AV_LOG_DEBUG,

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

               h->slice_num,

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

               first_mb_in_slice,

               av_get_picture_type_char(h->slice_type),

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

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

               pps_id, h->frame_num,

               h->cur_pic_ptr->field_poc[0],

               h->cur_pic_ptr->field_poc[1],

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

               h->qscale,

               h->deblocking_filter,

               h->slice_alpha_c0_offset / 2 - 26, h->slice_beta_offset / 2 - 26,

               h->use_weight,

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

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

    }

    return 0;

}


void bdrv_drained_begin(BlockDriverState *bs)

{

    if (!bs->quiesce_counter++) {

        aio_disable_external(bdrv_get_aio_context(bs));

        bdrv_parent_drained_begin(bs);

    }

    bdrv_io_unplugged_begin(bs);

    bdrv_drain_recurse(bs);

    if (qemu_in_coroutine()) {

        bdrv_co_yield_to_drain(bs);

    } else {

        bdrv_drain_poll(bs);

    }

    bdrv_io_unplugged_end(bs);

}


static ssize_t block_crypto_init_func(QCryptoBlock *block,

                                      void *opaque,

                                      size_t headerlen,

                                      Error **errp)

{

    struct BlockCryptoCreateData *data = opaque;

    int ret;

    /* User provided size should reflect amount of space made

     * available to the guest, so we must take account of that

     * which will be used by the crypto header

     */

    data->size += headerlen;

    qemu_opt_set_number(data->opts, BLOCK_OPT_SIZE, data->size, &error_abort);

    ret = bdrv_create_file(data->filename, data->opts, errp);

    if (ret < 0) {

        return -1;

    }

    data->blk = blk_new_open(data->filename, NULL, NULL,

                             BDRV_O_RDWR | BDRV_O_PROTOCOL, errp);

    if (!data->blk) {

        return -1;

    }

    return 0;

}


ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size)

{

    RAMBlock *new_block, *block;

    size = TARGET_PAGE_ALIGN(size);

    new_block = qemu_mallocz(sizeof(*new_block));

    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {

        char *id = dev->parent_bus->info->get_dev_path(dev);

        if (id) {

            snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);

            qemu_free(id);

        }

    }

    pstrcat(new_block->idstr, sizeof(new_block->idstr), name);

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        if (!strcmp(block->idstr, new_block->idstr)) {

            fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",

                    new_block->idstr);

            abort();

        }

    }

    if (mem_path) {

#if defined (__linux__) && !defined(TARGET_S390X)

        new_block->host = file_ram_alloc(new_block, size, mem_path);

        if (!new_block->host) {

            new_block->host = qemu_vmalloc(size);

#ifdef MADV_MERGEABLE

            madvise(new_block->host, size, MADV_MERGEABLE);

#endif

        }

#else

        fprintf(stderr, "-mem-path option unsupported\n");

        exit(1);

#endif

    } else {

#if defined(TARGET_S390X) && defined(CONFIG_KVM)

        /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */

        new_block->host = mmap((void*)0x1000000, size,

                                PROT_EXEC|PROT_READ|PROT_WRITE,

                                MAP_SHARED | MAP_ANONYMOUS, -1, 0);

#else

        new_block->host = qemu_vmalloc(size);

#endif

#ifdef MADV_MERGEABLE

        madvise(new_block->host, size, MADV_MERGEABLE);

#endif

    }

    new_block->offset = find_ram_offset(size);

    new_block->length = size;

    QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);

    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,

                                       last_ram_offset() >> TARGET_PAGE_BITS);

    memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),

           0xff, size >> TARGET_PAGE_BITS);

    if (kvm_enabled())

        kvm_setup_guest_memory(new_block->host, size);

    return new_block->offset;

}


void HELPER(ucf64_set_fpscr)(CPUUniCore32State *env, uint32_t val)

{

    int i;

    uint32_t changed;

    changed = env->ucf64.xregs[UC32_UCF64_FPSCR];

    env->ucf64.xregs[UC32_UCF64_FPSCR] = (val & UCF64_FPSCR_MASK);

    changed ^= val;

    if (changed & (UCF64_FPSCR_RND_MASK)) {

        i = UCF64_FPSCR_RND(val);

        switch (i) {

        case 0:

            i = float_round_nearest_even;

            break;

        case 1:

            i = float_round_to_zero;

            break;

        case 2:

            i = float_round_up;

            break;

        case 3:

            i = float_round_down;

            break;

        default: /* 100 and 101 not implement */

            cpu_abort(env, "Unsupported UniCore-F64 round mode");

        }

        set_float_rounding_mode(i, &env->ucf64.fp_status);

    }

    i = ucf64_exceptbits_to_host(UCF64_FPSCR_TRAPEN(val));

    set_float_exception_flags(i, &env->ucf64.fp_status);

}


static void qemu_rbd_close(BlockDriverState *bs)

{

    BDRVRBDState *s = bs->opaque;

    close(s->fds[0]);

    close(s->fds[1]);

    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL, NULL, NULL);

    rbd_close(s->image);

    rados_ioctx_destroy(s->io_ctx);

    g_free(s->snap);

    rados_shutdown(s->cluster);

}


static av_cold int channelmap_init(AVFilterContext *ctx)

{

    ChannelMapContext *s = ctx->priv;

    int ret;

    char *mapping, separator = '|';

    int map_entries = 0;

    char buf[256];

    enum MappingMode mode;

    uint64_t out_ch_mask = 0;

    int i;

    mapping = s->mapping_str;

    if (!mapping) {

        mode = MAP_NONE;

    } else {

        char *dash = strchr(mapping, '-');

        if (!dash) {  // short mapping

            if (av_isdigit(*mapping))

                mode = MAP_ONE_INT;

            else

                mode = MAP_ONE_STR;

        } else if (av_isdigit(*mapping)) {

            if (av_isdigit(*(dash+1)))

                mode = MAP_PAIR_INT_INT;

            else

                mode = MAP_PAIR_INT_STR;

        } else {

            if (av_isdigit(*(dash+1)))

                mode = MAP_PAIR_STR_INT;

            else

                mode = MAP_PAIR_STR_STR;

        }

#if FF_API_OLD_FILTER_OPTS

        if (strchr(mapping, ',')) {

            av_log(ctx, AV_LOG_WARNING, "This syntax is deprecated, use "

                   "'|' to separate the mappings.\n");

            separator = ',';

        }

#endif

    }

    if (mode != MAP_NONE) {

        char *sep = mapping;

        map_entries = 1;

        while ((sep = strchr(sep, separator))) {

            if (*++sep)  // Allow trailing comma

                map_entries++;

        }

    }

    if (map_entries > MAX_CH) {

        av_log(ctx, AV_LOG_ERROR, "Too many channels mapped: '%d'.\n", map_entries);

        ret = AVERROR(EINVAL);

        goto fail;

    }

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

        int in_ch_idx = -1, out_ch_idx = -1;

        uint64_t in_ch = 0, out_ch = 0;

        static const char err[] = "Failed to parse channel map\n";

        switch (mode) {

        case MAP_ONE_INT:

            if (get_channel_idx(&mapping, &in_ch_idx, separator, MAX_CH) < 0) {

                ret = AVERROR(EINVAL);

                av_log(ctx, AV_LOG_ERROR, err);

                goto fail;

            }

            s->map[i].in_channel_idx  = in_ch_idx;

            s->map[i].out_channel_idx = i;

            break;

        case MAP_ONE_STR:

            if (!get_channel(&mapping, &in_ch, separator)) {

                av_log(ctx, AV_LOG_ERROR, err);

                ret = AVERROR(EINVAL);

                goto fail;

            }

            s->map[i].in_channel      = in_ch;

            s->map[i].out_channel_idx = i;

            break;

        case MAP_PAIR_INT_INT:

            if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||

                get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {

                av_log(ctx, AV_LOG_ERROR, err);

                ret = AVERROR(EINVAL);

                goto fail;

            }

            s->map[i].in_channel_idx  = in_ch_idx;

            s->map[i].out_channel_idx = out_ch_idx;

            break;

        case MAP_PAIR_INT_STR:

            if (get_channel_idx(&mapping, &in_ch_idx, '-', MAX_CH) < 0 ||

                get_channel(&mapping, &out_ch, separator) < 0 ||

                out_ch & out_ch_mask) {

                av_log(ctx, AV_LOG_ERROR, err);

                ret = AVERROR(EINVAL);

                goto fail;

            }

            s->map[i].in_channel_idx  = in_ch_idx;

            s->map[i].out_channel     = out_ch;

            out_ch_mask |= out_ch;

            break;

        case MAP_PAIR_STR_INT:

            if (get_channel(&mapping, &in_ch, '-') < 0 ||

                get_channel_idx(&mapping, &out_ch_idx, separator, MAX_CH) < 0) {

                av_log(ctx, AV_LOG_ERROR, err);

                ret = AVERROR(EINVAL);

                goto fail;

            }

            s->map[i].in_channel      = in_ch;

            s->map[i].out_channel_idx = out_ch_idx;

            break;

        case MAP_PAIR_STR_STR:

            if (get_channel(&mapping, &in_ch, '-') < 0 ||

                get_channel(&mapping, &out_ch, separator) < 0 ||

                out_ch & out_ch_mask) {

                av_log(ctx, AV_LOG_ERROR, err);

                ret = AVERROR(EINVAL);

                goto fail;

            }

            s->map[i].in_channel = in_ch;

            s->map[i].out_channel = out_ch;

            out_ch_mask |= out_ch;

            break;

        }

    }

    s->mode          = mode;

    s->nch           = map_entries;

    s->output_layout = out_ch_mask ? out_ch_mask :

                       av_get_default_channel_layout(map_entries);

    if (s->channel_layout_str) {

        uint64_t fmt;

        if ((fmt = av_get_channel_layout(s->channel_layout_str)) == 0) {

            av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout: '%s'.\n",

                   s->channel_layout_str);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        if (mode == MAP_NONE) {

            int i;

            s->nch = av_get_channel_layout_nb_channels(fmt);

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

                s->map[i].in_channel_idx  = i;

                s->map[i].out_channel_idx = i;

            }

        } else if (out_ch_mask && out_ch_mask != fmt) {

            av_get_channel_layout_string(buf, sizeof(buf), 0, out_ch_mask);

            av_log(ctx, AV_LOG_ERROR,

                   "Output channel layout '%s' does not match the list of channel mapped: '%s'.\n",

                   s->channel_layout_str, buf);

            ret = AVERROR(EINVAL);

            goto fail;

        } else if (s->nch != av_get_channel_layout_nb_channels(fmt)) {

            av_log(ctx, AV_LOG_ERROR,

                   "Output channel layout %s does not match the number of channels mapped %d.\n",

                   s->channel_layout_str, s->nch);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        s->output_layout = fmt;

    }

    ff_add_channel_layout(&s->channel_layouts, s->output_layout);

    if (mode == MAP_PAIR_INT_STR || mode == MAP_PAIR_STR_STR) {

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

            s->map[i].out_channel_idx = av_get_channel_layout_channel_index(

                s->output_layout, s->map[i].out_channel);

        }

    }

fail:

    av_opt_free(s);

    return ret;

}


static void pred_weight_table(HEVCContext *s, GetBitContext *gb)

{

    int i = 0;

    int j = 0;

    uint8_t luma_weight_l0_flag[16];

    uint8_t chroma_weight_l0_flag[16];

    uint8_t luma_weight_l1_flag[16];

    uint8_t chroma_weight_l1_flag[16];

    int luma_log2_weight_denom;

    luma_log2_weight_denom = get_ue_golomb_long(gb);

    if (luma_log2_weight_denom < 0 || luma_log2_weight_denom > 7)

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

    s->sh.luma_log2_weight_denom = av_clip_uintp2(luma_log2_weight_denom, 3);

    if (s->ps.sps->chroma_format_idc != 0) {

        int delta = get_se_golomb(gb);

        s->sh.chroma_log2_weight_denom = av_clip_uintp2(s->sh.luma_log2_weight_denom + delta, 3);

    }

    for (i = 0; i < s->sh.nb_refs[L0]; i++) {

        luma_weight_l0_flag[i] = get_bits1(gb);

        if (!luma_weight_l0_flag[i]) {

            s->sh.luma_weight_l0[i] = 1 << s->sh.luma_log2_weight_denom;

            s->sh.luma_offset_l0[i] = 0;

        }

    }

    if (s->ps.sps->chroma_format_idc != 0) {

        for (i = 0; i < s->sh.nb_refs[L0]; i++)

            chroma_weight_l0_flag[i] = get_bits1(gb);

    } else {

        for (i = 0; i < s->sh.nb_refs[L0]; i++)

            chroma_weight_l0_flag[i] = 0;

    }

    for (i = 0; i < s->sh.nb_refs[L0]; i++) {

        if (luma_weight_l0_flag[i]) {

            int delta_luma_weight_l0 = get_se_golomb(gb);

            s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0;

            s->sh.luma_offset_l0[i] = get_se_golomb(gb);

        }

        if (chroma_weight_l0_flag[i]) {

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

                int delta_chroma_weight_l0 = get_se_golomb(gb);

                int delta_chroma_offset_l0 = get_se_golomb(gb);

                s->sh.chroma_weight_l0[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l0;

                s->sh.chroma_offset_l0[i][j] = av_clip((delta_chroma_offset_l0 - ((128 * s->sh.chroma_weight_l0[i][j])

                                                                                >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);

            }

        } else {

            s->sh.chroma_weight_l0[i][0] = 1 << s->sh.chroma_log2_weight_denom;

            s->sh.chroma_offset_l0[i][0] = 0;

            s->sh.chroma_weight_l0[i][1] = 1 << s->sh.chroma_log2_weight_denom;

            s->sh.chroma_offset_l0[i][1] = 0;

        }

    }

    if (s->sh.slice_type == HEVC_SLICE_B) {

        for (i = 0; i < s->sh.nb_refs[L1]; i++) {

            luma_weight_l1_flag[i] = get_bits1(gb);

            if (!luma_weight_l1_flag[i]) {

                s->sh.luma_weight_l1[i] = 1 << s->sh.luma_log2_weight_denom;

                s->sh.luma_offset_l1[i] = 0;

            }

        }

        if (s->ps.sps->chroma_format_idc != 0) {

            for (i = 0; i < s->sh.nb_refs[L1]; i++)

                chroma_weight_l1_flag[i] = get_bits1(gb);

        } else {

            for (i = 0; i < s->sh.nb_refs[L1]; i++)

                chroma_weight_l1_flag[i] = 0;

        }

        for (i = 0; i < s->sh.nb_refs[L1]; i++) {

            if (luma_weight_l1_flag[i]) {

                int delta_luma_weight_l1 = get_se_golomb(gb);

                s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1;

                s->sh.luma_offset_l1[i] = get_se_golomb(gb);

            }

            if (chroma_weight_l1_flag[i]) {

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

                    int delta_chroma_weight_l1 = get_se_golomb(gb);

                    int delta_chroma_offset_l1 = get_se_golomb(gb);

                    s->sh.chroma_weight_l1[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l1;

                    s->sh.chroma_offset_l1[i][j] = av_clip((delta_chroma_offset_l1 - ((128 * s->sh.chroma_weight_l1[i][j])

                                                                                >> s->sh.chroma_log2_weight_denom) + 128), -128, 127);

                }

            } else {

                s->sh.chroma_weight_l1[i][0] = 1 << s->sh.chroma_log2_weight_denom;

                s->sh.chroma_offset_l1[i][0] = 0;

                s->sh.chroma_weight_l1[i][1] = 1 << s->sh.chroma_log2_weight_denom;

                s->sh.chroma_offset_l1[i][1] = 0;

            }

        }

    }

}


void slirp_output(const uint8_t *pkt, int pkt_len)

{

#ifdef DEBUG_SLIRP

    printf("slirp output:\n");

    hex_dump(stdout, pkt, pkt_len);

#endif

    if (!slirp_vc)

        return;

    qemu_send_packet(slirp_vc, pkt, pkt_len);

}