static void memory_region_iorange_write(IORange *iorange,

                                        uint64_t offset,

                                        unsigned width,

                                        uint64_t data)

{

    MemoryRegionIORange *mrio

        = container_of(iorange, MemoryRegionIORange, iorange);

    MemoryRegion *mr = mrio->mr;

    offset += mrio->offset;

    if (mr->ops->old_portio) {

        const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset,

                                                    width, true);

        if (mrp) {

            mrp->write(mr->opaque, offset, data);

        } else if (width == 2) {

            mrp = find_portio(mr, offset - mrio->offset, 1, true);

            assert(mrp);

            mrp->write(mr->opaque, offset, data & 0xff);

            mrp->write(mr->opaque, offset + 1, data >> 8);

        }

        return;

    }

    access_with_adjusted_size(offset, &data, width,

                              mr->ops->impl.min_access_size,

                              mr->ops->impl.max_access_size,

                              memory_region_write_accessor, mr);

}


int msi_init(struct PCIDevice *dev, uint8_t offset,

             unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask)

{

    unsigned int vectors_order;

    uint16_t flags;

    uint8_t cap_size;

    int config_offset;

    if (!msi_supported) {

        return -ENOTSUP;

    }

    MSI_DEV_PRINTF(dev,

                   "init offset: 0x%"PRIx8" vector: %"PRId8

                   " 64bit %d mask %d\n",

                   offset, nr_vectors, msi64bit, msi_per_vector_mask);

    assert(!(nr_vectors & (nr_vectors - 1)));   /* power of 2 */

    assert(nr_vectors > 0);

    assert(nr_vectors <= PCI_MSI_VECTORS_MAX);

    /* the nr of MSI vectors is up to 32 */

    vectors_order = ffs(nr_vectors) - 1;

    flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1);

    if (msi64bit) {

        flags |= PCI_MSI_FLAGS_64BIT;

    }

    if (msi_per_vector_mask) {

        flags |= PCI_MSI_FLAGS_MASKBIT;

    }

    cap_size = msi_cap_sizeof(flags);

    config_offset = pci_add_capability(dev, PCI_CAP_ID_MSI, offset, cap_size);

    if (config_offset < 0) {

        return config_offset;

    }

    dev->msi_cap = config_offset;

    dev->cap_present |= QEMU_PCI_CAP_MSI;

    pci_set_word(dev->config + msi_flags_off(dev), flags);

    pci_set_word(dev->wmask + msi_flags_off(dev),

                 PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE);

    pci_set_long(dev->wmask + msi_address_lo_off(dev),

                 PCI_MSI_ADDRESS_LO_MASK);

    if (msi64bit) {

        pci_set_long(dev->wmask + msi_address_hi_off(dev), 0xffffffff);

    }

    pci_set_word(dev->wmask + msi_data_off(dev, msi64bit), 0xffff);

    if (msi_per_vector_mask) {

        /* Make mask bits 0 to nr_vectors - 1 writable. */

        pci_set_long(dev->wmask + msi_mask_off(dev, msi64bit),

                     0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));

    }

    return config_offset;

}


static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)

{

    MuxDriver *d = chr->opaque;

    int ret;

    if (!d->timestamps) {

        ret = d->drv->chr_write(d->drv, buf, len);

    } else {

        int i;

        ret = 0;

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

            if (d->linestart) {

                char buf1[64];

                int64_t ti;

                int secs;

                ti = qemu_get_clock(rt_clock);

                if (d->timestamps_start == -1)

                    d->timestamps_start = ti;

                ti -= d->timestamps_start;

                secs = ti / 1000;

                snprintf(buf1, sizeof(buf1),

                         "[%02d:%02d:%02d.%03d] ",

                         secs / 3600,

                         (secs / 60) % 60,

                         secs % 60,

                         (int)(ti % 1000));

                d->drv->chr_write(d->drv, (uint8_t *)buf1, strlen(buf1));

                d->linestart = 0;

            }

            ret += d->drv->chr_write(d->drv, buf+i, 1);

            if (buf[i] == '\n') {

                d->linestart = 1;

            }

        }

    }

    return ret;

}


int qio_channel_socket_listen_sync(QIOChannelSocket *ioc,

                                   SocketAddress *addr,

                                   Error **errp)

{

    int fd;

    trace_qio_channel_socket_listen_sync(ioc, addr);

    fd = socket_listen(addr, errp);

    if (fd < 0) {

        trace_qio_channel_socket_listen_fail(ioc);

        return -1;

    }

    trace_qio_channel_socket_listen_complete(ioc, fd);

    if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {

        close(fd);

        return -1;

    }

    qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_LISTEN);

    return 0;

}


static int rtc_post_load(void *opaque, int version_id)

{

    RTCState *s = opaque;

    if (version_id <= 2 || rtc_clock == QEMU_CLOCK_REALTIME) {

        rtc_set_time(s);

        s->offset = 0;

        check_update_timer(s);

    }

    uint64_t now = qemu_clock_get_ns(rtc_clock);

    if (now < s->next_periodic_time ||

        now > (s->next_periodic_time + get_max_clock_jump())) {

        periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));

    }

#ifdef TARGET_I386

    if (version_id >= 2) {

        if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {

            rtc_coalesced_timer_update(s);

        }

    }

#endif

    return 0;

}


static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)

{

    VirtIOSerial *s = VIRTIO_SERIAL(vdev);

    VirtIOSerialPort *port;

    uint32_t nr_active_ports;

    unsigned int i, max_nr_ports;

    struct virtio_console_config config;

    /* The config space (ignored on the far end in current versions) */

    get_config(vdev, (uint8_t *)&config);

    qemu_put_be16s(f, &config.cols);

    qemu_put_be16s(f, &config.rows);

    qemu_put_be32s(f, &config.max_nr_ports);

    /* The ports map */

    max_nr_ports = s->serial.max_virtserial_ports;

    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {

        qemu_put_be32s(f, &s->ports_map[i]);

    }

    /* Ports */

    nr_active_ports = 0;

    QTAILQ_FOREACH(port, &s->ports, next) {

        nr_active_ports++;

    }

    qemu_put_be32s(f, &nr_active_ports);

    /*

     * Items in struct VirtIOSerialPort.

     */

    QTAILQ_FOREACH(port, &s->ports, next) {

        uint32_t elem_popped;

        qemu_put_be32s(f, &port->id);

        qemu_put_byte(f, port->guest_connected);

        qemu_put_byte(f, port->host_connected);

	elem_popped = 0;

        if (port->elem.out_num) {

            elem_popped = 1;

        }

        qemu_put_be32s(f, &elem_popped);

        if (elem_popped) {

            qemu_put_be32s(f, &port->iov_idx);

            qemu_put_be64s(f, &port->iov_offset);

            qemu_put_buffer(f, (unsigned char *)&port->elem,

                            sizeof(port->elem));

        }

    }

}


static int init_directories(BDRVVVFATState* s,

                            const char *dirname, int heads, int secs,

                            Error **errp)

{

    bootsector_t* bootsector;

    mapping_t* mapping;

    unsigned int i;

    unsigned int cluster;

    memset(&(s->first_sectors[0]),0,0x40*0x200);

    s->cluster_size=s->sectors_per_cluster*0x200;

    s->cluster_buffer=g_malloc(s->cluster_size);

    /*

     * The formula: sc = spf+1+spf*spc*(512*8/fat_type),

     * where sc is sector_count,

     * spf is sectors_per_fat,

     * spc is sectors_per_clusters, and

     * fat_type = 12, 16 or 32.

     */

    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;

    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */

    array_init(&(s->mapping),sizeof(mapping_t));

    array_init(&(s->directory),sizeof(direntry_t));

    /* add volume label */

    {

	direntry_t* entry=array_get_next(&(s->directory));

	entry->attributes=0x28; /* archive | volume label */

        memcpy(entry->name, "QEMU VVFAT ", sizeof(entry->name));

    }

    /* Now build FAT, and write back information into directory */

    init_fat(s);

    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;

    s->cluster_count=sector2cluster(s, s->sector_count);

    mapping = array_get_next(&(s->mapping));

    mapping->begin = 0;

    mapping->dir_index = 0;

    mapping->info.dir.parent_mapping_index = -1;

    mapping->first_mapping_index = -1;

    mapping->path = g_strdup(dirname);

    i = strlen(mapping->path);

    if (i > 0 && mapping->path[i - 1] == '/')

	mapping->path[i - 1] = '\0';

    mapping->mode = MODE_DIRECTORY;

    mapping->read_only = 0;

    s->path = mapping->path;

    for (i = 0, cluster = 0; i < s->mapping.next; i++) {

	/* MS-DOS expects the FAT to be 0 for the root directory

	 * (except for the media byte). */

	/* LATER TODO: still true for FAT32? */

	int fix_fat = (i != 0);

	mapping = array_get(&(s->mapping), i);

        if (mapping->mode & MODE_DIRECTORY) {

	    mapping->begin = cluster;

	    if(read_directory(s, i)) {

                error_setg(errp, "Could not read directory %s",

                           mapping->path);

		return -1;

	    }

	    mapping = array_get(&(s->mapping), i);

	} else {

	    assert(mapping->mode == MODE_UNDEFINED);

	    mapping->mode=MODE_NORMAL;

	    mapping->begin = cluster;

	    if (mapping->end > 0) {

		direntry_t* direntry = array_get(&(s->directory),

			mapping->dir_index);

		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;

		set_begin_of_direntry(direntry, mapping->begin);

	    } else {

		mapping->end = cluster + 1;

		fix_fat = 0;

	    }

	}

	assert(mapping->begin < mapping->end);

	/* next free cluster */

	cluster = mapping->end;

	if(cluster > s->cluster_count) {

            error_setg(errp,

                       "Directory does not fit in FAT%d (capacity %.2f MB)",

                       s->fat_type, s->sector_count / 2000.0);

            return -1;

	}

	/* fix fat for entry */

	if (fix_fat) {

	    int j;

	    for(j = mapping->begin; j < mapping->end - 1; j++)

		fat_set(s, j, j+1);

	    fat_set(s, mapping->end - 1, s->max_fat_value);

	}

    }

    mapping = array_get(&(s->mapping), 0);

    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;

    s->last_cluster_of_root_directory = mapping->end;

    /* the FAT signature */

    fat_set(s,0,s->max_fat_value);

    fat_set(s,1,s->max_fat_value);

    s->current_mapping = NULL;

    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);

    bootsector->jump[0]=0xeb;

    bootsector->jump[1]=0x3e;

    bootsector->jump[2]=0x90;

    memcpy(bootsector->name,"QEMU    ",8);

    bootsector->sector_size=cpu_to_le16(0x200);

    bootsector->sectors_per_cluster=s->sectors_per_cluster;

    bootsector->reserved_sectors=cpu_to_le16(1);

    bootsector->number_of_fats=0x2; /* number of FATs */

    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);

    bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);

    bootsector->media_type=(s->first_sectors_number>1?0xf8:0xf0); /* media descriptor (f8=hd, f0=3.5 fd)*/

    s->fat.pointer[0] = bootsector->media_type;

    bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);

    bootsector->sectors_per_track = cpu_to_le16(secs);

    bootsector->number_of_heads = cpu_to_le16(heads);

    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);

    bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);

    /* LATER TODO: if FAT32, this is wrong */

    bootsector->u.fat16.drive_number=s->first_sectors_number==1?0:0x80; /* fda=0, hda=0x80 */

    bootsector->u.fat16.current_head=0;

    bootsector->u.fat16.signature=0x29;

    bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);

    memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);

    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);

    bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;

    return 0;

}


