static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)

{

    int header_size, backing_filename_len, l1_size, shift, i;

    QCowHeader header;

    uint8_t *tmp;

    int64_t total_size = 0;

    char *backing_file = NULL;

    Error *local_err = NULL;

    int ret;

    BlockBackend *qcow_blk;

    const char *encryptfmt = NULL;

    QDict *options;

    QDict *encryptopts = NULL;

    QCryptoBlockCreateOptions *crypto_opts = NULL;

    QCryptoBlock *crypto = NULL;

    /* Read out options */

    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),

                          BDRV_SECTOR_SIZE);

    if (total_size == 0) {

        error_setg(errp, "Image size is too small, cannot be zero length");

        ret = -EINVAL;

        goto cleanup;

    }

    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    encryptfmt = qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT);

    if (encryptfmt) {

        if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) {

            error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and "

                       BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive");

            ret = -EINVAL;

            goto cleanup;

        }

    } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {

        encryptfmt = "aes";

    }

    ret = bdrv_create_file(filename, opts, &local_err);

    if (ret < 0) {

        error_propagate(errp, local_err);

        goto cleanup;

    }

    qcow_blk = blk_new_open(filename, NULL, NULL,

                            BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,

                            &local_err);

    if (qcow_blk == NULL) {

        error_propagate(errp, local_err);

        ret = -EIO;

        goto cleanup;

    }

    blk_set_allow_write_beyond_eof(qcow_blk, true);

    ret = blk_truncate(qcow_blk, 0, PREALLOC_MODE_OFF, errp);

    if (ret < 0) {

        goto exit;

    }

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

    header.magic = cpu_to_be32(QCOW_MAGIC);

    header.version = cpu_to_be32(QCOW_VERSION);

    header.size = cpu_to_be64(total_size);

    header_size = sizeof(header);

    backing_filename_len = 0;

    if (backing_file) {

        if (strcmp(backing_file, "fat:")) {

            header.backing_file_offset = cpu_to_be64(header_size);

            backing_filename_len = strlen(backing_file);

            header.backing_file_size = cpu_to_be32(backing_filename_len);

            header_size += backing_filename_len;

        } else {

            /* special backing file for vvfat */

            g_free(backing_file);

            backing_file = NULL;

        }

        header.cluster_bits = 9; /* 512 byte cluster to avoid copying

                                    unmodified sectors */

        header.l2_bits = 12; /* 32 KB L2 tables */

    } else {

        header.cluster_bits = 12; /* 4 KB clusters */

        header.l2_bits = 9; /* 4 KB L2 tables */

    }

    header_size = (header_size + 7) & ~7;

    shift = header.cluster_bits + header.l2_bits;

    l1_size = (total_size + (1LL << shift) - 1) >> shift;

    header.l1_table_offset = cpu_to_be64(header_size);

    options = qemu_opts_to_qdict(opts, NULL);

    qdict_extract_subqdict(options, &encryptopts, "encrypt.");

    QDECREF(options);

    if (encryptfmt) {

        if (!g_str_equal(encryptfmt, "aes")) {

            error_setg(errp, "Unknown encryption format '%s', expected 'aes'",

                       encryptfmt);

            ret = -EINVAL;

            goto exit;

        }

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);

        crypto_opts = block_crypto_create_opts_init(

            Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp);

        if (!crypto_opts) {

            ret = -EINVAL;

            goto exit;

        }

        crypto = qcrypto_block_create(crypto_opts, "encrypt.",

                                      NULL, NULL, NULL, errp);

        if (!crypto) {

            ret = -EINVAL;

            goto exit;

        }

    } else {

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);

    }

    /* write all the data */

    ret = blk_pwrite(qcow_blk, 0, &header, sizeof(header), 0);

    if (ret != sizeof(header)) {

        goto exit;

    }

    if (backing_file) {

        ret = blk_pwrite(qcow_blk, sizeof(header),

                         backing_file, backing_filename_len, 0);

        if (ret != backing_filename_len) {

            goto exit;

        }

    }

    tmp = g_malloc0(BDRV_SECTOR_SIZE);

    for (i = 0; i < DIV_ROUND_UP(sizeof(uint64_t) * l1_size, BDRV_SECTOR_SIZE);

         i++) {

        ret = blk_pwrite(qcow_blk, header_size + BDRV_SECTOR_SIZE * i,

                         tmp, BDRV_SECTOR_SIZE, 0);

        if (ret != BDRV_SECTOR_SIZE) {

            g_free(tmp);

            goto exit;

        }

    }

    g_free(tmp);

    ret = 0;

exit:

    blk_unref(qcow_blk);

cleanup:

    QDECREF(encryptopts);

    qcrypto_block_free(crypto);

    qapi_free_QCryptoBlockCreateOptions(crypto_opts);

    g_free(backing_file);

    return ret;

}


static int hls_append_segment(struct AVFormatContext *s, HLSContext *hls, double duration,

                              int64_t pos, int64_t size)

{

    HLSSegment *en = av_malloc(sizeof(*en));

    const char  *filename;

    int ret;

    if (!en)

        return AVERROR(ENOMEM);

    if ((hls->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) &&

        strlen(hls->current_segment_final_filename_fmt)) {

        char * old_filename = av_strdup(hls->avf->filename);  // %%s will be %s after strftime

        av_strlcpy(hls->avf->filename, hls->current_segment_final_filename_fmt, sizeof(hls->avf->filename));

        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {

            char * filename = av_strdup(hls->avf->filename);  // %%s will be %s after strftime

            if (!filename)

                return AVERROR(ENOMEM);

            if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),

                filename, 's', pos + size) < 1) {

                av_log(hls, AV_LOG_ERROR,

                       "Invalid second level segment filename template '%s', "

                        "you can try to remove second_level_segment_size flag\n",

                       filename);

                av_free(filename);

                av_free(old_filename);

                return AVERROR(EINVAL);

            }

            av_free(filename);

        }

        if (hls->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {

            char * filename = av_strdup(hls->avf->filename);  // %%t will be %t after strftime

            if (!filename)

                return AVERROR(ENOMEM);

            if (replace_int_data_in_filename(hls->avf->filename, sizeof(hls->avf->filename),

                filename, 't',  (int64_t)round(1000000 * duration)) < 1) {

                av_log(hls, AV_LOG_ERROR,

                       "Invalid second level segment filename template '%s', "

                        "you can try to remove second_level_segment_time flag\n",

                       filename);

                av_free(filename);

                av_free(old_filename);

                return AVERROR(EINVAL);

            }

            av_free(filename);

        }

        ff_rename(old_filename, hls->avf->filename, hls);

        av_free(old_filename);

    }

    filename = av_basename(hls->avf->filename);

    if (hls->use_localtime_mkdir) {

        filename = hls->avf->filename;

    }

    if (find_segment_by_filename(hls->segments, filename)

        || find_segment_by_filename(hls->old_segments, filename)) {

        av_log(hls, AV_LOG_WARNING, "Duplicated segment filename detected: %s\n", filename);

    }

    av_strlcpy(en->filename, filename, sizeof(en->filename));

    if(hls->has_subtitle)

        av_strlcpy(en->sub_filename, av_basename(hls->vtt_avf->filename), sizeof(en->sub_filename));

    else

        en->sub_filename[0] = '\0';

    en->duration = duration;

    en->pos      = pos;

    en->size     = size;

    en->next     = NULL;

    en->discont  = 0;

    if (hls->discontinuity) {

        en->discont = 1;

        hls->discontinuity = 0;

    }

    if (hls->key_info_file) {

        av_strlcpy(en->key_uri, hls->key_uri, sizeof(en->key_uri));

        av_strlcpy(en->iv_string, hls->iv_string, sizeof(en->iv_string));

    }

    if (!hls->segments)

        hls->segments = en;

    else

        hls->last_segment->next = en;

    hls->last_segment = en;

    // EVENT or VOD playlists imply sliding window cannot be used

    if (hls->pl_type != PLAYLIST_TYPE_NONE)

        hls->max_nb_segments = 0;

    if (hls->max_nb_segments && hls->nb_entries >= hls->max_nb_segments) {

        en = hls->segments;

        hls->initial_prog_date_time += en->duration;

        hls->segments = en->next;

        if (en && hls->flags & HLS_DELETE_SEGMENTS &&

                !(hls->flags & HLS_SINGLE_FILE || hls->wrap)) {

            en->next = hls->old_segments;

            hls->old_segments = en;

            if ((ret = hls_delete_old_segments(hls)) < 0)

                return ret;

        } else

            av_free(en);

    } else

        hls->nb_entries++;

    if (hls->max_seg_size > 0) {

        return 0;

    }

    hls->sequence++;

    return 0;

}


