static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)

{

    MovieContext *movie = ctx->priv;

    AVPacket *pkt = &movie->pkt;

    enum AVMediaType frame_type;

    MovieStream *st;

    int ret, got_frame = 0, pkt_out_id;

    AVFilterLink *outlink;

    if (!pkt->size) {

        if (movie->eof) {

            if (movie->st[out_id].done) {

                if (movie->loop_count != 1) {

                    ret = rewind_file(ctx);

                    if (ret < 0)

                        return ret;

                    movie->loop_count -= movie->loop_count > 1;

                    av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n");

                    return 0; /* retry */

                }

                return AVERROR_EOF;

            }

            pkt->stream_index = movie->st[out_id].st->index;

            /* packet is already ready for flushing */

        } else {

            ret = av_read_frame(movie->format_ctx, &movie->pkt0);

            if (ret < 0) {

                av_init_packet(&movie->pkt0); /* ready for flushing */

                *pkt = movie->pkt0;

                if (ret == AVERROR_EOF) {

                    movie->eof = 1;

                    return 0; /* start flushing */

                }

                return ret;

            }

            *pkt = movie->pkt0;

        }

    }

    pkt_out_id = pkt->stream_index > movie->max_stream_index ? -1 :

                 movie->out_index[pkt->stream_index];

    if (pkt_out_id < 0) {

        av_free_packet(&movie->pkt0);

        pkt->size = 0; /* ready for next run */

        pkt->data = NULL;

        return 0;

    }

    st = &movie->st[pkt_out_id];

    outlink = ctx->outputs[pkt_out_id];

    movie->frame = av_frame_alloc();

    if (!movie->frame)

        return AVERROR(ENOMEM);

    frame_type = st->st->codec->codec_type;

    switch (frame_type) {

    case AVMEDIA_TYPE_VIDEO:

        ret = avcodec_decode_video2(st->st->codec, movie->frame, &got_frame, pkt);

        break;

    case AVMEDIA_TYPE_AUDIO:

        ret = avcodec_decode_audio4(st->st->codec, movie->frame, &got_frame, pkt);

        break;

    default:

        ret = AVERROR(ENOSYS);

        break;

    }

    if (ret < 0) {

        av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret));

        av_frame_free(&movie->frame);

        av_free_packet(&movie->pkt0);

        movie->pkt.size = 0;

        movie->pkt.data = NULL;

        return 0;

    }

    if (!ret || st->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

        ret = pkt->size;

    pkt->data += ret;

    pkt->size -= ret;

    if (pkt->size <= 0) {

        av_free_packet(&movie->pkt0);

        pkt->size = 0; /* ready for next run */

        pkt->data = NULL;

    }

    if (!got_frame) {

        if (!ret)

            st->done = 1;

        av_frame_free(&movie->frame);

        return 0;

    }

    movie->frame->pts = av_frame_get_best_effort_timestamp(movie->frame);

    av_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name,

            describe_frame_to_str((char[1024]){0}, 1024, movie->frame, frame_type, outlink));

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

        if (movie->frame->format != outlink->format) {

            av_log(ctx, AV_LOG_ERROR, "Format changed %s -> %s, discarding frame\n",

                av_get_pix_fmt_name(outlink->format),

                av_get_pix_fmt_name(movie->frame->format)

                );

            av_frame_free(&movie->frame);

            return 0;

        }

    }

    ret = ff_filter_frame(outlink, movie->frame);

    movie->frame = NULL;

    if (ret < 0)

        return ret;

    return pkt_out_id == out_id;

}


void blk_remove_bs(BlockBackend *blk)

{

    BlockDriverState *bs;

    ThrottleTimers *tt;

    notifier_list_notify(&blk->remove_bs_notifiers, blk);

    if (blk->public.throttle_group_member.throttle_state) {

        tt = &blk->public.throttle_group_member.throttle_timers;

        bs = blk_bs(blk);

        bdrv_drained_begin(bs);

        throttle_timers_detach_aio_context(tt);

        bdrv_drained_end(bs);

    }

    blk_update_root_state(blk);

    bdrv_root_unref_child(blk->root);

    blk->root = NULL;

}