static void lsp2polyf(const double *lsp, double *f, int lp_half_order)

{

    int i, j;

    f[0] = 1.0;

    f[1] = -2 * lsp[0];

    lsp -= 2;

    for(i=2; i<=lp_half_order; i++)

    {

        double val = -2 * lsp[2*i];

        f[i] = val * f[i-1] + 2*f[i-2];

        for(j=i-1; j>1; j--)

            f[j] += f[j-1] * val + f[j-2];

        f[1] += val;

    }

}


static uint32_t slow_bar_readl(void *opaque, target_phys_addr_t addr)

{

    AssignedDevRegion *d = opaque;

    uint32_t *in = (uint32_t *)(d->u.r_virtbase + addr);

    uint32_t r;

    r = *in;

    DEBUG("slow_bar_readl addr=0x" TARGET_FMT_plx " val=0x%08x\n", addr, r);

    return r;

}


void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,

                            Error **errp)

{

    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);

    if (lpc->pm.acpi_memory_hotplug.is_enabled &&

        object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {

        acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug,

                            dev, errp);

    } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {

        if (lpc->pm.cpu_hotplug_legacy) {

            legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp);

        } else {

            acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.cpuhp_state, dev, errp);

        }

    } else {

        error_setg(errp, "acpi: device plug request for not supported device"

                   " type: %s", object_get_typename(OBJECT(dev)));

    }

}


static int megasas_dcmd_ld_get_list(MegasasState *s, MegasasCmd *cmd)

{

    struct mfi_ld_list info;

    size_t dcmd_size = sizeof(info), resid;

    uint32_t num_ld_disks = 0, max_ld_disks = s->fw_luns;

    uint64_t ld_size;

    BusChild *kid;

    memset(&info, 0, dcmd_size);

    if (cmd->iov_size < dcmd_size) {

        trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size,

                                            dcmd_size);

        return MFI_STAT_INVALID_PARAMETER;

    }

    if (megasas_is_jbod(s)) {

        max_ld_disks = 0;

    }

    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);

        BlockConf *conf = &sdev->conf;

        if (num_ld_disks >= max_ld_disks) {

            break;

        }

        /* Logical device size is in blocks */

        bdrv_get_geometry(conf->bs, &ld_size);

        info.ld_list[num_ld_disks].ld.v.target_id = sdev->id;

        info.ld_list[num_ld_disks].ld.v.lun_id = sdev->lun;

        info.ld_list[num_ld_disks].state = MFI_LD_STATE_OPTIMAL;

        info.ld_list[num_ld_disks].size = cpu_to_le64(ld_size);

        num_ld_disks++;

    }

    info.ld_count = cpu_to_le32(num_ld_disks);

    trace_megasas_dcmd_ld_get_list(cmd->index, num_ld_disks, max_ld_disks);

    resid = dma_buf_read((uint8_t *)&info, dcmd_size, &cmd->qsg);

    cmd->iov_size = dcmd_size - resid;

    return MFI_STAT_OK;

}


static void resume_all_vcpus(void)

{

    CPUState *penv = first_cpu;

    while (penv) {

        penv->stop = 0;

        penv->stopped = 0;

        qemu_thread_signal(penv->thread, SIGUSR1);

        qemu_cpu_kick(penv);

        penv = (CPUState *)penv->next_cpu;

    }

}


static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,

                                         int64_t sector_num, int nb_sectors,

                                         QEMUIOVector *iov)

{

    return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);

}


static void do_audio_out(AVFormatContext *s,

                         AVOutputStream *ost,

                         AVInputStream *ist,

                         unsigned char *buf, int size)

{

    uint8_t *buftmp;

    int64_t audio_out_size, audio_buf_size;

    int64_t allocated_for_size= size;

    int size_out, frame_bytes, ret;

    AVCodecContext *enc= ost->st->codec;

    AVCodecContext *dec= ist->st->codec;

    int osize= av_get_bits_per_sample_format(enc->sample_fmt)/8;

    int isize= av_get_bits_per_sample_format(dec->sample_fmt)/8;

    const int coded_bps = av_get_bits_per_sample(enc->codec->id);

need_realloc:

    audio_buf_size= (allocated_for_size + isize*dec->channels - 1) / (isize*dec->channels);

    audio_buf_size= (audio_buf_size*enc->sample_rate + dec->sample_rate) / dec->sample_rate;

    audio_buf_size= audio_buf_size*2 + 10000; //safety factors for the deprecated resampling API

    audio_buf_size= FFMAX(audio_buf_size, enc->frame_size);

    audio_buf_size*= osize*enc->channels;

    audio_out_size= FFMAX(audio_buf_size, enc->frame_size * osize * enc->channels);

    if(coded_bps > 8*osize)

        audio_out_size= audio_out_size * coded_bps / (8*osize);

    audio_out_size += FF_MIN_BUFFER_SIZE;

    if(audio_out_size > INT_MAX || audio_buf_size > INT_MAX){

        fprintf(stderr, "Buffer sizes too large\n");

        ffmpeg_exit(1);

    }

    av_fast_malloc(&audio_buf, &allocated_audio_buf_size, audio_buf_size);

    av_fast_malloc(&audio_out, &allocated_audio_out_size, audio_out_size);

    if (!audio_buf || !audio_out){

        fprintf(stderr, "Out of memory in do_audio_out\n");

        ffmpeg_exit(1);

    }

    if (enc->channels != dec->channels)

        ost->audio_resample = 1;

    if (ost->audio_resample && !ost->resample) {

        if (dec->sample_fmt != SAMPLE_FMT_S16)

            fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");

        ost->resample = av_audio_resample_init(enc->channels,    dec->channels,

                                               enc->sample_rate, dec->sample_rate,

                                               enc->sample_fmt,  dec->sample_fmt,

                                               16, 10, 0, 0.8);

        if (!ost->resample) {

            fprintf(stderr, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",

                    dec->channels, dec->sample_rate,

                    enc->channels, enc->sample_rate);

            ffmpeg_exit(1);

        }

    }

#define MAKE_SFMT_PAIR(a,b) ((a)+SAMPLE_FMT_NB*(b))

    if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt &&

        MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt)!=ost->reformat_pair) {

        if (ost->reformat_ctx)

            av_audio_convert_free(ost->reformat_ctx);

        ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,

                                                   dec->sample_fmt, 1, NULL, 0);

        if (!ost->reformat_ctx) {

            fprintf(stderr, "Cannot convert %s sample format to %s sample format\n",

                avcodec_get_sample_fmt_name(dec->sample_fmt),

                avcodec_get_sample_fmt_name(enc->sample_fmt));

            ffmpeg_exit(1);

        }

        ost->reformat_pair=MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);

    }

    if(audio_sync_method){

        double delta = get_sync_ipts(ost) * enc->sample_rate - ost->sync_opts

                - av_fifo_size(ost->fifo)/(enc->channels * 2);

        double idelta= delta*dec->sample_rate / enc->sample_rate;

        int byte_delta= ((int)idelta)*2*dec->channels;

        //FIXME resample delay

        if(fabs(delta) > 50){

            if(ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate){

                if(byte_delta < 0){

                    byte_delta= FFMAX(byte_delta, -size);

                    size += byte_delta;

                    buf  -= byte_delta;

                    if(verbose > 2)

                        fprintf(stderr, "discarding %d audio samples\n", (int)-delta);

                    if(!size)

                        return;

                    ist->is_start=0;

                }else{

                    static uint8_t *input_tmp= NULL;

                    input_tmp= av_realloc(input_tmp, byte_delta + size);

                    if(byte_delta > allocated_for_size - size){

                        allocated_for_size= byte_delta + (int64_t)size;

                        goto need_realloc;

                    }

                    ist->is_start=0;

                    memset(input_tmp, 0, byte_delta);

                    memcpy(input_tmp + byte_delta, buf, size);

                    buf= input_tmp;

                    size += byte_delta;

                    if(verbose > 2)

                        fprintf(stderr, "adding %d audio samples of silence\n", (int)delta);

                }

            }else if(audio_sync_method>1){

                int comp= av_clip(delta, -audio_sync_method, audio_sync_method);

                assert(ost->audio_resample);

                if(verbose > 2)

                    fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);

//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));

                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);

            }

        }

    }else

        ost->sync_opts= lrintf(get_sync_ipts(ost) * enc->sample_rate)

                        - av_fifo_size(ost->fifo)/(enc->channels * 2); //FIXME wrong

    if (ost->audio_resample) {

        buftmp = audio_buf;

        size_out = audio_resample(ost->resample,

                                  (short *)buftmp, (short *)buf,

                                  size / (dec->channels * isize));

        size_out = size_out * enc->channels * osize;

    } else {

        buftmp = buf;

        size_out = size;

    }

    if (!ost->audio_resample && dec->sample_fmt!=enc->sample_fmt) {

        const void *ibuf[6]= {buftmp};

        void *obuf[6]= {audio_buf};

        int istride[6]= {isize};

        int ostride[6]= {osize};

        int len= size_out/istride[0];

        if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {

            printf("av_audio_convert() failed\n");

            if (exit_on_error)

                ffmpeg_exit(1);

            return;

        }

        buftmp = audio_buf;

        size_out = len*osize;

    }

    /* now encode as many frames as possible */

    if (enc->frame_size > 1) {

        /* output resampled raw samples */

        if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {

            fprintf(stderr, "av_fifo_realloc2() failed\n");

            ffmpeg_exit(1);

        }

        av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);

        frame_bytes = enc->frame_size * osize * enc->channels;

        while (av_fifo_size(ost->fifo) >= frame_bytes) {

            AVPacket pkt;

            av_init_packet(&pkt);

            av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);

            //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()

            ret = avcodec_encode_audio(enc, audio_out, audio_out_size,

                                       (short *)audio_buf);

            if (ret < 0) {

                fprintf(stderr, "Audio encoding failed\n");

                ffmpeg_exit(1);

            }

            audio_size += ret;

            pkt.stream_index= ost->index;

            pkt.data= audio_out;

            pkt.size= ret;

            if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)

                pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);

            pkt.flags |= AV_PKT_FLAG_KEY;

            write_frame(s, &pkt, enc, bitstream_filters[ost->file_index][pkt.stream_index]);

            ost->sync_opts += enc->frame_size;

        }

    } else {

        AVPacket pkt;

        av_init_packet(&pkt);

        ost->sync_opts += size_out / (osize * enc->channels);

        /* output a pcm frame */

        /* determine the size of the coded buffer */

        size_out /= osize;

        if (coded_bps)

            size_out = size_out*coded_bps/8;

        if(size_out > audio_out_size){

            fprintf(stderr, "Internal error, buffer size too small\n");

            ffmpeg_exit(1);

        }

        //FIXME pass ost->sync_opts as AVFrame.pts in avcodec_encode_audio()

        ret = avcodec_encode_audio(enc, audio_out, size_out,

                                   (short *)buftmp);

        if (ret < 0) {

            fprintf(stderr, "Audio encoding failed\n");

            ffmpeg_exit(1);

        }

        audio_size += ret;

        pkt.stream_index= ost->index;

        pkt.data= audio_out;

        pkt.size= ret;

        if(enc->coded_frame && enc->coded_frame->pts != AV_NOPTS_VALUE)

            pkt.pts= av_rescale_q(enc->coded_frame->pts, enc->time_base, ost->st->time_base);

        pkt.flags |= AV_PKT_FLAG_KEY;

        write_frame(s, &pkt, enc, bitstream_filters[ost->file_index][pkt.stream_index]);

    }

}


