static void ppc_prep_init(QEMUMachineInitArgs *args)

{

    ram_addr_t ram_size = args->ram_size;

    const char *cpu_model = args->cpu_model;

    const char *kernel_filename = args->kernel_filename;

    const char *kernel_cmdline = args->kernel_cmdline;

    const char *initrd_filename = args->initrd_filename;

    const char *boot_device = args->boot_device;

    MemoryRegion *sysmem = get_system_memory();

    PowerPCCPU *cpu = NULL;

    CPUPPCState *env = NULL;

    char *filename;

    nvram_t nvram;

    M48t59State *m48t59;

    MemoryRegion *PPC_io_memory = g_new(MemoryRegion, 1);

    PortioList *port_list = g_new(PortioList, 1);

#if 0

    MemoryRegion *xcsr = g_new(MemoryRegion, 1);

#endif

    int linux_boot, i, nb_nics1, bios_size;

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *bios = g_new(MemoryRegion, 1);

    uint32_t kernel_base, initrd_base;

    long kernel_size, initrd_size;

    DeviceState *dev;

    PCIHostState *pcihost;

    PCIBus *pci_bus;

    PCIDevice *pci;

    ISABus *isa_bus;

    ISADevice *isa;

    qemu_irq *cpu_exit_irq;

    int ppc_boot_device;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    sysctrl = g_malloc0(sizeof(sysctrl_t));

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */

    if (cpu_model == NULL)

        cpu_model = "602";

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

        cpu = cpu_ppc_init(cpu_model);

        if (cpu == NULL) {

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

            exit(1);

        }

        env = &cpu->env;

        if (env->flags & POWERPC_FLAG_RTC_CLK) {

            /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */

            cpu_ppc_tb_init(env, 7812500UL);

        } else {

            /* Set time-base frequency to 100 Mhz */

            cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);

        }

        qemu_register_reset(ppc_prep_reset, cpu);

    }

    /* allocate RAM */

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

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(sysmem, 0, ram);

    /* allocate and load BIOS */

    memory_region_init_ram(bios, NULL, "ppc_prep.bios", BIOS_SIZE);

    memory_region_set_readonly(bios, true);

    memory_region_add_subregion(sysmem, (uint32_t)(-BIOS_SIZE), bios);

    vmstate_register_ram_global(bios);

    if (bios_name == NULL)

        bios_name = BIOS_FILENAME;

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    if (filename) {

        bios_size = load_elf(filename, NULL, NULL, NULL,

                             NULL, NULL, 1, ELF_MACHINE, 0);

        if (bios_size < 0) {

            bios_size = get_image_size(filename);

            if (bios_size > 0 && bios_size <= BIOS_SIZE) {

                hwaddr bios_addr;

                bios_size = (bios_size + 0xfff) & ~0xfff;

                bios_addr = (uint32_t)(-bios_size);

                bios_size = load_image_targphys(filename, bios_addr, bios_size);

            }

            if (bios_size > BIOS_SIZE) {

                fprintf(stderr, "qemu: PReP bios '%s' is too large (0x%x)\n",

                        bios_name, bios_size);

                exit(1);

            }

        }

    } else {

        bios_size = -1;

    }

    if (bios_size < 0 && !qtest_enabled()) {

        fprintf(stderr, "qemu: could not load PPC PReP bios '%s'\n",

                bios_name);

        exit(1);

    }

    if (filename) {

        g_free(filename);

    }

    if (linux_boot) {

        kernel_base = KERNEL_LOAD_ADDR;

        /* now we can load the kernel */

        kernel_size = load_image_targphys(kernel_filename, kernel_base,

                                          ram_size - kernel_base);

        if (kernel_size < 0) {

            hw_error("qemu: could not load kernel '%s'\n", kernel_filename);

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            initrd_base = INITRD_LOAD_ADDR;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              ram_size - initrd_base);

            if (initrd_size < 0) {

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

                          initrd_filename);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

        ppc_boot_device = 'm';

    } else {

        kernel_base = 0;

        kernel_size = 0;

        initrd_base = 0;

        initrd_size = 0;

        ppc_boot_device = '\0';

        /* For now, OHW cannot boot from the network. */

        for (i = 0; boot_device[i] != '\0'; i++) {

            if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {

                ppc_boot_device = boot_device[i];

                break;

            }

        }

        if (ppc_boot_device == '\0') {

            fprintf(stderr, "No valid boot device for Mac99 machine\n");

            exit(1);

        }

    }

    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {

        hw_error("Only 6xx bus is supported on PREP machine\n");

    }

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

    pcihost = PCI_HOST_BRIDGE(dev);

    object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);

    qdev_init_nofail(dev);

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

    if (pci_bus == NULL) {

        fprintf(stderr, "Couldn't create PCI host controller.\n");

        exit(1);

    }

    /* PCI -> ISA bridge */

    pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "i82378");

    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);

    cpu = POWERPC_CPU(first_cpu);

    qdev_connect_gpio_out(&pci->qdev, 0,

                          cpu->env.irq_inputs[PPC6xx_INPUT_INT]);

    qdev_connect_gpio_out(&pci->qdev, 1, *cpu_exit_irq);

    sysbus_connect_irq(&pcihost->busdev, 0, qdev_get_gpio_in(&pci->qdev, 9));

    sysbus_connect_irq(&pcihost->busdev, 1, qdev_get_gpio_in(&pci->qdev, 11));

    sysbus_connect_irq(&pcihost->busdev, 2, qdev_get_gpio_in(&pci->qdev, 9));

    sysbus_connect_irq(&pcihost->busdev, 3, qdev_get_gpio_in(&pci->qdev, 11));

    isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci), "isa.0"));

    /* Super I/O (parallel + serial ports) */

    isa = isa_create(isa_bus, TYPE_PC87312);

    dev = DEVICE(isa);

    qdev_prop_set_uint8(dev, "config", 13); /* fdc, ser0, ser1, par0 */

    qdev_init_nofail(dev);

    /* Register 8 MB of ISA IO space (needed for non-contiguous map) */

    memory_region_init_io(PPC_io_memory, NULL, &PPC_prep_io_ops, sysctrl,

                          "ppc-io", 0x00800000);

    memory_region_add_subregion(sysmem, 0x80000000, PPC_io_memory);

    /* init basic PC hardware */

    pci_vga_init(pci_bus);

    nb_nics1 = nb_nics;

    if (nb_nics1 > NE2000_NB_MAX)

        nb_nics1 = NE2000_NB_MAX;

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

        if (nd_table[i].model == NULL) {

	    nd_table[i].model = g_strdup("ne2k_isa");

        }

        if (strcmp(nd_table[i].model, "ne2k_isa") == 0) {

            isa_ne2000_init(isa_bus, ne2000_io[i], ne2000_irq[i],

                            &nd_table[i]);

        } else {

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

        }

    }

    ide_drive_get(hd, MAX_IDE_BUS);

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

        isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],

                     hd[2 * i],

		     hd[2 * i + 1]);

    }

    isa_create_simple(isa_bus, "i8042");

    cpu = POWERPC_CPU(first_cpu);

    sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];

    portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");

    portio_list_add(port_list, get_system_io(), 0x0);

    /* PowerPC control and status register group */

#if 0

    memory_region_init_io(xcsr, NULL, &PPC_XCSR_ops, NULL, "ppc-xcsr", 0x1000);

    memory_region_add_subregion(sysmem, 0xFEFF0000, xcsr);

#endif

    if (usb_enabled(false)) {

        pci_create_simple(pci_bus, -1, "pci-ohci");

    }

    m48t59 = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);

    if (m48t59 == NULL)

        return;

    sysctrl->nvram = m48t59;

    /* Initialise NVRAM */

    nvram.opaque = m48t59;

    nvram.read_fn = &m48t59_read;

    nvram.write_fn = &m48t59_write;

    PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,

                         kernel_base, kernel_size,

                         kernel_cmdline,

                         initrd_base, initrd_size,

                         /* XXX: need an option to load a NVRAM image */

                         0,

                         graphic_width, graphic_height, graphic_depth);

}


static void smc91c111_cleanup(NetClientState *nc)

{

    smc91c111_state *s = qemu_get_nic_opaque(nc);

    s->nic = NULL;

}


e1000e_setup_tx_offloads(E1000ECore *core, struct e1000e_tx *tx)

{

    if (tx->props.tse && tx->props.cptse) {

        net_tx_pkt_build_vheader(tx->tx_pkt, true, true, tx->props.mss);

        net_tx_pkt_update_ip_checksums(tx->tx_pkt);

        e1000x_inc_reg_if_not_full(core->mac, TSCTC);

        return;

    }

    if (tx->props.sum_needed & E1000_TXD_POPTS_TXSM) {

        net_tx_pkt_build_vheader(tx->tx_pkt, false, true, 0);

    }

    if (tx->props.sum_needed & E1000_TXD_POPTS_IXSM) {

        net_tx_pkt_update_ip_hdr_checksum(tx->tx_pkt);

    }

}


static ssize_t proxy_pwritev(FsContext *ctx, V9fsFidOpenState *fs,

                             const struct iovec *iov,

                             int iovcnt, off_t offset)

{

    ssize_t ret;

#ifdef CONFIG_PREADV

    ret = pwritev(fs->fd, iov, iovcnt, offset);

#else

    ret = lseek(fs->fd, offset, SEEK_SET);

    if (ret >= 0) {

        ret = writev(fs->fd, iov, iovcnt);

    }

#endif

#ifdef CONFIG_SYNC_FILE_RANGE

    if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) {

        /*

         * Initiate a writeback. This is not a data integrity sync.

         * We want to ensure that we don't leave dirty pages in the cache

         * after write when writeout=immediate is sepcified.

         */

        sync_file_range(fs->fd, offset, ret,

                        SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE);

    }

#endif

    return ret;

}


static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,

                             target_ulong eaddr, int rw, int access_type)

{

    ppc6xx_tlb_t *tlb;

    int nr, best, way;

    int ret;

    best = -1;

    ret = -1; /* No TLB found */

    for (way = 0; way < env->nb_ways; way++) {

        nr = ppc6xx_tlb_getnum(env, eaddr, way,

                               access_type == ACCESS_CODE ? 1 : 0);

        tlb = &env->tlb[nr].tlb6;

        /* This test "emulates" the PTE index match for hardware TLBs */

        if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "TLB %d/%d %s [" ADDRX " " ADDRX

                        "] <> " ADDRX "\n",

                        nr, env->nb_tlb,

                        pte_is_valid(tlb->pte0) ? "valid" : "inval",

                        tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);

            }

#endif

            continue;

        }

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "TLB %d/%d %s " ADDRX " <> " ADDRX " " ADDRX

                    " %c %c\n",

                    nr, env->nb_tlb,

                    pte_is_valid(tlb->pte0) ? "valid" : "inval",

                    tlb->EPN, eaddr, tlb->pte1,

                    rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');

        }

#endif

        switch (pte32_check(ctx, tlb->pte0, tlb->pte1, 0, rw)) {

        case -3:

            /* TLB inconsistency */

            return -1;

        case -2:

            /* Access violation */

            ret = -2;

            best = nr;

            break;

        case -1:

        default:

            /* No match */

            break;

        case 0:

            /* access granted */

            /* XXX: we should go on looping to check all TLBs consistency

             *      but we can speed-up the whole thing as the

             *      result would be undefined if TLBs are not consistent.

             */

            ret = 0;

            best = nr;

            goto done;

        }

    }

    if (best != -1) {

    done:

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "found TLB at addr 0x%08lx prot=0x%01x ret=%d\n",

                    ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);

        }

