uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,

                      uint64_t arg3)

{

    CPU_DoubleU farg1, farg2, farg3;

    farg1.ll = arg1;

    farg2.ll = arg2;

    farg3.ll = arg3;

    if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||

                 (float64_is_zero(farg1.d) &&

                  float64_is_infinity(farg2.d)))) {

        /* Multiplication of zero by infinity */

        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);

    } else {

        if (unlikely(float64_is_signaling_nan(farg1.d) ||

                     float64_is_signaling_nan(farg2.d) ||

                     float64_is_signaling_nan(farg3.d))) {

            /* sNaN operation */

            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);

        }

        /* This is the way the PowerPC specification defines it */

        float128 ft0_128, ft1_128;

        ft0_128 = float64_to_float128(farg1.d, &env->fp_status);

        ft1_128 = float64_to_float128(farg2.d, &env->fp_status);

        ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);

        if (unlikely(float128_is_infinity(ft0_128) &&

                     float64_is_infinity(farg3.d) &&

                     float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {

            /* Magnitude subtraction of infinities */

            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);

        } else {

            ft1_128 = float64_to_float128(farg3.d, &env->fp_status);

            ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);

            farg1.d = float128_to_float64(ft0_128, &env->fp_status);

        }

    }

    return farg1.ll;

}


static bool bdrv_exceed_bps_limits(BlockDriverState *bs, int nb_sectors,

                 bool is_write, double elapsed_time, uint64_t *wait)

{

    uint64_t bps_limit = 0;

    double   bytes_limit, bytes_base, bytes_res;

    double   slice_time, wait_time;

    if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) {

        bps_limit = bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];

    } else if (bs->io_limits.bps[is_write]) {

        bps_limit = bs->io_limits.bps[is_write];

    } else {

        if (wait) {

            *wait = 0;

        }

        return false;

    }

    slice_time = bs->slice_end - bs->slice_start;

    slice_time /= (NANOSECONDS_PER_SECOND);

    bytes_limit = bps_limit * slice_time;

    bytes_base  = bs->nr_bytes[is_write] - bs->io_base.bytes[is_write];

    if (bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]) {

        bytes_base += bs->nr_bytes[!is_write] - bs->io_base.bytes[!is_write];

    }

    /* bytes_base: the bytes of data which have been read/written; and

     *             it is obtained from the history statistic info.

     * bytes_res: the remaining bytes of data which need to be read/written.

     * (bytes_base + bytes_res) / bps_limit: used to calcuate

     *             the total time for completing reading/writting all data.

     */

    bytes_res   = (unsigned) nb_sectors * BDRV_SECTOR_SIZE;

    if (bytes_base + bytes_res <= bytes_limit) {

        if (wait) {

            *wait = 0;

        }

        return false;

    }

    /* Calc approx time to dispatch */

    wait_time = (bytes_base + bytes_res) / bps_limit - elapsed_time;

    /* When the I/O rate at runtime exceeds the limits,

     * bs->slice_end need to be extended in order that the current statistic

     * info can be kept until the timer fire, so it is increased and tuned

     * based on the result of experiment.

     */

    bs->slice_time = wait_time * BLOCK_IO_SLICE_TIME * 10;

    bs->slice_end += bs->slice_time - 3 * BLOCK_IO_SLICE_TIME;

    if (wait) {

        *wait = wait_time * BLOCK_IO_SLICE_TIME * 10;

    }

    return true;

}


static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,

        GetBitContext * gb, const IndividualChannelStream * ics) {

    int w, filt, i, coef_len, coef_res, coef_compress;

    const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;

    const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;

    for (w = 0; w < ics->num_windows; w++) {

        tns->n_filt[w] = get_bits(gb, 2 - is8);

        if (tns->n_filt[w])

            coef_res = get_bits1(gb);

        for (filt = 0; filt < tns->n_filt[w]; filt++) {

            int tmp2_idx;

            tns->length[w][filt] = get_bits(gb, 6 - 2*is8);

            if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) {

                av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.",

                       tns->order[w][filt], tns_max_order);

                tns->order[w][filt] = 0;

                return -1;

            }

            tns->direction[w][filt] = get_bits1(gb);

            coef_compress = get_bits1(gb);

            coef_len = coef_res + 3 - coef_compress;

            tmp2_idx = 2*coef_compress + coef_res;

            for (i = 0; i < tns->order[w][filt]; i++)

                tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];

        }

    }

    return 0;

}


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

{

    XilinxAXIEnet *s = XILINX_AXI_ENET(dev);

    XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);

    XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(

                                                            &s->rx_control_dev);

    Error *local_errp = NULL;

    object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",

                             (Object **) &ds->enet,

                             OBJ_PROP_LINK_UNREF_ON_RELEASE,

                             &local_errp);

    object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",

                             (Object **) &cs->enet,

                             OBJ_PROP_LINK_UNREF_ON_RELEASE,

                             &local_errp);

    if (local_errp) {

        goto xilinx_enet_realize_fail;

    }

    object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_errp);

    object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_errp);

    if (local_errp) {

        goto xilinx_enet_realize_fail;

    }

    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf,

                          object_get_typename(OBJECT(dev)), dev->id, s);

    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);

    tdk_init(&s->TEMAC.phy);

    mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);

    s->TEMAC.parent = s;

    s->rxmem = g_malloc(s->c_rxmem);

    return;

xilinx_enet_realize_fail:

    if (!*errp) {

        *errp = local_errp;

    }

}


static int mpc8_read_header(AVFormatContext *s)

{

    MPCContext *c = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st;

    int tag = 0;

    int64_t size, pos;

    c->header_pos = avio_tell(pb);

    if(avio_rl32(pb) != TAG_MPCK){

        av_log(s, AV_LOG_ERROR, "Not a Musepack8 file\n");

    while(!avio_feof(pb)){

        pos = avio_tell(pb);

        mpc8_get_chunk_header(pb, &tag, &size);

        if(tag == TAG_STREAMHDR)

            break;

        mpc8_handle_chunk(s, tag, pos, size);

    if(tag != TAG_STREAMHDR){

        av_log(s, AV_LOG_ERROR, "Stream header not found\n");

    pos = avio_tell(pb);

    avio_skip(pb, 4); //CRC

    c->ver = avio_r8(pb);

    if(c->ver != 8){

        av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver);

        return AVERROR_PATCHWELCOME;

    c->samples = ffio_read_varlen(pb);

    ffio_read_varlen(pb); //silence samples at the beginning

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_id = AV_CODEC_ID_MUSEPACK8;

    st->codec->bits_per_coded_sample = 16;

    if (ff_get_extradata(st->codec, pb, 2) < 0)

        return AVERROR(ENOMEM);

    st->codec->channels = (st->codec->extradata[1] >> 4) + 1;

    st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5];

    avpriv_set_pts_info(st, 32, 1152  << (st->codec->extradata[1]&3)*2, st->codec->sample_rate);

    st->start_time = 0;

    st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);

    size -= avio_tell(pb) - pos;

    if (size > 0)

        avio_skip(pb, size);

    if (pb->seekable) {

        int64_t pos = avio_tell(s->pb);

        c->apetag_start = ff_ape_parse_tag(s);

        avio_seek(s->pb, pos, SEEK_SET);

    return 0;


static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,

                                Error **errp)

{

    const char *buf;

    const char *serial;

    int ro = 0;

    int bdrv_flags = 0;

    int on_read_error, on_write_error;

    DriveInfo *dinfo;

    ThrottleConfig cfg;

    int snapshot = 0;

    bool copy_on_read;

    int ret;

    Error *error = NULL;

    QemuOpts *opts;

    const char *id;

    bool has_driver_specific_opts;

    BlockdevDetectZeroesOptions detect_zeroes;

    BlockDriver *drv = NULL;

    /* Check common options by copying from bs_opts to opts, all other options

     * stay in bs_opts for processing by bdrv_open(). */

    id = qdict_get_try_str(bs_opts, "id");

    opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);

    if (error) {

        error_propagate(errp, error);

        return NULL;

    }

    qemu_opts_absorb_qdict(opts, bs_opts, &error);

    if (error) {

        error_propagate(errp, error);

        goto early_err;

    }

    if (id) {

        qdict_del(bs_opts, "id");

    }

    has_driver_specific_opts = !!qdict_size(bs_opts);

    /* extract parameters */

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

    ro = qemu_opt_get_bool(opts, "read-only", 0);

    copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false);

    serial = qemu_opt_get(opts, "serial");

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

        if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) {

            error_setg(errp, "invalid discard option");

            goto early_err;

        }

    }

    if (qemu_opt_get_bool(opts, "cache.writeback", true)) {

        bdrv_flags |= BDRV_O_CACHE_WB;

    }

    if (qemu_opt_get_bool(opts, "cache.direct", false)) {

        bdrv_flags |= BDRV_O_NOCACHE;

    }

    if (qemu_opt_get_bool(opts, "cache.no-flush", false)) {

        bdrv_flags |= BDRV_O_NO_FLUSH;

    }

#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 {

           error_setg(errp, "invalid aio option");

           goto early_err;

        }

    }