static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s,

                        MemoryRegion *address_space, MemoryRegion *io)

{

    s->scratch_size = SVGA_SCRATCH_SIZE;

    s->scratch = g_malloc(s->scratch_size * 4);

    s->vga.con = graphic_console_init(dev, 0, &vmsvga_ops, s);

    s->fifo_size = SVGA_FIFO_SIZE;

    memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size,

                           &error_abort);

    vmstate_register_ram_global(&s->fifo_ram);

    s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);

    vga_common_init(&s->vga, OBJECT(dev), true);

    vga_init(&s->vga, OBJECT(dev), address_space, io, true);

    vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);

    s->new_depth = 32;

}


static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
{
    X86CPUClass *xcc = X86_CPU_CLASS(oc);
    CPUClass *cc = CPU_CLASS(oc);
    DeviceClass *dc = DEVICE_CLASS(oc);
    xcc->parent_realize = dc->realize;
    dc->realize = x86_cpu_realizefn;
    dc->props = x86_cpu_properties;
    xcc->parent_reset = cc->reset;
    cc->reset = x86_cpu_reset;
    cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
    cc->class_by_name = x86_cpu_class_by_name;
    cc->parse_features = x86_cpu_parse_featurestr;
    cc->has_work = x86_cpu_has_work;
    cc->do_interrupt = x86_cpu_do_interrupt;
    cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
    cc->dump_state = x86_cpu_dump_state;
    cc->set_pc = x86_cpu_set_pc;
    cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
    cc->gdb_read_register = x86_cpu_gdb_read_register;
    cc->gdb_write_register = x86_cpu_gdb_write_register;
    cc->get_arch_id = x86_cpu_get_arch_id;
    cc->get_paging_enabled = x86_cpu_get_paging_enabled;
#ifdef CONFIG_USER_ONLY
    cc->handle_mmu_fault = x86_cpu_handle_mmu_fault;
#else
    cc->get_memory_mapping = x86_cpu_get_memory_mapping;
    cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
    cc->write_elf64_note = x86_cpu_write_elf64_note;
    cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
    cc->write_elf32_note = x86_cpu_write_elf32_note;
    cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
    cc->vmsd = &vmstate_x86_cpu;
#endif
    cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
#ifndef CONFIG_USER_ONLY
    cc->debug_excp_handler = breakpoint_handler;
#endif
    cc->cpu_exec_enter = x86_cpu_exec_enter;
    cc->cpu_exec_exit = x86_cpu_exec_exit;
}


static int ds1225y_set_to_mode(ds1225y_t *NVRAM, nvram_open_mode mode, const char *filemode)

{

    if (NVRAM->open_mode != mode)

    {

        if (NVRAM->file)

            qemu_fclose(NVRAM->file);

        NVRAM->file = qemu_fopen(NVRAM->filename, filemode);

        NVRAM->open_mode = mode;

    }

    return (NVRAM->file != NULL);

}


static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p)

{

    USBWacomState *s = (USBWacomState *) dev;

    int ret = 0;

    switch (p->pid) {

    case USB_TOKEN_IN:

        if (p->devep == 1) {

            if (!(s->changed || s->idle))

                return USB_RET_NAK;

            s->changed = 0;

            if (s->mode == WACOM_MODE_HID)

                ret = usb_mouse_poll(s, p->data, p->len);

            else if (s->mode == WACOM_MODE_WACOM)

                ret = usb_wacom_poll(s, p->data, p->len);

            break;

        }

        /* Fall through.  */

    case USB_TOKEN_OUT:

    default:

        ret = USB_RET_STALL;

        break;

    }

    return ret;

}


static float quantize_band_cost(struct AACEncContext *s, const float *in,

                                const float *scaled, int size, int scale_idx,

                                int cb, const float lambda, const float uplim,

                                int *bits)

{

    const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];

    const float  Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];

    const float CLIPPED_ESCAPE = 165140.0f*IQ;

    int i, j, k;

    float cost = 0;

    const int dim = cb < FIRST_PAIR_BT ? 4 : 2;

    int resbits = 0;