#endif

        /* Update page flags */

        pte_update_flags(ctx, &env->tlb[best].tlb6.pte1, ret, rw);

    }

    return ret;

}


static inline bool media_is_dvd(SCSIDiskState *s)

{

    uint64_t nb_sectors;

    if (s->qdev.type != TYPE_ROM) {

        return false;

    }

    if (!bdrv_is_inserted(s->qdev.conf.bs)) {

        return false;

    }

    bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors);

    return nb_sectors > CD_MAX_SECTORS;

}


int avpriv_exif_decode_ifd(AVCodecContext *avctx, GetByteContext *gbytes, int le,

                           int depth, AVDictionary **metadata)

{

    int i, ret;

    int entries;

    entries = ff_tget_short(gbytes, le);

    if (bytestream2_get_bytes_left(gbytes) < entries * 12) {

        return AVERROR_INVALIDDATA;

    }

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

        if ((ret = exif_decode_tag(avctx, gbytes, le, depth, metadata)) < 0) {

            return ret;

        }

    }

    // return next IDF offset or 0x000000000 or a value < 0 for failure

    return ff_tget_long(gbytes, le);

}


DeviceState *qdev_create(BusState *bus, const char *name)

{

    DeviceType *t;

    DeviceState *dev;

    for (t = device_type_list; t; t = t->next) {

        if (strcmp(t->info->name, name) == 0) {

            break;

        }

    }

    if (!t) {

        hw_error("Unknown device '%s'\n", name);

    }

    dev = qemu_mallocz(t->info->size);

    dev->type = t;

    if (!bus) {

        /* ???: This assumes system busses have no additional state.  */

        if (!main_system_bus) {

            main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState),

                                          NULL, "main-system-bus");

        }

        bus = main_system_bus;

    }

    if (t->info->bus_type != bus->type) {

        /* TODO: Print bus type names.  */

        hw_error("Device '%s' on wrong bus type (%d/%d)", name,

                 t->info->bus_type, bus->type);

    }

    dev->parent_bus = bus;

    LIST_INSERT_HEAD(&bus->children, dev, sibling);

    return dev;

}


static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri)

{

    if (ri->opc2 & 4) {

        /* Other states are only available with TrustZone; in

         * a non-TZ implementation these registers don't exist

         * at all, which is an Uncategorized trap. This underdecoding

         * is safe because the reginfo is NO_MIGRATE.

         */

        return CP_ACCESS_TRAP_UNCATEGORIZED;

    }

    return CP_ACCESS_OK;

}


on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming)

{

    uint32_t *capabilities = (incoming->capabilities);

    int num_capabilities =

        1 + ((mhHeader->length - sizeof(VSCMsgInit)) / sizeof(uint32_t));

    int i;

    QemuThread thread_id;

    incoming->version = ntohl(incoming->version);

    if (incoming->version != VSCARD_VERSION) {

        if (verbose > 0) {

            printf("warning: host has version %d, we have %d\n",

                verbose, VSCARD_VERSION);

        }

    }

    if (incoming->magic != VSCARD_MAGIC) {

        printf("unexpected magic: got %d, expected %d\n",

            incoming->magic, VSCARD_MAGIC);

        return -1;

    }

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

        capabilities[i] = ntohl(capabilities[i]);

    }

    /* Future: check capabilities */

    /* remove whatever reader might be left in qemu,

     * in case of an unclean previous exit. */

    send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0);

    /* launch the event_thread. This will trigger reader adds for all the

     * existing readers */

    qemu_thread_create(&thread_id, "vsc/event", event_thread, NULL, 0);

    return 0;

}


static GenericList *qmp_input_next_list(Visitor *v, GenericList *tail,

                                        size_t size)

{

    QmpInputVisitor *qiv = to_qiv(v);

    StackObject *so = &qiv->stack[qiv->nb_stack - 1];

    if (!so->entry) {

        return NULL;

    }

    tail->next = g_malloc0(size);

    return tail->next;

}


static size_t handle_aiocb_ioctl(struct qemu_paiocb *aiocb)

{

	int ret;

	ret = ioctl(aiocb->aio_fildes, aiocb->aio_ioctl_cmd, aiocb->aio_ioctl_buf);

	if (ret == -1)

		return -errno;

	/*

	 * This looks weird, but the aio code only consideres a request

	 * successfull if it has written the number full number of bytes.

	 *

	 * Now we overload aio_nbytes as aio_ioctl_cmd for the ioctl command,

	 * so in fact we return the ioctl command here to make posix_aio_read()

	 * happy..

	 */

	return aiocb->aio_nbytes;

}


static always_inline void gen_load_mem (DisasContext *ctx,

                                        void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1, int flags),

                                        int ra, int rb, int32_t disp16,

                                        int fp, int clear)

{

    TCGv addr;

    if (unlikely(ra == 31))

        return;

    addr = tcg_temp_new(TCG_TYPE_I64);

    if (rb != 31) {

        tcg_gen_addi_i64(addr, cpu_ir[rb], disp16);

        if (clear)

            tcg_gen_andi_i64(addr, addr, ~0x7);

    } else {

        if (clear)

            disp16 &= ~0x7;

        tcg_gen_movi_i64(addr, disp16);

    }

    if (fp)

        tcg_gen_qemu_load(cpu_fir[ra], addr, ctx->mem_idx);

    else

        tcg_gen_qemu_load(cpu_ir[ra], addr, ctx->mem_idx);

    tcg_temp_free(addr);

}


int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,

                          int flags)

{

    target_ulong len_mask = ~(len - 1);

    CPUWatchpoint *wp;

    TAILQ_FOREACH(wp, &env->watchpoints, entry) {

        if (addr == wp->vaddr && len_mask == wp->len_mask

                && flags == (wp->flags & ~BP_WATCHPOINT_HIT)) {

            cpu_watchpoint_remove_by_ref(env, wp);

            return 0;

        }

    }

    return -ENOENT;

}


static int segment_start(AVFormatContext *s, int write_header)

{

    SegmentContext *c = s->priv_data;

    AVFormatContext *oc = c->avf;

    int err = 0;

    if (write_header) {

        avformat_free_context(oc);

        c->avf = NULL;

        if ((err = segment_mux_init(s)) < 0)

            return err;

        oc = c->avf;

    }

    if (c->wrap)

        c->number %= c->wrap;

    if (av_get_frame_filename(oc->filename, sizeof(oc->filename),

                              s->filename, c->number++) < 0)

        return AVERROR(EINVAL);

    if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,

                          &s->interrupt_callback, NULL)) < 0)

        return err;

    if (oc->oformat->priv_class && oc->priv_data)

        av_opt_set(oc->priv_data, "resend_headers", "1", 0); /* mpegts specific */

    if (write_header) {

        if ((err = avformat_write_header(oc, NULL)) < 0)

            return err;

    }

    return 0;

}


static void s390x_cpu_set_id(Object *obj, Visitor *v, const char *name,

                             void *opaque, Error **errp)

{

    S390CPU *cpu = S390_CPU(obj);

    DeviceState *dev = DEVICE(obj);

    const int64_t min = 0;

    const int64_t max = UINT32_MAX;

    Error *err = NULL;

    int64_t value;

    if (dev->realized) {

        error_setg(errp, "Attempt to set property '%s' on '%s' after "

                   "it was realized", name, object_get_typename(obj));

        return;

    }

    visit_type_int(v, name, &value, &err);

    if (err) {

        error_propagate(errp, err);

        return;

    }

    if (value < min || value > max) {

        error_setg(errp, "Property %s.%s doesn't take value %" PRId64

                   " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,

                   object_get_typename(obj), name, value, min, max);

        return;

    }

    cpu->id = value;

}


static void sunmouse_event(void *opaque,

                               int dx, int dy, int dz, int buttons_state)

{

    ChannelState *s = opaque;

    int ch;

    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);

    ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */

    if (buttons_state & MOUSE_EVENT_LBUTTON)

        ch ^= 0x4;

    if (buttons_state & MOUSE_EVENT_MBUTTON)

        ch ^= 0x2;

    if (buttons_state & MOUSE_EVENT_RBUTTON)

        ch ^= 0x1;

    put_queue(s, ch);

    ch = dx;

    if (ch > 127)

        ch=127;

    else if (ch < -127)

        ch=-127;

    put_queue(s, ch & 0xff);

    ch = -dy;

    if (ch > 127)

        ch=127;

    else if (ch < -127)

        ch=-127;

    put_queue(s, ch & 0xff);

    // MSC protocol specify two extra motion bytes

    put_queue(s, 0);

    put_queue(s, 0);

}


void bdrv_dirty_bitmap_serialize_part(const BdrvDirtyBitmap *bitmap,

                                      uint8_t *buf, uint64_t start,

                                      uint64_t count)

{

    hbitmap_serialize_part(bitmap->bitmap, buf, start, count);

}


int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,

             Error **errp)

{

    unsigned long sectors = info->size / BDRV_SECTOR_SIZE;

    if (info->size / BDRV_SECTOR_SIZE != sectors) {

        error_setg(errp, "Export size %" PRIu64 " too large for 32-bit kernel",

                   info->size);

        return -E2BIG;

    }

    trace_nbd_init_set_socket();

    if (ioctl(fd, NBD_SET_SOCK, (unsigned long) sioc->fd) < 0) {

        int serrno = errno;

        error_setg(errp, "Failed to set NBD socket");

        return -serrno;

    }

    trace_nbd_init_set_block_size(BDRV_SECTOR_SIZE);

    if (ioctl(fd, NBD_SET_BLKSIZE, (unsigned long)BDRV_SECTOR_SIZE) < 0) {

        int serrno = errno;

        error_setg(errp, "Failed setting NBD block size");

        return -serrno;

    }

    trace_nbd_init_set_size(sectors);

    if (info->size % BDRV_SECTOR_SIZE) {

        trace_nbd_init_trailing_bytes(info->size % BDRV_SECTOR_SIZE);

    }

    if (ioctl(fd, NBD_SET_SIZE_BLOCKS, sectors) < 0) {

        int serrno = errno;

        error_setg(errp, "Failed setting size (in blocks)");

        return -serrno;

    }

    if (ioctl(fd, NBD_SET_FLAGS, (unsigned long) info->flags) < 0) {

        if (errno == ENOTTY) {

            int read_only = (info->flags & NBD_FLAG_READ_ONLY) != 0;

            trace_nbd_init_set_readonly();

            if (ioctl(fd, BLKROSET, (unsigned long) &read_only) < 0) {

                int serrno = errno;

                error_setg(errp, "Failed setting read-only attribute");

                return -serrno;

            }

        } else {

            int serrno = errno;

            error_setg(errp, "Failed setting flags");

            return -serrno;

        }

    }

    trace_nbd_init_finish();

    return 0;

}


void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t is_dcbzl)

{

    int dcbz_size = env->dcache_line_size;

#if !defined(CONFIG_USER_ONLY) && defined(TARGET_PPC64)

    if (!is_dcbzl &&

        (env->excp_model == POWERPC_EXCP_970) &&

        ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {

        dcbz_size = 32;

    }

#endif

    /* XXX add e500mc support */

    do_dcbz(env, addr, dcbz_size);

}


static void nvme_rw_cb(void *opaque, int ret)

{

    NvmeRequest *req = opaque;

    NvmeSQueue *sq = req->sq;

    NvmeCtrl *n = sq->ctrl;

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

    block_acct_done(bdrv_get_stats(n->conf.bs), &req->acct);

    if (!ret) {

        req->status = NVME_SUCCESS;

    } else {

        req->status = NVME_INTERNAL_DEV_ERROR;

    }

    qemu_sglist_destroy(&req->qsg);

    nvme_enqueue_req_completion(cq, req);

}


static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)