#endif

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

        if (is_help_option(buf)) {

            error_printf("Supported formats:");

            bdrv_iterate_format(bdrv_format_print, NULL);

            error_printf("\n");

            goto early_err;

        }

        drv = bdrv_find_format(buf);

        if (!drv) {

            error_setg(errp, "'%s' invalid format", buf);

            goto early_err;

        }

    }

    /* disk I/O throttling */

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

    cfg.buckets[THROTTLE_BPS_TOTAL].avg =

        qemu_opt_get_number(opts, "throttling.bps-total", 0);

    cfg.buckets[THROTTLE_BPS_READ].avg  =

        qemu_opt_get_number(opts, "throttling.bps-read", 0);

    cfg.buckets[THROTTLE_BPS_WRITE].avg =

        qemu_opt_get_number(opts, "throttling.bps-write", 0);

    cfg.buckets[THROTTLE_OPS_TOTAL].avg =

        qemu_opt_get_number(opts, "throttling.iops-total", 0);

    cfg.buckets[THROTTLE_OPS_READ].avg =

        qemu_opt_get_number(opts, "throttling.iops-read", 0);

    cfg.buckets[THROTTLE_OPS_WRITE].avg =

        qemu_opt_get_number(opts, "throttling.iops-write", 0);

    cfg.buckets[THROTTLE_BPS_TOTAL].max =

        qemu_opt_get_number(opts, "throttling.bps-total-max", 0);

    cfg.buckets[THROTTLE_BPS_READ].max  =

        qemu_opt_get_number(opts, "throttling.bps-read-max", 0);

    cfg.buckets[THROTTLE_BPS_WRITE].max =

        qemu_opt_get_number(opts, "throttling.bps-write-max", 0);

    cfg.buckets[THROTTLE_OPS_TOTAL].max =

        qemu_opt_get_number(opts, "throttling.iops-total-max", 0);

    cfg.buckets[THROTTLE_OPS_READ].max =

        qemu_opt_get_number(opts, "throttling.iops-read-max", 0);

    cfg.buckets[THROTTLE_OPS_WRITE].max =

        qemu_opt_get_number(opts, "throttling.iops-write-max", 0);

    cfg.op_size = qemu_opt_get_number(opts, "throttling.iops-size", 0);

    if (!check_throttle_config(&cfg, &error)) {

        error_propagate(errp, error);

        goto early_err;

    }

    on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;

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

        on_write_error = parse_block_error_action(buf, 0, &error);

        if (error) {

            error_propagate(errp, error);

            goto early_err;

        }

    }

    on_read_error = BLOCKDEV_ON_ERROR_REPORT;

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

        on_read_error = parse_block_error_action(buf, 1, &error);

        if (error) {

            error_propagate(errp, error);

            goto early_err;

        }

    }

    detect_zeroes =

        parse_enum_option(BlockdevDetectZeroesOptions_lookup,

                          qemu_opt_get(opts, "detect-zeroes"),

                          BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,

                          BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,

                          &error);

    if (error) {

        error_propagate(errp, error);

        goto early_err;

    }

    if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&

        !(bdrv_flags & BDRV_O_UNMAP)) {

        error_setg(errp, "setting detect-zeroes to unmap is not allowed "

                         "without setting discard operation to unmap");

        goto early_err;

    }

    /* init */

    dinfo = g_malloc0(sizeof(*dinfo));

    dinfo->id = g_strdup(qemu_opts_id(opts));

    dinfo->bdrv = bdrv_new(dinfo->id, &error);

    if (error) {

        error_propagate(errp, error);

        goto bdrv_new_err;

    }

    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;

    dinfo->bdrv->read_only = ro;

    dinfo->bdrv->detect_zeroes = detect_zeroes;

    dinfo->refcount = 1;

    if (serial != NULL) {

        dinfo->serial = g_strdup(serial);

    }

    QTAILQ_INSERT_TAIL(&drives, dinfo, next);

    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);

    /* disk I/O throttling */

    if (throttle_enabled(&cfg)) {

        bdrv_io_limits_enable(dinfo->bdrv);

        bdrv_set_io_limits(dinfo->bdrv, &cfg);

    }

    if (!file || !*file) {

        if (has_driver_specific_opts) {

            file = NULL;

        } else {

            QDECREF(bs_opts);

            qemu_opts_del(opts);

            return dinfo;

        }

    }

    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 (copy_on_read) {

        bdrv_flags |= BDRV_O_COPY_ON_READ;

    }

    if (runstate_check(RUN_STATE_INMIGRATE)) {

        bdrv_flags |= BDRV_O_INCOMING;

    }

    bdrv_flags |= ro ? 0 : BDRV_O_RDWR;

    QINCREF(bs_opts);

    ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error);

    if (ret < 0) {

        error_setg(errp, "could not open disk image %s: %s",

                   file ?: dinfo->id, error_get_pretty(error));

        error_free(error);

        goto err;

    }

    if (bdrv_key_required(dinfo->bdrv))

        autostart = 0;

    QDECREF(bs_opts);

    qemu_opts_del(opts);

    return dinfo;

err:

    bdrv_unref(dinfo->bdrv);

    QTAILQ_REMOVE(&drives, dinfo, next);

bdrv_new_err:

    g_free(dinfo->id);

    g_free(dinfo);

early_err:

    QDECREF(bs_opts);

    qemu_opts_del(opts);

    return NULL;

}


static int fourxm_read_header(AVFormatContext *s,

                              AVFormatParameters *ap)

{

    AVIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size;

    int header_size;

    FourxmDemuxContext *fourxm = s->priv_data;

    unsigned char *header;

    int i, ret;

    AVStream *st;

    fourxm->track_count = 0;

    fourxm->tracks = NULL;

    fourxm->fps = 1.0;

    /* skip the first 3 32-bit numbers */

    avio_skip(pb, 12);

    /* check for LIST-HEAD */

    GET_LIST_HEADER();

    header_size = size - 4;

    if (fourcc_tag != HEAD_TAG || header_size < 0)

        return AVERROR_INVALIDDATA;

    /* allocate space for the header and load the whole thing */

    header = av_malloc(header_size);

    if (!header)

        return AVERROR(ENOMEM);

    if (avio_read(pb, header, header_size) != header_size){

        av_free(header);

        return AVERROR(EIO);

    }

    /* take the lazy approach and search for any and all vtrk and strk chunks */

    for (i = 0; i < header_size - 8; i++) {

        fourcc_tag = AV_RL32(&header[i]);

        size = AV_RL32(&header[i + 4]);

        if (fourcc_tag == std__TAG) {

            fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));

        } else if (fourcc_tag == vtrk_TAG) {

            /* check that there is enough data */

            if (size != vtrk_SIZE) {

                ret= AVERROR_INVALIDDATA;

                goto fail;

            }

            fourxm->width  = AV_RL32(&header[i + 36]);

            fourxm->height = AV_RL32(&header[i + 40]);

            /* allocate a new AVStream */

            st = av_new_stream(s, 0);

            if (!st){

                ret= AVERROR(ENOMEM);

                goto fail;

            }

            av_set_pts_info(st, 60, 1, fourxm->fps);

            fourxm->video_stream_index = st->index;

            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_4XM;

            st->codec->extradata_size = 4;

            st->codec->extradata = av_malloc(4);

            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));

            st->codec->width  = fourxm->width;

            st->codec->height = fourxm->height;

            i += 8 + size;

        } else if (fourcc_tag == strk_TAG) {

            int current_track;

            /* check that there is enough data */

            if (size != strk_SIZE) {

                ret= AVERROR_INVALIDDATA;

                goto fail;

            }

            current_track = AV_RL32(&header[i + 8]);

            if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){

                av_log(s, AV_LOG_ERROR, "current_track too large\n");

                ret= -1;

                goto fail;

            }

            if (current_track + 1 > fourxm->track_count) {

                fourxm->track_count = current_track + 1;

                fourxm->tracks = av_realloc(fourxm->tracks,

                    fourxm->track_count * sizeof(AudioTrack));

                if (!fourxm->tracks) {

                    ret=  AVERROR(ENOMEM);

                    goto fail;

                }

            }

            fourxm->tracks[current_track].adpcm       = AV_RL32(&header[i + 12]);

            fourxm->tracks[current_track].channels    = AV_RL32(&header[i + 36]);

            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);

            fourxm->tracks[current_track].bits        = AV_RL32(&header[i + 44]);

            fourxm->tracks[current_track].audio_pts   = 0;

            if(   fourxm->tracks[current_track].channels    <= 0

               || fourxm->tracks[current_track].sample_rate <= 0

               || fourxm->tracks[current_track].bits        <  0){

                av_log(s, AV_LOG_ERROR, "audio header invalid\n");

                ret= -1;

                goto fail;

            }

            i += 8 + size;

            /* allocate a new AVStream */

            st = av_new_stream(s, current_track);

            if (!st){

                ret= AVERROR(ENOMEM);

                goto fail;

            }

            av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);

            fourxm->tracks[current_track].stream_index = st->index;

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            st->codec->codec_tag = 0;

            st->codec->channels              = fourxm->tracks[current_track].channels;

            st->codec->sample_rate           = fourxm->tracks[current_track].sample_rate;

            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;

            st->codec->bit_rate              = st->codec->channels * st->codec->sample_rate *

                st->codec->bits_per_coded_sample;

            st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;

            if (fourxm->tracks[current_track].adpcm){

                st->codec->codec_id = CODEC_ID_ADPCM_4XM;

            }else if (st->codec->bits_per_coded_sample == 8){

                st->codec->codec_id = CODEC_ID_PCM_U8;

            }else

                st->codec->codec_id = CODEC_ID_PCM_S16LE;

        }

    }

    /* skip over the LIST-MOVI chunk (which is where the stream should be */

    GET_LIST_HEADER();

    if (fourcc_tag != MOVI_TAG){

        ret= AVERROR_INVALIDDATA;

        goto fail;

    }

    av_free(header);

    /* initialize context members */

    fourxm->video_pts = -1;  /* first frame will push to 0 */

    return 0;

fail:

    av_freep(&fourxm->tracks);

    av_free(header);

    return ret;

}


static int read_extra_header(FFV1Context *f)

{

    RangeCoder *const c = &f->c;

    uint8_t state[CONTEXT_SIZE];

    int i, j, k, ret;

    uint8_t state2[32][CONTEXT_SIZE];

    unsigned crc = 0;

    memset(state2, 128, sizeof(state2));

    memset(state, 128, sizeof(state));

    ff_init_range_decoder(c, f->avctx->extradata, f->avctx->extradata_size);

    ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);

    f->version = get_symbol(c, state, 0);

    if (f->version < 2) {

        av_log(f->avctx, AV_LOG_ERROR, "Invalid version in global header\n");

        return AVERROR_INVALIDDATA;

    }

    if (f->version > 2) {

        c->bytestream_end -= 4;

        f->micro_version = get_symbol(c, state, 0);

        if (f->micro_version < 0)

            return AVERROR_INVALIDDATA;

    }

    f->ac = f->avctx->coder_type = get_symbol(c, state, 0);

    if (f->ac > 1) {

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

            f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i];

    }

    f->colorspace                 = get_symbol(c, state, 0); //YUV cs type

    f->avctx->bits_per_raw_sample = get_symbol(c, state, 0);

    f->chroma_planes              = get_rac(c, state);

    f->chroma_h_shift             = get_symbol(c, state, 0);

    f->chroma_v_shift             = get_symbol(c, state, 0);

    f->transparency               = get_rac(c, state);

    f->plane_count                = 1 + (f->chroma_planes || f->version<4) + f->transparency;

    f->num_h_slices               = 1 + get_symbol(c, state, 0);

    f->num_v_slices               = 1 + get_symbol(c, state, 0);

    if (f->chroma_h_shift > 4U || f->chroma_v_shift > 4U) {

        av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n",

               f->chroma_h_shift, f->chroma_v_shift);

        return AVERROR_INVALIDDATA;

    }

    if (f->num_h_slices > (unsigned)f->width  || !f->num_h_slices ||

        f->num_v_slices > (unsigned)f->height || !f->num_v_slices

       ) {

        av_log(f->avctx, AV_LOG_ERROR, "slice count invalid\n");

        return AVERROR_INVALIDDATA;

    }

    f->quant_table_count = get_symbol(c, state, 0);

    if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES)

        return AVERROR_INVALIDDATA;

    for (i = 0; i < f->quant_table_count; i++) {

        f->context_count[i] = read_quant_tables(c, f->quant_tables[i]);

        if (f->context_count[i] < 0) {

            av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");

            return AVERROR_INVALIDDATA;

        }

    }

    if ((ret = ff_ffv1_allocate_initial_states(f)) < 0)

        return ret;

    for (i = 0; i < f->quant_table_count; i++)

        if (get_rac(c, state)) {

            for (j = 0; j < f->context_count[i]; j++)

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

                    int pred = j ? f->initial_states[i][j - 1][k] : 128;

                    f->initial_states[i][j][k] =

                        (pred + get_symbol(c, state2[k], 1)) & 0xFF;

                }

        }

    if (f->version > 2) {

        f->ec = get_symbol(c, state, 0);

        if (f->micro_version > 2)

            f->intra = get_symbol(c, state, 0);

    }

    if (f->version > 2) {

        unsigned v;

        v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0,

                   f->avctx->extradata, f->avctx->extradata_size);

        if (v || f->avctx->extradata_size < 4) {

            av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", v);

            return AVERROR_INVALIDDATA;

        }

        crc = AV_RB32(f->avctx->extradata + f->avctx->extradata_size - 4);

    }

    if (f->avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(f->avctx, AV_LOG_DEBUG,

               "global: ver:%d.%d, coder:%d, colorspace: %d bpr:%d chroma:%d(%d:%d), alpha:%d slices:%dx%d qtabs:%d ec:%d intra:%d CRC:0x%08X\n",

               f->version, f->micro_version,

               f->ac,

               f->colorspace,

               f->avctx->bits_per_raw_sample,

               f->chroma_planes, f->chroma_h_shift, f->chroma_v_shift,

               f->transparency,

               f->num_h_slices, f->num_v_slices,

               f->quant_table_count,

               f->ec,

               f->intra,

               crc

              );

    return 0;

}