static int emulated_initfn(CCIDCardState *base)

{

    EmulatedState *card = DO_UPCAST(EmulatedState, base, base);

    VCardEmulError ret;

    const EnumTable *ptable;

    QSIMPLEQ_INIT(&card->event_list);

    QSIMPLEQ_INIT(&card->guest_apdu_list);

    qemu_mutex_init(&card->event_list_mutex);

    qemu_mutex_init(&card->vreader_mutex);

    qemu_mutex_init(&card->handle_apdu_mutex);

    qemu_cond_init(&card->handle_apdu_cond);

    card->reader = NULL;

    card->quit_apdu_thread = 0;

    if (init_pipe_signaling(card) < 0) {

        return -1;

    }

    card->backend = parse_enumeration(card->backend_str, backend_enum_table, 0);

    if (card->backend == 0) {

        printf("unknown backend, must be one of:\n");

        for (ptable = backend_enum_table; ptable->name != NULL; ++ptable) {

            printf("%s\n", ptable->name);

        }

        return -1;

    }

    /* TODO: a passthru backened that works on local machine. third card type?*/

    if (card->backend == BACKEND_CERTIFICATES) {

        if (card->cert1 != NULL && card->cert2 != NULL && card->cert3 != NULL) {

            ret = emulated_initialize_vcard_from_certificates(card);

        } else {

            printf("%s: you must provide all three certs for"

                   " certificates backend\n", EMULATED_DEV_NAME);

            return -1;

        }

    } else {

        if (card->backend != BACKEND_NSS_EMULATED) {

            printf("%s: bad backend specified. The options are:\n%s (default),"

                " %s.\n", EMULATED_DEV_NAME, BACKEND_NSS_EMULATED_NAME,

                BACKEND_CERTIFICATES_NAME);

            return -1;

        }

        if (card->cert1 != NULL || card->cert2 != NULL || card->cert3 != NULL) {

            printf("%s: unexpected cert parameters to nss emulated backend\n",

                   EMULATED_DEV_NAME);

            return -1;

        }

        /* default to mirroring the local hardware readers */

        ret = wrap_vcard_emul_init(NULL);

    }

    if (ret != VCARD_EMUL_OK) {

        printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME);

        return -1;

    }

    qemu_thread_create(&card->event_thread_id, event_thread, card,

                       QEMU_THREAD_JOINABLE);

    qemu_thread_create(&card->apdu_thread_id, handle_apdu_thread, card,

                       QEMU_THREAD_JOINABLE);

    return 0;

}


static void mirror_exit(BlockJob *job, void *opaque)

{

    MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);

    MirrorExitData *data = opaque;

    AioContext *replace_aio_context = NULL;

    BlockDriverState *src = blk_bs(s->common.blk);

    BlockDriverState *target_bs = blk_bs(s->target);

    /* Make sure that the source BDS doesn't go away before we called

     * block_job_completed(). */

    bdrv_ref(src);

    if (s->to_replace) {

        replace_aio_context = bdrv_get_aio_context(s->to_replace);

        aio_context_acquire(replace_aio_context);

    }

    if (s->should_complete && data->ret == 0) {

        BlockDriverState *to_replace = src;

        if (s->to_replace) {

            to_replace = s->to_replace;

        }

        if (bdrv_get_flags(target_bs) != bdrv_get_flags(to_replace)) {

            bdrv_reopen(target_bs, bdrv_get_flags(to_replace), NULL);

        }

        /* The mirror job has no requests in flight any more, but we need to

         * drain potential other users of the BDS before changing the graph. */

        bdrv_drained_begin(target_bs);

        bdrv_replace_in_backing_chain(to_replace, target_bs);

        bdrv_drained_end(target_bs);

        /* We just changed the BDS the job BB refers to */

        blk_remove_bs(job->blk);

        blk_insert_bs(job->blk, src);

    }

    if (s->to_replace) {

        bdrv_op_unblock_all(s->to_replace, s->replace_blocker);

        error_free(s->replace_blocker);

        bdrv_unref(s->to_replace);

    }

    if (replace_aio_context) {

        aio_context_release(replace_aio_context);

    }

    g_free(s->replaces);

    bdrv_op_unblock_all(target_bs, s->common.blocker);

    blk_unref(s->target);

    block_job_completed(&s->common, data->ret);

    g_free(data);

    bdrv_drained_end(src);

    if (qemu_get_aio_context() == bdrv_get_aio_context(src)) {

        aio_enable_external(iohandler_get_aio_context());

    }

    bdrv_unref(src);

}


static void init_proc_620 (CPUPPCState *env)

{

    gen_spr_ne_601(env);

    gen_spr_620(env);

    /* Time base */

    gen_tbl(env);

    /* Hardware implementation registers */

    /* XXX : not implemented */

    spr_register(env, SPR_HID0, "HID0",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Memory management */

    gen_low_BATs(env);

    gen_high_BATs(env);

    init_excp_620(env);

    env->dcache_line_size = 64;

    env->icache_line_size = 64;

    /* XXX: TODO: initialize internal interrupt controller */

}


static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,

                                                  TranslationBlock *tb,

                                                  bool search_pc)

{

    CPUState *cs = CPU(cpu);

    CPUPPCState *env = &cpu->env;

    DisasContext ctx, *ctxp = &ctx;

    opc_handler_t **table, *handler;

    target_ulong pc_start;

    uint16_t *gen_opc_end;

    CPUBreakpoint *bp;

    int j, lj = -1;

    int num_insns;

    int max_insns;

    pc_start = tb->pc;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    ctx.nip = pc_start;

    ctx.tb = tb;

    ctx.exception = POWERPC_EXCP_NONE;

    ctx.spr_cb = env->spr_cb;

    ctx.mem_idx = env->mmu_idx;

    ctx.insns_flags = env->insns_flags;

    ctx.insns_flags2 = env->insns_flags2;

    ctx.access_type = -1;

    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;

#if defined(TARGET_PPC64)

    ctx.sf_mode = msr_is_64bit(env, env->msr);

    ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);