{

    PowerPCCPU *cpu = POWERPC_CPU(dev);

    CPUPPCState *env = &cpu->env;

    int i;

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

        if (env->opcodes[i] != &invalid_handler) {

            g_free(env->opcodes[i]);

        }

    }

}


static void xen_exit_notifier(Notifier *n, void *data)

{

    XenIOState *state = container_of(n, XenIOState, exit);

    xc_evtchn_close(state->xce_handle);

    xs_daemon_close(state->xenstore);

}


static void avc_loopfilter_cb_or_cr_inter_edge_ver_msa(uint8_t *data,

                                                       uint8_t bs0, uint8_t bs1,

                                                       uint8_t bs2, uint8_t bs3,

                                                       uint8_t tc0, uint8_t tc1,

                                                       uint8_t tc2, uint8_t tc3,

                                                       uint8_t alpha_in,

                                                       uint8_t beta_in,

                                                       uint32_t img_width)

{

    uint8_t *src;

    uint16_t out0, out1, out2, out3;

    v16u8 alpha, beta;

    v16u8 p0_asub_q0, p1_asub_p0, q1_asub_q0;

    v16u8 is_less_than, is_less_than_beta, is_less_than_alpha;

    v16u8 p0, q0;

    v8i16 p0_r = { 0 };

    v8i16 q0_r = { 0 };

    v16u8 p1_org, p0_org, q0_org, q1_org;

    v8i16 p1_org_r, p0_org_r, q0_org_r, q1_org_r;

    v16u8 is_bs_greater_than0;

    v8i16 tc_r, negate_tc_r;

    v16i8 negate_tc, sign_negate_tc;

    v16i8 zero = { 0 };

    v16u8 row0, row1, row2, row3, row4, row5, row6, row7;

    v8i16 tmp1, tmp_vec, bs = { 0 };

    v8i16 tc = { 0 };

    tmp_vec = (v8i16) __msa_fill_b(bs0);

    bs = __msa_insve_h(bs, 0, tmp_vec);

    tmp_vec = (v8i16) __msa_fill_b(bs1);

    bs = __msa_insve_h(bs, 1, tmp_vec);

    tmp_vec = (v8i16) __msa_fill_b(bs2);

    bs = __msa_insve_h(bs, 2, tmp_vec);

    tmp_vec = (v8i16) __msa_fill_b(bs3);

    bs = __msa_insve_h(bs, 3, tmp_vec);

    if (!__msa_test_bz_v((v16u8) bs)) {

        tmp_vec = (v8i16) __msa_fill_b(tc0);

        tc = __msa_insve_h(tc, 0, tmp_vec);

        tmp_vec = (v8i16) __msa_fill_b(tc1);

        tc = __msa_insve_h(tc, 1, tmp_vec);

        tmp_vec = (v8i16) __msa_fill_b(tc2);

        tc = __msa_insve_h(tc, 2, tmp_vec);

        tmp_vec = (v8i16) __msa_fill_b(tc3);

        tc = __msa_insve_h(tc, 3, tmp_vec);

        is_bs_greater_than0 = (v16u8) (zero < (v16i8) bs);

        LOAD_8VECS_UB((data - 2), img_width,

                      row0, row1, row2, row3, row4, row5, row6, row7);

        TRANSPOSE8x4_B_UB(row0, row1, row2, row3,

                          row4, row5, row6, row7,

                          p1_org, p0_org, q0_org, q1_org);

        p0_asub_q0 = __msa_asub_u_b(p0_org, q0_org);

        p1_asub_p0 = __msa_asub_u_b(p1_org, p0_org);

        q1_asub_q0 = __msa_asub_u_b(q1_org, q0_org);

        alpha = (v16u8) __msa_fill_b(alpha_in);

        beta = (v16u8) __msa_fill_b(beta_in);

        is_less_than_alpha = (p0_asub_q0 < alpha);

        is_less_than_beta = (p1_asub_p0 < beta);

        is_less_than = is_less_than_beta & is_less_than_alpha;

        is_less_than_beta = (q1_asub_q0 < beta);

        is_less_than = is_less_than_beta & is_less_than;

        is_less_than = is_bs_greater_than0 & is_less_than;

        is_less_than = (v16u8) __msa_ilvr_d((v2i64) zero, (v2i64) is_less_than);

        if (!__msa_test_bz_v(is_less_than)) {

            p1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p1_org);

            p0_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) p0_org);

            q0_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q0_org);

            q1_org_r = (v8i16) __msa_ilvr_b(zero, (v16i8) q1_org);

            negate_tc = zero - (v16i8) tc;

            sign_negate_tc = __msa_clti_s_b(negate_tc, 0);

            negate_tc_r = (v8i16) __msa_ilvr_b(sign_negate_tc, negate_tc);

            tc_r = (v8i16) __msa_ilvr_b(zero, (v16i8) tc);

            AVC_LOOP_FILTER_P0Q0(q0_org_r, p0_org_r, p1_org_r, q1_org_r,

                                 negate_tc_r, tc_r, p0_r, q0_r);

            p0 = (v16u8) __msa_pckev_b(zero, (v16i8) p0_r);

            q0 = (v16u8) __msa_pckev_b(zero, (v16i8) q0_r);

            p0_org = __msa_bmnz_v(p0_org, p0, is_less_than);

            q0_org = __msa_bmnz_v(q0_org, q0, is_less_than);

            tmp1 = (v8i16) __msa_ilvr_b((v16i8) q0_org, (v16i8) p0_org);

            src = data - 1;

            out0 = __msa_copy_u_h(tmp1, 0);

            out1 = __msa_copy_u_h(tmp1, 1);

            out2 = __msa_copy_u_h(tmp1, 2);

            out3 = __msa_copy_u_h(tmp1, 3);

            STORE_HWORD(src, out0);

            src += img_width;

            STORE_HWORD(src, out1);

            src += img_width;

            STORE_HWORD(src, out2);

            src += img_width;

            STORE_HWORD(src, out3);

            out0 = __msa_copy_u_h(tmp1, 4);

            out1 = __msa_copy_u_h(tmp1, 5);

            out2 = __msa_copy_u_h(tmp1, 6);

            out3 = __msa_copy_u_h(tmp1, 7);

            src += img_width;

            STORE_HWORD(src, out0);

            src += img_width;

            STORE_HWORD(src, out1);

            src += img_width;

            STORE_HWORD(src, out2);

            src += img_width;

            STORE_HWORD(src, out3);

        }

    }

}