static void qemu_rbd_aio_event_reader(void *opaque)

{

    BDRVRBDState *s = opaque;

    ssize_t ret;

    do {

        char *p = (char *)&s->event_rcb;

        /* now read the rcb pointer that was sent from a non qemu thread */

        ret = read(s->fds[RBD_FD_READ], p + s->event_reader_pos,

                   sizeof(s->event_rcb) - s->event_reader_pos);

        if (ret > 0) {

            s->event_reader_pos += ret;

            if (s->event_reader_pos == sizeof(s->event_rcb)) {

                s->event_reader_pos = 0;

                qemu_rbd_complete_aio(s->event_rcb);

            }

        }

    } while (ret < 0 && errno == EINTR);

}


void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values)

{

    int i;

    list[0].sort = 0;

    list[1].sort = 1;

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

        int j;

        list[i].low  = 0;

        list[i].high = 1;

        list[i].sort = i;

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

            int tmp = list[j].x;

            if (tmp < list[i].x) {

                if (tmp > list[list[i].low].x)

                    list[i].low  =  j;

            } else {

                if (tmp < list[list[i].high].x)

                    list[i].high = j;

            }

        }

    }

    for (i = 0; i < values - 1; i++) {

        int j;

        for (j = i + 1; j < values; j++) {

            if (list[list[i].sort].x > list[list[j].sort].x) {

                int tmp = list[i].sort;

                list[i].sort = list[j].sort;

                list[j].sort = tmp;

            }

        }

    }

}


static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)

{

    gen_helper_wsr_windowbase(cpu_env, v);

    reset_used_window(dc);

}


static void virtio_pci_exit(PCIDevice *pci_dev)

{

    VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);

    virtio_pci_stop_ioeventfd(proxy);

    memory_region_destroy(&proxy->bar);

    msix_uninit_exclusive_bar(pci_dev);

}


static av_cold void init_cavlc_level_tab(void){

    int suffix_length, mask;

    unsigned int i;

    for(suffix_length=0; suffix_length<7; suffix_length++){

        for(i=0; i<(1<<LEVEL_TAB_BITS); i++){

            int prefix= LEVEL_TAB_BITS - av_log2(2*i);

            int level_code= (prefix<<suffix_length) + (i>>(LEVEL_TAB_BITS-prefix-1-suffix_length)) - (1<<suffix_length);

            mask= -(level_code&1);

            level_code= (((2+level_code)>>1) ^ mask) - mask;

            if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){

                cavlc_level_tab[suffix_length][i][0]= level_code;

                cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length;

            }else if(prefix + 1 <= LEVEL_TAB_BITS){

                cavlc_level_tab[suffix_length][i][0]= prefix+100;

                cavlc_level_tab[suffix_length][i][1]= prefix + 1;

            }else{

                cavlc_level_tab[suffix_length][i][0]= LEVEL_TAB_BITS+100;

                cavlc_level_tab[suffix_length][i][1]= LEVEL_TAB_BITS;

            }

        }

    }

}


static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)

{

    const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;

    uint8_t r, g, b;

    int i, y, cb, cr;

    int r_add, g_add, b_add;

    for (i = num_values; i > 0; i--) {

        y = *ycbcr++;

        cr = *ycbcr++;

        cb = *ycbcr++;

        YUV_TO_RGB1_CCIR(cb, cr);

        YUV_TO_RGB2_CCIR(r, g, b, y);

        *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b;

    }

}


static int init_muxer(AVFormatContext *s, AVDictionary **options)

{

    int ret = 0, i;

    AVStream *st;

    AVDictionary *tmp = NULL;

    AVCodecParameters *par = NULL;

    AVOutputFormat *of = s->oformat;

    const AVCodecDescriptor *desc;

    AVDictionaryEntry *e;

    if (options)

        av_dict_copy(&tmp, *options, 0);

    if ((ret = av_opt_set_dict(s, &tmp)) < 0)

        goto fail;

    if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&

        (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)

        goto fail;

#if FF_API_LAVF_AVCTX

FF_DISABLE_DEPRECATION_WARNINGS

    if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) {

        if (!(s->flags & AVFMT_FLAG_BITEXACT)) {

#if FF_API_LAVF_BITEXACT

            av_log(s, AV_LOG_WARNING,

                   "Setting the AVFormatContext to bitexact mode, because "

                   "the AVCodecContext is in that mode. This behavior will "

                   "change in the future. To keep the current behavior, set "

                   "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");

            s->flags |= AVFMT_FLAG_BITEXACT;

#else

            av_log(s, AV_LOG_WARNING,

                   "The AVFormatContext is not in set to bitexact mode, only "

                   "the AVCodecContext. If this is not intended, set "

                   "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");

#endif

        }

    }

FF_ENABLE_DEPRECATION_WARNINGS

#endif

    // some sanity checks

    if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {

        av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n");

        ret = AVERROR(EINVAL);

        goto fail;

    }

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

        st  = s->streams[i];

        par = st->codecpar;

#if FF_API_LAVF_CODEC_TB && FF_API_LAVF_AVCTX

FF_DISABLE_DEPRECATION_WARNINGS

        if (!st->time_base.num && st->codec->time_base.num) {

            av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a "

                   "timebase hint to the muxer is deprecated. Set "

                   "AVStream.time_base instead.\n");

            avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);

        }

FF_ENABLE_DEPRECATION_WARNINGS

#endif

#if FF_API_LAVF_AVCTX

FF_DISABLE_DEPRECATION_WARNINGS

        if (st->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN &&

            st->codec->codec_type    != AVMEDIA_TYPE_UNKNOWN) {

            av_log(s, AV_LOG_WARNING, "Using AVStream.codec to pass codec "

                   "parameters to muxers is deprecated, use AVStream.codecpar "

                   "instead.\n");

            ret = avcodec_parameters_from_context(st->codecpar, st->codec);

            if (ret < 0)

                goto fail;

        }

FF_ENABLE_DEPRECATION_WARNINGS

#endif

        /* update internal context from codecpar, old bsf api needs this

         * FIXME: remove when autobsf uses new bsf API */

        ret = avcodec_parameters_to_context(st->internal->avctx, st->codecpar);

        if (ret < 0)

            goto fail;

        if (!st->time_base.num) {

            /* fall back on the default timebase values */

            if (par->codec_type == AVMEDIA_TYPE_AUDIO && par->sample_rate)

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

            else

                avpriv_set_pts_info(st, 33, 1, 90000);

        }

        switch (par->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            if (par->sample_rate <= 0) {

                av_log(s, AV_LOG_ERROR, "sample rate not set\n");

                ret = AVERROR(EINVAL);

                goto fail;

            }

            if (!par->block_align)

                par->block_align = par->channels *

                                   av_get_bits_per_sample(par->codec_id) >> 3;

            break;

        case AVMEDIA_TYPE_VIDEO:

            if ((par->width <= 0 || par->height <= 0) &&

                !(of->flags & AVFMT_NODIMENSIONS)) {

                av_log(s, AV_LOG_ERROR, "dimensions not set\n");

                ret = AVERROR(EINVAL);

                goto fail;

            }

            if (av_cmp_q(st->sample_aspect_ratio, par->sample_aspect_ratio)

                && fabs(av_q2d(st->sample_aspect_ratio) - av_q2d(par->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)

            ) {

                if (st->sample_aspect_ratio.num != 0 &&

                    st->sample_aspect_ratio.den != 0 &&

                    par->sample_aspect_ratio.num != 0 &&

                    par->sample_aspect_ratio.den != 0) {

                    av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "

                           "(%d/%d) and encoder layer (%d/%d)\n",

                           st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,

                           par->sample_aspect_ratio.num,

                           par->sample_aspect_ratio.den);

                    ret = AVERROR(EINVAL);

                    goto fail;

                }

            }

            break;

        }

        desc = avcodec_descriptor_get(par->codec_id);

        if (desc && desc->props & AV_CODEC_PROP_REORDER)

            st->internal->reorder = 1;

        if (of->codec_tag) {

            if (   par->codec_tag

                && par->codec_id == AV_CODEC_ID_RAWVIDEO

                && (   av_codec_get_tag(of->codec_tag, par->codec_id) == 0

                    || av_codec_get_tag(of->codec_tag, par->codec_id) == MKTAG('r', 'a', 'w', ' '))

                && !validate_codec_tag(s, st)) {

                // the current rawvideo encoding system ends up setting

                // the wrong codec_tag for avi/mov, we override it here

                par->codec_tag = 0;

            }

            if (par->codec_tag) {

                if (!validate_codec_tag(s, st)) {

                    char tagbuf[32], tagbuf2[32];

                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), par->codec_tag);

                    av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, par->codec_id));

                    av_log(s, AV_LOG_ERROR,

                           "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",

                           tagbuf, par->codec_tag, par->codec_id, tagbuf2);

                    ret = AVERROR_INVALIDDATA;

                    goto fail;

                }

            } else

                par->codec_tag = av_codec_get_tag(of->codec_tag, par->codec_id);

        }

        if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT)

            s->internal->nb_interleaved_streams++;

    }

    if (!s->priv_data && of->priv_data_size > 0) {

        s->priv_data = av_mallocz(of->priv_data_size);

        if (!s->priv_data) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        if (of->priv_class) {

            *(const AVClass **)s->priv_data = of->priv_class;

            av_opt_set_defaults(s->priv_data);

            if ((ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)

                goto fail;

        }

    }

    /* set muxer identification string */

    if (!(s->flags & AVFMT_FLAG_BITEXACT)) {

        av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);

    } else {

        av_dict_set(&s->metadata, "encoder", NULL, 0);

    }

    for (e = NULL; e = av_dict_get(s->metadata, "encoder-", e, AV_DICT_IGNORE_SUFFIX); ) {

        av_dict_set(&s->metadata, e->key, NULL, 0);

    }

    if (options) {

         av_dict_free(options);

         *options = tmp;

    }

    if (s->oformat->init) {

        if ((ret = s->oformat->init(s)) < 0) {

            if (s->oformat->deinit)

                s->oformat->deinit(s);

            return ret;

        }

        return ret == 0;

    }

    return 0;

fail:

    av_dict_free(&tmp);

    return ret;

}


static void gen_stf_asi(DisasContext *dc, TCGv addr,

                        int insn, int size, int rd)