static int x8_decode_intra_mb(IntraX8Context* const w, const int chroma){

    MpegEncContext * const s= w->s;

    uint8_t * scantable;

    int final,run,level;

    int ac_mode,dc_mode,est_run,dc_level;

    int pos,n;

    int zeros_only;

    int use_quant_matrix;

    int sign;

    assert(w->orient<12);

    s->dsp.clear_block(s->block[0]);

    if(chroma){

        dc_mode=2;

    }else{

        dc_mode=!!w->est_run;//0,1

    }

    if(x8_get_dc_rlf(w, dc_mode, &dc_level, &final)) return -1;

    n=0;

    zeros_only=0;

    if(!final){//decode ac

        use_quant_matrix=w->use_quant_matrix;

        if(chroma){

            ac_mode = 1;

            est_run = 64;//not used

        }else{

            if (w->raw_orient < 3){

                use_quant_matrix = 0;

            }

            if(w->raw_orient > 4){

                ac_mode = 0;

                est_run = 64;

            }else{

                if(w->est_run > 1){

                    ac_mode = 2;

                    est_run=w->est_run;

                }else{

                    ac_mode = 3;

                    est_run = 64;

                }

            }

        }

        x8_select_ac_table(w,ac_mode);

        /*scantable_selector[12]={0,2,0,1,1,1,0,2,2,0,1,2};<-

        -> 10'01' 00'10' 10'00' 01'01' 01'00' 10'00 =>0x928548 */

        scantable = w->scantable[ (0x928548>>(2*w->orient))&3 ].permutated;

        pos=0;

        do {

            n++;

            if( n >= est_run ){

                ac_mode=3;

                x8_select_ac_table(w,3);

            }

            x8_get_ac_rlf(w,ac_mode,&run,&level,&final);

            pos+=run+1;

            if(pos>63){

                //this also handles vlc error in x8_get_ac_rlf

                return -1;

            }

            level= (level+1) * w->dquant;

            level+= w->qsum;

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

            level = (level ^ sign) - sign;

            if(use_quant_matrix){

                level = (level*quant_table[pos])>>8;

            }

            s->block[0][ scantable[pos] ]=level;

        }while(!final);

        s->block_last_index[0]=pos;

    }else{//DC only

        s->block_last_index[0]=0;

        if(w->flat_dc && ((unsigned)(dc_level+1)) < 3){//[-1;1]

            int32_t divide_quant= !chroma ? w->divide_quant_dc_luma:

                                            w->divide_quant_dc_chroma;

            int32_t dc_quant    = !chroma ? w->quant:

                                            w->quant_dc_chroma;

            //original intent dc_level+=predicted_dc/quant; but it got lost somewhere in the rounding

            dc_level+= (w->predicted_dc*divide_quant + (1<<12) )>>13;

            dsp_x8_put_solidcolor( av_clip_uint8((dc_level*dc_quant+4)>>3),

                                   s->dest[chroma], s->current_picture.f.linesize[!!chroma]);

            goto block_placed;

        }

        zeros_only = (dc_level == 0);

    }

    if(!chroma){

        s->block[0][0] = dc_level*w->quant;

    }else{

        s->block[0][0] = dc_level*w->quant_dc_chroma;

    }

    //there is !zero_only check in the original, but dc_level check is enough

    if( (unsigned int)(dc_level+1) >= 3 && (w->edges&3) != 3 ){

        int direction;

        /*ac_comp_direction[orient] = { 0, 3, 3, 1, 1, 0, 0, 0, 2, 2, 2, 1 };<-

        -> 01'10' 10'10' 00'00' 00'01' 01'11' 11'00 =>0x6A017C */

        direction= (0x6A017C>>(w->orient*2))&3;

        if (direction != 3){

            x8_ac_compensation(w, direction, s->block[0][0]);//modify block_last[]

        }

    }

    if(w->flat_dc){

        dsp_x8_put_solidcolor(w->predicted_dc, s->dest[chroma], s->current_picture.f.linesize[!!chroma]);

    }else{

        w->dsp.spatial_compensation[w->orient]( s->edge_emu_buffer,

                                            s->dest[chroma],

                                            s->current_picture.f.linesize[!!chroma] );

    }

    if(!zeros_only)

        s->dsp.idct_add ( s->dest[chroma],

                          s->current_picture.f.linesize[!!chroma],

                          s->block[0] );

block_placed:

    if(!chroma){

        x8_update_predictions(w,w->orient,n);

    }

    if(s->loop_filter){

        uint8_t* ptr = s->dest[chroma];

        int linesize = s->current_picture.f.linesize[!!chroma];

        if(!( (w->edges&2) || ( zeros_only && (w->orient|4)==4 ) )){

            w->dsp.h_loop_filter(ptr, linesize, w->quant);

        }

        if(!( (w->edges&1) || ( zeros_only && (w->orient|8)==8 ) )){

            w->dsp.v_loop_filter(ptr, linesize, w->quant);

        }

    }

    return 0;

}


static void pci_device_reset(PCIDevice *dev)

{

    int r;

    memset(dev->irq_state, 0, sizeof dev->irq_state);

    dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY |

                                  PCI_COMMAND_MASTER);

    dev->config[PCI_CACHE_LINE_SIZE] = 0x0;

    dev->config[PCI_INTERRUPT_LINE] = 0x0;

    for (r = 0; r < PCI_NUM_REGIONS; ++r) {

        if (!dev->io_regions[r].size) {

            continue;

        }

        pci_set_long(dev->config + pci_bar(dev, r), dev->io_regions[r].type);

    }

    pci_update_mappings(dev);

}


static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)

{

    AVStream *st = c->fc->streams[c->fc->nb_streams-1];

    //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;

    int entries, i;

    int64_t duration=0;

    int64_t total_sample_count=0;

    print_atom("stts", atom);

    get_byte(pb); /* version */

    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */

    entries = get_be32(pb);

    c->streams[c->fc->nb_streams-1]->stts_count = entries;

    c->streams[c->fc->nb_streams-1]->stts_data = (uint64_t*) av_malloc(entries * sizeof(uint64_t));

#ifdef DEBUG

av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);

#endif

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

        int32_t sample_duration;

        int32_t sample_count;

        sample_count=get_be32(pb);

        sample_duration = get_be32(pb);

        c->streams[c->fc->nb_streams - 1]->stts_data[i] = (uint64_t)sample_count<<32 | (uint64_t)sample_duration;

#ifdef DEBUG

        av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);

#endif

        duration+=sample_duration*sample_count;

        total_sample_count+=sample_count;

#if 0 //We calculate an average instead, needed by .mp4-files created with nec e606 3g phone

        if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) {

            st->codec.frame_rate_base = sample_duration ? sample_duration : 1;

            st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale;

#ifdef DEBUG

            av_log(NULL, AV_LOG_DEBUG, "VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration);

#endif

        }

#endif

    }

    /*The stsd atom which contain codec type sometimes comes after the stts so we cannot check for codec_type*/

    if(duration>0)

    {

        av_reduce(

            &st->codec.frame_rate,

            &st->codec.frame_rate_base,

            c->streams[c->fc->nb_streams-1]->time_scale * total_sample_count,

            duration,

            INT_MAX

        );

#ifdef DEBUG

        av_log(NULL, AV_LOG_DEBUG, "FRAME RATE average (video or audio)= %f (tot sample count= %i ,tot dur= %i timescale=%d)\n", (float)st->codec.frame_rate/st->codec.frame_rate_base,total_sample_count,duration,c->streams[c->fc->nb_streams-1]->time_scale);

#endif

    }

    else

    {

        st->codec.frame_rate_base = 1;

        st->codec.frame_rate = c->streams[c->fc->nb_streams-1]->time_scale;

    }

    return 0;

}


static int window(venc_context_t * venc, signed short * audio, int samples) {

    int i, j, channel;

    const float * win = venc->win[0];

    int window_len = 1 << (venc->blocksize[0] - 1);

    float n = (float)(1 << venc->blocksize[0]) / 4.;

    // FIXME use dsp

    if (!venc->have_saved && !samples) return 0;

    if (venc->have_saved) {

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

            memcpy(venc->samples + channel*window_len*2, venc->saved + channel*window_len, sizeof(float)*window_len);

        }

    } else {

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

            memset(venc->samples + channel*window_len*2, 0, sizeof(float)*window_len);

        }

    }

    if (samples) {

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

            float * offset = venc->samples + channel*window_len*2 + window_len;

            j = channel;

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

                offset[i] = audio[j] / 32768. * win[window_len - i] / n;

        }

    } else {

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

            memset(venc->samples + channel*window_len*2 + window_len, 0, sizeof(float)*window_len);

        }

    }

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

        ff_mdct_calc(&venc->mdct[0], venc->coeffs + channel*window_len, venc->samples + channel*window_len*2, venc->floor/*tmp*/);

    }

    if (samples) {

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

            float * offset = venc->saved + channel*window_len;

            j = channel;

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

                offset[i] = audio[j] / 32768. * win[i] / n;

        }

        venc->have_saved = 1;

    } else {

        venc->have_saved = 0;

    }

    return 1;

}


DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)