#endif

    ctx.fpu_enabled = msr_fp;

    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)

        ctx.spe_enabled = msr_spe;

    else

        ctx.spe_enabled = 0;

    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)

        ctx.altivec_enabled = msr_vr;

    else

        ctx.altivec_enabled = 0;

    if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {

        ctx.vsx_enabled = msr_vsx;

    } else {

        ctx.vsx_enabled = 0;

    if ((env->flags & POWERPC_FLAG_SE) && msr_se)

        ctx.singlestep_enabled = CPU_SINGLE_STEP;

    else

        ctx.singlestep_enabled = 0;

    if ((env->flags & POWERPC_FLAG_BE) && msr_be)

        ctx.singlestep_enabled |= CPU_BRANCH_STEP;

    if (unlikely(cs->singlestep_enabled)) {

        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;

#if defined (DO_SINGLE_STEP) && 0

    /* Single step trace mode */

    msr_se = 1;

#endif

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0)

        max_insns = CF_COUNT_MASK;

    gen_tb_start();

    tcg_clear_temp_count();

    /* Set env in case of segfault during code fetch */

    while (ctx.exception == POWERPC_EXCP_NONE

            && tcg_ctx.gen_opc_ptr < gen_opc_end) {

        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {

            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {

                if (bp->pc == ctx.nip) {

                    gen_debug_exception(ctxp);

                    break;

        if (unlikely(search_pc)) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j)

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

            tcg_ctx.gen_opc_pc[lj] = ctx.nip;

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = num_insns;

        LOG_DISAS("----------------\n");

        LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",

                  ctx.nip, ctx.mem_idx, (int)msr_ir);

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))

            gen_io_start();

        if (unlikely(ctx.le_mode)) {

            ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));

        } else {

            ctx.opcode = cpu_ldl_code(env, ctx.nip);

        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",

                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),

                    opc3(ctx.opcode), ctx.le_mode ? "little" : "big");

        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {

            tcg_gen_debug_insn_start(ctx.nip);

        ctx.nip += 4;

        table = env->opcodes;

        num_insns++;

        handler = table[opc1(ctx.opcode)];

        if (is_indirect_opcode(handler)) {

            table = ind_table(handler);

            handler = table[opc2(ctx.opcode)];

            if (is_indirect_opcode(handler)) {

                table = ind_table(handler);

                handler = table[opc3(ctx.opcode)];

        /* Is opcode *REALLY* valid ? */

        if (unlikely(handler->handler == &gen_invalid)) {

            if (qemu_log_enabled()) {

                qemu_log("invalid/unsupported opcode: "

                         "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",

                         opc1(ctx.opcode), opc2(ctx.opcode),

                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);

        } else {

            uint32_t inval;

            if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {

                inval = handler->inval2;

            } else {

                inval = handler->inval1;

            if (unlikely((ctx.opcode & inval) != 0)) {

                if (qemu_log_enabled()) {

                    qemu_log("invalid bits: %08x for opcode: "

                             "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",

                             ctx.opcode & inval, opc1(ctx.opcode),

                             opc2(ctx.opcode), opc3(ctx.opcode),

                             ctx.opcode, ctx.nip - 4);

                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);

                break;

        (*(handler->handler))(&ctx);

#if defined(DO_PPC_STATISTICS)

        handler->count++;

#endif

        /* Check trace mode exceptions */

        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&

                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&

                     ctx.exception != POWERPC_SYSCALL &&

                     ctx.exception != POWERPC_EXCP_TRAP &&

                     ctx.exception != POWERPC_EXCP_BRANCH)) {

            gen_exception(ctxp, POWERPC_EXCP_TRACE);

        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||

                            (cs->singlestep_enabled) ||

                            singlestep ||

                            num_insns >= max_insns)) {

            /* if we reach a page boundary or are single stepping, stop

             * generation

             */

            break;

    if (tb->cflags & CF_LAST_IO)

        gen_io_end();

    if (ctx.exception == POWERPC_EXCP_NONE) {

        gen_goto_tb(&ctx, 0, ctx.nip);

    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {

        if (unlikely(cs->singlestep_enabled)) {

            gen_debug_exception(ctxp);

        /* Generate the return instruction */

        tcg_gen_exit_tb(0);

    gen_tb_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

    if (unlikely(search_pc)) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        lj++;

        while (lj <= j)

            tcg_ctx.gen_opc_instr_start[lj++] = 0;

    } else {

        tb->size = ctx.nip - pc_start;

        tb->icount = num_insns;

#if defined(DEBUG_DISAS)

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        int flags;

        flags = env->bfd_mach;

        flags |= ctx.le_mode << 16;

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

        log_target_disas(env, pc_start, ctx.nip - pc_start, flags);

        qemu_log("\n");

#endif


static void gen_mfsri(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    int ra = rA(ctx->opcode);

    int rd = rD(ctx->opcode);

    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);

    tcg_gen_shri_tl(t0, t0, 28);

    tcg_gen_andi_tl(t0, t0, 0xF);

    gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);

    tcg_temp_free(t0);

    if (ra != 0 && ra != rd)

        tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);

#endif

}


static int rv20_decode_picture_header(MpegEncContext *s)

{

    int seq, mb_pos, i;

    if(s->avctx->sub_id == 0x30202002 || s->avctx->sub_id == 0x30203002){

        if (get_bits(&s->gb, 3)){

            av_log(s->avctx, AV_LOG_ERROR, "unknown triplet set\n");

            return -1;

        }

    }

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

    switch(i){

    case 0: s->pict_type= I_TYPE; break;

    case 1: s->pict_type= I_TYPE; break; //hmm ...

    case 2: s->pict_type= P_TYPE; break;

    case 3: s->pict_type= B_TYPE; break;

    default:

        av_log(s->avctx, AV_LOG_ERROR, "unknown frame type\n");

        return -1;

    }

    if (get_bits(&s->gb, 1)){

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

        return -1;

    }

    s->qscale = get_bits(&s->gb, 5);

    if(s->qscale==0){

        av_log(s->avctx, AV_LOG_ERROR, "error, qscale:0\n");

        return -1;

    }

    if(s->avctx->sub_id == 0x30203002){

        if (get_bits(&s->gb, 1)){

            av_log(s->avctx, AV_LOG_ERROR, "unknown bit2 set\n");

            return -1;

        }

    }

    if(s->avctx->has_b_frames){

        if (get_bits(&s->gb, 1)){

            av_log(s->avctx, AV_LOG_ERROR, "unknown bit3 set\n");

            return -1;

        }

        seq= get_bits(&s->gb, 15);

    }else

        seq= get_bits(&s->gb, 8)*128;

//printf("%d\n", seq);

    seq |= s->time &~0x7FFF;

    if(seq - s->time >  0x4000) seq -= 0x8000;

    if(seq - s->time < -0x4000) seq += 0x8000;

    if(seq != s->time){

        if(s->pict_type!=B_TYPE){

            s->time= seq;

            s->pp_time= s->time - s->last_non_b_time;

            s->last_non_b_time= s->time;

        }else{

            s->time= seq;

            s->pb_time= s->pp_time - (s->last_non_b_time - s->time);

            if(s->pp_time <=s->pb_time || s->pp_time <= s->pp_time - s->pb_time || s->pp_time<=0){

                printf("messed up order, seeking?, skiping current b frame\n");

                return FRAME_SKIPED;

            }

        }

    }

//    printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time);

    mb_pos= ff_h263_decode_mba(s);

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

    s->f_code = 1;

    s->unrestricted_mv = 1;

    s->h263_aic= s->pict_type == I_TYPE;

//    s->alt_inter_vlc=1;

//    s->obmc=1;

//    s->umvplus=1;

    s->modified_quant=1;

    s->loop_filter=1;

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

            av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n",

                   seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding);

    }

    assert(s->pict_type != B_TYPE || !s->low_delay);

    return s->mb_width*s->mb_height - mb_pos;

}


static void hpet_timer(void *opaque)

{

    HPETTimer *t = (HPETTimer*)opaque;

    uint64_t diff;

    uint64_t period = t->period;

    uint64_t cur_tick = hpet_get_ticks();

    if (timer_is_periodic(t) && period != 0) {

        if (t->config & HPET_TN_32BIT) {

            while (hpet_time_after(cur_tick, t->cmp))

                t->cmp = (uint32_t)(t->cmp + t->period);

        } else

            while (hpet_time_after64(cur_tick, t->cmp))

                t->cmp += period;

        diff = hpet_calculate_diff(t, cur_tick);

        qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)

                       + (int64_t)ticks_to_ns(diff));

    } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {

        if (t->wrap_flag) {

            diff = hpet_calculate_diff(t, cur_tick);

            qemu_mod_timer(t->qemu_timer, qemu_get_clock(vm_clock)

                           + (int64_t)ticks_to_ns(diff));

            t->wrap_flag = 0;

        }

    }

    update_irq(t);

}


static AddrRange addrrange_make(uint64_t start, uint64_t size)

{

    return (AddrRange) { start, size };

}


int bdrv_file_open(BlockDriverState **pbs, const char *filename,

                   const char *reference, QDict *options, int flags,

                   Error **errp)

{

    BlockDriverState *bs = NULL;

    BlockDriver *drv;

    const char *drvname;

    bool allow_protocol_prefix = false;

    Error *local_err = NULL;

    int ret;

    /* NULL means an empty set of options */

    if (options == NULL) {

        options = qdict_new();

    }

    if (reference) {

        if (filename || qdict_size(options)) {

            error_setg(errp, "Cannot reference an existing block device with "

                       "additional options or a new filename");

            return -EINVAL;

        }

        QDECREF(options);

        bs = bdrv_find(reference);

        if (!bs) {

            error_setg(errp, "Cannot find block device '%s'", reference);

            return -ENODEV;

        }

        bdrv_ref(bs);

        *pbs = bs;

        return 0;

    }

    bs = bdrv_new("");

    bs->options = options;

    options = qdict_clone_shallow(options);

    /* Fetch the file name from the options QDict if necessary */

    if (!filename) {

        filename = qdict_get_try_str(options, "filename");

    } else if (filename && !qdict_haskey(options, "filename")) {

        qdict_put(options, "filename", qstring_from_str(filename));

        allow_protocol_prefix = true;

    } else {

        error_setg(errp, "Can't specify 'file' and 'filename' options at the "

                   "same time");

        ret = -EINVAL;

        goto fail;

    }

    /* Find the right block driver */

    drvname = qdict_get_try_str(options, "driver");

    if (drvname) {

        drv = bdrv_find_format(drvname);

        if (!drv) {

            error_setg(errp, "Unknown driver '%s'", drvname);

        }

        qdict_del(options, "driver");

    } else if (filename) {

        drv = bdrv_find_protocol(filename, allow_protocol_prefix);

        if (!drv) {

            error_setg(errp, "Unknown protocol");

        }

    } else {

        error_setg(errp, "Must specify either driver or file");

        drv = NULL;

    }

    if (!drv) {

        /* errp has been set already */

        ret = -ENOENT;

        goto fail;

    }

    /* Parse the filename and open it */

    if (drv->bdrv_parse_filename && filename) {

        drv->bdrv_parse_filename(filename, options, &local_err);

        if (error_is_set(&local_err)) {

            error_propagate(errp, local_err);

            ret = -EINVAL;

            goto fail;

        }

        qdict_del(options, "filename");

    } else if (drv->bdrv_needs_filename && !filename) {

        error_setg(errp, "The '%s' block driver requires a file name",

                   drv->format_name);

        ret = -EINVAL;

        goto fail;

    }

    if (!drv->bdrv_file_open) {

        ret = bdrv_open(bs, filename, options, flags, drv, &local_err);

        options = NULL;

    } else {

        ret = bdrv_open_common(bs, NULL, options, flags, drv, &local_err);

    }

    if (ret < 0) {

        error_propagate(errp, local_err);

        goto fail;

    }

    /* Check if any unknown options were used */

    if (options && (qdict_size(options) != 0)) {

        const QDictEntry *entry = qdict_first(options);

        error_setg(errp, "Block protocol '%s' doesn't support the option '%s'",

                   drv->format_name, entry->key);

        ret = -EINVAL;

        goto fail;

    }

    QDECREF(options);

    bs->growable = 1;

    *pbs = bs;

    return 0;

fail:

    QDECREF(options);

    if (!bs->drv) {

        QDECREF(bs->options);

    }

    bdrv_unref(bs);

    return ret;

}


static av_cold int concat_open(URLContext *h, const char *uri, int flags)

{

    char *node_uri = NULL;

    int err = 0;

    int64_t size;

    size_t  len, i;

    URLContext *uc;

    struct concat_data  *data = h->priv_data;

    struct concat_nodes *nodes;

    av_strstart(uri, "concat:", &uri);

    for (i = 0, len = 1; uri[i]; i++)

        if (uri[i] == *AV_CAT_SEPARATOR)

            /* integer overflow */

            if (++len == UINT_MAX / sizeof(*nodes)) {

                av_freep(&h->priv_data);

                return AVERROR(ENAMETOOLONG);

            }

    if (!(nodes = av_malloc(sizeof(*nodes) * len))) {

        return AVERROR(ENOMEM);

    } else

        data->nodes = nodes;

    /* handle input */

    if (!*uri)

        err = AVERROR(ENOENT);

    for (i = 0; *uri; i++) {

        /* parsing uri */

        len = strcspn(uri, AV_CAT_SEPARATOR);

        if ((err = av_reallocp(&node_uri, len + 1)) < 0)

            break;

        av_strlcpy(node_uri, uri, len+1);

        uri += len + strspn(uri+len, AV_CAT_SEPARATOR);

        /* creating URLContext */

        if ((err = ffurl_open(&uc, node_uri, flags,

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

            break;

        /* creating size */

        if ((size = ffurl_size(uc)) < 0) {

            ffurl_close(uc);

            err = AVERROR(ENOSYS);

            break;

        }

        /* assembling */

        nodes[i].uc   = uc;

        nodes[i].size = size;

    }

    av_free(node_uri);

    data->length = i;

    if (err < 0)

        concat_close(h);

    else if ((err = av_reallocp(&nodes, data->length * sizeof(*nodes))) < 0)

        concat_close(h);

    else

        data->nodes = nodes;

    return err;

}


static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                        const AVFrame *frame, int *got_packet_ptr)
{
    DCAEncContext *c = avctx->priv_data;
    const int32_t *samples;
    int ret, i;
    if ((ret = ff_alloc_packet2(avctx, avpkt, c->frame_size , 0)) < 0)
        return ret;
    samples = (const int32_t *)frame->data[0];
    subband_transform(c, samples);
    if (c->lfe_channel)
        lfe_downsample(c, samples);
    calc_masking(c, samples);
    find_peaks(c);
    assign_bits(c);
    calc_scales(c);
    quantize_all(c);
    shift_history(c, samples);
    init_put_bits(&c->pb, avpkt->data, avpkt->size);
    put_frame_header(c);
    put_primary_audio_header(c);
    for (i = 0; i < SUBFRAMES; i++)
        put_subframe(c, i);
    flush_put_bits(&c->pb);
    avpkt->pts      = frame->pts;
    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
    avpkt->size     = c->frame_size + 1;
    *got_packet_ptr = 1;
    return 0;
}


static void qobject_input_type_null(Visitor *v, const char *name, Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qobject_input_get_object(qiv, name, true, errp);

    if (!qobj) {

        return;

    }

    if (qobject_type(qobj) != QTYPE_QNULL) {

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "null");

    }

}


void ff_subblock_synthesis(RA144Context *ractx, const int16_t *lpc_coefs,

                           int cba_idx, int cb1_idx, int cb2_idx,

                           int gval, int gain)

{

    int16_t *block;

    int m[3];

    if (cba_idx) {

        cba_idx += BLOCKSIZE/2 - 1;

        ff_copy_and_dup(ractx->buffer_a, ractx->adapt_cb, cba_idx);

        m[0] = (ff_irms(&ractx->adsp, ractx->buffer_a) * gval) >> 12;

    } else {

        m[0] = 0;

    }

    m[1] = (ff_cb1_base[cb1_idx] * gval) >> 8;

    m[2] = (ff_cb2_base[cb2_idx] * gval) >> 8;

    memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,

            (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));

    block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;

    add_wav(block, gain, cba_idx, m, cba_idx? ractx->buffer_a: NULL,

            ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);

    memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,

           LPC_ORDER*sizeof(*ractx->curr_sblock));

    if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,

                                    block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))

        memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));

}