static int mov_write_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    MOVMuxContext *mov = s->priv_data;

    AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);

    int i, ret, hint_track = 0, tmcd_track = 0;

    mov->fc = s;

    /* Default mode == MP4 */

    mov->mode = MODE_MP4;

    if (s->oformat) {

        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;

        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;

        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;

        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;

        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;

        else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;

        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;

    }

    if (s->flags & AVFMT_FLAG_BITEXACT)

        mov->exact = 1;

    if (mov->flags & FF_MOV_FLAG_DELAY_MOOV)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV;

    /* Set the FRAGMENT flag if any of the fragmentation methods are

     * enabled. */

    if (mov->max_fragment_duration || mov->max_fragment_size ||

        mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_FRAG_KEYFRAME |

                      FF_MOV_FLAG_FRAG_CUSTOM))

        mov->flags |= FF_MOV_FLAG_FRAGMENT;

    /* Set other implicit flags immediately */

    if (mov->mode == MODE_ISM)

        mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |

                      FF_MOV_FLAG_FRAGMENT;

    if (mov->flags & FF_MOV_FLAG_DASH)

        mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV |

                      FF_MOV_FLAG_DEFAULT_BASE_MOOF;

    if (mov->flags & FF_MOV_FLAG_FASTSTART) {

        mov->reserved_moov_size = -1;

    }

    if (mov->use_editlist < 0) {

        mov->use_editlist = 1;

        if (mov->flags & FF_MOV_FLAG_FRAGMENT &&

            !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

            // If we can avoid needing an edit list by shifting the

            // tracks, prefer that over (trying to) write edit lists

            // in fragmented output.

            if (s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO ||

                s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)

                mov->use_editlist = 0;

        }

    }

    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&

        !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist)

        av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n");

    if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO)

        s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO;

    /* Clear the omit_tfhd_offset flag if default_base_moof is set;

     * if the latter is set that's enough and omit_tfhd_offset doesn't

     * add anything extra on top of that. */

    if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&

        mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF)

        mov->flags &= ~FF_MOV_FLAG_OMIT_TFHD_OFFSET;

    if (mov->frag_interleave &&

        mov->flags & (FF_MOV_FLAG_OMIT_TFHD_OFFSET | FF_MOV_FLAG_SEPARATE_MOOF)) {

        av_log(s, AV_LOG_ERROR,

               "Sample interleaving in fragments is mutually exclusive with "

               "omit_tfhd_offset and separate_moof\n");

        return AVERROR(EINVAL);

    }

    /* Non-seekable output is ok if using fragmentation. If ism_lookahead

     * is enabled, we don't support non-seekable output at all. */

    if (!s->pb->seekable &&

        (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {

        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");

        return AVERROR(EINVAL);

    }

    if (!(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

        if ((ret = mov_write_identification(pb, s)) < 0)

            return ret;

    }

    mov->nb_streams = s->nb_streams;

    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)

        mov->chapter_track = mov->nb_streams++;

    if (mov->flags & FF_MOV_FLAG_RTP_HINT) {

        /* Add hint tracks for each audio and video stream */

        hint_track = mov->nb_streams;

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

            AVStream *st = s->streams[i];

            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||

                st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

                mov->nb_streams++;

            }

        }

    }

    if (mov->mode == MODE_MOV) {

        tmcd_track = mov->nb_streams;

        /* +1 tmcd track for each video stream with a timecode */

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

            AVStream *st = s->streams[i];

            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&

                (global_tcr || av_dict_get(st->metadata, "timecode", NULL, 0)))

                mov->nb_meta_tmcd++;

        }

        /* check if there is already a tmcd track to remux */

        if (mov->nb_meta_tmcd) {

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

                AVStream *st = s->streams[i];

                if (st->codec->codec_tag == MKTAG('t','m','c','d')) {

                    av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "

                           "so timecode metadata are now ignored\n");

                    mov->nb_meta_tmcd = 0;

                }

            }

        }

        mov->nb_streams += mov->nb_meta_tmcd;

    }

    // Reserve an extra stream for chapters for the case where chapters

    // are written in the trailer

    mov->tracks = av_mallocz_array((mov->nb_streams + 1), sizeof(*mov->tracks));

    if (!mov->tracks)

        return AVERROR(ENOMEM);

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

        AVStream *st= s->streams[i];

        MOVTrack *track= &mov->tracks[i];

        AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);

        track->st  = st;

        track->enc = st->codec;

        track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);

        if (track->language < 0)

            track->language = 0;

        track->mode = mov->mode;

        track->tag  = mov_find_codec_tag(s, track);

        if (!track->tag) {

            av_log(s, AV_LOG_ERROR, "Could not find tag for codec %s in stream #%d, "

                   "codec not currently supported in container\n",

                   avcodec_get_name(st->codec->codec_id), i);

            ret = AVERROR(EINVAL);

            goto error;

        }

        /* If hinting of this track is enabled by a later hint track,

         * this is updated. */

        track->hint_track = -1;

        track->start_dts  = AV_NOPTS_VALUE;

        track->start_cts  = AV_NOPTS_VALUE;

        track->end_pts    = AV_NOPTS_VALUE;

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

            if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||

                track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||

                track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {

                if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) {

                    av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");

                    ret = AVERROR(EINVAL);

                    goto error;

                }

                track->height = track->tag >> 24 == 'n' ? 486 : 576;

            }

            if (mov->video_track_timescale) {

                track->timescale = mov->video_track_timescale;

            } else {

                track->timescale = st->time_base.den;

                while(track->timescale < 10000)

                    track->timescale *= 2;

            }

            if (st->codec->width > 65535 || st->codec->height > 65535) {

                av_log(s, AV_LOG_ERROR, "Resolution %dx%d too large for mov/mp4\n", st->codec->width, st->codec->height);

                ret = AVERROR(EINVAL);

                goto error;

            }

            if (track->mode == MODE_MOV && track->timescale > 100000)

                av_log(s, AV_LOG_WARNING,

                       "WARNING codec timebase is very high. If duration is too long,\n"

                       "file may not be playable by quicktime. Specify a shorter timebase\n"

                       "or choose different container.\n");

        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

            track->timescale = st->codec->sample_rate;

            if (!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {

                av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);

                track->audio_vbr = 1;

            }else if (st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||

                     st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||

                     st->codec->codec_id == AV_CODEC_ID_ILBC){

                if (!st->codec->block_align) {

                    av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);

                    ret = AVERROR(EINVAL);

                    goto error;

                }

                track->sample_size = st->codec->block_align;

            }else if (st->codec->frame_size > 1){ /* assume compressed audio */

                track->audio_vbr = 1;

            }else{

                track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;

            }

            if (st->codec->codec_id == AV_CODEC_ID_ILBC ||

                st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) {

                track->audio_vbr = 1;

            }

            if (track->mode != MODE_MOV &&

                track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {

                if (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {

                    av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not standard, to mux anyway set strict to -1\n",

                        i, track->enc->sample_rate);

                    ret = AVERROR(EINVAL);

                    goto error;

                } else {

                    av_log(s, AV_LOG_WARNING, "track %d: muxing mp3 at %dhz is not standard in MP4\n",

                           i, track->enc->sample_rate);

                }

            }

        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {

            track->timescale = st->time_base.den;

        } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {

            track->timescale = st->time_base.den;

        } else {

            track->timescale = MOV_TIMESCALE;

        }

        if (!track->height)

            track->height = st->codec->height;

        /* The ism specific timescale isn't mandatory, but is assumed by

         * some tools, such as mp4split. */

        if (mov->mode == MODE_ISM)

            track->timescale = 10000000;

        avpriv_set_pts_info(st, 64, 1, track->timescale);

        /* copy extradata if it exists */

        if (st->codec->extradata_size) {

            if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)

                mov_create_dvd_sub_decoder_specific_info(track, st);

            else if (!TAG_IS_AVCI(track->tag) && st->codec->codec_id != AV_CODEC_ID_DNXHD) {

                track->vos_len  = st->codec->extradata_size;

                track->vos_data = av_malloc(track->vos_len);

                if (!track->vos_data) {

                    ret = AVERROR(ENOMEM);

                    goto error;

                }

                memcpy(track->vos_data, st->codec->extradata, track->vos_len);

            }

        }

    }

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

        int j;

        AVStream *st= s->streams[i];

        MOVTrack *track= &mov->tracks[i];

        if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO ||

            track->enc->channel_layout != AV_CH_LAYOUT_MONO)

            continue;

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

            AVStream *stj= s->streams[j];

            MOVTrack *trackj= &mov->tracks[j];

            if (j == i)

                continue;

            if (stj->codec->codec_type != AVMEDIA_TYPE_AUDIO ||

                trackj->enc->channel_layout != AV_CH_LAYOUT_MONO ||

                trackj->language != track->language ||

                trackj->tag != track->tag

            )

                continue;

            track->multichannel_as_mono++;

        }

    }

    enable_tracks(s);

    if (mov->reserved_moov_size){

        mov->reserved_moov_pos= avio_tell(pb);

        if (mov->reserved_moov_size > 0)

            avio_skip(pb, mov->reserved_moov_size);

    }

    if (mov->flags & FF_MOV_FLAG_FRAGMENT) {

        /* If no fragmentation options have been set, set a default. */

        if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |

                            FF_MOV_FLAG_FRAG_CUSTOM)) &&

            !mov->max_fragment_duration && !mov->max_fragment_size)

            mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;

    } else {

        if (mov->flags & FF_MOV_FLAG_FASTSTART)

            mov->reserved_moov_pos = avio_tell(pb);

        mov_write_mdat_tag(pb, mov);

    }

    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))

        mov->time = ff_iso8601_to_unix_time(t->value);

    if (mov->time)

        mov->time += 0x7C25B080; // 1970 based -> 1904 based

    if (mov->chapter_track)

        if ((ret = mov_create_chapter_track(s, mov->chapter_track)) < 0)

            goto error;

    if (mov->flags & FF_MOV_FLAG_RTP_HINT) {

        /* Initialize the hint tracks for each audio and video stream */

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

            AVStream *st = s->streams[i];

            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||

                st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

                if ((ret = ff_mov_init_hinting(s, hint_track, i)) < 0)

                    goto error;

                hint_track++;

            }

        }

    }

    if (mov->nb_meta_tmcd) {

        /* Initialize the tmcd tracks */

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

            AVStream *st = s->streams[i];

            t = global_tcr;

            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

                if (!t)

                    t = av_dict_get(st->metadata, "timecode", NULL, 0);

                if (!t)

                    continue;

                if ((ret = mov_create_timecode_track(s, tmcd_track, i, t->value)) < 0)

                    goto error;

                tmcd_track++;

            }

        }

    }

    avio_flush(pb);

    if (mov->flags & FF_MOV_FLAG_ISML)

        mov_write_isml_manifest(pb, mov);

    if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV &&

        !(mov->flags & FF_MOV_FLAG_DELAY_MOOV)) {

        if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)

            return ret;

        mov->moov_written = 1;

        if (mov->flags & FF_MOV_FLAG_FASTSTART)

            mov->reserved_moov_pos = avio_tell(pb);

    }

    return 0;

 error:

    mov_free(s);

    return ret;

}