{

    const char *buf;

    const char *file = NULL;

    char devname[128];

    const char *serial;

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriver *drv = NULL;

    int max_devs;

    int index;

    int ro = 0;

    int bdrv_flags = 0;

    int on_read_error, on_write_error;

    const char *devaddr;

    DriveInfo *dinfo;

    int snapshot = 0;

    int ret;

    *fatal_error = 1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    if (default_to_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

        pstrcpy(devname, sizeof(devname), "scsi");

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

        pstrcpy(devname, sizeof(devname), "ide");

    }

    media = MEDIA_DISK;

    /* extract parameters */

    bus_id  = qemu_opt_get_number(opts, "bus", 0);

    unit_id = qemu_opt_get_number(opts, "unit", -1);

    index   = qemu_opt_get_number(opts, "index", -1);

    cyls  = qemu_opt_get_number(opts, "cyls", 0);

    heads = qemu_opt_get_number(opts, "heads", 0);

    secs  = qemu_opt_get_number(opts, "secs", 0);

    snapshot = qemu_opt_get_bool(opts, "snapshot", 0);

    ro = qemu_opt_get_bool(opts, "readonly", 0);

    file = qemu_opt_get(opts, "file");

    serial = qemu_opt_get(opts, "serial");

    if ((buf = qemu_opt_get(opts, "if")) != NULL) {

        pstrcpy(devname, sizeof(devname), buf);

        if (!strcmp(buf, "ide")) {

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

        } else if (!strcmp(buf, "scsi")) {

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

        } else if (!strcmp(buf, "floppy")) {

	    type = IF_FLOPPY;

            max_devs = 0;

        } else if (!strcmp(buf, "pflash")) {

	    type = IF_PFLASH;

            max_devs = 0;

	} else if (!strcmp(buf, "mtd")) {

	    type = IF_MTD;

            max_devs = 0;

	} else if (!strcmp(buf, "sd")) {

	    type = IF_SD;

            max_devs = 0;

        } else if (!strcmp(buf, "virtio")) {

            type = IF_VIRTIO;

            max_devs = 0;

	} else if (!strcmp(buf, "xen")) {

	    type = IF_XEN;

            max_devs = 0;

	} else if (!strcmp(buf, "none")) {

	    type = IF_NONE;

            max_devs = 0;

	} else {

            fprintf(stderr, "qemu: unsupported bus type '%s'\n", buf);

            return NULL;

	}

    }

    if (cyls || heads || secs) {

        if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {

            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", buf);

	    return NULL;

	}

        if (heads < 1 || (type == IF_IDE && heads > 16)) {

            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", buf);

	    return NULL;

	}

        if (secs < 1 || (type == IF_IDE && secs > 63)) {

            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {

        if (!cyls) {

            fprintf(stderr,

                    "qemu: '%s' trans must be used with cyls,heads and secs\n",

                    buf);

            return NULL;

        }

        if (!strcmp(buf, "none"))

            translation = BIOS_ATA_TRANSLATION_NONE;

        else if (!strcmp(buf, "lba"))

            translation = BIOS_ATA_TRANSLATION_LBA;

        else if (!strcmp(buf, "auto"))

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

            fprintf(stderr, "qemu: '%s' invalid translation type\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "media")) != NULL) {

        if (!strcmp(buf, "disk")) {

	    media = MEDIA_DISK;

	} else if (!strcmp(buf, "cdrom")) {

            if (cyls || secs || heads) {

                fprintf(stderr,

                        "qemu: '%s' invalid physical CHS format\n", buf);

	        return NULL;

            }

	    media = MEDIA_CDROM;

	} else {

	    fprintf(stderr, "qemu: '%s' invalid media\n", buf);

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "cache")) != NULL) {

        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {

            bdrv_flags |= BDRV_O_NOCACHE;

        } else if (!strcmp(buf, "writeback")) {

            bdrv_flags |= BDRV_O_CACHE_WB;

        } else if (!strcmp(buf, "unsafe")) {

            bdrv_flags |= BDRV_O_CACHE_WB;

            bdrv_flags |= BDRV_O_NO_FLUSH;

        } else if (!strcmp(buf, "writethrough")) {

            /* this is the default */

        } else {

           fprintf(stderr, "qemu: invalid cache option\n");

           return NULL;

        }

    }

#ifdef CONFIG_LINUX_AIO

    if ((buf = qemu_opt_get(opts, "aio")) != NULL) {

        if (!strcmp(buf, "native")) {

            bdrv_flags |= BDRV_O_NATIVE_AIO;

        } else if (!strcmp(buf, "threads")) {

            /* this is the default */

        } else {

           fprintf(stderr, "qemu: invalid aio option\n");

           return NULL;

        }

    }

#endif

    if ((buf = qemu_opt_get(opts, "format")) != NULL) {

       if (strcmp(buf, "?") == 0) {

            fprintf(stderr, "qemu: Supported formats:");

            bdrv_iterate_format(bdrv_format_print, NULL);

            fprintf(stderr, "\n");

	    return NULL;

        }

        drv = bdrv_find_whitelisted_format(buf);

        if (!drv) {

            fprintf(stderr, "qemu: '%s' invalid format\n", buf);

            return NULL;

        }

    }

    on_write_error = BLOCK_ERR_STOP_ENOSPC;

    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {

            fprintf(stderr, "werror is no supported by this format\n");

            return NULL;

        }

        on_write_error = parse_block_error_action(buf, 0);

        if (on_write_error < 0) {

            return NULL;

        }

    }

    on_read_error = BLOCK_ERR_REPORT;

    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {

        if (type != IF_IDE && type != IF_VIRTIO && type != IF_NONE) {

            fprintf(stderr, "rerror is no supported by this format\n");

            return NULL;

        }

        on_read_error = parse_block_error_action(buf, 1);

        if (on_read_error < 0) {

            return NULL;

        }

    }

    if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {

        if (type != IF_VIRTIO) {

            fprintf(stderr, "addr is not supported\n");

            return NULL;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

        if (bus_id != 0 || unit_id != -1) {

            fprintf(stderr,

                    "qemu: index cannot be used with bus and unit\n");

            return NULL;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

       while (drive_get(type, bus_id, unit_id) != NULL) {

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

        fprintf(stderr, "qemu: unit %d too big (max is %d)\n",

                unit_id, max_devs - 1);

        return NULL;

    }

    /*

     * ignore multiple definitions

     */

    if (drive_get(type, bus_id, unit_id) != NULL) {

        *fatal_error = 0;

        return NULL;

    }

    /* init */

    dinfo = qemu_mallocz(sizeof(*dinfo));

    if ((buf = qemu_opts_id(opts)) != NULL) {

        dinfo->id = qemu_strdup(buf);

    } else {

        /* no id supplied -> create one */

        dinfo->id = qemu_mallocz(32);

        if (type == IF_IDE || type == IF_SCSI)

            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";

        if (max_devs)

            snprintf(dinfo->id, 32, "%s%i%s%i",

                     devname, bus_id, mediastr, unit_id);

        else

            snprintf(dinfo->id, 32, "%s%s%i",

                     devname, mediastr, unit_id);

    }

    dinfo->bdrv = bdrv_new(dinfo->id);

    dinfo->devaddr = devaddr;

    dinfo->type = type;

    dinfo->bus = bus_id;

    dinfo->unit = unit_id;

    dinfo->on_read_error = on_read_error;

    dinfo->on_write_error = on_write_error;

    dinfo->opts = opts;

    if (serial)

        strncpy(dinfo->serial, serial, sizeof(serial));

    QTAILQ_INSERT_TAIL(&drives, dinfo, next);

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

    case IF_NONE:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

                bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);

                bdrv_set_translation_hint(dinfo->bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

        /* FIXME: This isn't really a floppy, but it's a reasonable

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

        break;

    case IF_VIRTIO:

        /* add virtio block device */

        opts = qemu_opts_create(&qemu_device_opts, NULL, 0);

        qemu_opt_set(opts, "driver", "virtio-blk-pci");

        qemu_opt_set(opts, "drive", dinfo->id);

        if (devaddr)

            qemu_opt_set(opts, "addr", devaddr);

        break;

    case IF_COUNT:

        abort();

    }

    if (!file) {

        *fatal_error = 0;

        return NULL;

    }

    if (snapshot) {

        /* always use cache=unsafe with snapshot */

        bdrv_flags &= ~BDRV_O_CACHE_MASK;

        bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);

    }

    if (media == MEDIA_CDROM) {

        /* CDROM is fine for any interface, don't check.  */

        ro = 1;

    } else if (ro == 1) {

        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY && type != IF_NONE) {

            fprintf(stderr, "qemu: readonly flag not supported for drive with this interface\n");

            return NULL;

        }

    }

    bdrv_flags |= ro ? 0 : BDRV_O_RDWR;

    ret = bdrv_open(dinfo->bdrv, file, bdrv_flags, drv);

    if (ret < 0) {

        fprintf(stderr, "qemu: could not open disk image %s: %s\n",

                        file, strerror(-ret));

        return NULL;

    }

    if (bdrv_key_required(dinfo->bdrv))

        autostart = 0;

    *fatal_error = 0;

    return dinfo;

}


static int rtsp_read_play(AVFormatContext *s)

{

    RTSPState *rt = s->priv_data;

    RTSPMessageHeader reply1, *reply = &reply1;

    int i;

    char cmd[1024];

    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);

    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {

        if (rt->state == RTSP_STATE_PAUSED) {

            cmd[0] = 0;

        } else {

            snprintf(cmd, sizeof(cmd),

                     "Range: npt=%0.3f-\r\n",

                     (double)rt->seek_timestamp / AV_TIME_BASE);

        }

        ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);

        if (reply->status_code != RTSP_STATUS_OK) {

            return -1;

        }

        if (reply->range_start != AV_NOPTS_VALUE &&

            rt->transport == RTSP_TRANSPORT_RTP) {

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

                RTSPStream *rtsp_st = rt->rtsp_streams[i];

                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;

                AVStream *st = NULL;

                if (rtsp_st->stream_index >= 0)

                    st = s->streams[rtsp_st->stream_index];

                rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;

                rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;

                if (st)

                    rtpctx->range_start_offset = av_rescale_q(reply->range_start,

                                                              AV_TIME_BASE_Q,

                                                              st->time_base);

            }

        }

    }

    rt->state = RTSP_STATE_STREAMING;

    return 0;

}


static int aiff_read_header(AVFormatContext *s)