{

    TCGv_i32 r_asi, r_size, r_rd;

    r_asi = gen_get_asi(dc, insn);

    r_size = tcg_const_i32(size);

    r_rd = tcg_const_i32(rd);

    gen_helper_stf_asi(cpu_env, addr, r_asi, r_size, r_rd);

    tcg_temp_free_i32(r_rd);

    tcg_temp_free_i32(r_size);

    tcg_temp_free_i32(r_asi);

}


static int kvm_arch_set_tsc_khz(CPUState *cs)

{

    X86CPU *cpu = X86_CPU(cs);

    CPUX86State *env = &cpu->env;

    int r;

    if (!env->tsc_khz) {

        return 0;

    }

    r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL) ?

        kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz) :

        -ENOTSUP;

    if (r < 0) {

        /* When KVM_SET_TSC_KHZ fails, it's an error only if the current

         * TSC frequency doesn't match the one we want.

         */

        int cur_freq = kvm_check_extension(cs->kvm_state, KVM_CAP_GET_TSC_KHZ) ?

                       kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ) :

                       -ENOTSUP;

        if (cur_freq <= 0 || cur_freq != env->tsc_khz) {

            error_report("warning: TSC frequency mismatch between "

                         "VM (%" PRId64 " kHz) and host (%d kHz), "

                         "and TSC scaling unavailable",

                         env->tsc_khz, cur_freq);

            return r;

        }

    }

    return 0;

}


int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){

    int i=0;

    ThreadContext *c;

    if(   !(avctx->thread_type & FF_THREAD_FRAME)

       || !(avctx->codec->capabilities & CODEC_CAP_INTRA_ONLY))

        return 0;

    if(   !avctx->thread_count

       && avctx->codec_id == AV_CODEC_ID_MJPEG

       && !(avctx->flags & CODEC_FLAG_QSCALE)) {

        av_log(avctx, AV_LOG_DEBUG,

               "Forcing thread count to 1 for MJPEG encoding, use -thread_type slice "

               "or a constant quantizer if you want to use multiple cpu cores\n");

        avctx->thread_count = 1;

    }

    if(   avctx->thread_count > 1

       && avctx->codec_id == AV_CODEC_ID_MJPEG

       && !(avctx->flags & CODEC_FLAG_QSCALE))

        av_log(avctx, AV_LOG_WARNING,

               "MJPEG CBR encoding works badly with frame multi-threading, consider "

               "using -threads 1, -thread_type slice or a constant quantizer.\n");

    if(!avctx->thread_count) {

        avctx->thread_count = av_cpu_count();

        avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS);

    }

    if(avctx->thread_count <= 1)

        return 0;

    if (avctx->codec_id == AV_CODEC_ID_HUFFYUV ||

        avctx->codec_id == AV_CODEC_ID_FFVHUFF) {

        // huffyuv doesnt support these with multiple frame threads currently

        if (avctx->context_model > 0 || (avctx->flags & CODEC_FLAG_PASS1))

            return 0;

    }

    if(avctx->thread_count > MAX_THREADS)

        return AVERROR(EINVAL);

    av_assert0(!avctx->internal->frame_thread_encoder);

    c = avctx->internal->frame_thread_encoder = av_mallocz(sizeof(ThreadContext));

    if(!c)

        return AVERROR(ENOMEM);

    c->parent_avctx = avctx;

    c->task_fifo = av_fifo_alloc(sizeof(Task) * BUFFER_SIZE);

    if(!c->task_fifo)

        goto fail;

    pthread_mutex_init(&c->task_fifo_mutex, NULL);

    pthread_mutex_init(&c->finished_task_mutex, NULL);

    pthread_mutex_init(&c->buffer_mutex, NULL);

    pthread_cond_init(&c->task_fifo_cond, NULL);

    pthread_cond_init(&c->finished_task_cond, NULL);

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

        AVDictionary *tmp = NULL;

        void *tmpv;

        AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec);

        if(!thread_avctx)

            goto fail;

        tmpv = thread_avctx->priv_data;

        *thread_avctx = *avctx;

        thread_avctx->priv_data = tmpv;

        thread_avctx->internal = NULL;

        memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size);

        thread_avctx->thread_count = 1;

        thread_avctx->active_thread_type &= ~FF_THREAD_FRAME;

        av_dict_copy(&tmp, options, 0);

        av_dict_set(&tmp, "threads", "1", 0);

        if(avcodec_open2(thread_avctx, avctx->codec, &tmp) < 0) {

            av_dict_free(&tmp);

            goto fail;

        }

        av_dict_free(&tmp);

        av_assert0(!thread_avctx->internal->frame_thread_encoder);

        thread_avctx->internal->frame_thread_encoder = c;

        if(pthread_create(&c->worker[i], NULL, worker, thread_avctx)) {

            goto fail;

        }

    }

    avctx->active_thread_type = FF_THREAD_FRAME;

    return 0;

fail:

    avctx->thread_count = i;

    av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n");

    ff_frame_thread_encoder_free(avctx);

    return -1;

}


static void intra_predict_mad_cow_dc_0l0_8x8_msa(uint8_t *src, int32_t stride)

{

    uint8_t lp_cnt;

    uint32_t src0 = 0;

    uint64_t out0, out1;

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

        src0 += src[(4 + lp_cnt) * stride - 1];

    }

    src0 = (src0 + 2) >> 2;

    out0 = 0x8080808080808080;

    out1 = src0 * 0x0101010101010101;

    for (lp_cnt = 4; lp_cnt--;) {

        SD(out0, src);

        SD(out1, src + stride * 4);

        src += stride;

    }

}


static void srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,

                       const char *in, int x1, int y1, int x2, int y2)

{

    if (x1 >= 0 && y1 >= 0) {

        /* XXX: here we rescale coordinate assuming they are in DVD resolution

         * (720x480) since we don't have anything better */

        if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1) && x2 >= x1 && y2 >= y1) {

            /* text rectangle defined, write the text at the center of the rectangle */

            const int cx = x1 + (x2 - x1)/2;

            const int cy = y1 + (y2 - y1)/2;

            const int scaled_x = cx * (int64_t)ASS_DEFAULT_PLAYRESX / 720;

            const int scaled_y = cy * (int64_t)ASS_DEFAULT_PLAYRESY / 480;

            av_bprintf(dst, "{\\an5}{\\pos(%d,%d)}", scaled_x, scaled_y);

        } else {

            /* only the top left corner, assume the text starts in that corner */

            const int scaled_x = x1 * (int64_t)ASS_DEFAULT_PLAYRESX / 720;

            const int scaled_y = y1 * (int64_t)ASS_DEFAULT_PLAYRESY / 480;

            av_bprintf(dst, "{\\an1}{\\pos(%d,%d)}", scaled_x, scaled_y);

        }

    }

    ff_htmlmarkup_to_ass(avctx, dst, in);

}


static int msvideo1_decode_frame(AVCodecContext *avctx,

                                void *data, int *got_frame,

                                AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    Msvideo1Context *s = avctx->priv_data;

    int ret;

    s->buf = buf;

    s->size = buf_size;

    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)

        return ret;

    if (s->mode_8bit) {

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

        if (pal) {

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

            s->frame->palette_has_changed = 1;

        }

    }

    if (s->mode_8bit)

        msvideo1_decode_8bit(s);

    else

        msvideo1_decode_16bit(s);

    if ((ret = av_frame_ref(data, s->frame)) < 0)

        return ret;

    *got_frame      = 1;

    /* report that the buffer was completely consumed */

    return buf_size;

}


pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)

{

    PVSCSIState *s = PVSCSI(pci_dev);

    trace_pvscsi_state("init");

    /* PCI subsystem ID, subsystem vendor ID, revision */

    if (PVSCSI_USE_OLD_PCI_CONFIGURATION(s)) {

        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, 0x1000);

    } else {

        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,

                     PCI_VENDOR_ID_VMWARE);

        pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,

                     PCI_DEVICE_ID_VMWARE_PVSCSI);

        pci_config_set_revision(pci_dev->config, 0x2);

    }

    /* PCI latency timer = 255 */

    pci_dev->config[PCI_LATENCY_TIMER] = 0xff;

    /* Interrupt pin A */

    pci_config_set_interrupt_pin(pci_dev->config, 1);

    memory_region_init_io(&s->io_space, OBJECT(s), &pvscsi_ops, s,

                          "pvscsi-io", PVSCSI_MEM_SPACE_SIZE);

    pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io_space);

    pvscsi_init_msi(s);

    if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus)) {

        pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);

    }

    s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);

    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),

                 &pvscsi_scsi_info, NULL);

    /* override default SCSI bus hotplug-handler, with pvscsi's one */

    qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort);

    pvscsi_reset_state(s);

}


static void vde_from_qemu(void *opaque, const uint8_t *buf, int size)

{

    VDEState *s = opaque;

    int ret;

    for(;;) {

        ret = vde_send(s->vde, (const char *)buf, size, 0);

        if (ret < 0 && errno == EINTR) {

        } else {

            break;

        }

    }

}


int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,

                               int bytes, uint8_t *_dst, int coeffs)

{

    int i, b, c_idx = 0;

    int32_t *dst = (int32_t *)_dst;

    DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];

    INIT_RESIDUE(res, 0, 0);

#define APPEND_RESIDUE(N, M)         \

    N          |= M >> (N ## _bits); \

    N ## _bits +=      (M ## _bits)

    for (b = 1; b <= bytes; b++) {

        future[0] = &lut_ctx[buf[b]];

        future[1] = future[0] + 1*LUT_SIZE;

        future[2] = future[0] + 2*LUT_SIZE;

        future[3] = future[0] + 3*LUT_SIZE;

        if ((c_idx + 1) > coeffs)

            return c_idx;

        /* res_bits is a hint for better branch prediction */

        if (res_bits && l->sign) {

            int32_t coeff = 1;

            APPEND_RESIDUE(res, l->preamble);

            for (i = 0; i < (res_bits >> 1) - 1; i++) {

                coeff <<= 1;

                coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;

            }

            dst[c_idx++] = l->sign * (coeff - 1);

            res_bits = res = 0;

        }

        memcpy(&dst[c_idx], l->ready, LUT_BITS*sizeof(int32_t));

        c_idx += l->ready_num;

        APPEND_RESIDUE(res, l->leftover);

        l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];

    }

    return c_idx;

}