static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame)
{
    ALSSpecificConfig *sconf = &ctx->sconf;
    AVCodecContext *avctx    = ctx->avctx;
    GetBitContext *gb = &ctx->gb;
    unsigned int div_blocks[32];                ///< block sizes.
    unsigned int c;
    unsigned int js_blocks[2];
    uint32_t bs_info = 0;
    int ret;
    // skip the size of the ra unit if present in the frame
    if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame)
        skip_bits_long(gb, 32);
    if (sconf->mc_coding && sconf->joint_stereo) {
        ctx->js_switch = get_bits1(gb);
        align_get_bits(gb);
    if (!sconf->mc_coding || ctx->js_switch) {
        int independent_bs = !sconf->joint_stereo;
        for (c = 0; c < avctx->channels; c++) {
            js_blocks[0] = 0;
            js_blocks[1] = 0;
            get_block_sizes(ctx, div_blocks, &bs_info);
            // if joint_stereo and block_switching is set, independent decoding
            // is signaled via the first bit of bs_info
            if (sconf->joint_stereo && sconf->block_switching)
                if (bs_info >> 31)
                    independent_bs = 2;
            // if this is the last channel, it has to be decoded independently
            if (c == avctx->channels - 1)
                independent_bs = 1;
            if (independent_bs) {
                ret = decode_blocks_ind(ctx, ra_frame, c,
                                        div_blocks, js_blocks);
                if (ret < 0)
                    return ret;
                independent_bs--;
            } else {
                ret = decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks);
                if (ret < 0)
                    return ret;
                c++;
            // store carryover raw samples
            memmove(ctx->raw_samples[c] - sconf->max_order,
                    ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
                    sizeof(*ctx->raw_samples[c]) * sconf->max_order);
    } else { // multi-channel coding
        ALSBlockData   bd = { 0 };
        int            b, ret;
        int            *reverted_channels = ctx->reverted_channels;
        unsigned int   offset             = 0;
        for (c = 0; c < avctx->channels; c++)
            if (ctx->chan_data[c] < ctx->chan_data_buffer) {
                av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data.\n");
        memset(reverted_channels, 0, sizeof(*reverted_channels) * avctx->channels);
        bd.ra_block         = ra_frame;
        bd.prev_raw_samples = ctx->prev_raw_samples;
        get_block_sizes(ctx, div_blocks, &bs_info);
        for (b = 0; b < ctx->num_blocks; b++) {
            bd.block_length = div_blocks[b];
            if (bd.block_length <= 0) {
                av_log(ctx->avctx, AV_LOG_WARNING,
                       "Invalid block length %u in channel data!\n",
                       bd.block_length);
                continue;
            for (c = 0; c < avctx->channels; c++) {
                bd.const_block = ctx->const_block + c;
                bd.shift_lsbs  = ctx->shift_lsbs + c;
                bd.opt_order   = ctx->opt_order + c;
                bd.store_prev_samples = ctx->store_prev_samples + c;
                bd.use_ltp     = ctx->use_ltp + c;
                bd.ltp_lag     = ctx->ltp_lag + c;
                bd.ltp_gain    = ctx->ltp_gain[c];
                bd.lpc_cof     = ctx->lpc_cof[c];
                bd.quant_cof   = ctx->quant_cof[c];
                bd.raw_samples = ctx->raw_samples[c] + offset;
                bd.raw_other   = NULL;
                if ((ret = read_block(ctx, &bd)) < 0)
                    return ret;
                if ((ret = read_channel_data(ctx, ctx->chan_data[c], c)) < 0)
                    return ret;
            for (c = 0; c < avctx->channels; c++) {
                ret = revert_channel_correlation(ctx, &bd, ctx->chan_data,
                                                 reverted_channels, offset, c);
                if (ret < 0)
                    return ret;
            for (c = 0; c < avctx->channels; c++) {
                bd.const_block = ctx->const_block + c;
                bd.shift_lsbs  = ctx->shift_lsbs + c;
                bd.opt_order   = ctx->opt_order + c;
                bd.store_prev_samples = ctx->store_prev_samples + c;
                bd.use_ltp     = ctx->use_ltp + c;
                bd.ltp_lag     = ctx->ltp_lag + c;
                bd.ltp_gain    = ctx->ltp_gain[c];
                bd.lpc_cof     = ctx->lpc_cof[c];
                bd.quant_cof   = ctx->quant_cof[c];
                bd.raw_samples = ctx->raw_samples[c] + offset;
                if ((ret = decode_block(ctx, &bd)) < 0)
                    return ret;
            memset(reverted_channels, 0, avctx->channels * sizeof(*reverted_channels));
            offset      += div_blocks[b];
            bd.ra_block  = 0;
        // store carryover raw samples
        for (c = 0; c < avctx->channels; c++)
            memmove(ctx->raw_samples[c] - sconf->max_order,
                    ctx->raw_samples[c] - sconf->max_order + sconf->frame_length,
                    sizeof(*ctx->raw_samples[c]) * sconf->max_order);
    // TODO: read_diff_float_data
    return 0;


int swr_resample(AVResampleContext *c, short *dst, const short *src, int *consumed, int src_size, int dst_size, int update_ctx){

    int dst_index, i;

    int index= c->index;

    int frac= c->frac;

    int dst_incr_frac= c->dst_incr % c->src_incr;

    int dst_incr=      c->dst_incr / c->src_incr;

    int compensation_distance= c->compensation_distance;

    if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){

        int64_t index2= ((int64_t)index)<<32;

        int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;

        dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);

        for(dst_index=0; dst_index < dst_size; dst_index++){

            dst[dst_index] = src[index2>>32];

            index2 += incr;

        }

        frac += dst_index * dst_incr_frac;

        index += dst_index * dst_incr;

        index += frac / c->src_incr;

        frac %= c->src_incr;

    }else{

        for(dst_index=0; dst_index < dst_size; dst_index++){

            FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask);

            int sample_index= index >> c->phase_shift;

            FELEM2 val=0;

            if(sample_index < 0){

                for(i=0; i<c->filter_length; i++)

                    val += src[FFABS(sample_index + i) % src_size] * filter[i];

            }else if(sample_index + c->filter_length > src_size){

                break;

            }else if(c->linear){

                FELEM2 v2=0;

                for(i=0; i<c->filter_length; i++){

                    val += src[sample_index + i] * (FELEM2)filter[i];

                    v2  += src[sample_index + i] * (FELEM2)filter[i + c->filter_length];

                }

                val+=(v2-val)*(FELEML)frac / c->src_incr;

            }else{

                for(i=0; i<c->filter_length; i++){

                    val += src[sample_index + i] * (FELEM2)filter[i];

                }

            }

#ifdef CONFIG_RESAMPLE_AUDIOPHILE_KIDDY_MODE

            dst[dst_index] = av_clip_int16(lrintf(val));

#else

            val = (val + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;

            dst[dst_index] = (unsigned)(val + 32768) > 65535 ? (val>>31) ^ 32767 : val;

#endif

            frac += dst_incr_frac;

            index += dst_incr;

            if(frac >= c->src_incr){

                frac -= c->src_incr;

                index++;

            }

            if(dst_index + 1 == compensation_distance){

                compensation_distance= 0;

                dst_incr_frac= c->ideal_dst_incr % c->src_incr;

                dst_incr=      c->ideal_dst_incr / c->src_incr;

            }

        }

    }

    *consumed= FFMAX(index, 0) >> c->phase_shift;

    if(index>=0) index &= c->phase_mask;

    if(compensation_distance){

        compensation_distance -= dst_index;

        assert(compensation_distance > 0);

    }

    if(update_ctx){

        c->frac= frac;

        c->index= index;

        c->dst_incr= dst_incr_frac + c->src_incr*dst_incr;

        c->compensation_distance= compensation_distance;

    }

#if 0

    if(update_ctx && !c->compensation_distance){

#undef rand

        av_resample_compensate(c, rand() % (8000*2) - 8000, 8000*2);

av_log(NULL, AV_LOG_DEBUG, "%d %d %d\n", c->dst_incr, c->ideal_dst_incr, c->compensation_distance);

    }

#endif

    return dst_index;

}


static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)

{

    STM32F205State *s = STM32F205_SOC(dev_soc);

    DeviceState *syscfgdev, *usartdev, *timerdev;

    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;

    qemu_irq *pic;

    Error *err = NULL;

    int i;

    MemoryRegion *system_memory = get_system_memory();

    MemoryRegion *sram = g_new(MemoryRegion, 1);

    MemoryRegion *flash = g_new(MemoryRegion, 1);

    MemoryRegion *flash_alias = g_new(MemoryRegion, 1);

    memory_region_init_ram(flash, NULL, "STM32F205.flash", FLASH_SIZE,

                           &error_abort);

    memory_region_init_alias(flash_alias, NULL, "STM32F205.flash.alias",

                             flash, 0, FLASH_SIZE);

    vmstate_register_ram_global(flash);

    memory_region_set_readonly(flash, true);

    memory_region_set_readonly(flash_alias, true);

    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, flash);

    memory_region_add_subregion(system_memory, 0, flash_alias);

    memory_region_init_ram(sram, NULL, "STM32F205.sram", SRAM_SIZE,

                           &error_abort);

    vmstate_register_ram_global(sram);

    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);

    pic = armv7m_init(get_system_memory(), FLASH_SIZE, 96,

                      s->kernel_filename, s->cpu_model);

    /* System configuration controller */

    syscfgdev = DEVICE(&s->syscfg);

    object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);

    if (err != NULL) {

        error_propagate(errp, err);

        return;

    }

    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);

    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);

    sysbus_connect_irq(syscfgbusdev, 0, pic[71]);

    /* Attach UART (uses USART registers) and USART controllers */

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

        usartdev = DEVICE(&(s->usart[i]));

        object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);

        if (err != NULL) {

            error_propagate(errp, err);

            return;

        }

        usartbusdev = SYS_BUS_DEVICE(usartdev);

        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);

        sysbus_connect_irq(usartbusdev, 0, pic[usart_irq[i]]);

    }

    /* Timer 2 to 5 */

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

        timerdev = DEVICE(&(s->timer[i]));

        qdev_prop_set_uint64(timerdev, "clock-frequency", 1000000000);

        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);

        if (err != NULL) {

            error_propagate(errp, err);

            return;

        }

        timerbusdev = SYS_BUS_DEVICE(timerdev);

        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);

        sysbus_connect_irq(timerbusdev, 0, pic[timer_irq[i]]);

    }

}


static int cmp_int(const void *p1, const void *p2)

{

    int left = *(const int *)p1;

    int right = *(const int *)p2;

    return ((left > right) - (left < right));

}


static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)

{

    const CodecMime *mime = ff_id3v2_mime_tags;

    enum  CodecID      id = CODEC_ID_NONE;

    uint8_t mimetype[64], *desc = NULL, *data = NULL;

    AVIOContext *pb = NULL;

    AVStream *st;

    int type, width, height;

    int len, ret = 0;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL);

    if (!pb)

        return AVERROR(ENOMEM);

    /* read the picture type */

    type      = avio_rb32(pb);

    if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {

        av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    /* picture mimetype */

    len  = avio_rb32(pb);

    if (len <= 0 ||

        avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) {

        av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached "

               "picture.\n");

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    mimetype[len] = 0;

    while (mime->id != CODEC_ID_NONE) {

        if (!strncmp(mime->str, mimetype, sizeof(mimetype))) {

            id = mime->id;

            break;

        }

        mime++;

    }

    if (id == CODEC_ID_NONE) {

        av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n",

               mimetype);

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    /* picture description */

    len = avio_rb32(pb);

    if (len > 0) {

        if (!(desc = av_malloc(len + 1))) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        if (avio_read(pb, desc, len) != len) {

            ret = AVERROR(EIO);

            goto fail;

        }

        desc[len] = 0;

    }

    /* picture metadata */

    width  = avio_rb32(pb);

    height = avio_rb32(pb);

    avio_skip(pb, 8);

    /* picture data */

    len = avio_rb32(pb);

    if (len <= 0) {

        ret = AVERROR_INVALIDDATA;

        goto fail;

    }

    if (!(data = av_malloc(len))) {

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    if (avio_read(pb, data, len) != len) {

        ret = AVERROR(EIO);

        goto fail;

    }

    av_init_packet(&st->attached_pic);

    st->attached_pic.data         = data;

    st->attached_pic.size         = len;

    st->attached_pic.destruct     = av_destruct_packet;

    st->attached_pic.stream_index = st->index;

    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;

    st->disposition      |= AV_DISPOSITION_ATTACHED_PIC;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id   = id;

    st->codec->width      = width;

    st->codec->height     = height;

    av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0);

    if (desc)

        av_dict_set(&st->metadata, "title",   desc, AV_DICT_DONT_STRDUP_VAL);

    av_freep(&pb);

    return 0;

fail:

    av_freep(&desc);

    av_freep(&data);

    av_freep(&pb);

    return ret;

}


void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns, Error **errp)

{

    error_setg(errp, "AioContext polling is not implemented on Windows");

}


static void host_memory_backend_set_prealloc(Object *obj, bool value,

                                             Error **errp)

{

    Error *local_err = NULL;

    HostMemoryBackend *backend = MEMORY_BACKEND(obj);

    if (backend->force_prealloc) {

        if (value) {

            error_setg(errp,

                       "remove -mem-prealloc to use the prealloc property");

            return;

        }

    }

    if (!memory_region_size(&backend->mr)) {

        backend->prealloc = value;

        return;

    }

    if (value && !backend->prealloc) {

        int fd = memory_region_get_fd(&backend->mr);

        void *ptr = memory_region_get_ram_ptr(&backend->mr);

        uint64_t sz = memory_region_size(&backend->mr);

        os_mem_prealloc(fd, ptr, sz, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return;

        }

        backend->prealloc = true;

    }

}


void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,

                              int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))

{

    AVPacketList **next_point, *this_pktl;

    this_pktl = av_mallocz(sizeof(AVPacketList));

    this_pktl->pkt= *pkt;

    pkt->destruct= NULL;             // do not free original but only the copy

    av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-alloced memory

    if(s->streams[pkt->stream_index]->last_in_packet_buffer){

        next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);

    }else

        next_point = &s->packet_buffer;

    if(*next_point){

        if(compare(s, &s->packet_buffer_end->pkt, pkt)){

            while(!compare(s, &(*next_point)->pkt, pkt)){

                next_point= &(*next_point)->next;

            }

            goto next_non_null;

        }else{

            next_point = &(s->packet_buffer_end->next);

        }

    }

    assert(!*next_point);

    s->packet_buffer_end= this_pktl;

next_non_null:

    this_pktl->next= *next_point;

    s->streams[pkt->stream_index]->last_in_packet_buffer=

    *next_point= this_pktl;

}


static void read_partition(uint8_t *p, struct partition_record *r)

{

    r->bootable = p[0];

    r->start_head = p[1];

    r->start_cylinder = p[3] | ((p[2] << 2) & 0x0300);

    r->start_sector = p[2] & 0x3f;

    r->system = p[4];

    r->end_head = p[5];

    r->end_cylinder = p[7] | ((p[6] << 2) & 0x300);

    r->end_sector = p[6] & 0x3f;

    r->start_sector_abs = p[8] | p[9] << 8 | p[10] << 16 | p[11] << 24;

    r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;

}


static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)