{

    int size, filesize;

    int64_t offset = 0;

    uint32_t tag;

    unsigned version = AIFF_C_VERSION1;

    AVIOContext *pb = s->pb;

    AVStream * st;

    AIFFInputContext *aiff = s->priv_data;

    /* check FORM header */

    filesize = get_tag(pb, &tag);

    if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))

        return AVERROR_INVALIDDATA;

    /* AIFF data type */

    tag = avio_rl32(pb);

    if (tag == MKTAG('A', 'I', 'F', 'F'))       /* Got an AIFF file */

        version = AIFF;

    else if (tag != MKTAG('A', 'I', 'F', 'C'))  /* An AIFF-C file then */

        return AVERROR_INVALIDDATA;

    filesize -= 4;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    while (filesize > 0) {

        /* parse different chunks */

        size = get_tag(pb, &tag);

        if (size < 0)

            return size;

        filesize -= size + 8;

        switch (tag) {

        case MKTAG('C', 'O', 'M', 'M'):     /* Common chunk */

            /* Then for the complete header info */

            st->nb_frames = get_aiff_header(s, size, version);

            if (st->nb_frames < 0)

                return st->nb_frames;

            if (offset > 0) // COMM is after SSND

                goto got_sound;

            break;

        case MKTAG('F', 'V', 'E', 'R'):     /* Version chunk */

            version = avio_rb32(pb);

            break;

        case MKTAG('N', 'A', 'M', 'E'):     /* Sample name chunk */

            get_meta(s, "title"    , size);

            break;

        case MKTAG('A', 'U', 'T', 'H'):     /* Author chunk */

            get_meta(s, "author"   , size);

            break;

        case MKTAG('(', 'c', ')', ' '):     /* Copyright chunk */

            get_meta(s, "copyright", size);

            break;

        case MKTAG('A', 'N', 'N', 'O'):     /* Annotation chunk */

            get_meta(s, "comment"  , size);

            break;

        case MKTAG('S', 'S', 'N', 'D'):     /* Sampled sound chunk */

            aiff->data_end = avio_tell(pb) + size;

            offset = avio_rb32(pb);      /* Offset of sound data */

            avio_rb32(pb);               /* BlockSize... don't care */

            offset += avio_tell(pb);    /* Compute absolute data offset */

            if (st->codecpar->block_align)    /* Assume COMM already parsed */

                goto got_sound;

            if (!pb->seekable) {

                av_log(s, AV_LOG_ERROR, "file is not seekable\n");

                return -1;

            }

            avio_skip(pb, size - 8);

            break;

        case MKTAG('w', 'a', 'v', 'e'):

            if ((uint64_t)size > (1<<30))

                return -1;

            st->codecpar->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codecpar->extradata)

                return AVERROR(ENOMEM);

            st->codecpar->extradata_size = size;

            avio_read(pb, st->codecpar->extradata, size);

            break;

        default: /* Jump */

            avio_skip(pb, size);

        }

        /* Skip required padding byte for odd-sized chunks. */

        if (size & 1) {

            filesize--;

            avio_skip(pb, 1);

        }

    }

got_sound:

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

        av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");

        return -1;

    }

    /* Now positioned, get the sound data start and end */

    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);

    st->start_time = 0;

    st->duration = st->nb_frames * aiff->block_duration;

    /* Position the stream at the first block */

    avio_seek(pb, offset, SEEK_SET);

    return 0;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->no_hotplug = 1;

    k->init = piix4_initfn;

    k->vendor_id = PCI_VENDOR_ID_INTEL;

    k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;

    k->class_id = PCI_CLASS_BRIDGE_ISA;

    dc->desc = "ISA bridge";

    dc->no_user = 1;

    dc->vmsd = &vmstate_piix4;

}


static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,

                               AVStream *st, AVPacket *pkt,

                               uint32_t *timestamp,

                               const uint8_t *buf, int len, int flags)

{

    AVIOContext *pb = &asf->pb;

    int res, mflags, len_off;

    RTSPState *rt = s->priv_data;

    if (!rt->asf_ctx)

    if (len > 0) {

        int off, out_len = 0;

        if (len < 4)

        av_freep(&asf->buf);

        ffio_init_context(pb, buf, len, 0, NULL, NULL, NULL, NULL);

        while (avio_tell(pb) + 4 < len) {

            int start_off = avio_tell(pb);

            mflags = avio_r8(pb);

            if (mflags & 0x80)

                flags |= RTP_FLAG_KEY;

            len_off = avio_rb24(pb);

            if (mflags & 0x20)   /**< relative timestamp */

                avio_skip(pb, 4);

            if (mflags & 0x10)   /**< has duration */

                avio_skip(pb, 4);

            if (mflags & 0x8)    /**< has location ID */

                avio_skip(pb, 4);

            off = avio_tell(pb);

            if (!(mflags & 0x40)) {

                /**

                 * If 0x40 is not set, the len_off field specifies an offset

                 * of this packet's payload data in the complete (reassembled)

                 * ASF packet. This is used to spread one ASF packet over

                 * multiple RTP packets.

                 */

                if (asf->pktbuf && len_off != avio_tell(asf->pktbuf)) {

                    uint8_t *p;

                    avio_close_dyn_buf(asf->pktbuf, &p);

                    asf->pktbuf = NULL;

                    av_free(p);

                }

                if (!len_off && !asf->pktbuf &&

                    (res = avio_open_dyn_buf(&asf->pktbuf)) < 0)

                    return res;

                if (!asf->pktbuf)

                    return AVERROR(EIO);

                avio_write(asf->pktbuf, buf + off, len - off);

                avio_skip(pb, len - off);

                if (!(flags & RTP_FLAG_MARKER))

                out_len     = avio_close_dyn_buf(asf->pktbuf, &asf->buf);

                asf->pktbuf = NULL;

            } else {

                /**

                 * If 0x40 is set, the len_off field specifies the length of

                 * the next ASF packet that can be read from this payload

                 * data alone. This is commonly the same as the payload size,

                 * but could be less in case of packet splitting (i.e.

                 * multiple ASF packets in one RTP packet).

                 */

                int cur_len = start_off + len_off - off;

                int prev_len = out_len;

                out_len += cur_len;

                asf->buf = av_realloc(asf->buf, out_len);

                memcpy(asf->buf + prev_len, buf + off,

                       FFMIN(cur_len, len - off));

                avio_skip(pb, cur_len);

            }

        }

        init_packetizer(pb, asf->buf, out_len);

        pb->pos += rt->asf_pb_pos;

        pb->eof_reached = 0;

        rt->asf_ctx->pb = pb;

    }

    for (;;) {

        int i;

        res = av_read_packet(rt->asf_ctx, pkt);

        rt->asf_pb_pos = avio_tell(pb);

        if (res != 0)

            break;

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

            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {

                pkt->stream_index = i;

                return 1; // FIXME: return 0 if last packet

            }

        }

        av_free_packet(pkt);

    }

    return res == 1 ? -1 : res;

}


int match_ext(const char *filename, const char *extensions)

{

    const char *ext, *p;

    char ext1[32], *q;

    if(!filename)

        return 0;

    ext = strrchr(filename, '.');

    if (ext) {

        ext++;

        p = extensions;

        for(;;) {

            q = ext1;

            while (*p != '\0' && *p != ',')

                *q++ = *p++;

            *q = '\0';

            if (!strcasecmp(ext1, ext))

                return 1;

            if (*p == '\0')

                break;

            p++;

        }

    }

    return 0;

}


static int avi_read_header(AVFormatContext *s)