static int dirac_unpack_idwt_params(DiracContext *s)
{
    GetBitContext *gb = &s->gb;
    int i, level;
    unsigned tmp;
#define CHECKEDREAD(dst, cond, errmsg) \
    tmp = svq3_get_ue_golomb(gb); \
    if (cond) { \
        av_log(s->avctx, AV_LOG_ERROR, errmsg); \
        return -1; \
    }\
    dst = tmp;
    align_get_bits(gb);
    s->zero_res = s->num_refs ? get_bits1(gb) : 0;
    if (s->zero_res)
        return 0;
    /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */
    CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n")
    CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
    if (!s->low_delay) {
        /* Codeblock paramaters (core syntax only) */
        if (get_bits1(gb)) {
            for (i = 0; i <= s->wavelet_depth; i++) {
                CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n")
                CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n")
            CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
        } else
            for (i = 0; i <= s->wavelet_depth; i++)
                s->codeblock[i].width = s->codeblock[i].height = 1;
    } else {
        /* Slice parameters + quantization matrix*/
        /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */
        s->lowdelay.num_x     = svq3_get_ue_golomb(gb);
        s->lowdelay.num_y     = svq3_get_ue_golomb(gb);
        s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
        s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
        /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */
        if (get_bits1(gb)) {
            av_log(s->avctx,AV_LOG_DEBUG,"Low Delay: Has Custom Quantization Matrix!\n");
            /* custom quantization matrix */
            s->lowdelay.quant[0][0] = svq3_get_ue_golomb(gb);
            for (level = 0; level < s->wavelet_depth; level++) {
                s->lowdelay.quant[level][1] = svq3_get_ue_golomb(gb);
                s->lowdelay.quant[level][2] = svq3_get_ue_golomb(gb);
                s->lowdelay.quant[level][3] = svq3_get_ue_golomb(gb);
        } else {
            /* default quantization matrix */
            for (level = 0; level < s->wavelet_depth; level++)
                for (i = 0; i < 4; i++) {
                    s->lowdelay.quant[level][i] = default_qmat[s->wavelet_idx][level][i];
                    /* haar with no shift differs for different depths */
                    if (s->wavelet_idx == 3)
                        s->lowdelay.quant[level][i] += 4*(s->wavelet_depth-1 - level);
    return 0;


static int ffm_read_data(AVFormatContext *s,

                         uint8_t *buf, int size, int header)

{

    FFMContext *ffm = s->priv_data;

    AVIOContext *pb = s->pb;

    int len, fill_size, size1, frame_offset;

    uint32_t id;

    int64_t last_pos = -1;

    size1 = size;

    while (size > 0) {

    redo:

        len = ffm->packet_end - ffm->packet_ptr;

        if (len < 0)

            return -1;

        if (len > size)

            len = size;

        if (len == 0) {

            if (avio_tell(pb) == ffm->file_size) {

                if (ffm->server_attached) {

                    avio_seek(pb, ffm->packet_size, SEEK_SET);

                } else

                    return AVERROR_EOF;

            }

    retry_read:

            if (pb->buffer_size != ffm->packet_size) {

                int64_t tell = avio_tell(pb);

                int ret = ffio_set_buf_size(pb, ffm->packet_size);

                if (ret < 0)

                    return ret;

                avio_seek(pb, tell, SEEK_SET);

            }

            id = avio_rb16(pb); /* PACKET_ID */

            if (id != PACKET_ID) {

                if (ffm_resync(s, id) < 0)

                    return -1;

                last_pos = avio_tell(pb);

            }

            fill_size = avio_rb16(pb);

            ffm->dts = avio_rb64(pb);

            frame_offset = avio_rb16(pb);

            avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);

            if (ffm->packet_size < FFM_HEADER_SIZE + fill_size || frame_offset < 0) {

                return -1;

            }

            ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);

            /* if first packet or resynchronization packet, we must

               handle it specifically */

            if (ffm->first_packet || (frame_offset & 0x8000)) {

                if (!frame_offset) {

                    /* This packet has no frame headers in it */

                    if (avio_tell(pb) >= ffm->packet_size * 3LL) {

                        int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos);

                        seekback = FFMAX(seekback, 0);

                        avio_seek(pb, -seekback, SEEK_CUR);

                        goto retry_read;

                    }

                    /* This is bad, we cannot find a valid frame header */

                    return 0;

                }

                ffm->first_packet = 0;

                if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) {

                    ffm->packet_end = ffm->packet_ptr;

                    return -1;

                }

                ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;

                if (!header)

                    break;

            } else {

                ffm->packet_ptr = ffm->packet;

            }

            goto redo;

        }

        memcpy(buf, ffm->packet_ptr, len);

        buf += len;

        ffm->packet_ptr += len;

        size -= len;

        header = 0;

    }

    return size1 - size;

}


static void mipsnet_ioport_write(void *opaque, target_phys_addr_t addr,

                                 uint64_t val, unsigned int size)

{

    MIPSnetState *s = opaque;

    addr &= 0x3f;

    trace_mipsnet_write(addr, val);

    switch (addr) {

    case MIPSNET_TX_DATA_COUNT:

	s->tx_count = (val <= MAX_ETH_FRAME_SIZE) ? val : 0;

        s->tx_written = 0;

        break;

    case MIPSNET_INT_CTL:

        if (val & MIPSNET_INTCTL_TXDONE) {

            s->intctl &= ~MIPSNET_INTCTL_TXDONE;

        } else if (val & MIPSNET_INTCTL_RXDONE) {

            s->intctl &= ~MIPSNET_INTCTL_RXDONE;

        } else if (val & MIPSNET_INTCTL_TESTBIT) {

            mipsnet_reset(s);

            s->intctl |= MIPSNET_INTCTL_TESTBIT;

        } else if (!val) {

            /* ACK testbit interrupt, flag was cleared on read. */

        }

        s->busy = !!s->intctl;

        mipsnet_update_irq(s);

        break;

    case MIPSNET_TX_DATA_BUFFER:

        s->tx_buffer[s->tx_written++] = val;

        if (s->tx_written == s->tx_count) {

            /* Send buffer. */

            trace_mipsnet_send(s->tx_count);

            qemu_send_packet(&s->nic->nc, s->tx_buffer, s->tx_count);

            s->tx_count = s->tx_written = 0;

            s->intctl |= MIPSNET_INTCTL_TXDONE;

            s->busy = 1;

            mipsnet_update_irq(s);

        }

        break;

    /* Read-only registers */

    case MIPSNET_DEV_ID:

    case MIPSNET_BUSY:

    case MIPSNET_RX_DATA_COUNT:

    case MIPSNET_INTERRUPT_INFO:

    case MIPSNET_RX_DATA_BUFFER:

    default:

        break;

    }

}


mac_writereg(E1000State *s, int index, uint32_t val)

{

    uint32_t macaddr[2];

    s->mac_reg[index] = val;

    if (index == RA || index == RA + 1) {

        macaddr[0] = cpu_to_le32(s->mac_reg[RA]);

        macaddr[1] = cpu_to_le32(s->mac_reg[RA + 1]);

        qemu_format_nic_info_str(qemu_get_queue(s->nic), (uint8_t *)macaddr);

    }

}


static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,

                                  XenPTReg *cfg_entry, uint16_t *val,

                                  uint16_t dev_value, uint16_t valid_mask)

{

    XenPTRegInfo *reg = cfg_entry->reg;

    uint16_t writable_mask = 0;

    uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask);

    /* modify emulate register */

    writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask;

    cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask);

    /* create value for writing to I/O device register */

    *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS,

                              throughable_mask);

    return 0;

}


static int net_socket_connect_init(VLANState *vlan,

                                   const char *model,

                                   const char *name,

                                   const char *host_str)

{

    NetSocketState *s;

    int fd, connected, ret, err;

    struct sockaddr_in saddr;

    if (parse_host_port(&saddr, host_str) < 0)

        return -1;

    fd = qemu_socket(PF_INET, SOCK_STREAM, 0);

    if (fd < 0) {

        perror("socket");

        return -1;

    }

    socket_set_nonblock(fd);

    connected = 0;

    for(;;) {

        ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr));

        if (ret < 0) {

            err = socket_error();

            if (err == EINTR || err == EWOULDBLOCK) {

            } else if (err == EINPROGRESS) {

                break;

#ifdef _WIN32

            } else if (err == WSAEALREADY) {

                break;

#endif

            } else {

                perror("connect");

                closesocket(fd);

                return -1;

            }

        } else {

            connected = 1;

            break;

        }

    }

    s = net_socket_fd_init(vlan, model, name, fd, connected);

    if (!s)

        return -1;

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),

             "socket: connect to %s:%d",

             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    return 0;

}


static int usb_device_del(const char *devname)

{

    USBPort *port;

    USBPort **lastp;

    USBDevice *dev;

    int bus_num, addr;

    const char *p;

    if (!used_usb_ports)

        return -1;

    p = strchr(devname, '.');

    if (!p)

        return -1;

    bus_num = strtoul(devname, NULL, 0);

    addr = strtoul(p + 1, NULL, 0);

    if (bus_num != 0)

        return -1;

    lastp = &used_usb_ports;

    port = used_usb_ports;

    while (port && port->dev->addr != addr) {

        lastp = &port->next;

        port = port->next;

    }

    if (!port)

        return -1;

    dev = port->dev;

    *lastp = port->next;

    usb_attach(port, NULL);

    dev->handle_destroy(dev);

    port->next = free_usb_ports;

    free_usb_ports = port;

    return 0;

}


void qmp_migrate_set_parameters(bool has_compress_level,

                                int64_t compress_level,

                                bool has_compress_threads,

                                int64_t compress_threads,

                                bool has_decompress_threads,

                                int64_t decompress_threads,

                                bool has_cpu_throttle_initial,

                                int64_t cpu_throttle_initial,

                                bool has_cpu_throttle_increment,

                                int64_t cpu_throttle_increment,

                                bool has_tls_creds,

                                const char *tls_creds,

                                bool has_tls_hostname,

                                const char *tls_hostname,

                                Error **errp)

{

    MigrationState *s = migrate_get_current();

    if (has_compress_level && (compress_level < 0 || compress_level > 9)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "compress_level",

                   "is invalid, it should be in the range of 0 to 9");

        return;

    if (has_compress_threads &&

            (compress_threads < 1 || compress_threads > 255)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "compress_threads",

                   "is invalid, it should be in the range of 1 to 255");

        return;

    if (has_decompress_threads &&

            (decompress_threads < 1 || decompress_threads > 255)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "decompress_threads",

                   "is invalid, it should be in the range of 1 to 255");

        return;

    if (has_cpu_throttle_initial &&

            (cpu_throttle_initial < 1 || cpu_throttle_initial > 99)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "cpu_throttle_initial",

                   "an integer in the range of 1 to 99");

    if (has_cpu_throttle_increment &&

            (cpu_throttle_increment < 1 || cpu_throttle_increment > 99)) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,

                   "cpu_throttle_increment",

                   "an integer in the range of 1 to 99");

    if (has_compress_level) {

        s->parameters.compress_level = compress_level;

    if (has_compress_threads) {

        s->parameters.compress_threads = compress_threads;

    if (has_decompress_threads) {

        s->parameters.decompress_threads = decompress_threads;

    if (has_cpu_throttle_initial) {

        s->parameters.cpu_throttle_initial = cpu_throttle_initial;

    if (has_cpu_throttle_increment) {

        s->parameters.cpu_throttle_increment = cpu_throttle_increment;


static int drop_sync(QIOChannel *ioc, size_t size, Error **errp)

{

    ssize_t ret = 0;

    char small[1024];

    char *buffer;

    buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size));

    while (size > 0) {

        ssize_t count = MIN(65536, size);

        ret = read_sync(ioc, buffer, MIN(65536, size), errp);

        if (ret < 0) {

            goto cleanup;

        }

        size -= count;

    }

 cleanup:

    if (buffer != small) {

        g_free(buffer);

    }

    return ret;

}


static int check_refcounts_l1(BlockDriverState *bs,

                              BdrvCheckResult *res,

                              void **refcount_table,

                              int64_t *refcount_table_size,

                              int64_t l1_table_offset, int l1_size,

                              int flags)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t *l1_table = NULL, l2_offset, l1_size2;

    int i, ret;

    l1_size2 = l1_size * sizeof(uint64_t);

    /* Mark L1 table as used */

    ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                        l1_table_offset, l1_size2);

    if (ret < 0) {

        goto fail;

    }

    /* Read L1 table entries from disk */

    if (l1_size2 > 0) {

        l1_table = g_try_malloc(l1_size2);

        if (l1_table == NULL) {

            ret = -ENOMEM;

            res->check_errors++;

            goto fail;

        }

        ret = bdrv_pread(bs->file, l1_table_offset, l1_table, l1_size2);

        if (ret < 0) {

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

            res->check_errors++;

            goto fail;

        }

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

            be64_to_cpus(&l1_table[i]);

    }

    /* Do the actual checks */

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

        l2_offset = l1_table[i];

        if (l2_offset) {

            /* Mark L2 table as used */

            l2_offset &= L1E_OFFSET_MASK;

            ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                                l2_offset, s->cluster_size);

            if (ret < 0) {

                goto fail;

            }

            /* L2 tables are cluster aligned */

            if (offset_into_cluster(s, l2_offset)) {

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

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

                res->corruptions++;

            }

            /* Process and check L2 entries */

            ret = check_refcounts_l2(bs, res, refcount_table,

                                     refcount_table_size, l2_offset, flags);

            if (ret < 0) {

                goto fail;

            }

        }

    }

    g_free(l1_table);

    return 0;