{

    AVFrame *frame = data;

    DxaDecContext * const c = avctx->priv_data;

    uint8_t *outptr, *srcptr, *tmpptr;

    unsigned long dsize;

    int i, j, compr, ret;

    int stride;

    int pc = 0;

    GetByteContext gb;

    bytestream2_init(&gb, avpkt->data, avpkt->size);

    /* make the palette available on the way out */

    if (bytestream2_peek_le32(&gb) == MKTAG('C','M','A','P')) {

        bytestream2_skip(&gb, 4);

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

            c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&gb);

        }

        pc = 1;

    }

    if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)

        return ret;

    memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);

    frame->palette_has_changed = pc;

    outptr = frame->data[0];

    srcptr = c->decomp_buf;

    tmpptr = c->prev->data[0];

    stride = frame->linesize[0];

    if (bytestream2_get_le32(&gb) == MKTAG('N','U','L','L'))

        compr = -1;

    else

        compr = bytestream2_get_byte(&gb);

    dsize = c->dsize;

    if (compr != 4 && compr != -1) {

        bytestream2_skip(&gb, 4);

        if (uncompress(c->decomp_buf, &dsize, avpkt->data + bytestream2_tell(&gb),

                       bytestream2_get_bytes_left(&gb)) != Z_OK) {

            av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");

            return AVERROR_UNKNOWN;

        }

        memset(c->decomp_buf + dsize, 0, DECOMP_BUF_PADDING);

    }

    if (avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(avctx, AV_LOG_DEBUG, "compr:%2d, dsize:%d\n", compr, (int)dsize);

    switch(compr){

    case -1:

        frame->key_frame = 0;

        frame->pict_type = AV_PICTURE_TYPE_P;

        if (c->prev->data[0])

            memcpy(frame->data[0], c->prev->data[0], frame->linesize[0] * avctx->height);

        else{ // Should happen only when first frame is 'NULL'

            memset(frame->data[0], 0, frame->linesize[0] * avctx->height);

            frame->key_frame = 1;

            frame->pict_type = AV_PICTURE_TYPE_I;

        }

        break;

    case 2:

    case 4:

        frame->key_frame = 1;

        frame->pict_type = AV_PICTURE_TYPE_I;

        for (j = 0; j < avctx->height; j++) {

                memcpy(outptr, srcptr, avctx->width);

            outptr += stride;

            srcptr += avctx->width;

        }

        break;

    case 3:

    case 5:

        if (!tmpptr) {

            av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");

            if (!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL))

                return AVERROR_INVALIDDATA;

        }

        frame->key_frame = 0;

        frame->pict_type = AV_PICTURE_TYPE_P;

        for (j = 0; j < avctx->height; j++) {

            if(tmpptr){

                for(i = 0; i < avctx->width; i++)

                    outptr[i] = srcptr[i] ^ tmpptr[i];

                tmpptr += stride;

            }else

                memcpy(outptr, srcptr, avctx->width);

            outptr += stride;

            srcptr += avctx->width;

        }

        break;

    case 12: // ScummVM coding

    case 13:

        frame->key_frame = 0;

        frame->pict_type = AV_PICTURE_TYPE_P;

        if (!c->prev->data[0]) {

            av_log(avctx, AV_LOG_ERROR, "Missing reference frame\n");

            return AVERROR_INVALIDDATA;

        }

        decode_13(avctx, c, frame->data[0], frame->linesize[0], srcptr, c->prev->data[0]);

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", compr);

        return AVERROR_INVALIDDATA;

    }

    av_frame_unref(c->prev);

    if ((ret = av_frame_ref(c->prev, frame)) < 0)

        return ret;

    *got_frame = 1;

    /* always report that the buffer was completely consumed */

    return avpkt->size;

}


static void virtio_gpu_resource_destroy(VirtIOGPU *g,

                                        struct virtio_gpu_simple_resource *res)

{

    pixman_image_unref(res->image);

    QTAILQ_REMOVE(&g->reslist, res, next);

    g->hostmem -= res->hostmem;

    g_free(res);

}


void virtio_save(VirtIODevice *vdev, QEMUFile *f)

{

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

    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);

    uint32_t guest_features_lo = (vdev->guest_features & 0xffffffff);

    int i;

    if (k->save_config) {

        k->save_config(qbus->parent, f);

    }

    qemu_put_8s(f, &vdev->status);

    qemu_put_8s(f, &vdev->isr);

    qemu_put_be16s(f, &vdev->queue_sel);

    qemu_put_be32s(f, &guest_features_lo);

    qemu_put_be32(f, vdev->config_len);

    qemu_put_buffer(f, vdev->config, vdev->config_len);

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

        if (vdev->vq[i].vring.num == 0)

            break;

    }

    qemu_put_be32(f, i);

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

        if (vdev->vq[i].vring.num == 0)

            break;

        qemu_put_be32(f, vdev->vq[i].vring.num);

        if (k->has_variable_vring_alignment) {

            qemu_put_be32(f, vdev->vq[i].vring.align);

        }

        /* XXX virtio-1 devices */

        qemu_put_be64(f, vdev->vq[i].vring.desc);

        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);

        if (k->save_queue) {

            k->save_queue(qbus->parent, i, f);

        }

    }

    if (vdc->save != NULL) {

        vdc->save(vdev, f);

    }

    if (vdc->vmsd) {

        vmstate_save_state(f, vdc->vmsd, vdev, NULL);

    }

    /* Subsections */

    vmstate_save_state(f, &vmstate_virtio, vdev, NULL);

}


static void virtio_blk_dma_restart_cb(void *opaque, int running,

                                      RunState state)

{

    VirtIOBlock *s = opaque;

    if (!running)

        return;

    if (!s->bh) {

        s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);

        qemu_bh_schedule(s->bh);

    }

}


static char *json_escape_str(const char *s)

{

    static const char json_escape[] = {'"', '\\', '\b', '\f', '\n', '\r', '\t', 0};

    static const char json_subst[]  = {'"', '\\',  'b',  'f',  'n',  'r',  't', 0};

    char *ret, *p;

    int i, len = 0;

    // compute the length of the escaped string

    for (i = 0; s[i]; i++) {

        if (strchr(json_escape, s[i]))     len += 2; // simple escape

        else if ((unsigned char)s[i] < 32) len += 6; // handle non-printable chars

        else                               len += 1; // char copy

    }

    p = ret = av_malloc(len + 1);

    if (!p)

        return NULL;

    for (i = 0; s[i]; i++) {

        char *q = strchr(json_escape, s[i]);

        if (q) {

            *p++ = '\\';

            *p++ = json_subst[q - json_escape];

        } else if ((unsigned char)s[i] < 32) {

            snprintf(p, 7, "\\u00%02x", s[i] & 0xff);

            p += 6;

        } else {

            *p++ = s[i];

        }

    }

    *p = 0;

    return ret;

}


static int gif_image_write_header(ByteIOContext *pb,

                                  int width, int height, uint32_t *palette)

{

    int i;

    unsigned int v;

    put_tag(pb, "GIF");

    put_tag(pb, "89a");

    put_le16(pb, width);

    put_le16(pb, height);

    put_byte(pb, 0xf7); /* flags: global clut, 256 entries */

    put_byte(pb, 0x1f); /* background color index */

    put_byte(pb, 0); /* aspect ratio */

    /* the global palette */

    if (!palette) {

        put_buffer(pb, (unsigned char *)gif_clut, 216*3);

        for(i=0;i<((256-216)*3);i++)

            put_byte(pb, 0);

    } else {

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

            v = palette[i];

            put_byte(pb, (v >> 16) & 0xff);

            put_byte(pb, (v >> 8) & 0xff);

            put_byte(pb, (v) & 0xff);

        }

    }

    /* application extension header */

    /* XXX: not really sure what to put in here... */

#ifdef GIF_ADD_APP_HEADER

    put_byte(pb, 0x21);

    put_byte(pb, 0xff);

    put_byte(pb, 0x0b);

    put_tag(pb, "NETSCAPE2.0");

    put_byte(pb, 0x03);

    put_byte(pb, 0x01);

    put_byte(pb, 0x00);

    put_byte(pb, 0x00);

#endif

    return 0;

}


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

                                     int *got_frame, AVPacket *avpkt)

{

    RsccContext *ctx = avctx->priv_data;

    GetByteContext *gbc = &ctx->gbc;

    GetByteContext tiles_gbc;

    AVFrame *frame = data;

    const uint8_t *pixels, *raw;

    uint8_t *inflated_tiles = NULL;

    int tiles_nb, packed_size, pixel_size = 0;

    int i, ret = 0;

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

    /* Size check */

    if (bytestream2_get_bytes_left(gbc) < 12) {

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

        return AVERROR_INVALIDDATA;

    }

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

    tiles_nb = bytestream2_get_le16(gbc);

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

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

    if (!ctx->tiles) {

        ret = AVERROR(ENOMEM);

        goto end;

    }

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

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

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

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

    if (tiles_nb > 5) {

        uLongf packed_tiles_size;

        if (tiles_nb < 32)

            packed_tiles_size = bytestream2_get_byte(gbc);

        else

            packed_tiles_size = bytestream2_get_le16(gbc);

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

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

        if (packed_tiles_size != tiles_nb * TILE_SIZE) {

            uLongf length = tiles_nb * TILE_SIZE;

            inflated_tiles = av_malloc(length);

            if (!inflated_tiles) {

                ret = AVERROR(ENOMEM);

                goto end;

            }

            ret = uncompress(inflated_tiles, &length,

                             gbc->buffer, packed_tiles_size);

            if (ret) {

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

                ret = AVERROR_UNKNOWN;

                goto end;

            }

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

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

            bytestream2_skip(gbc, packed_tiles_size);

            bytestream2_init(&tiles_gbc, inflated_tiles, length);

            gbc = &tiles_gbc;

        }

    }

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

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

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

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

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

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

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

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

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

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

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

            av_log(avctx, AV_LOG_ERROR,

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

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

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

            ret = AVERROR_INVALIDDATA;

            goto end;

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

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

            av_log(avctx, AV_LOG_ERROR,

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

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

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

            ret = AVERROR_INVALIDDATA;

            goto end;

        }

    }

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

    gbc = &ctx->gbc;

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

    if (pixel_size < 0x100)

        packed_size = bytestream2_get_byte(gbc);

    else if (pixel_size < 0x10000)

        packed_size = bytestream2_get_le16(gbc);

    else if (pixel_size < 0x1000000)

        packed_size = bytestream2_get_le24(gbc);

    else

        packed_size = bytestream2_get_le32(gbc);

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

    if (packed_size < 0) {

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

        ret = AVERROR_INVALIDDATA;

        goto end;

    }

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

    if (pixel_size == packed_size) {

        if (bytestream2_get_bytes_left(gbc) < pixel_size) {

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

            ret = AVERROR_INVALIDDATA;

            goto end;

        }

        pixels = gbc->buffer;

    } else {

        uLongf len = ctx->inflated_size;

        if (bytestream2_get_bytes_left(gbc) < packed_size) {

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

            ret = AVERROR_INVALIDDATA;

            goto end;

        }

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

        if (ret) {

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

            ret = AVERROR_UNKNOWN;

            goto end;

        }

        pixels = ctx->inflated_buf;

    }

    /* Allocate when needed */

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

    if (ret < 0)

        goto end;

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

    raw = pixels;

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

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

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

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

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

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

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

                            ctx->tiles[i].h);

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

    }

    /* Frame is ready to be output */

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

    if (ret < 0)

        goto end;

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

    if (pixel_size == ctx->inflated_size) {

        frame->pict_type = AV_PICTURE_TYPE_I;

        frame->key_frame = 1;

    } else {

        frame->pict_type = AV_PICTURE_TYPE_P;

    }

    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {

        const uint8_t *pal = av_packet_get_side_data(avpkt,

                                                     AV_PKT_DATA_PALETTE,

                                                     NULL);

        if (pal) {

            frame->palette_has_changed = 1;

            memcpy(ctx->pal, pal, AVPALETTE_SIZE);

        }

        memcpy (frame->data[1], ctx->pal, AVPALETTE_SIZE);

    }

    *got_frame = 1;

end:

    av_free(inflated_tiles);

    return ret;

}


static int parse_frame_header(DCACoreDecoder *s)