{

    AVIContext *avi = s->priv_data;

    AVIOContext *pb = s->pb;

    unsigned int tag, tag1, handler;

    int codec_type, stream_index, frame_period;

    unsigned int size;

    int i;

    AVStream *st;

    AVIStream *ast      = NULL;

    int avih_width      = 0, avih_height = 0;

    int amv_file_format = 0;

    uint64_t list_end   = 0;

    int64_t pos;

    int ret;

    AVDictionaryEntry *dict_entry;

    avi->stream_index = -1;

    ret = get_riff(s, pb);

    if (ret < 0)

        return ret;

    av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);

    avi->io_fsize = avi->fsize = avio_size(pb);

    if (avi->fsize <= 0 || avi->fsize < avi->riff_end)

        avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;

    /* first list tag */

    stream_index = -1;

    codec_type   = -1;

    frame_period = 0;

    for (;;) {

        if (avio_feof(pb))

            goto fail;

        tag  = avio_rl32(pb);

        size = avio_rl32(pb);

        print_tag("tag", tag, size);

        switch (tag) {

        case MKTAG('L', 'I', 'S', 'T'):

            list_end = avio_tell(pb) + size;

            /* Ignored, except at start of video packets. */

            tag1 = avio_rl32(pb);

            print_tag("list", tag1, 0);

            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {

                avi->movi_list = avio_tell(pb) - 4;

                if (size)

                    avi->movi_end = avi->movi_list + size + (size & 1);

                else

                    avi->movi_end = avi->fsize;

                av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);

                goto end_of_header;

            } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))

                ff_read_riff_info(s, size - 4);

            else if (tag1 == MKTAG('n', 'c', 'd', 't'))

                avi_read_nikon(s, list_end);

            break;

        case MKTAG('I', 'D', 'I', 'T'):

        {

            unsigned char date[64] = { 0 };

            size += (size & 1);

            size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));

            avio_skip(pb, size);

            avi_metadata_creation_time(&s->metadata, date);

            break;

        case MKTAG('d', 'm', 'l', 'h'):

            avi->is_odml = 1;

            avio_skip(pb, size + (size & 1));

            break;

        case MKTAG('a', 'm', 'v', 'h'):

            amv_file_format = 1;

        case MKTAG('a', 'v', 'i', 'h'):

            /* AVI header */

            /* using frame_period is bad idea */

            frame_period = avio_rl32(pb);

            avio_rl32(pb); /* max. bytes per second */

            avio_rl32(pb);

            avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;

            avio_skip(pb, 2 * 4);

            avio_rl32(pb);

            avio_rl32(pb);

            avih_width  = avio_rl32(pb);

            avih_height = avio_rl32(pb);

            avio_skip(pb, size - 10 * 4);

            break;

        case MKTAG('s', 't', 'r', 'h'):

            /* stream header */

            tag1    = avio_rl32(pb);

            handler = avio_rl32(pb); /* codec tag */

            if (tag1 == MKTAG('p', 'a', 'd', 's')) {

                avio_skip(pb, size - 8);

                break;

            } else {

                stream_index++;

                st = avformat_new_stream(s, NULL);

                if (!st)

                    goto fail;

                st->id = stream_index;

                ast    = av_mallocz(sizeof(AVIStream));

                if (!ast)

                    goto fail;

                st->priv_data = ast;

            if (amv_file_format)

                tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')

                                    : MKTAG('v', 'i', 'd', 's');

            print_tag("strh", tag1, -1);

            if (tag1 == MKTAG('i', 'a', 'v', 's') ||

                tag1 == MKTAG('i', 'v', 'a', 's')) {

                int64_t dv_dur;

                /* After some consideration -- I don't think we

                 * have to support anything but DV in type1 AVIs. */

                if (s->nb_streams != 1)

                    goto fail;

                if (handler != MKTAG('d', 'v', 's', 'd') &&

                    handler != MKTAG('d', 'v', 'h', 'd') &&

                    handler != MKTAG('d', 'v', 's', 'l'))

                    goto fail;

                ast = s->streams[0]->priv_data;

                av_freep(&s->streams[0]->codecpar->extradata);

                av_freep(&s->streams[0]->codecpar);

#if FF_API_LAVF_AVCTX

FF_DISABLE_DEPRECATION_WARNINGS

                av_freep(&s->streams[0]->codec);

FF_ENABLE_DEPRECATION_WARNINGS

#endif

                if (s->streams[0]->info)

                    av_freep(&s->streams[0]->info->duration_error);

                av_freep(&s->streams[0]->info);

                if (s->streams[0]->internal)

                    av_freep(&s->streams[0]->internal->avctx);

                av_freep(&s->streams[0]->internal);

                av_freep(&s->streams[0]);

                s->nb_streams = 0;

                if (CONFIG_DV_DEMUXER) {

                    avi->dv_demux = avpriv_dv_init_demux(s);

                    if (!avi->dv_demux)

                        goto fail;

                } else

                    goto fail;

                s->streams[0]->priv_data = ast;

                avio_skip(pb, 3 * 4);

                ast->scale = avio_rl32(pb);

                ast->rate  = avio_rl32(pb);

                avio_skip(pb, 4);  /* start time */

                dv_dur = avio_rl32(pb);

                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {

                    dv_dur     *= AV_TIME_BASE;

                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);

                /* else, leave duration alone; timing estimation in utils.c

                 * will make a guess based on bitrate. */

                stream_index = s->nb_streams - 1;

                avio_skip(pb, size - 9 * 4);

                break;

            av_assert0(stream_index < s->nb_streams);

            ast->handler = handler;

            avio_rl32(pb); /* flags */

            avio_rl16(pb); /* priority */

            avio_rl16(pb); /* language */

            avio_rl32(pb); /* initial frame */

            ast->scale = avio_rl32(pb);

            ast->rate  = avio_rl32(pb);

            if (!(ast->scale && ast->rate)) {

                av_log(s, AV_LOG_WARNING,

                       "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "

                       "(This file has been generated by broken software.)\n",

                       ast->scale,

                       ast->rate);

                if (frame_period) {

                    ast->rate  = 1000000;

                    ast->scale = frame_period;

                } else {

                    ast->rate  = 25;

                    ast->scale = 1;

            avpriv_set_pts_info(st, 64, ast->scale, ast->rate);

            ast->cum_len  = avio_rl32(pb); /* start */

            st->nb_frames = avio_rl32(pb);

            st->start_time = 0;

            avio_rl32(pb); /* buffer size */

            avio_rl32(pb); /* quality */

            if (ast->cum_len*ast->scale/ast->rate > 3600) {

                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");

                ast->cum_len = 0;

            ast->sample_size = avio_rl32(pb);

            ast->cum_len    *= FFMAX(1, ast->sample_size);

            av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",

                    ast->rate, ast->scale, ast->sample_size);

            switch (tag1) {

            case MKTAG('v', 'i', 'd', 's'):

                codec_type = AVMEDIA_TYPE_VIDEO;

                ast->sample_size = 0;

                st->avg_frame_rate = av_inv_q(st->time_base);

                break;

            case MKTAG('a', 'u', 'd', 's'):

                codec_type = AVMEDIA_TYPE_AUDIO;

                break;

            case MKTAG('t', 'x', 't', 's'):

                codec_type = AVMEDIA_TYPE_SUBTITLE;

                break;

            case MKTAG('d', 'a', 't', 's'):

                codec_type = AVMEDIA_TYPE_DATA;

                break;

            default:

                av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);

            if (ast->sample_size < 0) {

                if (s->error_recognition & AV_EF_EXPLODE) {

                    av_log(s, AV_LOG_ERROR,

                           "Invalid sample_size %d at stream %d\n",

                           ast->sample_size,

                           stream_index);

                    goto fail;

                av_log(s, AV_LOG_WARNING,

                       "Invalid sample_size %d at stream %d "

                       "setting it to 0\n",

                       ast->sample_size,

                       stream_index);

                ast->sample_size = 0;

            if (ast->sample_size == 0) {

                st->duration = st->nb_frames;

                if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {

                    av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");

                    st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);

            ast->frame_offset = ast->cum_len;

            avio_skip(pb, size - 12 * 4);

            break;

        case MKTAG('s', 't', 'r', 'f'):

            /* stream header */

            if (!size)

                break;

            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {

                avio_skip(pb, size);

            } else {

                uint64_t cur_pos = avio_tell(pb);

                unsigned esize;

                if (cur_pos < list_end)

                    size = FFMIN(size, list_end - cur_pos);

                st = s->streams[stream_index];

                if (st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN) {

                    avio_skip(pb, size);

                    break;

                switch (codec_type) {

                case AVMEDIA_TYPE_VIDEO:

                    if (amv_file_format) {

                        st->codecpar->width      = avih_width;

                        st->codecpar->height     = avih_height;

                        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

                        st->codecpar->codec_id   = AV_CODEC_ID_AMV;

                        avio_skip(pb, size);

                        break;

                    tag1 = ff_get_bmp_header(pb, st, &esize);

                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||

                        tag1 == MKTAG('D', 'X', 'S', 'A')) {

                        st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;

                        st->codecpar->codec_tag  = tag1;

                        st->codecpar->codec_id   = AV_CODEC_ID_XSUB;

                        break;

                    if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {

                        if (esize == size-1 && (esize&1)) {

                            st->codecpar->extradata_size = esize - 10 * 4;

                        } else

                            st->codecpar->extradata_size =  size - 10 * 4;

                        if (ff_get_extradata(s, st->codecpar, pb, st->codecpar->extradata_size) < 0)

                            return AVERROR(ENOMEM);

                    // FIXME: check if the encoder really did this correctly

                    if (st->codecpar->extradata_size & 1)

                        avio_r8(pb);

                    /* Extract palette from extradata if bpp <= 8.

                     * This code assumes that extradata contains only palette.

                     * This is true for all paletted codecs implemented in

                     * FFmpeg. */

                    if (st->codecpar->extradata_size &&

                        (st->codecpar->bits_per_coded_sample <= 8)) {

                        int pal_size = (1 << st->codecpar->bits_per_coded_sample) << 2;

                        const uint8_t *pal_src;

                        pal_size = FFMIN(pal_size, st->codecpar->extradata_size);

                        pal_src  = st->codecpar->extradata +

                                   st->codecpar->extradata_size - pal_size;

                        /* Exclude the "BottomUp" field from the palette */

                        if (pal_src - st->codecpar->extradata >= 9 &&

                            !memcmp(st->codecpar->extradata + st->codecpar->extradata_size - 9, "BottomUp", 9))

                            pal_src -= 9;

                        for (i = 0; i < pal_size / 4; i++)

                            ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);

                        ast->has_pal = 1;

                    print_tag("video", tag1, 0);

                    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

                    st->codecpar->codec_tag  = tag1;

                    st->codecpar->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,

                                                            tag1);

                    /* If codec is not found yet, try with the mov tags. */

                    if (!st->codecpar->codec_id) {

                        char tag_buf[32];

                        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1);

                        st->codecpar->codec_id =

                            ff_codec_get_id(ff_codec_movvideo_tags, tag1);

                        if (st->codecpar->codec_id)

                           av_log(s, AV_LOG_WARNING,

                                  "mov tag found in avi (fourcc %s)\n",

                                  tag_buf);

                    /* This is needed to get the pict type which is necessary

                     * for generating correct pts. */

                    st->need_parsing = AVSTREAM_PARSE_HEADERS;

                    if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 &&

                        ast->handler == MKTAG('X', 'V', 'I', 'D'))

                        st->codecpar->codec_tag = MKTAG('X', 'V', 'I', 'D');

                    if (st->codecpar->codec_tag == MKTAG('V', 'S', 'S', 'H'))

                        st->need_parsing = AVSTREAM_PARSE_FULL;

                    if (st->codecpar->codec_id == AV_CODEC_ID_RV40)

                        st->need_parsing = AVSTREAM_PARSE_NONE;

                    if (st->codecpar->codec_tag == 0 && st->codecpar->height > 0 &&

                        st->codecpar->extradata_size < 1U << 30) {

                        st->codecpar->extradata_size += 9;

                        if ((ret = av_reallocp(&st->codecpar->extradata,

                                               st->codecpar->extradata_size +

                                               AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {

                            st->codecpar->extradata_size = 0;

                            return ret;

                        } else

                            memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9,

                                   "BottomUp", 9);

                    st->codecpar->height = FFABS(st->codecpar->height);

//                    avio_skip(pb, size - 5 * 4);

                    break;

                case AVMEDIA_TYPE_AUDIO:

                    ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);

                    if (ret < 0)

                        return ret;

                    ast->dshow_block_align = st->codecpar->block_align;

                    if (ast->sample_size && st->codecpar->block_align &&

                        ast->sample_size != st->codecpar->block_align) {

                        av_log(s,

                               AV_LOG_WARNING,

                               "sample size (%d) != block align (%d)\n",

                               ast->sample_size,

                               st->codecpar->block_align);

                        ast->sample_size = st->codecpar->block_align;

                    /* 2-aligned

                     * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */

                    if (size & 1)

                        avio_skip(pb, 1);

                    /* Force parsing as several audio frames can be in

                     * one packet and timestamps refer to packet start. */

                    st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;

                    /* ADTS header is in extradata, AAC without header must be

                     * stored as exact frames. Parser not needed and it will

                     * fail. */

                    if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&

                        st->codecpar->extradata_size)

                        st->need_parsing = AVSTREAM_PARSE_NONE;

                    // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS

                    if (st->codecpar->codec_id == AV_CODEC_ID_FLAC)

                        st->need_parsing = AVSTREAM_PARSE_NONE;

                    /* AVI files with Xan DPCM audio (wrongly) declare PCM

                     * audio in the header but have Axan as stream_code_tag. */

                    if (ast->handler == AV_RL32("Axan")) {

                        st->codecpar->codec_id  = AV_CODEC_ID_XAN_DPCM;

                        st->codecpar->codec_tag = 0;

                        ast->dshow_block_align = 0;

                    if (amv_file_format) {

                        st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;

                        ast->dshow_block_align = 0;

                    if ((st->codecpar->codec_id == AV_CODEC_ID_AAC  ||

                         st->codecpar->codec_id == AV_CODEC_ID_FLAC ||

                         st->codecpar->codec_id == AV_CODEC_ID_MP2 ) && ast->dshow_block_align <= 4 && ast->dshow_block_align) {

                        av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);

                        ast->dshow_block_align = 0;

                    if (st->codecpar->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||

                       st->codecpar->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||

                       st->codecpar->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {

                        av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");

                        ast->sample_size = 0;

                    break;

                case AVMEDIA_TYPE_SUBTITLE:

                    st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;

                    st->request_probe= 1;

                    avio_skip(pb, size);

                    break;

                default:

                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;

                    st->codecpar->codec_id   = AV_CODEC_ID_NONE;

                    st->codecpar->codec_tag  = 0;

                    avio_skip(pb, size);

                    break;

            break;

        case MKTAG('s', 't', 'r', 'd'):

            if (stream_index >= (unsigned)s->nb_streams

                || s->streams[stream_index]->codecpar->extradata_size

                || s->streams[stream_index]->codecpar->codec_tag == MKTAG('H','2','6','4')) {

                avio_skip(pb, size);

            } else {

                uint64_t cur_pos = avio_tell(pb);

                if (cur_pos < list_end)

                    size = FFMIN(size, list_end - cur_pos);

                st = s->streams[stream_index];

                if (size<(1<<30)) {

                        av_log(s, AV_LOG_WARNING, "New extradata in strd chunk, freeing previous one.\n");

                    if (ff_get_extradata(s, st->codecpar, pb, size) < 0)

                        return AVERROR(ENOMEM);

                if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly

                    avio_r8(pb);

                ret = avi_extract_stream_metadata(s, st);

                if (ret < 0) {

                    av_log(s, AV_LOG_WARNING, "could not decoding EXIF data in stream header.\n");

            break;

        case MKTAG('i', 'n', 'd', 'x'):

            pos = avio_tell(pb);

            if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&

                avi->use_odml &&

                read_braindead_odml_indx(s, 0) < 0 &&

                (s->error_recognition & AV_EF_EXPLODE))

                goto fail;

            avio_seek(pb, pos + size, SEEK_SET);

            break;

        case MKTAG('v', 'p', 'r', 'p'):

            if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {

                AVRational active, active_aspect;

                st = s->streams[stream_index];

                avio_rl32(pb);

                avio_rl32(pb);

                avio_rl32(pb);

                avio_rl32(pb);

                avio_rl32(pb);

                active_aspect.den = avio_rl16(pb);

                active_aspect.num = avio_rl16(pb);

                active.num        = avio_rl32(pb);

                active.den        = avio_rl32(pb);

                avio_rl32(pb); // nbFieldsPerFrame

                if (active_aspect.num && active_aspect.den &&

                    active.num && active.den) {

                    st->sample_aspect_ratio = av_div_q(active_aspect, active);

                    av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",

                            active_aspect.num, active_aspect.den,

                            active.num, active.den);

                size -= 9 * 4;

            avio_skip(pb, size);

            break;

        case MKTAG('s', 't', 'r', 'n'):

            if (s->nb_streams) {

                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);

                if (ret < 0)

                    return ret;

                break;

        default:

            if (size > 1000000) {

                char tag_buf[32];

                av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag);

                av_log(s, AV_LOG_ERROR,

                       "Something went wrong during header parsing, "

                       "tag %s has size %u, "

                       "I will ignore it and try to continue anyway.\n",

                       tag_buf, size);

                if (s->error_recognition & AV_EF_EXPLODE)

                    goto fail;

                avi->movi_list = avio_tell(pb) - 4;

                avi->movi_end  = avi->fsize;

                goto end_of_header;

        /* Do not fail for very large idx1 tags */

        case MKTAG('i', 'd', 'x', '1'):

            /* skip tag */

            size += (size & 1);

            avio_skip(pb, size);

            break;

end_of_header:

    /* check stream number */

    if (stream_index != s->nb_streams - 1) {

fail:

        return AVERROR_INVALIDDATA;

    if (!avi->index_loaded && pb->seekable)

        avi_load_index(s);

    calculate_bitrate(s);

    avi->index_loaded    |= 1;

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

        return ret;

    avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);

    dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);

    if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))

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

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

            if (   st->codecpar->codec_id == AV_CODEC_ID_MPEG1VIDEO

                || st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)

                st->need_parsing = AVSTREAM_PARSE_FULL;

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

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

        if (st->nb_index_entries)

            break;

    // DV-in-AVI cannot be non-interleaved, if set this must be

    // a mis-detection.

    if (avi->dv_demux)

        avi->non_interleaved = 0;

    if (i == s->nb_streams && avi->non_interleaved) {

        av_log(s, AV_LOG_WARNING,

               "Non-interleaved AVI without index, switching to interleaved\n");

        avi->non_interleaved = 0;

    if (avi->non_interleaved) {

        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");

        clean_index(s);

    ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);

    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);

    return 0;


static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,

				     int off_pitch, int bytesperline,

				     int lines)

{

    int y;

    int off_cur;

    int off_cur_end;

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

	off_cur = off_begin;

	off_cur_end = off_cur + bytesperline;

	off_cur &= TARGET_PAGE_MASK;

	while (off_cur < off_cur_end) {

	    cpu_physical_memory_set_dirty(s->vram_offset + off_cur);

	    off_cur += TARGET_PAGE_SIZE;

	}

	off_begin += off_pitch;

    }

}


static inline float to_float(uint8_t exp, int16_t mantissa)

{

    return ((float) (mantissa * scale_factors[exp]));

}


static int encode_init(AVCodecContext *avctx)

{

    HYuvContext *s = avctx->priv_data;

    int i, j, width, height;

    s->avctx= avctx;

    s->flags= avctx->flags;

    dsputil_init(&s->dsp, avctx);

    width= s->width= avctx->width;

    height= s->height= avctx->height;

    assert(width && height);

    avctx->extradata= av_mallocz(1024*30);

    avctx->stats_out= av_mallocz(1024*30);

    s->version=2;

    avctx->coded_frame= &s->picture;

    switch(avctx->pix_fmt){

    case PIX_FMT_YUV420P:

        s->bitstream_bpp= 12;

        break;

    case PIX_FMT_YUV422P:

        s->bitstream_bpp= 16;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "format not supported\n");

        return -1;

    }

    avctx->bits_per_sample= s->bitstream_bpp;

    s->decorrelate= s->bitstream_bpp >= 24;

    s->predictor= avctx->prediction_method;

    s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;

    if(avctx->context_model==1){

        s->context= avctx->context_model;

        if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){

            av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n");

            return -1;

        }

    }else s->context= 0;

    if(avctx->codec->id==CODEC_ID_HUFFYUV){

        if(avctx->pix_fmt==PIX_FMT_YUV420P){

            av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n");

            return -1;

        }

        if(avctx->context_model){

            av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n");

            return -1;

        }

        if(s->interlaced != ( height > 288 ))

            av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n");

    }else if(avctx->strict_std_compliance>=0){

        av_log(avctx, AV_LOG_ERROR, "This codec is under development; files encoded with it may not be decodeable with future versions!!! Set vstrict=-1 to use it anyway.\n");

        return -1;

    }

    ((uint8_t*)avctx->extradata)[0]= s->predictor;

    ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;

    ((uint8_t*)avctx->extradata)[2]= 0x20 | (s->interlaced ? 0x10 : 0);

    if(s->context)

        ((uint8_t*)avctx->extradata)[2]|= 0x40;

    ((uint8_t*)avctx->extradata)[3]= 0;

    s->avctx->extradata_size= 4;

    if(avctx->stats_in){

        char *p= avctx->stats_in;

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

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

                s->stats[i][j]= 1;

        for(;;){

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

                char *next;

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

                    s->stats[i][j]+= strtol(p, &next, 0);

                    if(next==p) return -1;

                    p=next;

                }

            }

            if(p[0]==0 || p[1]==0 || p[2]==0) break;

        }

    }else{

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

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

                int d= FFMIN(j, 256-j);

                s->stats[i][j]= 100000000/(d+1);

            }

    }

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

        generate_len_table(s->len[i], s->stats[i], 256);

        if(generate_bits_table(s->bits[i], s->len[i])<0){

            return -1;

        }

        s->avctx->extradata_size+=

        store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]);

    }

    if(s->context){

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

            int pels = width*height / (i?40:10);

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

                int d= FFMIN(j, 256-j);

                s->stats[i][j]= pels/(d+1);

            }

        }

    }else{

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

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

                s->stats[i][j]= 0;

    }

//    printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);

    s->picture_number=0;

    return 0;

}


void error_set_win32(Error **errp, int win32_err, ErrorClass err_class,

                     const char *fmt, ...)

{

    va_list ap;

    char *msg1, *msg2;

    if (errp == NULL) {

        return;

    }

    va_start(ap, fmt);

    error_setv(errp, err_class, fmt, ap);

    va_end(ap);

    if (win32_err != 0) {

        msg1 = (*errp)->msg;

        msg2 = g_win32_error_message(win32_err);

        (*errp)->msg = g_strdup_printf("%s: %s (error: %x)", msg1, msg2,

                                       (unsigned)win32_err);

        g_free(msg2);

        g_free(msg1);

    }

}


av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,

                                enum AVResampleDitherMethod method)

{

    int cpu_flags = av_get_cpu_flags();

    if (EXTERNAL_SSE2(cpu_flags)) {

        ddsp->quantize      = ff_quantize_sse2;

        ddsp->ptr_align     = 16;

        ddsp->samples_align = 8;

    }

    if (method == AV_RESAMPLE_DITHER_RECTANGULAR) {

        if (EXTERNAL_SSE2(cpu_flags)) {

            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_sse2;

        }

        if (EXTERNAL_AVX(cpu_flags)) {

            ddsp->dither_int_to_float = ff_dither_int_to_float_rectangular_avx;

        }

    } else {

        if (EXTERNAL_SSE2(cpu_flags)) {

            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_sse2;

        }

        if (EXTERNAL_AVX(cpu_flags)) {

            ddsp->dither_int_to_float = ff_dither_int_to_float_triangular_avx;

        }

    }

}


static int qio_channel_socket_dgram_worker(QIOTask *task,

                                           Error **errp,

                                           gpointer opaque)

{

    QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(qio_task_get_source(task));

    struct QIOChannelSocketDGramWorkerData *data = opaque;

    int ret;

    /* socket_dgram() blocks in DNS lookups, so we must use a thread */

    ret = qio_channel_socket_dgram_sync(ioc,

                                        data->localAddr,

                                        data->remoteAddr,

                                        errp);

    object_unref(OBJECT(ioc));

    return ret;

}


static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)

{

    uint16_t i;

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

        Aml *dev = aml_device("C%03x", i);

        aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));

        aml_append(dev, aml_name_decl("_UID", aml_int(i)));

        aml_append(scope, dev);

    }

}