static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,

                qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,

                struct omap_mpu_state_s *mpu)

{

    struct omap_prcm_s *s = (struct omap_prcm_s *)

            g_malloc0(sizeof(struct omap_prcm_s));

    s->irq[0] = mpu_int;

    s->irq[1] = dsp_int;

    s->irq[2] = iva_int;

    s->mpu = mpu;

    omap_prcm_coldreset(s);

    memory_region_init_io(&s->iomem0, NULL, &omap_prcm_ops, s, "omap.pcrm0",

                          omap_l4_region_size(ta, 0));

    memory_region_init_io(&s->iomem1, NULL, &omap_prcm_ops, s, "omap.pcrm1",

                          omap_l4_region_size(ta, 1));

    omap_l4_attach(ta, 0, &s->iomem0);

    omap_l4_attach(ta, 1, &s->iomem1);

    return s;

}


static void close_file(OutputStream *os)

{

    int64_t pos = avio_tell(os->out);

    avio_seek(os->out, 0, SEEK_SET);

    avio_wb32(os->out, pos);

    avio_flush(os->out);

    avio_close(os->out);

    os->out = NULL;

}


static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,

                             const AVFrame *frame, int *got_packet_ptr)

{

    G726Context *c = avctx->priv_data;

    const int16_t *samples = (const int16_t *)frame->data[0];

    PutBitContext pb;

    int i, ret, out_size;

    out_size = (frame->nb_samples * c->code_size + 7) / 8;

    if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)))

        return ret;

    init_put_bits(&pb, avpkt->data, avpkt->size);

    for (i = 0; i < frame->nb_samples; i++)

        put_bits(&pb, c->code_size, g726_encode(c, *samples++));

    flush_put_bits(&pb);

    avpkt->size = out_size;

    *got_packet_ptr = 1;

    return 0;

}


static int virtio_rng_load(QEMUFile *f, void *opaque, int version_id)

{

    if (version_id != 1) {

        return -EINVAL;

    }

    return virtio_load(VIRTIO_DEVICE(opaque), f, version_id);

}


static void dpy_refresh(DisplayState *s)

{

    DisplayChangeListener *dcl;

    QLIST_FOREACH(dcl, &s->listeners, next) {

        if (dcl->ops->dpy_refresh) {

            dcl->ops->dpy_refresh(dcl);

        }

    }

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = sysbus_ahci_realize;

    dc->vmsd = &vmstate_sysbus_ahci;

    dc->props = sysbus_ahci_properties;

    dc->reset = sysbus_ahci_reset;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

}


static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta)

{

    int enc, pic_type;

    char             mimetype[64];

    const CodecMime     *mime = ff_id3v2_mime_tags;

    enum AVCodecID           id = AV_CODEC_ID_NONE;

    ID3v2ExtraMetaAPIC  *apic = NULL;

    ID3v2ExtraMeta *new_extra = NULL;

    int64_t               end = avio_tell(pb) + taglen;

    if (taglen <= 4)

        goto fail;

    new_extra = av_mallocz(sizeof(*new_extra));

    apic      = av_mallocz(sizeof(*apic));

    if (!new_extra || !apic)

        goto fail;

    enc = avio_r8(pb);

    taglen--;

    /* mimetype */

    taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype));

    while (mime->id != AV_CODEC_ID_NONE) {

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

            id = mime->id;

            break;

        }

        mime++;

    }

    if (id == AV_CODEC_ID_NONE) {

        av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype);

        goto fail;

    }

    apic->id = id;

    /* picture type */

    pic_type = avio_r8(pb);

    taglen--;

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

        av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type);

        pic_type = 0;

    }

    apic->type = ff_id3v2_picture_types[pic_type];

    /* description and picture data */

    if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {

        av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n");

        goto fail;

    }

    apic->buf = av_buffer_alloc(taglen);

    if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)

        goto fail;

    new_extra->tag    = "APIC";

    new_extra->data   = apic;

    new_extra->next   = *extra_meta;

    *extra_meta       = new_extra;

    return;

fail:

    if (apic)

        free_apic(apic);

    av_freep(&new_extra);

    avio_seek(pb, end, SEEK_SET);

}


readv_f(int argc, char **argv)

{

	struct timeval t1, t2;

	int Cflag = 0, qflag = 0, vflag = 0;

	int c, cnt;

	char *buf;

	int64_t offset;

	int total;

	int nr_iov;

	QEMUIOVector qiov;

	int pattern = 0;

	int Pflag = 0;

	while ((c = getopt(argc, argv, "CP:qv")) != EOF) {

		switch (c) {

		case 'C':

			Cflag = 1;

			break;

		case 'P':

			Pflag = 1;

			pattern = atoi(optarg);

			break;

		case 'q':

			qflag = 1;

			break;

		case 'v':

			vflag = 1;

			break;

		default:

			return command_usage(&readv_cmd);

		}

	}

	if (optind > argc - 2)

		return command_usage(&readv_cmd);

	offset = cvtnum(argv[optind]);

	if (offset < 0) {

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

		return 0;

	}

	optind++;

	if (offset & 0x1ff) {

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

			(long long)offset);

		return 0;

	}

	nr_iov = argc - optind;

	buf = create_iovec(&qiov, &argv[optind], nr_iov, 0xab);

	gettimeofday(&t1, NULL);

	cnt = do_aio_readv(&qiov, offset, &total);

	gettimeofday(&t2, NULL);

	if (cnt < 0) {

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

		return 0;

	}

	if (Pflag) {

		void* cmp_buf = malloc(qiov.size);

		memset(cmp_buf, pattern, qiov.size);

		if (memcmp(buf, cmp_buf, qiov.size)) {

			printf("Pattern verification failed at offset %lld, "

				"%zd bytes\n",

				(long long) offset, qiov.size);

		}

		free(cmp_buf);

	}

	if (qflag)

		return 0;

        if (vflag)

		dump_buffer(buf, offset, qiov.size);

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

	t2 = tsub(t2, t1);

	print_report("read", &t2, offset, qiov.size, total, cnt, Cflag);

	qemu_io_free(buf);

	return 0;

}


static int opt_vstats(void *optctx, const char *opt, const char *arg)
{
    char filename[40];
    time_t today2 = time(NULL);
    struct tm *today = localtime(&today2);
    snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
             today->tm_sec);
    return opt_vstats_file(NULL, opt, filename);
}


static void gen_brcond(DisasContext *dc, TCGCond cond,

        TCGv_i32 t0, TCGv_i32 t1, uint32_t offset)

{

    int label = gen_new_label();

    tcg_gen_brcond_i32(cond, t0, t1, label);

    gen_jumpi(dc, dc->next_pc, 0);

    gen_set_label(label);

    gen_jumpi(dc, dc->pc + offset, 1);

}


void palette8tobgr24(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)

{

	unsigned i;

/*

	writes 1 byte o much and might cause alignment issues on some architectures?

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

		((unsigned *)(&dst[i*3])) = ((unsigned *)palette)[ src[i] ];

*/

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

	{

		//FIXME slow?

		dst[0]= palette[ src[i]*4+0 ];

		dst[1]= palette[ src[i]*4+1 ];

		dst[2]= palette[ src[i]*4+2 ];

		dst+= 3;

	}

}


bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)