#ifndef USE_REALLY_FULL_SEARCH

    const float  Q34 = sqrtf(Q * sqrtf(Q));

    const int range  = aac_cb_range[cb];

    const int maxval = aac_cb_maxval[cb];

    int offs[4];

#endif /* USE_REALLY_FULL_SEARCH */

    if (!cb) {

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

            cost += in[i]*in[i];

        if (bits)

            *bits = 0;

        return cost * lambda;

    }

#ifndef USE_REALLY_FULL_SEARCH

    offs[0] = 1;

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

        offs[i] = offs[i-1]*range;

    quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval);

#endif /* USE_REALLY_FULL_SEARCH */

    for (i = 0; i < size; i += dim) {

        float mincost;

        int minidx  = 0;

        int minbits = 0;

        const float *vec;

#ifndef USE_REALLY_FULL_SEARCH

        int (*quants)[2] = &s->qcoefs[i];

        mincost = 0.0f;

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

            mincost += in[i+j]*in[i+j];

        minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;

        minbits = ff_aac_spectral_bits[cb-1][minidx];

        mincost = mincost * lambda + minbits;

        for (j = 0; j < (1<<dim); j++) {

            float rd = 0.0f;

            int curbits;

            int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;

            int same   = 0;

            for (k = 0; k < dim; k++) {

                if ((j & (1 << k)) && quants[k][0] == quants[k][1]) {

                    same = 1;

                    break;

                }

            }

            if (same)

                continue;

            for (k = 0; k < dim; k++)

                curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];

            curbits =  ff_aac_spectral_bits[cb-1][curidx];

            vec     = &ff_aac_codebook_vectors[cb-1][curidx*dim];

#else

        mincost = INFINITY;

        vec = ff_aac_codebook_vectors[cb-1];

        for (j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim) {

            float rd = 0.0f;

            int curbits = ff_aac_spectral_bits[cb-1][j];

#endif /* USE_REALLY_FULL_SEARCH */

            if (IS_CODEBOOK_UNSIGNED(cb)) {

                for (k = 0; k < dim; k++) {

                    float t = fabsf(in[i+k]);

                    float di;

                    if (vec[k] == 64.0f) { //FIXME: slow

                        //do not code with escape sequence small values

                        if (t < 39.0f*IQ) {

                            rd = INFINITY;

                            break;

                        }

                        if (t >= CLIPPED_ESCAPE) {

                            di = t - CLIPPED_ESCAPE;

                            curbits += 21;

                        } else {

                            int c = av_clip(quant(t, Q), 0, 8191);

                            di = t - c*cbrtf(c)*IQ;

                            curbits += av_log2(c)*2 - 4 + 1;

                        }

                    } else {

                        di = t - vec[k]*IQ;

                    }

                    if (vec[k] != 0.0f)

                        curbits++;

                    rd += di*di;

                }

            } else {

                for (k = 0; k < dim; k++) {

                    float di = in[i+k] - vec[k]*IQ;

                    rd += di*di;

                }

            }

            rd = rd * lambda + curbits;

            if (rd < mincost) {

                mincost = rd;

                minidx  = j;

                minbits = curbits;

            }

        }

        cost    += mincost;

        resbits += minbits;

        if (cost >= uplim)

            return uplim;

    }

    if (bits)

        *bits = resbits;

    return cost;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sysbus_esp_realize;

    dc->reset = sysbus_esp_hard_reset;

    dc->vmsd = &vmstate_sysbus_esp_scsi;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

}


static int vfio_initfn(PCIDevice *pdev)