static int svq1_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             AVPacket *avpkt)

{

  const uint8_t *buf = avpkt->data;

  int buf_size = avpkt->size;

  MpegEncContext *s=avctx->priv_data;

  uint8_t        *current, *previous;

  int             result, i, x, y, width, height;

  AVFrame *pict = data;

  svq1_pmv *pmv;

  /* initialize bit buffer */

  init_get_bits(&s->gb,buf,buf_size*8);

  /* decode frame header */

  s->f_code = get_bits (&s->gb, 22);

  if ((s->f_code & ~0x70) || !(s->f_code & 0x60))

    return -1;

  /* swap some header bytes (why?) */

  if (s->f_code != 0x20) {

    uint32_t *src = (uint32_t *) (buf + 4);

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

      src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i];

    }

  }

  result = svq1_decode_frame_header (&s->gb, s);

  if (result != 0)

  {

    av_dlog(s->avctx, "Error in svq1_decode_frame_header %i\n",result);

    return result;

  }

  //FIXME this avoids some confusion for "B frames" without 2 references

  //this should be removed after libavcodec can handle more flexible picture types & ordering

  if(s->pict_type==AV_PICTURE_TYPE_B && s->last_picture_ptr==NULL) return buf_size;

  if(  (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==AV_PICTURE_TYPE_B)

     ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=AV_PICTURE_TYPE_I)

     || avctx->skip_frame >= AVDISCARD_ALL)

      return buf_size;

  if(MPV_frame_start(s, avctx) < 0)

      return -1;

  pmv = av_malloc((FFALIGN(s->width, 16)/8 + 3) * sizeof(*pmv));

  if (!pmv)

      return -1;

  /* decode y, u and v components */

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

    int linesize;

    if (i == 0) {

      width  = FFALIGN(s->width, 16);

      height = FFALIGN(s->height, 16);

      linesize= s->linesize;

    } else {

      if(s->flags&CODEC_FLAG_GRAY) break;

      width  = FFALIGN(s->width/4, 16);

      height = FFALIGN(s->height/4, 16);

      linesize= s->uvlinesize;

    }

    current = s->current_picture.f.data[i];

    if(s->pict_type==AV_PICTURE_TYPE_B){

        previous = s->next_picture.f.data[i];

    }else{

        previous = s->last_picture.f.data[i];

    }

    if (s->pict_type == AV_PICTURE_TYPE_I) {

      /* keyframe */

      for (y=0; y < height; y+=16) {

        for (x=0; x < width; x+=16) {

          result = svq1_decode_block_intra (&s->gb, &current[x], linesize);

          if (result != 0)

          {

            av_log(s->avctx, AV_LOG_INFO, "Error in svq1_decode_block %i (keyframe)\n",result);

            goto err;

          }

        }

        current += 16*linesize;

      }

    } else {

      /* delta frame */

      memset (pmv, 0, ((width / 8) + 3) * sizeof(svq1_pmv));

      for (y=0; y < height; y+=16) {

        for (x=0; x < width; x+=16) {

          result = svq1_decode_delta_block (s, &s->gb, &current[x], previous,

                                            linesize, pmv, x, y);

          if (result != 0)

          {

            av_dlog(s->avctx, "Error in svq1_decode_delta_block %i\n",result);

            goto err;

          }

        }

        pmv[0].x =

        pmv[0].y = 0;

        current += 16*linesize;

      }

    }

  }

  *pict = *(AVFrame*)&s->current_picture;

  MPV_frame_end(s);

  *data_size=sizeof(AVFrame);

  result = buf_size;