fail:

    g_free(l1_table);

    return ret;

}


static void pl061_update(pl061_state *s)

{

    uint8_t changed;

    uint8_t mask;

    uint8_t out;

    int i;

    /* Outputs float high.  */

    /* FIXME: This is board dependent.  */

    out = (s->data & s->dir) | ~s->dir;

    changed = s->old_data ^ out;

    if (!changed)

        return;

    s->old_data = out;

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

        mask = 1 << i;

        if ((changed & mask) && s->out) {

            DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);

            qemu_set_irq(s->out[i], (out & mask) != 0);

        }

    }

    /* FIXME: Implement input interrupts.  */

}


void gic_set_pending_private(GICState *s, int cpu, int irq)

{

    int cm = 1 << cpu;

    if (GIC_TEST_PENDING(irq, cm))

        return;

    DPRINTF("Set %d pending cpu %d\n", irq, cpu);

    GIC_SET_PENDING(irq, cm);

    gic_update(s);

}


static uint32_t pxa2xx_pm_read(void *opaque, target_phys_addr_t addr)

{

    struct pxa2xx_state_s *s = (struct pxa2xx_state_s *) opaque;

    if (addr > s->pm_base + PCMD31) {

        /* Special case: PWRI2C registers appear in the same range.  */

        return pxa2xx_i2c_read(s->i2c[1], addr);

    }

    addr -= s->pm_base;

    switch (addr) {

    case PMCR ... PCMD31:

        if (addr & 3)

            goto fail;

        return s->pm_regs[addr >> 2];

    default:

    fail:

        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);

        break;

    }

    return 0;

}


static void ssim_4x4x2_core(const uint8_t *main, int main_stride,

                            const uint8_t *ref, int ref_stride,

                            int sums[2][4])

{

    int x, y, z;

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

        uint32_t s1 = 0, s2 = 0, ss = 0, s12 = 0;

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

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

                int a = main[x + y * main_stride];

                int b = ref[x + y * ref_stride];

                s1  += a;

                s2  += b;

                ss  += a*a;

                ss  += b*b;

                s12 += a*b;

            }

        }

        sums[z][0] = s1;

        sums[z][1] = s2;

        sums[z][2] = ss;

        sums[z][3] = s12;

        main += 4;

        ref += 4;

    }

}


static void ivshmem_check_memdev_is_busy(Object *obj, const char *name,

                                         Object *val, Error **errp)

{

    MemoryRegion *mr;

    mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &error_abort);

    if (memory_region_is_mapped(mr)) {

        char *path = object_get_canonical_path_component(val);

        error_setg(errp, "can't use already busy memdev: %s", path);

        g_free(path);

    } else {

        qdev_prop_allow_set_link_before_realize(obj, name, val, errp);

    }

}


static int seq_parse_frame_data(SeqDemuxContext *seq, ByteIOContext *pb)

{

    unsigned int offset_table[4], buffer_num[4];

    TiertexSeqFrameBuffer *seq_buffer;

    int i, e;

    seq->current_frame_offs += SEQ_FRAME_SIZE;

    url_fseek(pb, seq->current_frame_offs, SEEK_SET);

    /* sound data */

    seq->current_audio_data_offs = get_le16(pb);

    if (seq->current_audio_data_offs != 0) {

        seq->current_audio_data_size = SEQ_AUDIO_BUFFER_SIZE * 2;

    } else {

        seq->current_audio_data_size = 0;

    }

    /* palette data */

    seq->current_pal_data_offs = get_le16(pb);

    if (seq->current_pal_data_offs != 0) {

        seq->current_pal_data_size = 768;

    } else {

        seq->current_pal_data_size = 0;

    }

    /* video data */

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

        buffer_num[i] = get_byte(pb);

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

        offset_table[i] = get_le16(pb);

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

        if (offset_table[i] != 0) {

            for (e = i + 1; e < 4 && offset_table[e] == 0; e++);

            seq_fill_buffer(seq, pb, buffer_num[1 + i],

              offset_table[i],

              offset_table[e] - offset_table[i]);

        }

    }

    if (buffer_num[0] != 255) {

        seq_buffer = &seq->frame_buffers[buffer_num[0]];

        seq->current_video_data_size = seq_buffer->fill_size;

        seq->current_video_data_ptr  = seq_buffer->data;

        seq_buffer->fill_size = 0;

    } else {

        seq->current_video_data_size = 0;

        seq->current_video_data_ptr  = 0;

    }

    return 0;

}


static void fd_chr_close(struct CharDriverState *chr)

{

    FDCharDriver *s = chr->opaque;

    if (s->fd_in_tag) {

        g_source_remove(s->fd_in_tag);

        s->fd_in_tag = 0;

    }

    if (s->fd_in) {

        g_io_channel_unref(s->fd_in);

    }

    if (s->fd_out) {

        g_io_channel_unref(s->fd_out);

    }

    g_free(s);

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);

}


static void async_complete(void *opaque)

{

    USBHostDevice *s = opaque;

    AsyncURB *aurb;

    int urbs = 0;

    while (1) {

        USBPacket *p;

        int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);

        if (r < 0) {

            if (errno == EAGAIN) {

                if (urbs > 2) {

                    fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);

                }

                return;

            }

            if (errno == ENODEV && !s->closing) {

                do_disconnect(s);

                return;

            }

            DPRINTF("husb: async. reap urb failed errno %d\n", errno);

            return;

        }

        DPRINTF("husb: async completed. aurb %p status %d alen %d\n",

                aurb, aurb->urb.status, aurb->urb.actual_length);

        /* If this is a buffered iso urb mark it as complete and don't do

           anything else (it is handled further in usb_host_handle_iso_data) */

        if (aurb->iso_frame_idx == -1) {

            int inflight;

            if (aurb->urb.status == -EPIPE) {

                set_halt(s, aurb->urb.endpoint & 0xf);

            }

            aurb->iso_frame_idx = 0;

            urbs++;

            inflight = change_iso_inflight(s, aurb->urb.endpoint & 0xf, -1);

            if (inflight == 0 && is_iso_started(s, aurb->urb.endpoint & 0xf)) {

                fprintf(stderr, "husb: out of buffers for iso stream\n");

            }

            continue;

        }

        p = aurb->packet;

        if (p) {

            switch (aurb->urb.status) {

            case 0:

                p->len += aurb->urb.actual_length;

                break;

            case -EPIPE:

                set_halt(s, p->devep);

                p->len = USB_RET_STALL;

                break;

            default:

                p->len = USB_RET_NAK;

                break;

            }

            if (aurb->urb.type == USBDEVFS_URB_TYPE_CONTROL) {

                usb_generic_async_ctrl_complete(&s->dev, p);

            } else if (!aurb->more) {

                usb_packet_complete(&s->dev, p);

            }

        }

        async_free(aurb);

    }

}


static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,

                        struct in_addr *preq_addr)

{

    const uint8_t *p, *p_end;

    int len, tag;

    *pmsg_type = 0;

    preq_addr->s_addr = htonl(0L);

    p = bp->bp_vend;

    p_end = p + DHCP_OPT_LEN;

    if (memcmp(p, rfc1533_cookie, 4) != 0)

        return;

    p += 4;