{

    uint32_t pba_entry;

    uint8_t bit_n = entry % 32;

    void *addr = dev->msix_pba + (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;

    g_assert(dev->msix_enabled);

    pba_entry = qpci_io_readl(dev, addr);

    qpci_io_writel(dev, addr, pba_entry & ~(1 << bit_n));

    return (pba_entry & (1 << bit_n)) != 0;

}


static void init_proc_750cx (CPUPPCState *env)

{

    gen_spr_ne_601(env);

    gen_spr_7xx(env);

    /* XXX : not implemented */

    spr_register(env, SPR_L2CR, "L2CR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, NULL,

                 0x00000000);

    /* Time base */

    gen_tbl(env);

    /* Thermal management */

    gen_spr_thrm(env);

    /* This register is not implemented but is present for compatibility */

    spr_register(env, SPR_SDA, "SDA",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Hardware implementation registers */

    /* XXX : not implemented */

    spr_register(env, SPR_HID0, "HID0",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* XXX : not implemented */

    spr_register(env, SPR_HID1, "HID1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Memory management */

    gen_low_BATs(env);

    /* PowerPC 750cx has 8 DBATs and 8 IBATs */

    gen_high_BATs(env);

    init_excp_750cx(env);

    env->dcache_line_size = 32;

    env->icache_line_size = 32;

    /* Allocate hardware IRQ controller */

    ppc6xx_irq_init(env);

}


static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program)

{

    AVStream *stream = ist->st;

    AVCodecParameters *par;

    AVCodecContext *dec_ctx;

    char val_str[128];

    const char *s;

    AVRational sar, dar;

    AVBPrint pbuf;

    const AVCodecDescriptor *cd;

    int ret = 0;

    const char *profile = NULL;

    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);

    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM : SECTION_ID_STREAM);

    print_int("index", stream->index);

    par     = stream->codecpar;

    dec_ctx = ist->dec_ctx;

    if (cd = avcodec_descriptor_get(par->codec_id)) {

        print_str("codec_name", cd->name);

        if (!do_bitexact) {

            print_str("codec_long_name",

                      cd->long_name ? cd->long_name : "unknown");

        }

    } else {

        print_str_opt("codec_name", "unknown");

        if (!do_bitexact) {

            print_str_opt("codec_long_name", "unknown");

        }

    }

    if (!do_bitexact && (profile = avcodec_profile_name(par->codec_id, par->profile)))

        print_str("profile", profile);

    else {

        if (par->profile != FF_PROFILE_UNKNOWN) {

            char profile_num[12];

            snprintf(profile_num, sizeof(profile_num), "%d", par->profile);

            print_str("profile", profile_num);

        } else

            print_str_opt("profile", "unknown");

    }

    s = av_get_media_type_string(par->codec_type);

    if (s) print_str    ("codec_type", s);

    else   print_str_opt("codec_type", "unknown");

#if FF_API_LAVF_AVCTX

    if (dec_ctx)

        print_q("codec_time_base", dec_ctx->time_base, '/');

#endif

    /* print AVI/FourCC tag */

    print_str("codec_tag_string",    av_fourcc2str(par->codec_tag));

    print_fmt("codec_tag", "0x%04"PRIx32, par->codec_tag);

    switch (par->codec_type) {

    case AVMEDIA_TYPE_VIDEO:

        print_int("width",        par->width);

        print_int("height",       par->height);

        if (dec_ctx) {

            print_int("coded_width",  dec_ctx->coded_width);

            print_int("coded_height", dec_ctx->coded_height);

        }

        print_int("has_b_frames", par->video_delay);

        sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);

        if (sar.den) {

            print_q("sample_aspect_ratio", sar, ':');

            av_reduce(&dar.num, &dar.den,

                      par->width  * sar.num,

                      par->height * sar.den,

                      1024*1024);

            print_q("display_aspect_ratio", dar, ':');

        } else {

            print_str_opt("sample_aspect_ratio", "N/A");

            print_str_opt("display_aspect_ratio", "N/A");

        }

        s = av_get_pix_fmt_name(par->format);

        if (s) print_str    ("pix_fmt", s);

        else   print_str_opt("pix_fmt", "unknown");

        print_int("level",   par->level);

        if (par->color_range != AVCOL_RANGE_UNSPECIFIED)

            print_str    ("color_range", av_color_range_name(par->color_range));

        else

            print_str_opt("color_range", "N/A");

        if (par->color_space != AVCOL_SPC_UNSPECIFIED)

            print_str("color_space", av_color_space_name(par->color_space));

        else

            print_str_opt("color_space", av_color_space_name(par->color_space));

        if (par->color_trc != AVCOL_TRC_UNSPECIFIED)

            print_str("color_transfer", av_color_transfer_name(par->color_trc));

        else

            print_str_opt("color_transfer", av_color_transfer_name(par->color_trc));

        if (par->color_primaries != AVCOL_PRI_UNSPECIFIED)

            print_str("color_primaries", av_color_primaries_name(par->color_primaries));

        else

            print_str_opt("color_primaries", av_color_primaries_name(par->color_primaries));

        if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED)

            print_str("chroma_location", av_chroma_location_name(par->chroma_location));

        else

            print_str_opt("chroma_location", av_chroma_location_name(par->chroma_location));

        if (par->field_order == AV_FIELD_PROGRESSIVE)

            print_str("field_order", "progressive");

        else if (par->field_order == AV_FIELD_TT)

            print_str("field_order", "tt");

        else if (par->field_order == AV_FIELD_BB)

            print_str("field_order", "bb");

        else if (par->field_order == AV_FIELD_TB)

            print_str("field_order", "tb");

        else if (par->field_order == AV_FIELD_BT)

            print_str("field_order", "bt");

        else

            print_str_opt("field_order", "unknown");

#if FF_API_PRIVATE_OPT

        if (dec_ctx && dec_ctx->timecode_frame_start >= 0) {

            char tcbuf[AV_TIMECODE_STR_SIZE];

            av_timecode_make_mpeg_tc_string(tcbuf, dec_ctx->timecode_frame_start);

            print_str("timecode", tcbuf);

        } else {

            print_str_opt("timecode", "N/A");

        }

#endif

        if (dec_ctx)

            print_int("refs", dec_ctx->refs);

        break;

    case AVMEDIA_TYPE_AUDIO:

        s = av_get_sample_fmt_name(par->format);

        if (s) print_str    ("sample_fmt", s);

        else   print_str_opt("sample_fmt", "unknown");

        print_val("sample_rate",     par->sample_rate, unit_hertz_str);

        print_int("channels",        par->channels);

        if (par->channel_layout) {

            av_bprint_clear(&pbuf);

            av_bprint_channel_layout(&pbuf, par->channels, par->channel_layout);

            print_str    ("channel_layout", pbuf.str);

        } else {

            print_str_opt("channel_layout", "unknown");

        }

        print_int("bits_per_sample", av_get_bits_per_sample(par->codec_id));

        break;

    case AVMEDIA_TYPE_SUBTITLE:

        if (par->width)

            print_int("width",       par->width);

        else

            print_str_opt("width",   "N/A");

        if (par->height)

            print_int("height",      par->height);

        else

            print_str_opt("height",  "N/A");

        break;

    }

    if (dec_ctx && dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {

        const AVOption *opt = NULL;

        while (opt = av_opt_next(dec_ctx->priv_data,opt)) {

            uint8_t *str;

            if (opt->flags) continue;

            if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {

                print_str(opt->name, str);

                av_free(str);

            }

        }

    }

    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt    ("id", "0x%x", stream->id);

    else                                          print_str_opt("id", "N/A");

    print_q("r_frame_rate",   stream->r_frame_rate,   '/');

    print_q("avg_frame_rate", stream->avg_frame_rate, '/');

    print_q("time_base",      stream->time_base,      '/');

    print_ts  ("start_pts",   stream->start_time);

    print_time("start_time",  stream->start_time, &stream->time_base);

    print_ts  ("duration_ts", stream->duration);

    print_time("duration",    stream->duration, &stream->time_base);

    if (par->bit_rate > 0)     print_val    ("bit_rate", par->bit_rate, unit_bit_per_second_str);

    else                       print_str_opt("bit_rate", "N/A");

#if FF_API_LAVF_AVCTX

    if (stream->codec->rc_max_rate > 0) print_val ("max_bit_rate", stream->codec->rc_max_rate, unit_bit_per_second_str);

    else                                print_str_opt("max_bit_rate", "N/A");

#endif

    if (dec_ctx && dec_ctx->bits_per_raw_sample > 0) print_fmt("bits_per_raw_sample", "%d", dec_ctx->bits_per_raw_sample);

    else                                             print_str_opt("bits_per_raw_sample", "N/A");

    if (stream->nb_frames) print_fmt    ("nb_frames", "%"PRId64, stream->nb_frames);

    else                   print_str_opt("nb_frames", "N/A");

    if (nb_streams_frames[stream_idx])  print_fmt    ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);

    else                                print_str_opt("nb_read_frames", "N/A");

    if (nb_streams_packets[stream_idx]) print_fmt    ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);

    else                                print_str_opt("nb_read_packets", "N/A");

    if (do_show_data)

        writer_print_data(w, "extradata", par->extradata,

                                          par->extradata_size);

    writer_print_data_hash(w, "extradata_hash", par->extradata,

                                                par->extradata_size);

    /* Print disposition information */

#define PRINT_DISPOSITION(flagname, name) do {                                \

        print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \

    } while (0)

    if (do_show_stream_disposition) {

    writer_print_section_header(w, in_program ? SECTION_ID_PROGRAM_STREAM_DISPOSITION : SECTION_ID_STREAM_DISPOSITION);

    PRINT_DISPOSITION(DEFAULT,          "default");

    PRINT_DISPOSITION(DUB,              "dub");

    PRINT_DISPOSITION(ORIGINAL,         "original");

    PRINT_DISPOSITION(COMMENT,          "comment");

    PRINT_DISPOSITION(LYRICS,           "lyrics");

    PRINT_DISPOSITION(KARAOKE,          "karaoke");

    PRINT_DISPOSITION(FORCED,           "forced");

    PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");

    PRINT_DISPOSITION(VISUAL_IMPAIRED,  "visual_impaired");

    PRINT_DISPOSITION(CLEAN_EFFECTS,    "clean_effects");

    PRINT_DISPOSITION(ATTACHED_PIC,     "attached_pic");

    PRINT_DISPOSITION(TIMED_THUMBNAILS, "timed_thumbnails");

    writer_print_section_footer(w);

    }

    if (do_show_stream_tags)

        ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);

    if (stream->nb_side_data) {

        print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,

                            SECTION_ID_STREAM_SIDE_DATA_LIST,

                            SECTION_ID_STREAM_SIDE_DATA);

    }

    writer_print_section_footer(w);

    av_bprint_finalize(&pbuf, NULL);

    fflush(stdout);

    return ret;

}


static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)

{

    unsigned int i;

    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)

        qemu_put_be32s(f, &q->queue[i]);

    qemu_put_sbe32s(f, &q->next);

    qemu_put_sbe32s(f, &q->priority);

}


static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t len)

{

    QEDIsAllocatedCB *cb = opaque;

    BDRVQEDState *s = cb->bs->opaque;

    *cb->pnum = len / BDRV_SECTOR_SIZE;

    switch (ret) {

    case QED_CLUSTER_FOUND:

        offset |= qed_offset_into_cluster(s, cb->pos);

        cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;

        *cb->file = cb->bs->file->bs;

        break;

    case QED_CLUSTER_ZERO:

        cb->status = BDRV_BLOCK_ZERO;

        break;

    case QED_CLUSTER_L2:

    case QED_CLUSTER_L1:

        cb->status = 0;

        break;

    default:

        assert(ret < 0);

        cb->status = ret;

        break;

    }

    if (cb->co) {

        qemu_coroutine_enter(cb->co, NULL);

    }

}


static av_cold int ffat_close_decoder(AVCodecContext *avctx)

{

    ATDecodeContext *at = avctx->priv_data;

    if (at->converter)

        AudioConverterDispose(at->converter);

    av_packet_unref(&at->new_in_pkt);

    av_packet_unref(&at->in_pkt);

    av_free(at->decoded_data);

    av_free(at->extradata);

    return 0;

}


static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    RTSPState *rt = s->priv_data;

    int ret;

    RTSPMessageHeader reply1, *reply = &reply1;

    char cmd[1024];

    if (rt->server_type == RTSP_SERVER_REAL) {

        int i;

        enum AVDiscard cache[MAX_STREAMS];

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

            cache[i] = s->streams[i]->discard;

        if (!rt->need_subscription) {

            if (memcmp (cache, rt->real_setup_cache,

                        sizeof(enum AVDiscard) * s->nb_streams)) {

                snprintf(cmd, sizeof(cmd),

                         "Unsubscribe: %s\r\n",

                         rt->last_subscription);

                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,

                                 cmd, reply, NULL);

                if (reply->status_code != RTSP_STATUS_OK)

                    return AVERROR_INVALIDDATA;

                rt->need_subscription = 1;

            }

        }

        if (rt->need_subscription) {

            int r, rule_nr, first = 1;

            memcpy(rt->real_setup_cache, cache,

                   sizeof(enum AVDiscard) * s->nb_streams);

            rt->last_subscription[0] = 0;

            snprintf(cmd, sizeof(cmd),

                     "Subscribe: ");

            for (i = 0; i < rt->nb_rtsp_streams; i++) {

                rule_nr = 0;

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

                    if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {

                        if (s->streams[r]->discard != AVDISCARD_ALL) {

                            if (!first)

                                av_strlcat(rt->last_subscription, ",",

                                           sizeof(rt->last_subscription));

                            ff_rdt_subscribe_rule(

                                rt->last_subscription,

                                sizeof(rt->last_subscription), i, rule_nr);

                            first = 0;

                        }

                        rule_nr++;

                    }

                }

            }

            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);

            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,

                             cmd, reply, NULL);

            if (reply->status_code != RTSP_STATUS_OK)

                return AVERROR_INVALIDDATA;

            rt->need_subscription = 0;

            if (rt->state == RTSP_STATE_STREAMING)

                rtsp_read_play (s);

        }

    }

    ret = rtsp_fetch_packet(s, pkt);

    if (ret < 0)

        return ret;

    /* send dummy request to keep TCP connection alive */

    if ((rt->server_type == RTSP_SERVER_WMS ||

         rt->server_type == RTSP_SERVER_REAL) &&

        (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {

        if (rt->server_type == RTSP_SERVER_WMS) {

            ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);

        } else {

            ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);

        }

    }

    return 0;

}


static void reset_contexts(SnowContext *s){

    int plane_index, level, orientation;

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

        for(level=0; level<s->spatial_decomposition_count; level++){

            for(orientation=level ? 1:0; orientation<4; orientation++){

                memset(s->plane[plane_index].band[level][orientation].state, 0, sizeof(s->plane[plane_index].band[level][orientation].state));

            }

        }

    }

    memset(s->mb_band.state, 0, sizeof(s->mb_band.state));

    memset(s->mv_band[0].state, 0, sizeof(s->mv_band[0].state));

    memset(s->mv_band[1].state, 0, sizeof(s->mv_band[1].state));

    memset(s->header_state, 0, sizeof(s->header_state));

}


static int encode_frame(AVCodecContext* avc_context, uint8_t *outbuf,

                        int buf_size, void *data)