err:

  av_free(pmv);

  return result;

}


static int parse_object_segment(AVCodecContext *avctx,

                                  const uint8_t *buf, int buf_size)

{

    PGSSubContext *ctx = avctx->priv_data;

    PGSSubObject *object;

    uint8_t sequence_desc;

    unsigned int rle_bitmap_len, width, height;

    int id;

    if (buf_size <= 4)

        return AVERROR_INVALIDDATA;

    buf_size -= 4;

    id = bytestream_get_be16(&buf);

    object = find_object(id, &ctx->objects);

    if (!object) {

        if (ctx->objects.count >= MAX_EPOCH_OBJECTS) {

            av_log(avctx, AV_LOG_ERROR, "Too many objects in epoch\n");

            return AVERROR_INVALIDDATA;

        }

        object = &ctx->objects.object[ctx->objects.count++];

        object->id = id;

    }

    /* skip object version number */

    buf += 1;

    /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */

    sequence_desc = bytestream_get_byte(&buf);

    if (!(sequence_desc & 0x80)) {

        /* Additional RLE data */

        if (buf_size > object->rle_remaining_len)

            return AVERROR_INVALIDDATA;

        memcpy(object->rle + object->rle_data_len, buf, buf_size);

        object->rle_data_len += buf_size;

        object->rle_remaining_len -= buf_size;

        return 0;

    }

    if (buf_size <= 7)

        return AVERROR_INVALIDDATA;

    buf_size -= 7;

    /* Decode rle bitmap length, stored size includes width/height data */

    rle_bitmap_len = bytestream_get_be24(&buf) - 2*2;

    if (buf_size > rle_bitmap_len) {

        av_log(avctx, AV_LOG_ERROR,

               "Buffer dimension %d larger than the expected RLE data %d\n",

               buf_size, rle_bitmap_len);

        return AVERROR_INVALIDDATA;

    }

    /* Get bitmap dimensions from data */

    width  = bytestream_get_be16(&buf);

    height = bytestream_get_be16(&buf);

    /* Make sure the bitmap is not too large */

    if (avctx->width < width || avctx->height < height) {

        av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger than video.\n");

        return AVERROR_INVALIDDATA;

    }

    object->w = width;

    object->h = height;

    av_fast_padded_malloc(&object->rle, &object->rle_buffer_size, rle_bitmap_len);

    if (!object->rle)

        return AVERROR(ENOMEM);

    memcpy(object->rle, buf, buf_size);

    object->rle_data_len = buf_size;

    object->rle_remaining_len = rle_bitmap_len - buf_size;

    return 0;

}