{

    DCACoreFrameHeader h = { 0 };

    int err = avpriv_dca_parse_core_frame_header(&s->gb, &h);

    if (err < 0) {

        switch (err) {

        case DCA_PARSE_ERROR_DEFICIT_SAMPLES:

            av_log(s->avctx, AV_LOG_ERROR, "Deficit samples are not supported\n");

            return h.normal_frame ? AVERROR_INVALIDDATA : AVERROR_PATCHWELCOME;

        case DCA_PARSE_ERROR_PCM_BLOCKS:

            av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of PCM sample blocks (%d)\n", h.npcmblocks);

            return (h.npcmblocks < 6 || h.normal_frame) ? AVERROR_INVALIDDATA : AVERROR_PATCHWELCOME;

        case DCA_PARSE_ERROR_FRAME_SIZE:

            av_log(s->avctx, AV_LOG_ERROR, "Invalid core frame size (%d bytes)\n", h.frame_size);

            return AVERROR_INVALIDDATA;

        case DCA_PARSE_ERROR_AMODE:

            av_log(s->avctx, AV_LOG_ERROR, "Unsupported audio channel arrangement (%d)\n", h.audio_mode);

            return AVERROR_PATCHWELCOME;

        case DCA_PARSE_ERROR_SAMPLE_RATE:

            av_log(s->avctx, AV_LOG_ERROR, "Invalid core audio sampling frequency\n");

            return AVERROR_INVALIDDATA;

        case DCA_PARSE_ERROR_RESERVED_BIT:

            av_log(s->avctx, AV_LOG_ERROR, "Reserved bit set\n");

            return AVERROR_INVALIDDATA;

        case DCA_PARSE_ERROR_LFE_FLAG:

            av_log(s->avctx, AV_LOG_ERROR, "Invalid low frequency effects flag\n");

            return AVERROR_INVALIDDATA;

        case DCA_PARSE_ERROR_PCM_RES:

            av_log(s->avctx, AV_LOG_ERROR, "Invalid source PCM resolution\n");

            return AVERROR_INVALIDDATA;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unknown core frame header error\n");

            return AVERROR_INVALIDDATA;

        }

    }

    s->crc_present          = h.crc_present;

    s->npcmblocks           = h.npcmblocks;

    s->frame_size           = h.frame_size;

    s->audio_mode           = h.audio_mode;

    s->sample_rate          = avpriv_dca_sample_rates[h.sr_code];

    s->bit_rate             = ff_dca_bit_rates[h.br_code];

    s->drc_present          = h.drc_present;

    s->ts_present           = h.ts_present;

    s->aux_present          = h.aux_present;

    s->ext_audio_type       = h.ext_audio_type;

    s->ext_audio_present    = h.ext_audio_present;

    s->sync_ssf             = h.sync_ssf;

    s->lfe_present          = h.lfe_present;

    s->predictor_history    = h.predictor_history;

    s->filter_perfect       = h.filter_perfect;

    s->source_pcm_res       = ff_dca_bits_per_sample[h.pcmr_code];

    s->es_format            = h.pcmr_code & 1;

    s->sumdiff_front        = h.sumdiff_front;

    s->sumdiff_surround     = h.sumdiff_surround;

    return 0;

}


static int insert_trim(OutputStream *ost, AVFilterContext **last_filter, int *pad_idx)

{

    OutputFile *of = output_files[ost->file_index];

    AVFilterGraph *graph = (*last_filter)->graph;

    AVFilterContext *ctx;

    const AVFilter *trim;

    const char *name = ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO ? "trim" : "atrim";

    char filter_name[128];

    int ret = 0;

    if (of->recording_time == INT64_MAX && !of->start_time)

        return 0;

    trim = avfilter_get_by_name(name);

    if (!trim) {

        av_log(NULL, AV_LOG_ERROR, "%s filter not present, cannot limit "

               "recording time.\n", name);

        return AVERROR_FILTER_NOT_FOUND;

    }

    snprintf(filter_name, sizeof(filter_name), "%s for output stream %d:%d",

             name, ost->file_index, ost->index);

    ctx = avfilter_graph_alloc_filter(graph, trim, filter_name);

    if (!ctx)

        return AVERROR(ENOMEM);

    if (of->recording_time != INT64_MAX) {

        ret = av_opt_set_double(ctx, "duration", (double)of->recording_time / 1e6,

                                AV_OPT_SEARCH_CHILDREN);

    }

    if (ret >= 0 && of->start_time) {

        ret = av_opt_set_double(ctx, "start", (double)of->start_time / 1e6,

                                AV_OPT_SEARCH_CHILDREN);

    }

    if (ret < 0) {

        av_log(ctx, AV_LOG_ERROR, "Error configuring the %s filter", name);

        return ret;

    }

    ret = avfilter_init_str(ctx, NULL);

    if (ret < 0)

        return ret;

    ret = avfilter_link(*last_filter, *pad_idx, ctx, 0);

    if (ret < 0)

        return ret;

    *last_filter = ctx;

    *pad_idx     = 0;

    return 0;

}


static int add_doubles_metadata(const uint8_t **buf, int count,

                                const char *name, const char *sep,

                                TiffContext *s)

{

    char *ap;

    int i;

    double *dp = av_malloc(count * sizeof(double));

    if (!dp)

        return AVERROR(ENOMEM);

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

        dp[i] = tget_double(buf, s->le);

    ap = doubles2str(dp, count, sep);

    av_freep(&dp);

    if (!ap)

        return AVERROR(ENOMEM);

    av_dict_set(&s->picture.metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);

    return 0;

}


static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,

                void *dest)

{

    uint8_t buf[512];

    if (s->blk_cur) {

        if (blk_read(s->blk_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) {

            return 1;

        }

        memcpy(dest, buf + ((sec & 31) << 4), secn << 4);

    } else if (sec + secn > s->secs_cur) {

        return 1;

    } else {

        memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4);

    }

    return 0;

}


X264_init(AVCodecContext *avctx)

{

    X264Context *x4 = avctx->priv_data;

    x264_param_default(&x4->params);

    x4->params.pf_log = X264_log;

    x4->params.p_log_private = avctx;

    x4->params.i_keyint_max = avctx->gop_size;

    x4->params.rc.i_bitrate = avctx->bit_rate / 1000;

    x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;

    x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate / 1000;

    x4->params.rc.b_stat_write = avctx->flags & CODEC_FLAG_PASS1;

    if(avctx->flags & CODEC_FLAG_PASS2) x4->params.rc.b_stat_read = 1;

    else{

        if(avctx->crf){

            x4->params.rc.i_rc_method = X264_RC_CRF;

            x4->params.rc.f_rf_constant = avctx->crf;

        }else if(avctx->cqp > -1){

            x4->params.rc.i_rc_method = X264_RC_CQP;

            x4->params.rc.i_qp_constant = avctx->cqp;

        }

    }

    // if neither crf nor cqp modes are selected we have to enable the RC

    // we do it this way because we cannot check if the bitrate has been set

    if(!(avctx->crf || (avctx->cqp > -1))) x4->params.rc.i_rc_method = X264_RC_ABR;

    x4->params.i_bframe = avctx->max_b_frames;

    x4->params.b_cabac = avctx->coder_type == FF_CODER_TYPE_AC;

    x4->params.b_bframe_adaptive = avctx->b_frame_strategy;

    x4->params.i_bframe_bias = avctx->bframebias;

    x4->params.b_bframe_pyramid = avctx->flags2 & CODEC_FLAG2_BPYRAMID;

    avctx->has_b_frames= avctx->flags2 & CODEC_FLAG2_BPYRAMID ? 2 : !!avctx->max_b_frames;

    x4->params.i_keyint_min = avctx->keyint_min;

    if(x4->params.i_keyint_min > x4->params.i_keyint_max)

        x4->params.i_keyint_min = x4->params.i_keyint_max;

    x4->params.i_scenecut_threshold = avctx->scenechange_threshold;

    x4->params.b_deblocking_filter = avctx->flags & CODEC_FLAG_LOOP_FILTER;

    x4->params.i_deblocking_filter_alphac0 = avctx->deblockalpha;

    x4->params.i_deblocking_filter_beta = avctx->deblockbeta;

    x4->params.rc.i_qp_min = avctx->qmin;

    x4->params.rc.i_qp_max = avctx->qmax;

    x4->params.rc.i_qp_step = avctx->max_qdiff;

    x4->params.rc.f_qcompress = avctx->qcompress;  /* 0.0 => cbr, 1.0 => constant qp */

    x4->params.rc.f_qblur = avctx->qblur;        /* temporally blur quants */

    x4->params.rc.f_complexity_blur = avctx->complexityblur;

    x4->params.i_frame_reference = avctx->refs;

    x4->params.i_width = avctx->width;

    x4->params.i_height = avctx->height;

    x4->params.vui.i_sar_width = avctx->sample_aspect_ratio.num;

    x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den;

    x4->params.i_fps_num = avctx->time_base.den;

    x4->params.i_fps_den = avctx->time_base.num;

    x4->params.analyse.inter = 0;

    if(avctx->partitions){

        if(avctx->partitions & X264_PART_I4X4)

            x4->params.analyse.inter |= X264_ANALYSE_I4x4;

        if(avctx->partitions & X264_PART_I8X8)

            x4->params.analyse.inter |= X264_ANALYSE_I8x8;

        if(avctx->partitions & X264_PART_P8X8)

            x4->params.analyse.inter |= X264_ANALYSE_PSUB16x16;

        if(avctx->partitions & X264_PART_P4X4)

            x4->params.analyse.inter |= X264_ANALYSE_PSUB8x8;

        if(avctx->partitions & X264_PART_B8X8)

            x4->params.analyse.inter |= X264_ANALYSE_BSUB16x16;

    }

    x4->params.analyse.i_direct_mv_pred = avctx->directpred;

    x4->params.analyse.b_weighted_bipred = avctx->flags2 & CODEC_FLAG2_WPRED;

    if(avctx->me_method == ME_EPZS)

        x4->params.analyse.i_me_method = X264_ME_DIA;

    else if(avctx->me_method == ME_HEX)

        x4->params.analyse.i_me_method = X264_ME_HEX;

    else if(avctx->me_method == ME_UMH)

        x4->params.analyse.i_me_method = X264_ME_UMH;

    else if(avctx->me_method == ME_FULL)

        x4->params.analyse.i_me_method = X264_ME_ESA;

    else if(avctx->me_method == ME_TESA)

        x4->params.analyse.i_me_method = X264_ME_TESA;

    else x4->params.analyse.i_me_method = X264_ME_HEX;

    x4->params.analyse.i_me_range = avctx->me_range;

    x4->params.analyse.i_subpel_refine = avctx->me_subpel_quality;

    x4->params.analyse.b_bidir_me = avctx->bidir_refine > 0;

    x4->params.analyse.b_bframe_rdo = avctx->flags2 & CODEC_FLAG2_BRDO;

    x4->params.analyse.b_mixed_references =

        avctx->flags2 & CODEC_FLAG2_MIXED_REFS;

    x4->params.analyse.b_chroma_me = avctx->me_cmp & FF_CMP_CHROMA;

    x4->params.analyse.b_transform_8x8 = avctx->flags2 & CODEC_FLAG2_8X8DCT;

    x4->params.analyse.b_fast_pskip = avctx->flags2 & CODEC_FLAG2_FASTPSKIP;

    x4->params.analyse.i_trellis = avctx->trellis;

    x4->params.analyse.i_noise_reduction = avctx->noise_reduction;

    if(avctx->level > 0) x4->params.i_level_idc = avctx->level;

    x4->params.rc.f_rate_tolerance =

        (float)avctx->bit_rate_tolerance/avctx->bit_rate;

    if((avctx->rc_buffer_size != 0) &&

            (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)){

        x4->params.rc.f_vbv_buffer_init =

            (float)avctx->rc_initial_buffer_occupancy/avctx->rc_buffer_size;

    }

    else x4->params.rc.f_vbv_buffer_init = 0.9;

    x4->params.rc.f_ip_factor = 1/fabs(avctx->i_quant_factor);

    x4->params.rc.f_pb_factor = avctx->b_quant_factor;

    x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;

    x4->params.rc.psz_rc_eq = avctx->rc_eq;

    x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR;

    x4->params.i_log_level = X264_LOG_DEBUG;

    x4->params.b_aud = avctx->flags2 & CODEC_FLAG2_AUD;

    x4->params.i_threads = avctx->thread_count;

    x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT;

    if(avctx->flags & CODEC_FLAG_GLOBAL_HEADER){

        x4->params.b_repeat_headers = 0;

    }

    x4->enc = x264_encoder_open(&x4->params);

    if(!x4->enc)

        return -1;

    avctx->coded_frame = &x4->out_pic;

    if(avctx->flags & CODEC_FLAG_GLOBAL_HEADER){

        x264_nal_t *nal;

        int nnal, i, s = 0;

        x264_encoder_headers(x4->enc, &nal, &nnal);

        /* 5 bytes NAL header + worst case escaping */

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

            s += 5 + nal[i].i_payload * 4 / 3;

        avctx->extradata = av_malloc(s);

        avctx->extradata_size = encode_nals(avctx->extradata, s, nal, nnal);

    }

    return 0;

}