{

    th_ycbcr_buffer t_yuv_buffer;

    TheoraContext *h = avc_context->priv_data;

    AVFrame *frame = data;

    ogg_packet o_packet;

    int result, i;

    // EOS, finish and get 1st pass stats if applicable

    if (!frame) {

        th_encode_packetout(h->t_state, 1, &o_packet);

        if (avc_context->flags & CODEC_FLAG_PASS1)

            if (get_stats(avc_context, 1))

                return -1;

        return 0;

    }

    /* Copy planes to the theora yuv_buffer */

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

        t_yuv_buffer[i].width  = FFALIGN(avc_context->width,  16) >> (i && h->uv_hshift);

        t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);

        t_yuv_buffer[i].stride = frame->linesize[i];

        t_yuv_buffer[i].data   = frame->data[i];

    }

    if (avc_context->flags & CODEC_FLAG_PASS2)

        if (submit_stats(avc_context))

            return -1;

    /* Now call into theora_encode_YUVin */

    result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);

    if (result) {

        const char* message;

        switch (result) {

        case -1:

            message = "differing frame sizes";

            break;

        case TH_EINVAL:

            message = "encoder is not ready or is finished";

            break;

        default:

            message = "unknown reason";

            break;

        }

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);

        return -1;

    }

    if (avc_context->flags & CODEC_FLAG_PASS1)

        if (get_stats(avc_context, 0))

            return -1;

    /* Pick up returned ogg_packet */

    result = th_encode_packetout(h->t_state, 0, &o_packet);

    switch (result) {

    case 0:

        /* No packet is ready */

        return 0;

    case 1:

        /* Success, we have a packet */

        break;

    default:

        av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);

        return -1;

    }

    /* Copy ogg_packet content out to buffer */

    if (buf_size < o_packet.bytes) {

        av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n");

        return -1;

    }

    memcpy(outbuf, o_packet.packet, o_packet.bytes);

    // HACK: does not take codec delay into account (neither does the decoder though)

    avc_context->coded_frame->pts = frame->pts;

    avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);

    return o_packet.bytes;

}


static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s)

{

    int x, y;

    unsigned char sample[2];

    /* dithered encoding */

    CHECK_STREAM_PTR(2);

    sample[0] = *s->stream_ptr++;

    sample[1] = *s->stream_ptr++;

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

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

            *s->pixel_ptr++ = sample[  y & 1 ];

            *s->pixel_ptr++ = sample[!(y & 1)];

        }

        s->pixel_ptr += s->line_inc;

    }

    /* report success */

    return 0;

}


static int compand_delay(AVFilterContext *ctx, AVFrame *frame)

{

    CompandContext *s = ctx->priv;

    AVFilterLink *inlink = ctx->inputs[0];

    const int channels = inlink->channels;

    const int nb_samples = frame->nb_samples;

    int chan, i, av_uninit(dindex), oindex, av_uninit(count);

    AVFrame *out_frame = NULL;

    av_assert1(channels > 0); /* would corrupt delay_count and delay_index */

    for (chan = 0; chan < channels; chan++) {

        const double *src = (double *)frame->extended_data[chan];

        double *dbuf = (double *)s->delayptrs[chan];

        ChanParam *cp = &s->channels[chan];

        double *dst;

        count  = s->delay_count;

        dindex = s->delay_index;

        for (i = 0, oindex = 0; i < nb_samples; i++) {

            const double in = src[i];

            update_volume(cp, fabs(in));

            if (count >= s->delay_samples) {

                if (!out_frame) {

                    out_frame = ff_get_audio_buffer(inlink, nb_samples - i);

                    if (!out_frame)

                        return AVERROR(ENOMEM);

                    av_frame_copy_props(out_frame, frame);

                    out_frame->pts = s->pts;

                    s->pts += av_rescale_q(nb_samples - i, (AVRational){1, inlink->sample_rate}, inlink->time_base);

                }

                dst = (double *)out_frame->extended_data[chan];

                dst[oindex++] = av_clipd(dbuf[dindex] * get_volume(s, cp->volume), -1, 1);

            } else {

                count++;

            }

            dbuf[dindex] = in;

            dindex = MOD(dindex + 1, s->delay_samples);

        }

    }

    s->delay_count = count;

    s->delay_index = dindex;

    av_frame_free(&frame);

    return out_frame ? ff_filter_frame(ctx->outputs[0], out_frame) : 0;

}


static void vga_reset(void *opaque)

{

    VGAState *s = (VGAState *) opaque;

    s->lfb_addr = 0;

    s->lfb_end = 0;

    s->map_addr = 0;

    s->map_end = 0;

    s->lfb_vram_mapped = 0;

    s->bios_offset = 0;

    s->bios_size = 0;

    s->sr_index = 0;

    memset(s->sr, '\0', sizeof(s->sr));

    s->gr_index = 0;

    memset(s->gr, '\0', sizeof(s->gr));

    s->ar_index = 0;

    memset(s->ar, '\0', sizeof(s->ar));

    s->ar_flip_flop = 0;

    s->cr_index = 0;

    memset(s->cr, '\0', sizeof(s->cr));

    s->msr = 0;

    s->fcr = 0;

    s->st00 = 0;

    s->st01 = 0;

    s->dac_state = 0;

    s->dac_sub_index = 0;

    s->dac_read_index = 0;

    s->dac_write_index = 0;

    memset(s->dac_cache, '\0', sizeof(s->dac_cache));

    s->dac_8bit = 0;

    memset(s->palette, '\0', sizeof(s->palette));

    s->bank_offset = 0;

#ifdef CONFIG_BOCHS_VBE

    s->vbe_index = 0;

    memset(s->vbe_regs, '\0', sizeof(s->vbe_regs));

    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;

    s->vbe_start_addr = 0;

    s->vbe_line_offset = 0;

    s->vbe_bank_mask = (s->vram_size >> 16) - 1;

#endif

    memset(s->font_offsets, '\0', sizeof(s->font_offsets));

    s->graphic_mode = -1; /* force full update */

    s->shift_control = 0;

    s->double_scan = 0;

    s->line_offset = 0;

    s->line_compare = 0;

    s->start_addr = 0;

    s->plane_updated = 0;

    s->last_cw = 0;

    s->last_ch = 0;

    s->last_width = 0;

    s->last_height = 0;

    s->last_scr_width = 0;

    s->last_scr_height = 0;

    s->cursor_start = 0;

    s->cursor_end = 0;

    s->cursor_offset = 0;

    memset(s->invalidated_y_table, '\0', sizeof(s->invalidated_y_table));

    memset(s->last_palette, '\0', sizeof(s->last_palette));

    memset(s->last_ch_attr, '\0', sizeof(s->last_ch_attr));

    switch (vga_retrace_method) {

    case VGA_RETRACE_DUMB:

        break;

    case VGA_RETRACE_PRECISE:

        memset(&s->retrace_info, 0, sizeof (s->retrace_info));

        break;

    }

}


vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz)

{

    unsigned int i, head, max;

    VuVirtqElement *elem;

    unsigned out_num, in_num;

    struct iovec iov[VIRTQUEUE_MAX_SIZE];

    struct vring_desc *desc;

    int rc;

    if (unlikely(dev->broken)) {

        return NULL;

    }

    if (vu_queue_empty(dev, vq)) {

        return NULL;

    }

    /* Needed after virtio_queue_empty(), see comment in

     * virtqueue_num_heads(). */

    smp_rmb();

    /* When we start there are none of either input nor output. */

    out_num = in_num = 0;

    max = vq->vring.num;

    if (vq->inuse >= vq->vring.num) {

        vu_panic(dev, "Virtqueue size exceeded");

        return NULL;

    }

    if (!virtqueue_get_head(dev, vq, vq->last_avail_idx++, &head)) {

        return NULL;

    }

    if (vu_has_feature(dev, VIRTIO_RING_F_EVENT_IDX)) {

        vring_set_avail_event(vq, vq->last_avail_idx);

    }

    i = head;

    desc = vq->vring.desc;

    if (desc[i].flags & VRING_DESC_F_INDIRECT) {

        if (desc[i].len % sizeof(struct vring_desc)) {

            vu_panic(dev, "Invalid size for indirect buffer table");

        }

        /* loop over the indirect descriptor table */

        max = desc[i].len / sizeof(struct vring_desc);

        desc = vu_gpa_to_va(dev, desc[i].addr);

        i = 0;

    }

    /* Collect all the descriptors */

    do {

        if (desc[i].flags & VRING_DESC_F_WRITE) {

            virtqueue_map_desc(dev, &in_num, iov + out_num,

                               VIRTQUEUE_MAX_SIZE - out_num, true,

                               desc[i].addr, desc[i].len);

        } else {

            if (in_num) {

                vu_panic(dev, "Incorrect order for descriptors");

                return NULL;

            }

            virtqueue_map_desc(dev, &out_num, iov,

                               VIRTQUEUE_MAX_SIZE, false,

                               desc[i].addr, desc[i].len);

        }

        /* If we've got too many, that implies a descriptor loop. */

        if ((in_num + out_num) > max) {

            vu_panic(dev, "Looped descriptor");

        }

        rc = virtqueue_read_next_desc(dev, desc, i, max, &i);

    } while (rc == VIRTQUEUE_READ_DESC_MORE);

    if (rc == VIRTQUEUE_READ_DESC_ERROR) {

        return NULL;

    }

    /* Now copy what we have collected and mapped */

    elem = virtqueue_alloc_element(sz, out_num, in_num);

    elem->index = head;

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

        elem->out_sg[i] = iov[i];

    }

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

        elem->in_sg[i] = iov[out_num + i];

    }

    vq->inuse++;

    return elem;

}


static void rtas_read_pci_config(sPAPREnvironment *spapr,

                                 uint32_t token, uint32_t nargs,

                                 target_ulong args,

                                 uint32_t nret, target_ulong rets)

{

    uint32_t val, size, addr;

    PCIDevice *dev = find_dev(spapr, 0, rtas_ld(args, 0));

    if (!dev) {

        rtas_st(rets, 0, -1);

        return;

    }

    size = rtas_ld(args, 1);

    addr = rtas_pci_cfgaddr(rtas_ld(args, 0));

    val = pci_default_read_config(dev, addr, size);

    rtas_st(rets, 0, 0);

    rtas_st(rets, 1, val);

}


static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc,

                                   const int16_t *hLumFilter,

                                   const int16_t *hLumFilterPos, int hLumFilterSize,

                                   uint8_t *formatConvBuffer,

                                   uint32_t *pal, int isAlpha)

{

    void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;

    void (*convertRange)(uint16_t *, int) = isAlpha ? NULL : c->lumConvertRange;

    src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset;

    if (toYV12) {

        toYV12(formatConvBuffer, src, srcW, pal);

        src= formatConvBuffer;

    }

    if (!c->hyscale_fast) {

        c->hScale(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);

    } else { // fast bilinear upscale / crap downscale

        c->hyscale_fast(c, dst, dstWidth, src, srcW, xInc);

    }

    if (convertRange)

        convertRange(dst, dstWidth);

}


static int dxtory_decode_v2(AVCodecContext *avctx, AVFrame *pic,

                            const uint8_t *src, int src_size)