{

    VFIODevice *pvdev, *vdev = DO_UPCAST(VFIODevice, pdev, pdev);

    VFIOGroup *group;

    char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name;

    ssize_t len;

    struct stat st;

    int groupid;

    int ret;

    /* Check that the host device exists */

    snprintf(path, sizeof(path),

             "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/",

             vdev->host.domain, vdev->host.bus, vdev->host.slot,

             vdev->host.function);

    if (stat(path, &st) < 0) {

        error_report("vfio: error: no such host device: %s", path);

        return -errno;

    }

    strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1);

    len = readlink(path, iommu_group_path, PATH_MAX);

    if (len <= 0) {

        error_report("vfio: error no iommu_group for device");

        return -errno;

    }

    iommu_group_path[len] = 0;

    group_name = basename(iommu_group_path);

    if (sscanf(group_name, "%d", &groupid) != 1) {

        error_report("vfio: error reading %s: %m", path);

        return -errno;

    }

    DPRINTF("%s(%04x:%02x:%02x.%x) group %d\n", __func__, vdev->host.domain,

            vdev->host.bus, vdev->host.slot, vdev->host.function, groupid);

    group = vfio_get_group(groupid);

    if (!group) {

        error_report("vfio: failed to get group %d", groupid);

        return -ENOENT;

    }

    snprintf(path, sizeof(path), "%04x:%02x:%02x.%01x",

            vdev->host.domain, vdev->host.bus, vdev->host.slot,

            vdev->host.function);

    QLIST_FOREACH(pvdev, &group->device_list, next) {

        if (pvdev->host.domain == vdev->host.domain &&

            pvdev->host.bus == vdev->host.bus &&

            pvdev->host.slot == vdev->host.slot &&

            pvdev->host.function == vdev->host.function) {

            error_report("vfio: error: device %s is already attached", path);

            vfio_put_group(group);

            return -EBUSY;

        }

    }

    ret = vfio_get_device(group, path, vdev);

    if (ret) {

        error_report("vfio: failed to get device %s", path);

        vfio_put_group(group);

        return ret;

    }

    /* Get a copy of config space */

    ret = pread(vdev->fd, vdev->pdev.config,

                MIN(pci_config_size(&vdev->pdev), vdev->config_size),

                vdev->config_offset);

    if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) {

        ret = ret < 0 ? -errno : -EFAULT;

        error_report("vfio: Failed to read device config space");

        goto out_put;

    }

    /* vfio emulates a lot for us, but some bits need extra love */

    vdev->emulated_config_bits = g_malloc0(vdev->config_size);

    /* QEMU can choose to expose the ROM or not */

    memset(vdev->emulated_config_bits + PCI_ROM_ADDRESS, 0xff, 4);

    /* QEMU can change multi-function devices to single function, or reverse */

    vdev->emulated_config_bits[PCI_HEADER_TYPE] =

                                              PCI_HEADER_TYPE_MULTI_FUNCTION;

    /* Restore or clear multifunction, this is always controlled by QEMU */

    if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {

        vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;

    } else {

        vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;

    }

    /*

     * Clear host resource mapping info.  If we choose not to register a

     * BAR, such as might be the case with the option ROM, we can get

     * confusing, unwritable, residual addresses from the host here.

     */

    memset(&vdev->pdev.config[PCI_BASE_ADDRESS_0], 0, 24);

    memset(&vdev->pdev.config[PCI_ROM_ADDRESS], 0, 4);

    vfio_pci_size_rom(vdev);

    ret = vfio_early_setup_msix(vdev);

    if (ret) {

        goto out_put;

    }

    vfio_map_bars(vdev);

    ret = vfio_add_capabilities(vdev);

    if (ret) {

        goto out_teardown;

    }

    /* QEMU emulates all of MSI & MSIX */

    if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {

        memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff,

               MSIX_CAP_LENGTH);

    }

    if (pdev->cap_present & QEMU_PCI_CAP_MSI) {

        memset(vdev->emulated_config_bits + pdev->msi_cap, 0xff,

               vdev->msi_cap_size);

    }

    if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {

        vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,

                                                  vfio_intx_mmap_enable, vdev);

        pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_update_irq);

        ret = vfio_enable_intx(vdev);

        if (ret) {

            goto out_teardown;

        }

    }

    add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);

    vfio_register_err_notifier(vdev);

    return 0;

out_teardown:

    pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);

    vfio_teardown_msi(vdev);

    vfio_unmap_bars(vdev);

out_put:

    g_free(vdev->emulated_config_bits);

    vfio_put_device(vdev);

    vfio_put_group(group);

    return ret;

}