    while (p < p_end) {

        tag = p[0];

        if (tag == RFC1533_PAD) {

            p++;

        } else if (tag == RFC1533_END) {

        } else {

            p++;

            if (p >= p_end)

            len = *p++;

            DPRINTF("dhcp: tag=%d len=%d\n", tag, len);

            switch(tag) {

            case RFC2132_MSG_TYPE:

                if (len >= 1)

                    *pmsg_type = p[0];

            case RFC2132_REQ_ADDR:

                if (len >= 4) {

                    memcpy(&(preq_addr->s_addr), p, 4);

            default:

            p += len;

    if (*pmsg_type == DHCPREQUEST && preq_addr->s_addr == htonl(0L) &&

        bp->bp_ciaddr.s_addr) {

        memcpy(&(preq_addr->s_addr), &bp->bp_ciaddr, 4);


static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr,

                                           const char *fmt, ...)

{

    va_list ap;

    gchar *buffer;

    va_start(ap, fmt);

    buffer = g_strdup_vprintf(fmt, ap);

    qtest_send(chr, buffer);

    va_end(ap);

}


static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,

                                  int version_id)

{

    VirtIOBlock *s = VIRTIO_BLK(vdev);

    while (qemu_get_sbyte(f)) {

        VirtIOBlockReq *req = virtio_blk_alloc_request(s);

        qemu_get_buffer(f, (unsigned char *)req->elem,

                        sizeof(VirtQueueElement));

        req->next = s->rq;

        s->rq = req;

        virtqueue_map_sg(req->elem->in_sg, req->elem->in_addr,

            req->elem->in_num, 1);

        virtqueue_map_sg(req->elem->out_sg, req->elem->out_addr,

            req->elem->out_num, 0);

    }

    return 0;

}


struct AACISError ff_aac_is_encoding_err(AACEncContext *s, ChannelElement *cpe,

                                         int start, int w, int g, float ener0,

                                         float ener1, float ener01,

                                         int use_pcoeffs, int phase)

{

    int i, w2;

    SingleChannelElement *sce0 = &cpe->ch[0];

    SingleChannelElement *sce1 = &cpe->ch[1];

    float *L = use_pcoeffs ? sce0->pcoeffs : sce0->coeffs;

    float *R = use_pcoeffs ? sce1->pcoeffs : sce1->coeffs;

    float *L34 = &s->scoefs[256*0], *R34 = &s->scoefs[256*1];

    float *IS  = &s->scoefs[256*2], *I34 = &s->scoefs[256*3];

    float dist1 = 0.0f, dist2 = 0.0f;

    struct AACISError is_error = {0};

    for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {

        FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];

        FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];

        int is_band_type, is_sf_idx = FFMAX(1, sce0->sf_idx[(w+w2)*16+g]-4);

        float e01_34 = phase*pow(ener1/ener0, 3.0/4.0);

        float maxval, dist_spec_err = 0.0f;

        float minthr = FFMIN(band0->threshold, band1->threshold);

        for (i = 0; i < sce0->ics.swb_sizes[g]; i++)

            IS[i] = (L[start+(w+w2)*128+i] + phase*R[start+(w+w2)*128+i])*sqrt(ener0/ener01);

        abs_pow34_v(L34, &L[start+(w+w2)*128], sce0->ics.swb_sizes[g]);

        abs_pow34_v(R34, &R[start+(w+w2)*128], sce0->ics.swb_sizes[g]);

        abs_pow34_v(I34, IS,                   sce0->ics.swb_sizes[g]);

        maxval = find_max_val(1, sce0->ics.swb_sizes[g], I34);

        is_band_type = find_min_book(maxval, is_sf_idx);

        dist1 += quantize_band_cost(s, &L[start + (w+w2)*128], L34,

                                    sce0->ics.swb_sizes[g],

                                    sce0->sf_idx[(w+w2)*16+g],

                                    sce0->band_type[(w+w2)*16+g],

                                    s->lambda / band0->threshold, INFINITY, NULL, 0);

        dist1 += quantize_band_cost(s, &R[start + (w+w2)*128], R34,

                                    sce1->ics.swb_sizes[g],

                                    sce1->sf_idx[(w+w2)*16+g],

                                    sce1->band_type[(w+w2)*16+g],

                                    s->lambda / band1->threshold, INFINITY, NULL, 0);

        dist2 += quantize_band_cost(s, IS, I34, sce0->ics.swb_sizes[g],

                                    is_sf_idx, is_band_type,

                                    s->lambda / minthr, INFINITY, NULL, 0);

        for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {

            dist_spec_err += (L34[i] - I34[i])*(L34[i] - I34[i]);

            dist_spec_err += (R34[i] - I34[i]*e01_34)*(R34[i] - I34[i]*e01_34);

        }

        dist_spec_err *= s->lambda / minthr;

        dist2 += dist_spec_err;

    }

    is_error.pass = dist2 <= dist1;

    is_error.phase = phase;

    is_error.error = fabsf(dist1 - dist2);

    is_error.dist1 = dist1;

    is_error.dist2 = dist2;

    return is_error;

}


static Picture * remove_short(H264Context *h, int frame_num){

    MpegEncContext * const s = &h->s;

    int i;

    if(s->avctx->debug&FF_DEBUG_MMCO)

        av_log(h->s.avctx, AV_LOG_DEBUG, "remove short %d count %d\n", frame_num, h->short_ref_count);

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

        Picture *pic= h->short_ref[i];

        if(s->avctx->debug&FF_DEBUG_MMCO)

            av_log(h->s.avctx, AV_LOG_DEBUG, "%d %d %p\n", i, pic->frame_num, pic);

        if(pic->frame_num == frame_num){

            h->short_ref[i]= NULL;

            memmove(&h->short_ref[i], &h->short_ref[i+1], (h->short_ref_count - i - 1)*sizeof(Picture*));

            h->short_ref_count--;

            return pic;

        }

    }

    return NULL;

}


static int cook_decode_frame(AVCodecContext *avctx,

            void *data, int *data_size,

            AVPacket *avpkt) {

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    COOKContext *q = avctx->priv_data;

    int i;

    int offset = 0;

    int chidx = 0;

    if (buf_size < avctx->block_align)

        return buf_size;

    /* estimate subpacket sizes */

    q->subpacket[0].size = avctx->block_align;

    for(i=1;i<q->num_subpackets;i++){

        q->subpacket[i].size = 2 * buf[avctx->block_align - q->num_subpackets + i];

        q->subpacket[0].size -= q->subpacket[i].size + 1;

        if (q->subpacket[0].size < 0) {

            av_log(avctx,AV_LOG_DEBUG,"frame subpacket size total > avctx->block_align!\n");

            return AVERROR_INVALIDDATA;

        }

    }

    /* decode supbackets */

    for(i=0;i<q->num_subpackets;i++){

        q->subpacket[i].bits_per_subpacket = (q->subpacket[i].size*8)>>q->subpacket[i].bits_per_subpdiv;

        q->subpacket[i].ch_idx = chidx;

        av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] size %i js %i %i block_align %i\n",i,q->subpacket[i].size,q->subpacket[i].joint_stereo,offset,avctx->block_align);

        decode_subpacket(q, &q->subpacket[i], buf + offset, data);

        offset += q->subpacket[i].size;

        chidx += q->subpacket[i].num_channels;

        av_log(avctx,AV_LOG_DEBUG,"subpacket[%i] %i %i\n",i,q->subpacket[i].size * 8,get_bits_count(&q->gb));

    }

    *data_size = q->nb_channels * q->samples_per_channel *

                 av_get_bytes_per_sample(avctx->sample_fmt);

    /* Discard the first two frames: no valid audio. */

    if (avctx->frame_number < 2) *data_size = 0;

    return avctx->block_align;

}


struct pxa2xx_state_s *pxa270_init(DisplayState *ds, const char *revision)

{

    struct pxa2xx_state_s *s;

    struct pxa2xx_ssp_s *ssp;

    char cpu_model[16];

    int iomemtype, i;

    s = (struct pxa2xx_state_s *) qemu_mallocz(sizeof(struct pxa2xx_state_s));

    s->env = cpu_init();

    snprintf(cpu_model, sizeof(cpu_model), "pxa270-%s", revision);

    cpu_arm_set_model(s->env, cpu_model);

    s->pic = pxa2xx_pic_init(0x40d00000, s->env);

    s->dma = pxa27x_dma_init(0x40000000, s->pic[PXA2XX_PIC_DMA]);

    pxa27x_timer_init(0x40a00000, &s->pic[PXA2XX_PIC_OST_0],

                    s->pic[PXA27X_PIC_OST_4_11], s->env);

    s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);

    s->mmc = pxa2xx_mmci_init(0x41100000, s->pic[PXA2XX_PIC_MMC], s->dma);

    for (i = 0; pxa270_serial[i].io_base; i ++)

        if (serial_hds[i])

            serial_mm_init(pxa270_serial[i].io_base, 2,

                            s->pic[pxa270_serial[i].irqn], serial_hds[i], 1);

        else

            break;

    if (serial_hds[i])

        s->fir = pxa2xx_fir_init(0x40800000, s->pic[PXA2XX_PIC_ICP],

                        s->dma, serial_hds[i]);

    if (ds)

        s->lcd = pxa2xx_lcdc_init(0x44000000, s->pic[PXA2XX_PIC_LCD], ds);

    s->cm_base = 0x41300000;

    s->cm_regs[CCCR >> 4] = 0x02000210;	/* 416.0 MHz */

    s->clkcfg = 0x00000009;		/* Turbo mode active */

    iomemtype = cpu_register_io_memory(0, pxa2xx_cm_readfn,

                    pxa2xx_cm_writefn, s);

    cpu_register_physical_memory(s->cm_base, 0xfff, iomemtype);

    cpu_arm_set_cp_io(s->env, 14, pxa2xx_cp14_read, pxa2xx_cp14_write, s);

    s->mm_base = 0x48000000;

    s->mm_regs[MDMRS >> 2] = 0x00020002;

    s->mm_regs[MDREFR >> 2] = 0x03ca4000;

    s->mm_regs[MECR >> 2] = 0x00000001;	/* Two PC Card sockets */

    iomemtype = cpu_register_io_memory(0, pxa2xx_mm_readfn,

                    pxa2xx_mm_writefn, s);

    cpu_register_physical_memory(s->mm_base, 0xfff, iomemtype);

    for (i = 0; pxa27x_ssp[i].io_base; i ++);

    s->ssp = (struct pxa2xx_ssp_s **)

            qemu_mallocz(sizeof(struct pxa2xx_ssp_s *) * i);

    ssp = (struct pxa2xx_ssp_s *)

            qemu_mallocz(sizeof(struct pxa2xx_ssp_s) * i);

    for (i = 0; pxa27x_ssp[i].io_base; i ++) {

        s->ssp[i] = &ssp[i];

        ssp[i].base = pxa27x_ssp[i].io_base;

        ssp[i].irq = s->pic[pxa27x_ssp[i].irqn];

        iomemtype = cpu_register_io_memory(0, pxa2xx_ssp_readfn,

                        pxa2xx_ssp_writefn, &ssp[i]);

        cpu_register_physical_memory(ssp[i].base, 0xfff, iomemtype);

    }

    if (usb_enabled) {

        usb_ohci_init_pxa(0x4c000000, 3, -1, s->pic[PXA2XX_PIC_USBH1]);

    }

    s->pcmcia[0] = pxa2xx_pcmcia_init(0x20000000);

    s->pcmcia[1] = pxa2xx_pcmcia_init(0x30000000);

    s->rtc_base = 0x40900000;

    iomemtype = cpu_register_io_memory(0, pxa2xx_rtc_readfn,

                    pxa2xx_rtc_writefn, s);

    cpu_register_physical_memory(s->rtc_base, 0xfff, iomemtype);

    pxa2xx_rtc_reset(s);

    s->pm_base = 0x40f00000;

    iomemtype = cpu_register_io_memory(0, pxa2xx_pm_readfn,

                    pxa2xx_pm_writefn, s);

    cpu_register_physical_memory(s->pm_base, 0xfff, iomemtype);

    s->i2s = pxa2xx_i2s_init(0x40400000, s->pic[PXA2XX_PIC_I2S], s->dma);

    /* GPIO1 resets the processor */

    /* The handler can be overriden by board-specific code */

    pxa2xx_gpio_handler_set(s->gpio, 1, pxa2xx_reset, s);

    return s;

}


static int hdev_has_zero_init(BlockDriverState *bs)

{

    return 0;

}


static int read_thread(void *arg)