{

    GetByteContext gb;

    GetBitContext  gb2;

    int nslices, slice, slice_height, ref_slice_height;

    int cur_y, next_y;

    uint32_t off, slice_size;

    uint8_t *Y, *U, *V;

    int ret;

    bytestream2_init(&gb, src, src_size);

    nslices = bytestream2_get_le16(&gb);

    off = FFALIGN(nslices * 4 + 2, 16);

    if (src_size < off) {

        av_log(avctx, AV_LOG_ERROR, "no slice data\n");

        return AVERROR_INVALIDDATA;

    }

    if (!nslices || avctx->height % nslices) {

        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,

                              avctx->width, avctx->height);

        return AVERROR(ENOSYS);

    }

    ref_slice_height = avctx->height / nslices;

    if ((avctx->width & 1) || (avctx->height & 1)) {

        avpriv_request_sample(avctx, "Frame dimensions %dx%d",

                              avctx->width, avctx->height);

    }

    avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)

        return ret;

    Y = pic->data[0];

    U = pic->data[1];

    V = pic->data[2];

    cur_y  = 0;

    next_y = ref_slice_height;

    for (slice = 0; slice < nslices; slice++) {

        slice_size   = bytestream2_get_le32(&gb);

        slice_height = (next_y & ~1) - (cur_y & ~1);

        if (slice_size > src_size - off) {

            av_log(avctx, AV_LOG_ERROR,

                   "invalid slice size %d (only %d bytes left)\n",

                   slice_size, src_size - off);

            return AVERROR_INVALIDDATA;

        }

        if (slice_size <= 16) {

            av_log(avctx, AV_LOG_ERROR, "invalid slice size %d\n", slice_size);

            return AVERROR_INVALIDDATA;

        }

        if (AV_RL32(src + off) != slice_size - 16) {

            av_log(avctx, AV_LOG_ERROR,

                   "Slice sizes mismatch: got %d instead of %d\n",

                   AV_RL32(src + off), slice_size - 16);

        }

        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);

        dx2_decode_slice(&gb2, avctx->width, slice_height, Y, U, V,

                         pic->linesize[0], pic->linesize[1], pic->linesize[2]);

        Y += pic->linesize[0] *  slice_height;

        U += pic->linesize[1] * (slice_height >> 1);

        V += pic->linesize[2] * (slice_height >> 1);

        off += slice_size;

        cur_y   = next_y;

        next_y += ref_slice_height;

    }

    return 0;

}


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

                         int *got_frame_ptr, AVPacket* avpkt)

{

    WMAProDecodeCtx *s = avctx->priv_data;

    GetBitContext* gb  = &s->pgb;

    const uint8_t* buf = avpkt->data;

    int buf_size       = avpkt->size;

    int num_bits_prev_frame;

    int packet_sequence_number;

    *got_frame_ptr = 0;

    if (s->packet_done || s->packet_loss) {

        s->packet_done = 0;

        /** sanity check for the buffer length */

        if (buf_size < avctx->block_align) {

            av_log(avctx, AV_LOG_ERROR, "Input packet too small (%d < %d)\n",

                   buf_size, avctx->block_align);

            return AVERROR_INVALIDDATA;

        }

        s->next_packet_start = buf_size - avctx->block_align;

        buf_size = avctx->block_align;

        s->buf_bit_size = buf_size << 3;

        /** parse packet header */

        init_get_bits(gb, buf, s->buf_bit_size);

        packet_sequence_number = get_bits(gb, 4);

        skip_bits(gb, 2);

        /** get number of bits that need to be added to the previous frame */

        num_bits_prev_frame = get_bits(gb, s->log2_frame_size);

        av_dlog(avctx, "packet[%d]: nbpf %x\n", avctx->frame_number,

                num_bits_prev_frame);

        /** check for packet loss */

        if (!s->packet_loss &&

            ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) {

            s->packet_loss = 1;

            av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",

                   s->packet_sequence_number, packet_sequence_number);

        }

        s->packet_sequence_number = packet_sequence_number;

        if (num_bits_prev_frame > 0) {

            int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);

            if (num_bits_prev_frame >= remaining_packet_bits) {

                num_bits_prev_frame = remaining_packet_bits;

                s->packet_done = 1;

            }

            /** append the previous frame data to the remaining data from the

                previous packet to create a full frame */

            save_bits(s, gb, num_bits_prev_frame, 1);

            av_dlog(avctx, "accumulated %x bits of frame data\n",

                    s->num_saved_bits - s->frame_offset);

            /** decode the cross packet frame if it is valid */

            if (!s->packet_loss)

                decode_frame(s, data, got_frame_ptr);

        } else if (s->num_saved_bits - s->frame_offset) {

            av_dlog(avctx, "ignoring %x previously saved bits\n",

                    s->num_saved_bits - s->frame_offset);

        }

        if (s->packet_loss) {

            /** reset number of saved bits so that the decoder

                does not start to decode incomplete frames in the

                s->len_prefix == 0 case */

            s->num_saved_bits = 0;

            s->packet_loss = 0;

        }

    } else {

        int frame_size;

        s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3;

        init_get_bits(gb, avpkt->data, s->buf_bit_size);

        skip_bits(gb, s->packet_offset);

        if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size &&

            (frame_size = show_bits(gb, s->log2_frame_size)) &&

            frame_size <= remaining_bits(s, gb)) {

            save_bits(s, gb, frame_size, 0);

            s->packet_done = !decode_frame(s, data, got_frame_ptr);

        } else if (!s->len_prefix

                   && s->num_saved_bits > get_bits_count(&s->gb)) {

            /** when the frames do not have a length prefix, we don't know

                the compressed length of the individual frames

                however, we know what part of a new packet belongs to the

                previous frame

                therefore we save the incoming packet first, then we append

                the "previous frame" data from the next packet so that

                we get a buffer that only contains full frames */

            s->packet_done = !decode_frame(s, data, got_frame_ptr);

        } else

            s->packet_done = 1;

    }

    if (s->packet_done && !s->packet_loss &&

        remaining_bits(s, gb) > 0) {

        /** save the rest of the data so that it can be decoded

            with the next packet */

        save_bits(s, gb, remaining_bits(s, gb), 0);

    }

    s->packet_offset = get_bits_count(gb) & 7;

    if (s->packet_loss)

        return AVERROR_INVALIDDATA;

    return get_bits_count(gb) >> 3;

}


static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)

{

    int error;

    static pa_sample_spec ss;

    static pa_buffer_attr ba;

    struct audsettings obt_as = *as;

    PAVoiceOut *pa = (PAVoiceOut *) hw;

    ss.format = audfmt_to_pa (as->fmt, as->endianness);

    ss.channels = as->nchannels;

    ss.rate = as->freq;

    /*

     * qemu audio tick runs at 250 Hz (by default), so processing

     * data chunks worth 4 ms of sound should be a good fit.

     */

    ba.tlength = pa_usec_to_bytes (4 * 1000, &ss);

    ba.minreq = pa_usec_to_bytes (2 * 1000, &ss);

    ba.maxlength = -1;

    ba.prebuf = -1;

    obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);

    pa->s = pa_simple_new (

        conf.server,

        "qemu",

        PA_STREAM_PLAYBACK,

        conf.sink,

        "pcm.playback",

        &ss,

        NULL,                   /* channel map */

        &ba,                    /* buffering attributes */

        &error

        );

    if (!pa->s) {

        qpa_logerr (error, "pa_simple_new for playback failed\n");

        goto fail1;

    }

    audio_pcm_init_info (&hw->info, &obt_as);

    hw->samples = conf.samples;

    pa->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);

    pa->rpos = hw->rpos;

    if (!pa->pcm_buf) {

        dolog ("Could not allocate buffer (%d bytes)\n",

               hw->samples << hw->info.shift);

        goto fail2;

    }

    if (audio_pt_init (&pa->pt, qpa_thread_out, hw, AUDIO_CAP, AUDIO_FUNC)) {

        goto fail3;

    }

    return 0;

 fail3:

    g_free (pa->pcm_buf);

    pa->pcm_buf = NULL;

 fail2:

    pa_simple_free (pa->s);

    pa->s = NULL;

 fail1:

    return -1;

}


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

                         Error **errp)

{

    BDRVRBDState *s = bs->opaque;

    char pool[RBD_MAX_POOL_NAME_SIZE];

    char snap_buf[RBD_MAX_SNAP_NAME_SIZE];

    char conf[RBD_MAX_CONF_SIZE];

    char clientname_buf[RBD_MAX_CONF_SIZE];

    char *clientname;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *filename;

    int r;

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        qemu_opts_del(opts);

        return -EINVAL;

    }

    filename = qemu_opt_get(opts, "filename");

    if (qemu_rbd_parsename(filename, pool, sizeof(pool),

                           snap_buf, sizeof(snap_buf),

                           s->name, sizeof(s->name),

                           conf, sizeof(conf), errp) < 0) {

        r = -EINVAL;

        goto failed_opts;

    }

    clientname = qemu_rbd_parse_clientname(conf, clientname_buf);

    r = rados_create(&s->cluster, clientname);

    if (r < 0) {

        error_setg(&local_err, "error initializing");

        goto failed_opts;

    }

    s->snap = NULL;

    if (snap_buf[0] != '\0') {

        s->snap = g_strdup(snap_buf);

    }

    /*

     * Fallback to more conservative semantics if setting cache

     * options fails. Ignore errors from setting rbd_cache because the

     * only possible error is that the option does not exist, and

     * librbd defaults to no caching. If write through caching cannot

     * be set up, fall back to no caching.

     */

    if (flags & BDRV_O_NOCACHE) {

        rados_conf_set(s->cluster, "rbd_cache", "false");

    } else {

        rados_conf_set(s->cluster, "rbd_cache", "true");

    }

    if (strstr(conf, "conf=") == NULL) {

        /* try default location, but ignore failure */

        rados_conf_read_file(s->cluster, NULL);

    }

    if (conf[0] != '\0') {

        r = qemu_rbd_set_conf(s->cluster, conf, errp);

        if (r < 0) {

            goto failed_shutdown;

        }

    }

    r = rados_connect(s->cluster);

    if (r < 0) {

        error_setg(&local_err, "error connecting");

        goto failed_shutdown;

    }

    r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);

    if (r < 0) {

        error_setg(&local_err, "error opening pool %s", pool);

        goto failed_shutdown;

    }

    r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);

    if (r < 0) {

        error_setg(&local_err, "error reading header from %s", s->name);

        goto failed_open;

    }

    bs->read_only = (s->snap != NULL);

    qemu_opts_del(opts);

    return 0;

failed_open:

    rados_ioctx_destroy(s->io_ctx);

failed_shutdown:

    rados_shutdown(s->cluster);

    g_free(s->snap);

failed_opts:

    qemu_opts_del(opts);

    return r;

}


static void co_schedule_bh_cb(void *opaque)
{
    AioContext *ctx = opaque;
    QSLIST_HEAD(, Coroutine) straight, reversed;
    QSLIST_MOVE_ATOMIC(&reversed, &ctx->scheduled_coroutines);
    QSLIST_INIT(&straight);
    while (!QSLIST_EMPTY(&reversed)) {
        Coroutine *co = QSLIST_FIRST(&reversed);
        QSLIST_REMOVE_HEAD(&reversed, co_scheduled_next);
        QSLIST_INSERT_HEAD(&straight, co, co_scheduled_next);
    }
    while (!QSLIST_EMPTY(&straight)) {
        Coroutine *co = QSLIST_FIRST(&straight);
        QSLIST_REMOVE_HEAD(&straight, co_scheduled_next);
        trace_aio_co_schedule_bh_cb(ctx, co);
        aio_context_acquire(ctx);
        qemu_coroutine_enter(co);
        aio_context_release(ctx);
    }
}