static int ram_load_postcopy(QEMUFile *f)

{

    int flags = 0, ret = 0;

    bool place_needed = false;

    bool matching_page_sizes = qemu_host_page_size == TARGET_PAGE_SIZE;

    MigrationIncomingState *mis = migration_incoming_get_current();

    /* Temporary page that is later 'placed' */

    void *postcopy_host_page = postcopy_get_tmp_page(mis);

    void *last_host = NULL;

    while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {

        ram_addr_t addr;

        void *host = NULL;

        void *page_buffer = NULL;

        void *place_source = NULL;

        uint8_t ch;

        bool all_zero = false;

        addr = qemu_get_be64(f);

        flags = addr & ~TARGET_PAGE_MASK;

        addr &= TARGET_PAGE_MASK;

        trace_ram_load_postcopy_loop((uint64_t)addr, flags);

        place_needed = false;

        if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE)) {

            host = host_from_stream_offset(f, addr, flags);

            if (!host) {

                error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);

                ret = -EINVAL;

                break;

            }

            page_buffer = host;

            /*

             * Postcopy requires that we place whole host pages atomically.

             * To make it atomic, the data is read into a temporary page

             * that's moved into place later.

             * The migration protocol uses,  possibly smaller, target-pages

             * however the source ensures it always sends all the components

             * of a host page in order.

             */

            page_buffer = postcopy_host_page +

                          ((uintptr_t)host & ~qemu_host_page_mask);

            /* If all TP are zero then we can optimise the place */

            if (!((uintptr_t)host & ~qemu_host_page_mask)) {

                all_zero = true;

            } else {

                /* not the 1st TP within the HP */

                if (host != (last_host + TARGET_PAGE_SIZE)) {

                    error_report("Non-sequential target page %p/%p\n",

                                  host, last_host);

                    ret = -EINVAL;

                    break;

                }

            }

            /*

             * If it's the last part of a host page then we place the host

             * page

             */

            place_needed = (((uintptr_t)host + TARGET_PAGE_SIZE) &

                                     ~qemu_host_page_mask) == 0;

            place_source = postcopy_host_page;

        }

        switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {

        case RAM_SAVE_FLAG_COMPRESS:

            ch = qemu_get_byte(f);

            memset(page_buffer, ch, TARGET_PAGE_SIZE);

            if (ch) {

                all_zero = false;

            }

            break;

        case RAM_SAVE_FLAG_PAGE:

            all_zero = false;

            if (!place_needed || !matching_page_sizes) {

                qemu_get_buffer(f, page_buffer, TARGET_PAGE_SIZE);

            } else {

                /* Avoids the qemu_file copy during postcopy, which is

                 * going to do a copy later; can only do it when we

                 * do this read in one go (matching page sizes)

                 */

                qemu_get_buffer_in_place(f, (uint8_t **)&place_source,

                                         TARGET_PAGE_SIZE);

            }

            break;

        case RAM_SAVE_FLAG_EOS:

            /* normal exit */

            break;

        default:

            error_report("Unknown combination of migration flags: %#x"

                         " (postcopy mode)", flags);

            ret = -EINVAL;

        }

        if (place_needed) {

            /* This gets called at the last target page in the host page */

            if (all_zero) {

                ret = postcopy_place_page_zero(mis,

                                               host + TARGET_PAGE_SIZE -

                                               qemu_host_page_size);

            } else {

                ret = postcopy_place_page(mis, host + TARGET_PAGE_SIZE -

                                               qemu_host_page_size,

                                               place_source);

            }

        }

        if (!ret) {

            ret = qemu_file_get_error(f);

        }

    }

    return ret;

}


static bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req)

{

    VirtIOSCSICommon *vs = &s->parent_obj;

    SCSIDevice *d;

    int rc;

    rc = virtio_scsi_parse_req(req, sizeof(VirtIOSCSICmdReq) + vs->cdb_size,

                               sizeof(VirtIOSCSICmdResp) + vs->sense_size);

    if (rc < 0) {

        if (rc == -ENOTSUP) {

            virtio_scsi_fail_cmd_req(req);

        } else {

            virtio_scsi_bad_req();

        }

        return false;

    }

    d = virtio_scsi_device_find(s, req->req.cmd.lun);

    if (!d) {

        req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET;

        virtio_scsi_complete_cmd_req(req);

        return false;

    }

    virtio_scsi_ctx_check(s, d);

    req->sreq = scsi_req_new(d, req->req.cmd.tag,

                             virtio_scsi_get_lun(req->req.cmd.lun),

                             req->req.cmd.cdb, req);

    if (req->sreq->cmd.mode != SCSI_XFER_NONE

        && (req->sreq->cmd.mode != req->mode ||

            req->sreq->cmd.xfer > req->qsgl.size)) {

        req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN;

        virtio_scsi_complete_cmd_req(req);

        return false;

    }

    scsi_req_ref(req->sreq);

    blk_io_plug(d->conf.blk);

    return true;

}


static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order,

                      uint32_t sums[][MAX_PARTITIONS])

{

    int i, j;

    int parts;

    uint32_t *res, *res_end;

    /* sums for highest level */

    parts   = (1 << pmax);

    res     = &data[pred_order];

    res_end = &data[n >> pmax];

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

        uint32_t sum = 0;

        while (res < res_end)

            sum += *(res++);

        sums[pmax][i] = sum;

        res_end += n >> pmax;

    }

    /* sums for lower levels */

    for (i = pmax - 1; i >= pmin; i--) {

        parts = (1 << i);

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

            sums[i][j] = sums[i+1][2*j] + sums[i+1][2*j+1];

    }

}


static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,

                                   MTPObject *o)

{

    MTPData *d = usb_mtp_data_alloc(c);

    trace_usb_mtp_op_get_object(s->dev.addr, o->handle, o->path);

    d->fd = open(o->path, O_RDONLY);

    if (d->fd == -1) {

        return NULL;

    }

    d->length = o->stat.st_size;

    d->alloc  = 512;

    d->data   = g_malloc(d->alloc);

    return d;

}


static void init_block_index(VC1Context *v)

{

    MpegEncContext *s = &v->s;

    ff_init_block_index(s);

    if (v->field_mode && !(v->second_field ^ v->tff)) {

        s->dest[0] += s->current_picture_ptr->f.linesize[0];

        s->dest[1] += s->current_picture_ptr->f.linesize[1];

        s->dest[2] += s->current_picture_ptr->f.linesize[2];

    }

}


bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,

                                            QVirtQueue *vq, uint64_t timeout)

{

    do {

        clock_step(100);

        if (bus->get_queue_isr_status(d, vq)) {

            break; /* It has ended */

        }

    } while (--timeout);

    return timeout != 0;

}


static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, int num_tracks)

{

    ebml_master cues_element;

    int64_t currentpos;

    int i, j;

    currentpos = avio_tell(pb);

    cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0);

    for (i = 0; i < cues->num_entries; i++) {

        ebml_master cuepoint, track_positions;

        mkv_cuepoint *entry = &cues->entries[i];

        uint64_t pts = entry->pts;

        cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks));

        put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts);

        // put all the entries from different tracks that have the exact same

        // timestamp into the same CuePoint

        for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) {

            track_positions = start_ebml_master(pb, MATROSKA_ID_CUETRACKPOSITION, MAX_CUETRACKPOS_SIZE);

            put_ebml_uint(pb, MATROSKA_ID_CUETRACK          , entry[j].tracknum   );

            put_ebml_uint(pb, MATROSKA_ID_CUECLUSTERPOSITION, entry[j].cluster_pos);

            end_ebml_master(pb, track_positions);

        }

        i += j - 1;

        end_ebml_master(pb, cuepoint);

    }

    end_ebml_master(pb, cues_element);

    av_free(cues->entries);

    av_free(cues);

    return currentpos;

}


static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter)

{

    DXVA2DevicePriv *priv = ctx->user_opaque;

    D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params;

    D3DDISPLAYMODEEX modeex = {0};

    IDirect3D9Ex *d3d9ex = NULL;

    IDirect3DDevice9Ex *exdev = NULL;

    HRESULT hr;

    pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)dlsym(priv->d3dlib, "Direct3DCreate9Ex");

    if (!createD3DEx)

        return AVERROR(ENOSYS);

    hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex);

    if (FAILED(hr))

        return AVERROR_UNKNOWN;

    IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL);

    d3dpp.BackBufferFormat = modeex.Format;

    hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(),

                                     FF_D3DCREATE_FLAGS,

                                     &d3dpp, NULL, &exdev);

    if (FAILED(hr)) {

        IDirect3D9Ex_Release(d3d9ex);

        return AVERROR_UNKNOWN;

    }

    av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n");

    priv->d3d9 = (IDirect3D9 *)d3d9ex;

    priv->d3d9device = (IDirect3DDevice9 *)exdev;

    return 0;

}


static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
{
    if (time) {
        if(time >= 2082844800)
            time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
        avpriv_dict_set_timestamp(metadata, "creation_time", time * 1000000);