{

    VideoState *is = arg;

    AVFormatContext *ic = NULL;

    int err, i, ret;

    int st_index[AVMEDIA_TYPE_NB];

    AVPacket pkt1, *pkt = &pkt1;

    int64_t stream_start_time;

    int pkt_in_play_range = 0;

    AVDictionaryEntry *t;

    AVDictionary **opts;

    int orig_nb_streams;

    SDL_mutex *wait_mutex = SDL_CreateMutex();

    int scan_all_pmts_set = 0;

    int64_t pkt_ts;

    if (!wait_mutex) {

        av_log(NULL, AV_LOG_FATAL, "SDL_CreateMutex(): %s\n", SDL_GetError());

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    memset(st_index, -1, sizeof(st_index));

    is->last_video_stream = is->video_stream = -1;

    is->last_audio_stream = is->audio_stream = -1;

    is->last_subtitle_stream = is->subtitle_stream = -1;

    is->eof = 0;

    ic = avformat_alloc_context();

    if (!ic) {

        av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    ic->interrupt_callback.callback = decode_interrupt_cb;

    ic->interrupt_callback.opaque = is;

    if (!av_dict_get(format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) {

        av_dict_set(&format_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE);

        scan_all_pmts_set = 1;

    }

    err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);

    if (err < 0) {

        print_error(is->filename, err);

        ret = -1;

        goto fail;

    }

    if (scan_all_pmts_set)

        av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);

    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {

        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);

        ret = AVERROR_OPTION_NOT_FOUND;

        goto fail;

    }

    is->ic = ic;

    if (genpts)

        ic->flags |= AVFMT_FLAG_GENPTS;

    av_format_inject_global_side_data(ic);

    opts = setup_find_stream_info_opts(ic, codec_opts);

    orig_nb_streams = ic->nb_streams;

    err = avformat_find_stream_info(ic, opts);

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

        av_dict_free(&opts[i]);

    av_freep(&opts);

    if (err < 0) {

        av_log(NULL, AV_LOG_WARNING,

               "%s: could not find codec parameters\n", is->filename);

        ret = -1;

        goto fail;

    }

    if (ic->pb)

        ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use avio_feof() to test for the end

    if (seek_by_bytes < 0)

        seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT) && strcmp("ogg", ic->iformat->name);

    is->max_frame_duration = (ic->iformat->flags & AVFMT_TS_DISCONT) ? 10.0 : 3600.0;

    if (!window_title && (t = av_dict_get(ic->metadata, "title", NULL, 0)))

        window_title = av_asprintf("%s - %s", t->value, input_filename);

    /* if seeking requested, we execute it */

    if (start_time != AV_NOPTS_VALUE) {

        int64_t timestamp;

        timestamp = start_time;

        /* add the stream start time */

        if (ic->start_time != AV_NOPTS_VALUE)

            timestamp += ic->start_time;

        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);

        if (ret < 0) {

            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",

                    is->filename, (double)timestamp / AV_TIME_BASE);

        }

    }

    is->realtime = is_realtime(ic);

    if (show_status)

        av_dump_format(ic, 0, is->filename, 0);

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

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

        enum AVMediaType type = st->codec->codec_type;

        st->discard = AVDISCARD_ALL;

        if (wanted_stream_spec[type] && st_index[type] == -1)

            if (avformat_match_stream_specifier(ic, st, wanted_stream_spec[type]) > 0)

                st_index[type] = i;

    }

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

        if (wanted_stream_spec[i] && st_index[i] == -1) {

            av_log(NULL, AV_LOG_ERROR, "Stream specifier %s does not match any %s stream\n", wanted_stream_spec[i], av_get_media_type_string(i));

            st_index[i] = INT_MAX;

        }

    }

    if (!video_disable)

        st_index[AVMEDIA_TYPE_VIDEO] =

            av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,

                                st_index[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);

    if (!audio_disable)

        st_index[AVMEDIA_TYPE_AUDIO] =

            av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,

                                st_index[AVMEDIA_TYPE_AUDIO],

                                st_index[AVMEDIA_TYPE_VIDEO],

                                NULL, 0);

    if (!video_disable && !subtitle_disable)

        st_index[AVMEDIA_TYPE_SUBTITLE] =

            av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,

                                st_index[AVMEDIA_TYPE_SUBTITLE],

                                (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?

                                 st_index[AVMEDIA_TYPE_AUDIO] :

                                 st_index[AVMEDIA_TYPE_VIDEO]),

                                NULL, 0);

    is->show_mode = show_mode;

    if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {

        AVStream *st = ic->streams[st_index[AVMEDIA_TYPE_VIDEO]];

        AVCodecContext *avctx = st->codec;

        AVRational sar = av_guess_sample_aspect_ratio(ic, st, NULL);

        if (avctx->width)

            set_default_window_size(avctx->width, avctx->height, sar);

    }

    /* open the streams */

    if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {

        stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);

    }

    ret = -1;

    if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {

        ret = stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);

    }

    if (is->show_mode == SHOW_MODE_NONE)

        is->show_mode = ret >= 0 ? SHOW_MODE_VIDEO : SHOW_MODE_RDFT;

    if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {

        stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);

    }

    if (is->video_stream < 0 && is->audio_stream < 0) {

        av_log(NULL, AV_LOG_FATAL, "Failed to open file '%s' or configure filtergraph\n",

               is->filename);

        ret = -1;

        goto fail;

    }

    if (infinite_buffer < 0 && is->realtime)

        infinite_buffer = 1;

    for (;;) {

        if (is->abort_request)

            break;

        if (is->paused != is->last_paused) {

            is->last_paused = is->paused;

            if (is->paused)

                is->read_pause_return = av_read_pause(ic);

            else

                av_read_play(ic);

        }

#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL

        if (is->paused &&

                (!strcmp(ic->iformat->name, "rtsp") ||

                 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {

            /* wait 10 ms to avoid trying to get another packet */

            /* XXX: horrible */

            SDL_Delay(10);

            continue;

        }

#endif

        if (is->seek_req) {

            int64_t seek_target = is->seek_pos;

            int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;

            int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;

// FIXME the +-2 is due to rounding being not done in the correct direction in generation

//      of the seek_pos/seek_rel variables

            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);

            if (ret < 0) {

                av_log(NULL, AV_LOG_ERROR,

                       "%s: error while seeking\n", is->ic->filename);

            } else {

                if (is->audio_stream >= 0) {

                    packet_queue_flush(&is->audioq);

                    packet_queue_put(&is->audioq, &flush_pkt);

                }

                if (is->subtitle_stream >= 0) {

                    packet_queue_flush(&is->subtitleq);

                    packet_queue_put(&is->subtitleq, &flush_pkt);

                }

                if (is->video_stream >= 0) {

                    packet_queue_flush(&is->videoq);

                    packet_queue_put(&is->videoq, &flush_pkt);

                }

                if (is->seek_flags & AVSEEK_FLAG_BYTE) {

                   set_clock(&is->extclk, NAN, 0);

                } else {

                   set_clock(&is->extclk, seek_target / (double)AV_TIME_BASE, 0);

                }

            }

            is->seek_req = 0;

            is->queue_attachments_req = 1;

            is->eof = 0;

            if (is->paused)

                step_to_next_frame(is);

        }

        if (is->queue_attachments_req) {

            if (is->video_st && is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC) {

                AVPacket copy;

                if ((ret = av_copy_packet(&copy, &is->video_st->attached_pic)) < 0)

                    goto fail;

                packet_queue_put(&is->videoq, &copy);

                packet_queue_put_nullpacket(&is->videoq, is->video_stream);

            }

            is->queue_attachments_req = 0;

        }

        /* if the queue are full, no need to read more */

        if (infinite_buffer<1 &&

              (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE

            || (   (is->audioq   .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)

                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request

                    || (is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC))

                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {

            /* wait 10 ms */

            SDL_LockMutex(wait_mutex);

            SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);

            SDL_UnlockMutex(wait_mutex);

            continue;

        }

        if (!is->paused &&

            (!is->audio_st || (is->auddec.finished == is->audioq.serial && frame_queue_nb_remaining(&is->sampq) == 0)) &&

            (!is->video_st || (is->viddec.finished == is->videoq.serial && frame_queue_nb_remaining(&is->pictq) == 0))) {

            if (loop != 1 && (!loop || --loop)) {

                stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);

            } else if (autoexit) {

                ret = AVERROR_EOF;

                goto fail;

            }

        }

        ret = av_read_frame(ic, pkt);

        if (ret < 0) {

            if ((ret == AVERROR_EOF || avio_feof(ic->pb)) && !is->eof) {

                if (is->video_stream >= 0)

                    packet_queue_put_nullpacket(&is->videoq, is->video_stream);

                if (is->audio_stream >= 0)

                    packet_queue_put_nullpacket(&is->audioq, is->audio_stream);

                if (is->subtitle_stream >= 0)

                    packet_queue_put_nullpacket(&is->subtitleq, is->subtitle_stream);

                is->eof = 1;

            }

            if (ic->pb && ic->pb->error)

                break;

            SDL_LockMutex(wait_mutex);

            SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);

            SDL_UnlockMutex(wait_mutex);

            continue;

        } else {

            is->eof = 0;

        }

        /* check if packet is in play range specified by user, then queue, otherwise discard */

        stream_start_time = ic->streams[pkt->stream_index]->start_time;

        pkt_ts = pkt->pts == AV_NOPTS_VALUE ? pkt->dts : pkt->pts;

        pkt_in_play_range = duration == AV_NOPTS_VALUE ||

                (pkt_ts - (stream_start_time != AV_NOPTS_VALUE ? stream_start_time : 0)) *

                av_q2d(ic->streams[pkt->stream_index]->time_base) -

                (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000

                <= ((double)duration / 1000000);

        if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {

            packet_queue_put(&is->audioq, pkt);

        } else if (pkt->stream_index == is->video_stream && pkt_in_play_range

                   && !(is->video_st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {

            packet_queue_put(&is->videoq, pkt);

        } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {

            packet_queue_put(&is->subtitleq, pkt);

        } else {

            av_free_packet(pkt);

        }

    }

    /* wait until the end */

    while (!is->abort_request) {

        SDL_Delay(100);

    }

    ret = 0;

 fail:

    /* close each stream */

    if (is->audio_stream >= 0)

        stream_component_close(is, is->audio_stream);

    if (is->video_stream >= 0)

        stream_component_close(is, is->video_stream);

    if (is->subtitle_stream >= 0)

        stream_component_close(is, is->subtitle_stream);

    if (ic) {

        avformat_close_input(&ic);

        is->ic = NULL;

    }

    if (ret != 0) {

        SDL_Event event;

        event.type = FF_QUIT_EVENT;

        event.user.data1 = is;

        SDL_PushEvent(&event);

    }

    SDL_DestroyMutex(wait_mutex);

    return 0;

}


static inline void RENAME(yuv2yuv1_ar)(SwsContext *c, const int16_t *lumSrc,

                                       const int16_t *chrUSrc, const int16_t *chrVSrc,

                                       const int16_t *alpSrc,

                                       uint8_t *dest, uint8_t *uDest, uint8_t *vDest,

                                       uint8_t *aDest, int dstW, int chrDstW)

{

    int p= 4;

    const uint8_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW };

    uint8_t *dst[4]= { aDest, dest, uDest, vDest };

    x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW };

    while (p--) {

        if (dst[p]) {

            __asm__ volatile(

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

                "pcmpeqw %%mm7, %%mm7                 \n\t"

                "psrlw                 $15, %%mm7     \n\t"

                "psllw                  $6, %%mm7     \n\t"

                ".p2align                4            \n\t" /* FIXME Unroll? */

                "1:                                   \n\t"

                "movq  (%0, %%"REG_a", 2), %%mm0      \n\t"

                "movq 8(%0, %%"REG_a", 2), %%mm1      \n\t"

                "paddsw             %%mm7, %%mm0      \n\t"

                "paddsw             %%mm7, %%mm1      \n\t"

                "psraw                 $7, %%mm0      \n\t"

                "psraw                 $7, %%mm1      \n\t"

                "packuswb           %%mm1, %%mm0      \n\t"

                MOVNTQ(%%mm0, (%1, %%REGa))

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

                "jnc                   1b             \n\t"

                :: "r" (src[p]), "r" (dst[p] + counter[p]),

                   "g" (-counter[p])

                : "%"REG_a

            );

        }

    }

}


void visit_start_struct(Visitor *v, const char *name, void **obj,

                        size_t size, Error **errp)

{

    Error *err = NULL;

    if (obj) {

        assert(size);

        assert(v->type != VISITOR_OUTPUT || *obj);

    }

    v->start_struct(v, name, obj, size, &err);

    if (obj && v->type == VISITOR_INPUT) {

        assert(!err != !*obj);

    }

    error_propagate(errp, err);

}