int configure_filtergraph(FilterGraph *fg)

{

    AVFilterInOut *inputs, *outputs, *cur;

    int ret, i, simple = !fg->graph_desc;

    const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :

                                      fg->graph_desc;

    avfilter_graph_free(&fg->graph);

    if (!(fg->graph = avfilter_graph_alloc()))

        return AVERROR(ENOMEM);

    if (simple) {

        OutputStream *ost = fg->outputs[0]->ost;

        char args[512];

        AVDictionaryEntry *e = NULL;

        snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);

        fg->graph->scale_sws_opts = av_strdup(args);

        args[0] = '\0';

        while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,

                                AV_DICT_IGNORE_SUFFIX))) {

            av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);

        }

        if (strlen(args))

            args[strlen(args) - 1] = '\0';

        fg->graph->resample_lavr_opts = av_strdup(args);

    }

    if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)

        return ret;

    if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {

        av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "

               "exactly one input and output.\n", graph_desc);

        return AVERROR(EINVAL);

    }

    for (cur = inputs, i = 0; cur; cur = cur->next, i++)

        if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0)

            return ret;

    avfilter_inout_free(&inputs);

    for (cur = outputs, i = 0; cur; cur = cur->next, i++)

        configure_output_filter(fg, fg->outputs[i], cur);

    avfilter_inout_free(&outputs);

    if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)

        return ret;

    return 0;

}


inline static void RENAME(hcscale)(uint16_t *dst, long dstWidth, uint8_t *src1, uint8_t *src2,

				   int srcW, int xInc, int flags, int canMMX2BeUsed, int16_t *hChrFilter,

				   int16_t *hChrFilterPos, int hChrFilterSize, void *funnyUVCode,

				   int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,

				   int32_t *mmx2FilterPos)

{

    if(srcFormat==IMGFMT_YUY2)

    {

	RENAME(yuy2ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_UYVY)

    {

	RENAME(uyvyToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_BGR32)

    {

	RENAME(bgr32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_BGR24)

    {

	RENAME(bgr24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_BGR16)

    {

	RENAME(bgr16ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_BGR15)

    {

	RENAME(bgr15ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_RGB32)

    {

	RENAME(rgb32ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(srcFormat==IMGFMT_RGB24)

    {

	RENAME(rgb24ToUV)(formatConvBuffer, formatConvBuffer+2048, src1, src2, srcW);

	src1= formatConvBuffer;

	src2= formatConvBuffer+2048;

    }

    else if(isGray(srcFormat))

    {

    	return;

    }

#ifdef HAVE_MMX

	// use the new MMX scaler if the mmx2 can't be used (its faster than the x86asm one)

    if(!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))

#else

    if(!(flags&SWS_FAST_BILINEAR))

#endif

    {

    	RENAME(hScale)(dst     , dstWidth, src1, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

    	RENAME(hScale)(dst+2048, dstWidth, src2, srcW, xInc, hChrFilter, hChrFilterPos, hChrFilterSize);

    }

    else // Fast Bilinear upscale / crap downscale

    {

#if defined(ARCH_X86) || defined(ARCH_X86_64)

#ifdef HAVE_MMX2

	int i;

	if(canMMX2BeUsed)

	{

		asm volatile(

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

			"mov %0, %%"REG_c"		\n\t"

			"mov %1, %%"REG_D"		\n\t"

			"mov %2, %%"REG_d"		\n\t"

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

			"xor %%"REG_a", %%"REG_a"	\n\t" // i

			PREFETCH" (%%"REG_c")		\n\t"

			PREFETCH" 32(%%"REG_c")		\n\t"

			PREFETCH" 64(%%"REG_c")		\n\t"

#ifdef ARCH_X86_64

#define FUNNY_UV_CODE \

			"movl (%%"REG_b"), %%esi	\n\t"\

			"call *%4			\n\t"\

			"movl (%%"REG_b", %%"REG_a"), %%esi\n\t"\

			"add %%"REG_S", %%"REG_c"	\n\t"\

			"add %%"REG_a", %%"REG_D"	\n\t"\

			"xor %%"REG_a", %%"REG_a"	\n\t"\

#else

#define FUNNY_UV_CODE \

			"movl (%%"REG_b"), %%esi	\n\t"\

			"call *%4			\n\t"\

			"addl (%%"REG_b", %%"REG_a"), %%"REG_c"\n\t"\

			"add %%"REG_a", %%"REG_D"	\n\t"\

			"xor %%"REG_a", %%"REG_a"	\n\t"\

#endif

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

			"xor %%"REG_a", %%"REG_a"	\n\t" // i

			"mov %5, %%"REG_c"		\n\t" // src

			"mov %1, %%"REG_D"		\n\t" // buf1

			"add $4096, %%"REG_D"		\n\t"

			PREFETCH" (%%"REG_c")		\n\t"

			PREFETCH" 32(%%"REG_c")		\n\t"

			PREFETCH" 64(%%"REG_c")		\n\t"

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

FUNNY_UV_CODE

			:: "m" (src1), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),

			"m" (funnyUVCode), "m" (src2)

			: "%"REG_a, "%"REG_b, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

		);

		for(i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)

		{

//			printf("%d %d %d\n", dstWidth, i, srcW);

			dst[i] = src1[srcW-1]*128;

			dst[i+2048] = src2[srcW-1]*128;

		}

	}

	else

	{

#endif

	long xInc_shr16 = (long) (xInc >> 16);

	int xInc_mask = xInc & 0xffff;

	asm volatile(

		"xor %%"REG_a", %%"REG_a"	\n\t" // i

		"xor %%"REG_b", %%"REG_b"		\n\t" // xx

		"xorl %%ecx, %%ecx		\n\t" // 2*xalpha

		ASMALIGN16

		"1:				\n\t"

		"mov %0, %%"REG_S"		\n\t"

		"movzbl  (%%"REG_S", %%"REG_b"), %%edi	\n\t" //src[xx]

		"movzbl 1(%%"REG_S", %%"REG_b"), %%esi	\n\t" //src[xx+1]

		"subl %%edi, %%esi		\n\t" //src[xx+1] - src[xx]

		"imull %%ecx, %%esi		\n\t" //(src[xx+1] - src[xx])*2*xalpha

		"shll $16, %%edi		\n\t"

		"addl %%edi, %%esi		\n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

		"mov %1, %%"REG_D"		\n\t"

		"shrl $9, %%esi			\n\t"

		"movw %%si, (%%"REG_D", %%"REG_a", 2)\n\t"

		"movzbl  (%5, %%"REG_b"), %%edi	\n\t" //src[xx]

		"movzbl 1(%5, %%"REG_b"), %%esi	\n\t" //src[xx+1]

		"subl %%edi, %%esi		\n\t" //src[xx+1] - src[xx]

		"imull %%ecx, %%esi		\n\t" //(src[xx+1] - src[xx])*2*xalpha

		"shll $16, %%edi		\n\t"

		"addl %%edi, %%esi		\n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

		"mov %1, %%"REG_D"		\n\t"

		"shrl $9, %%esi			\n\t"

		"movw %%si, 4096(%%"REG_D", %%"REG_a", 2)\n\t"

		"addw %4, %%cx			\n\t" //2*xalpha += xInc&0xFF

		"adc %3, %%"REG_b"		\n\t" //xx+= xInc>>8 + carry

		"add $1, %%"REG_a"		\n\t"

		"cmp %2, %%"REG_a"		\n\t"

		" jb 1b				\n\t"

/* GCC-3.3 makes MPlayer crash on IA-32 machines when using "g" operand here,

   which is needed to support GCC-4.0 */

#if defined(ARCH_X86_64) && ((__GNUC__ > 3) || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4))

		:: "m" (src1), "m" (dst), "g" ((long)dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#else

		:: "m" (src1), "m" (dst), "m" ((long)dstWidth), "m" (xInc_shr16), "m" (xInc_mask),

#endif

		"r" (src2)

		: "%"REG_a, "%"REG_b, "%ecx", "%"REG_D, "%esi"

		);

#ifdef HAVE_MMX2

	} //if MMX2 can't be used

#endif

#else

	int i;

	unsigned int xpos=0;

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

	{

		register unsigned int xx=xpos>>16;

		register unsigned int xalpha=(xpos&0xFFFF)>>9;

		dst[i]=(src1[xx]*(xalpha^127)+src1[xx+1]*xalpha);

		dst[i+2048]=(src2[xx]*(xalpha^127)+src2[xx+1]*xalpha);

/* slower

	  dst[i]= (src1[xx]<<7) + (src1[xx+1] - src1[xx])*xalpha;

	  dst[i+2048]=(src2[xx]<<7) + (src2[xx+1] - src2[xx])*xalpha;

*/

		xpos+=xInc;

	}

#endif

   }

}


static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,

                            void *value, size_t size, int flags)

{

    char *buffer;

    int ret;

    if (strncmp(name, "user.virtfs.", 12) == 0) {

        /*

         * Don't allow fetch of user.virtfs namesapce

         * in case of mapped security

         */

        errno = EACCES;

        return -1;

    }

    buffer = rpath(ctx, path);

    ret = lsetxattr(buffer, name, value, size, flags);

    g_free(buffer);

    return ret;

}


static void gen_tlbiva(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    TCGv t0;

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    t0 = tcg_temp_new();

    gen_addr_reg_index(ctx, t0);

    gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);

    tcg_temp_free(t0);

#endif

}


static void hdcd_reset(hdcd_state_t *state, unsigned rate)

{

    int i;

    state->window = 0;

    state->readahead = 32;

    state->arg = 0;

    state->control = 0;

    state->running_gain = 0;

    state->sustain = 0;

    state->sustain_reset = rate * 10;

    state->code_counterA = 0;

    state->code_counterA_almost = 0;

    state->code_counterB = 0;

    state->code_counterB_checkfails = 0;

    state->code_counterC = 0;

    state->code_counterC_unmatched = 0;

    state->count_peak_extend = 0;

    state->count_transient_filter = 0;

    for(i = 0; i < 16; i++) state->gain_counts[i] = 0;

    state->max_gain = 0;

    state->count_sustain_expired = -1;

}