static av_cold int bktr_init(const char *video_device, int width, int height,

    int format, int *video_fd, int *tuner_fd, int idev, double frequency)

{

    struct meteor_geomet geo;

    int h_max;

    long ioctl_frequency;

    char *arg;

    int c;

    struct sigaction act = { 0 }, old;

    if (idev < 0 || idev > 4)

    {

        arg = getenv ("BKTR_DEV");

        if (arg)

            idev = atoi (arg);

        if (idev < 0 || idev > 4)

            idev = 1;

    }

    if (format < 1 || format > 6)

    {

        arg = getenv ("BKTR_FORMAT");

        if (arg)

            format = atoi (arg);

        if (format < 1 || format > 6)

            format = VIDEO_FORMAT;

    }

    if (frequency <= 0)

    {

        arg = getenv ("BKTR_FREQUENCY");

        if (arg)

            frequency = atof (arg);

        if (frequency <= 0)

            frequency = 0.0;

    }

    sigemptyset(&act.sa_mask);

    act.sa_handler = catchsignal;

    sigaction(SIGUSR1, &act, &old);

    *tuner_fd = open("/dev/tuner0", O_RDONLY);

    if (*tuner_fd < 0)

        av_log(NULL, AV_LOG_ERROR, "Warning. Tuner not opened, continuing: %s\n", strerror(errno));

    *video_fd = open(video_device, O_RDONLY);

    if (*video_fd < 0) {

        av_log(NULL, AV_LOG_ERROR, "%s: %s\n", video_device, strerror(errno));

        return -1;

    }

    geo.rows = height;

    geo.columns = width;

    geo.frames = 1;

    geo.oformat = METEOR_GEO_YUV_422 | METEOR_GEO_YUV_12;

    switch (format) {

    case PAL:   h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALBDGHI; break;

    case PALN:  h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALN;     break;

    case PALM:  h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALM;     break;

    case SECAM: h_max = SECAM_HEIGHT; c = BT848_IFORM_F_SECAM;    break;

    case NTSC:  h_max = NTSC_HEIGHT;  c = BT848_IFORM_F_NTSCM;    break;

    case NTSCJ: h_max = NTSC_HEIGHT;  c = BT848_IFORM_F_NTSCJ;    break;

    default:    h_max = PAL_HEIGHT;   c = BT848_IFORM_F_PALBDGHI; break;

    }

    if (height <= h_max / 2)

        geo.oformat |= METEOR_GEO_EVEN_ONLY;

    if (ioctl(*video_fd, METEORSETGEO, &geo) < 0) {

        av_log(NULL, AV_LOG_ERROR, "METEORSETGEO: %s\n", strerror(errno));

        return -1;

    }

    if (ioctl(*video_fd, BT848SFMT, &c) < 0) {

        av_log(NULL, AV_LOG_ERROR, "BT848SFMT: %s\n", strerror(errno));

        return -1;

    }

    c = bktr_dev[idev];

    if (ioctl(*video_fd, METEORSINPUT, &c) < 0) {

        av_log(NULL, AV_LOG_ERROR, "METEORSINPUT: %s\n", strerror(errno));

        return -1;

    }

    video_buf_size = width * height * 12 / 8;

    video_buf = (uint8_t *)mmap((caddr_t)0, video_buf_size,

        PROT_READ, MAP_SHARED, *video_fd, (off_t)0);

    if (video_buf == MAP_FAILED) {

        av_log(NULL, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));

        return -1;

    }

    if (frequency != 0.0) {

        ioctl_frequency  = (unsigned long)(frequency*16);

        if (ioctl(*tuner_fd, TVTUNER_SETFREQ, &ioctl_frequency) < 0)

            av_log(NULL, AV_LOG_ERROR, "TVTUNER_SETFREQ: %s\n", strerror(errno));

    }

    c = AUDIO_UNMUTE;

    if (ioctl(*tuner_fd, BT848_SAUDIO, &c) < 0)

        av_log(NULL, AV_LOG_ERROR, "TVTUNER_SAUDIO: %s\n", strerror(errno));

    c = METEOR_CAP_CONTINOUS;

    ioctl(*video_fd, METEORCAPTUR, &c);

    c = SIGUSR1;

    ioctl(*video_fd, METEORSSIGNAL, &c);

    return 0;

}


static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
                                   void *dst_l, void *dst_r, const int type)
{
    int i, j, count = 0;
    int last, t;
    int A, B, L, L2, R, R2;
    int pos                 = s->pos;
    uint32_t crc            = s->sc.crc;
    uint32_t crc_extra_bits = s->extra_sc.crc;
    int16_t *dst16_l        = dst_l;
    int16_t *dst16_r        = dst_r;
    int32_t *dst32_l        = dst_l;
    int32_t *dst32_r        = dst_r;
    float *dstfl_l          = dst_l;
    float *dstfl_r          = dst_r;
    s->one = s->zero = s->zeroes = 0;
    do {
        L = wv_get_value(s, gb, 0, &last);
        if (last)
            break;
        R = wv_get_value(s, gb, 1, &last);
        if (last)
            break;
        for (i = 0; i < s->terms; i++) {
            t = s->decorr[i].value;
            if (t > 0) {
                if (t > 8) {
                    if (t & 1) {
                        A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
                        B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1];
                    } else {
                        A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
                        B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1;
                    s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
                    s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
                    j                        = 0;
                } else {
                    A = s->decorr[i].samplesA[pos];
                    B = s->decorr[i].samplesB[pos];
                    j = (pos + t) & 7;
                if (type != AV_SAMPLE_FMT_S16P) {
                    L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
                    R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
                } else {
                    L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
                    R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
                if (A && L)
                    s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
                if (B && R)
                    s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
                s->decorr[i].samplesA[j] = L = L2;
                s->decorr[i].samplesB[j] = R = R2;
            } else if (t == -1) {
                if (type != AV_SAMPLE_FMT_S16P)
                    L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
                else
                    L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
                UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
                L = L2;
                if (type != AV_SAMPLE_FMT_S16P)
                    R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
                else
                    R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
                UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
                R                        = R2;
                s->decorr[i].samplesA[0] = R;
            } else {
                if (type != AV_SAMPLE_FMT_S16P)
                    R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
                else
                    R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
                UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R);
                R = R2;
                if (t == -3) {
                    R2                       = s->decorr[i].samplesA[0];
                    s->decorr[i].samplesA[0] = R;
                if (type != AV_SAMPLE_FMT_S16P)
                    L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
                else
                    L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
                UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
                L                        = L2;
                s->decorr[i].samplesB[0] = L;
        pos = (pos + 1) & 7;
        if (s->joint)
            L += (R -= (L >> 1));
        crc = (crc * 3 + L) * 3 + R;
        if (type == AV_SAMPLE_FMT_FLTP) {
            *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
            *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
        } else if (type == AV_SAMPLE_FMT_S32P) {
            *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
            *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
        } else {
            *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
            *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
        count++;
    } while (!last && count < s->samples);
    wv_reset_saved_context(s);
    if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
        wv_check_crc(s, crc, crc_extra_bits))
        return AVERROR_INVALIDDATA;
    return 0;


static ExitStatus trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,

                                   const DisasInsn *di)

{

    unsigned rt = extract32(insn, 0, 5);

    unsigned ra = extract32(insn, 21, 5);

    return do_fop_wed(ctx, rt, ra, di->f_wed);

}


void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)

{

    int reslevelno, bandno, precno;

    for (reslevelno = 0;

         comp->reslevel && reslevelno < codsty->nreslevels;

         reslevelno++) {

        Jpeg2000ResLevel *reslevel;

        if (!comp->reslevel)

            continue;

        reslevel = comp->reslevel + reslevelno;

        for (bandno = 0; bandno < reslevel->nbands; bandno++) {

            Jpeg2000Band *band;

            if (!reslevel->band)

                continue;

            band = reslevel->band + bandno;

            for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++) {

                if (band->prec) {

                    Jpeg2000Prec *prec = band->prec + precno;

                    av_freep(&prec->zerobits);

                    av_freep(&prec->cblkincl);

                    av_freep(&prec->cblk);

                }

            }

            av_freep(&band->prec);

        }

        av_freep(&reslevel->band);

    }

    ff_dwt_destroy(&comp->dwt);

    av_freep(&comp->reslevel);

    av_freep(&comp->i_data);

    av_freep(&comp->f_data);

}


SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockBackend *blk,

                                      int unit, bool removable, int bootindex,

                                      const char *serial, Error **errp)

{

    const char *driver;

    char *name;

    DeviceState *dev;

    Error *err = NULL;

    driver = blk_is_sg(blk) ? "scsi-generic" : "scsi-disk";

    dev = qdev_create(&bus->qbus, driver);

    name = g_strdup_printf("legacy[%d]", unit);

    object_property_add_child(OBJECT(bus), name, OBJECT(dev), NULL);

    g_free(name);

    qdev_prop_set_uint32(dev, "scsi-id", unit);

    if (bootindex >= 0) {

        object_property_set_int(OBJECT(dev), bootindex, "bootindex",

                                &error_abort);

    }

    if (object_property_find(OBJECT(dev), "removable", NULL)) {

        qdev_prop_set_bit(dev, "removable", removable);

    }

    if (serial && object_property_find(OBJECT(dev), "serial", NULL)) {

        qdev_prop_set_string(dev, "serial", serial);

    }

    qdev_prop_set_drive(dev, "drive", blk, &err);

    if (err) {

        qerror_report_err(err);

        error_free(err);

        error_setg(errp, "Setting drive property failed");

        object_unparent(OBJECT(dev));

        return NULL;

    }

    object_property_set_bool(OBJECT(dev), true, "realized", &err);

    if (err != NULL) {

        error_propagate(errp, err);

        object_unparent(OBJECT(dev));

        return NULL;

    }

    return SCSI_DEVICE(dev);

}


static int smacker_decode_header_tree(SmackVContext *smk, BitstreamContext *bc,

                                      int **recodes, int *last, int size)

{

    int res;

    HuffContext huff;

    HuffContext tmp1, tmp2;

    VLC vlc[2] = { { 0 } };

    int escapes[3];

    DBCtx ctx;

    int err = 0;

    if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow

        av_log(smk->avctx, AV_LOG_ERROR, "size too large\n");

        return AVERROR_INVALIDDATA;

    }

    tmp1.length = 256;

    tmp1.maxlength = 0;

    tmp1.current = 0;

    tmp1.bits = av_mallocz(256 * 4);

    tmp1.lengths = av_mallocz(256 * sizeof(int));

    tmp1.values = av_mallocz(256 * sizeof(int));

    tmp2.length = 256;

    tmp2.maxlength = 0;

    tmp2.current = 0;

    tmp2.bits = av_mallocz(256 * 4);

    tmp2.lengths = av_mallocz(256 * sizeof(int));

    tmp2.values = av_mallocz(256 * sizeof(int));

    if (!tmp1.bits || !tmp1.lengths || !tmp1.values ||

        !tmp2.bits || !tmp2.lengths || !tmp2.values) {

        err = AVERROR(ENOMEM);

        goto error;

    }

    if (bitstream_read_bit(bc)) {

        smacker_decode_tree(bc, &tmp1, 0, 0);

        bitstream_skip(bc, 1);

        res = init_vlc(&vlc[0], SMKTREE_BITS, tmp1.length,

                    tmp1.lengths, sizeof(int), sizeof(int),

                    tmp1.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);

        if(res < 0) {

            av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");

            err = res;

            goto error;

        }

    } else {

        av_log(smk->avctx, AV_LOG_ERROR, "Skipping low bytes tree\n");

    }

    if (bitstream_read_bit(bc)) {

        smacker_decode_tree(bc, &tmp2, 0, 0);

        bitstream_skip(bc, 1);

        res = init_vlc(&vlc[1], SMKTREE_BITS, tmp2.length,

                    tmp2.lengths, sizeof(int), sizeof(int),

                    tmp2.bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);

        if(res < 0) {

            av_log(smk->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");

            err = res;

            goto error;

        }

    } else {

        av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n");

    }

    escapes[0]  = bitstream_read(bc, 8);

    escapes[0] |= bitstream_read(bc, 8) << 8;

    escapes[1]  = bitstream_read(bc, 8);

    escapes[1] |= bitstream_read(bc, 8) << 8;

    escapes[2]  = bitstream_read(bc, 8);

    escapes[2] |= bitstream_read(bc, 8) << 8;

    last[0] = last[1] = last[2] = -1;

    ctx.escapes[0] = escapes[0];

    ctx.escapes[1] = escapes[1];

    ctx.escapes[2] = escapes[2];

    ctx.v1 = &vlc[0];

    ctx.v2 = &vlc[1];

    ctx.recode1 = tmp1.values;

    ctx.recode2 = tmp2.values;

    ctx.last = last;

    huff.length = ((size + 3) >> 2) + 4;

    huff.maxlength = 0;

    huff.current = 0;

    huff.values = av_mallocz(huff.length * sizeof(int));

    if (!huff.values) {

        err = AVERROR(ENOMEM);

        goto error;

    }

    if ((res = smacker_decode_bigtree(bc, &huff, &ctx)) < 0)

        err = res;

    bitstream_skip(bc, 1);

    if(ctx.last[0] == -1) ctx.last[0] = huff.current++;

    if(ctx.last[1] == -1) ctx.last[1] = huff.current++;

    if(ctx.last[2] == -1) ctx.last[2] = huff.current++;

    if (ctx.last[0] >= huff.length ||

        ctx.last[1] >= huff.length ||

        ctx.last[2] >= huff.length) {

        av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n");

        err = AVERROR_INVALIDDATA;

    }

    *recodes = huff.values;

error:

    if(vlc[0].table)

        ff_free_vlc(&vlc[0]);

    if(vlc[1].table)

        ff_free_vlc(&vlc[1]);

    av_free(tmp1.bits);

    av_free(tmp1.lengths);

    av_free(tmp1.values);

    av_free(tmp2.bits);

    av_free(tmp2.lengths);

    av_free(tmp2.values);

    return err;

}


static BlockAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
        unsigned long int req, void *buf,
        BlockCompletionFunc *cb, void *opaque)
{
    BDRVRawState *s = bs->opaque;
    RawPosixAIOData *acb;
    ThreadPool *pool;
    if (fd_open(bs) < 0)
        return NULL;
    acb = g_new(RawPosixAIOData, 1);
    acb->bs = bs;
    acb->aio_type = QEMU_AIO_IOCTL;
    acb->aio_fildes = s->fd;
    acb->aio_offset = 0;
    acb->aio_ioctl_buf = buf;
    acb->aio_ioctl_cmd = req;
    pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
    return thread_pool_submit_aio(pool, aio_worker, acb, cb, opaque);


static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs,

                                            const char *tag)

{

    BDRVBlkdebugState *s = bs->opaque;

    BlkdebugSuspendedReq *r, *r_next;

    BlkdebugRule *rule, *next;

    int i, ret = -ENOENT;

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

        QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {

            if (rule->action == ACTION_SUSPEND &&

                !strcmp(rule->options.suspend.tag, tag)) {

                remove_rule(rule);

                ret = 0;

            }

        }

    }

    QLIST_FOREACH_SAFE(r, &s->suspended_reqs, next, r_next) {

        if (!strcmp(r->tag, tag)) {

            qemu_coroutine_enter(r->co, NULL);

            ret = 0;

        }

    }

    return ret;

}


static int ram_save_target_page(MigrationState *ms, QEMUFile *f,

                                RAMBlock *block, ram_addr_t offset,

                                bool last_stage,

                                uint64_t *bytes_transferred,

                                ram_addr_t dirty_ram_abs)

{

    int res = 0;

    /* Check the pages is dirty and if it is send it */

    if (migration_bitmap_clear_dirty(dirty_ram_abs)) {

        unsigned long *unsentmap;

        if (compression_switch && migrate_use_compression()) {

            res = ram_save_compressed_page(f, block, offset,

                                           last_stage,

                                           bytes_transferred);

        } else {

            res = ram_save_page(f, block, offset, last_stage,

                                bytes_transferred);

        }

        if (res < 0) {

            return res;

        }

        unsentmap = atomic_rcu_read(&migration_bitmap_rcu)->unsentmap;

        if (unsentmap) {

            clear_bit(dirty_ram_abs >> TARGET_PAGE_BITS, unsentmap);

        }

        last_sent_block = block;

    }

    return res;

}


static inline void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,

                                        const uint16_t *ubuf0, const uint16_t *ubuf1,

                                        const uint16_t *vbuf0, const uint16_t *vbuf1,

                                        const uint16_t *abuf0, uint8_t *dest,

                                        int dstW, int uvalpha, enum PixelFormat dstFormat,

                                        int flags, int y)

{

    x86_reg uv_off = c->uv_off << 1;

    const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1

    if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

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

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2RGB1(%%REGBP, %5, %6)

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

            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

            "paddusb "BLUE_DITHER"(%5), %%mm2      \n\t"

            "paddusb "GREEN_DITHER"(%5), %%mm4      \n\t"

            "paddusb "RED_DITHER"(%5), %%mm5      \n\t"

#endif

            WRITERGB16(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither), "m"(uv_off)

        );

    } else {

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

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

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2RGB1b(%%REGBP, %5, %6)

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

            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

            "paddusb "BLUE_DITHER"(%5), %%mm2      \n\t"

            "paddusb "GREEN_DITHER"(%5), %%mm4      \n\t"

            "paddusb "RED_DITHER"(%5), %%mm5      \n\t"

#endif

            WRITERGB16(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither), "m"(uv_off)

        );

    }

}


static void coroutine_enter_cb(void *opaque, int ret)

{

    Coroutine *co = opaque;

    qemu_coroutine_enter(co, NULL);

}


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

                             target_ulong eaddr, int rw, int access_type)

{

    ppc_tlb_t *tlb;

    int nr, best, way;

    int ret;

    best = -1;

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

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

        nr = ppc6xx_tlb_getnum(env, eaddr, way,

                               access_type == ACCESS_CODE ? 1 : 0);

        tlb = &env->tlb[nr];

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

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

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "TLB %d/%d %s [%08x %08x] <> %08x\n",

                        nr, env->nb_tlb,

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

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

            }

#endif

            continue;

        }

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "TLB %d/%d %s %08x <> %08x %08x %c %c\n",

                    nr, env->nb_tlb,

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

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

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

        }

#endif

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

        case -3:

            /* TLB inconsistency */

            return -1;

        case -2:

            /* Access violation */

            ret = -2;

            best = nr;

            break;

        case -1:

        default:

            /* No match */

            break;

        case 0:

            /* access granted */

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

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

             *      result would be undefined if TLBs are not consistent.

             */

            ret = 0;

            best = nr;

            goto done;

        }

    }

    if (best != -1) {

    done:

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel > 0) {

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

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

        }

#endif

        /* Update page flags */

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

    }

    return ret;

}


int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)

{

    int err = 0;

    BlockDriverState *bs;

    BdrvNextIterator *it = NULL;

    while (err == 0 && (it = bdrv_next(it, &bs))) {

        AioContext *ctx = bdrv_get_aio_context(bs);

        aio_context_acquire(ctx);

        if (bdrv_can_snapshot(bs)) {

            err = bdrv_snapshot_goto(bs, name);

        }

        aio_context_release(ctx);

    }

    *first_bad_bs = bs;

    return err;

}


int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){

    int dst_index, i;

    int index= c->index;

    int frac= c->frac;

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

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

    int compensation_distance= c->compensation_distance;

    av_assert1(c->filter_shift == FILTER_SHIFT);

    av_assert1(c->felem_size == sizeof(FELEM));

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

        int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index;

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

        int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr;

        dst_size= FFMIN(dst_size, new_size);

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

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

            index2 += incr;

        }

        index += dst_index * dst_incr;

        index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;

        frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;

        av_assert2(index >= 0);

        *consumed= index;

        index = 0;

    } else if (compensation_distance == 0 && index >= 0) {

        int64_t end_index = (1 + src_size - c->filter_length) << c->phase_shift;

        int64_t delta_frac = (end_index - index) * c->src_incr - c->frac;

        int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr;

        int n = FFMIN(dst_size, delta_n);

        int sample_index;

        if (!c->linear) {

            sample_index = index >> c->phase_shift;

            index &= c->phase_mask;

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

                FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;

#ifdef COMMON_CORE

                COMMON_CORE

#else

                FELEM2 val=0;

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

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

                }

                OUT(dst[dst_index], val);

#endif

                frac += dst_incr_frac;

                index += dst_incr;

                if (frac >= c->src_incr) {

                    frac -= c->src_incr;

                    index++;

                }

                sample_index += index >> c->phase_shift;

                index &= c->phase_mask;

            }

        } else {

            sample_index = index >> c->phase_shift;

            index &= c->phase_mask;

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

                FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index;

                FELEM2 val=0, v2 = 0;

#ifdef LINEAR_CORE

                LINEAR_CORE

#else

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

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

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

                }

#endif

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

                OUT(dst[dst_index], val);

                frac += dst_incr_frac;

                index += dst_incr;

                if (frac >= c->src_incr) {

                    frac -= c->src_incr;

                    index++;

                }

                sample_index += index >> c->phase_shift;

                index &= c->phase_mask;

            }

        }

        *consumed = sample_index;

    } else {

        int sample_index = 0;

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

            FELEM *filter;

            FELEM2 val=0;

            sample_index += index >> c->phase_shift;

            index &= c->phase_mask;

            filter = ((FELEM*)c->filter_bank) + c->filter_alloc*index;

            if(sample_index + c->filter_length > src_size || -sample_index >= src_size){

                break;

            }else if(sample_index < 0){

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

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

                OUT(dst[dst_index], val);

            }else if(c->linear){

                FELEM2 v2=0;

#ifdef LINEAR_CORE

                LINEAR_CORE

#else

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

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

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

                }

#endif

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

                OUT(dst[dst_index], val);

            }else{

#ifdef COMMON_CORE

                COMMON_CORE

#else

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

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

                }

                OUT(dst[dst_index], val);

#endif

            }

            frac += dst_incr_frac;

            index += dst_incr;

            if(frac >= c->src_incr){

                frac -= c->src_incr;

                index++;

            }

            if(dst_index + 1 == compensation_distance){

                compensation_distance= 0;

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

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

            }

        }

        *consumed= FFMAX(sample_index, 0);

        index += FFMIN(sample_index, 0) << c->phase_shift;

        if(compensation_distance){

            compensation_distance -= dst_index;

            av_assert1(compensation_distance > 0);

        }

    }

    if(update_ctx){

        c->frac= frac;

        c->index= index;

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

        c->compensation_distance= compensation_distance;

    }

    return dst_index;

}


static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)

{

    TCGv t0;

#if !defined(CONFIG_USER_ONLY)

    /* The Linux kernel will emulate rdhwr if it's not supported natively.

       Therefore only check the ISA in system mode.  */

    check_insn(ctx, ISA_MIPS32R2);

#endif

    t0 = tcg_temp_new();

    switch (rd) {

    case 0:

        gen_helper_rdhwr_cpunum(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 1:

        gen_helper_rdhwr_synci_step(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 2:

        if (ctx->tb->cflags & CF_USE_ICOUNT) {

            gen_io_start();

        }

        gen_helper_rdhwr_cc(t0, cpu_env);

        if (ctx->tb->cflags & CF_USE_ICOUNT) {

            gen_io_end();

        }

        gen_store_gpr(t0, rt);

        /* Break the TB to be able to take timer interrupts immediately

           after reading count. BS_STOP isn't sufficient, we need to ensure

           we break completely out of translated code.  */

        gen_save_pc(ctx->pc + 4);

        ctx->bstate = BS_EXCP;

        break;

    case 3:

        gen_helper_rdhwr_ccres(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 4:

        check_insn(ctx, ISA_MIPS32R6);

        if (sel != 0) {

            /* Performance counter registers are not implemented other than

             * control register 0.

             */

            generate_exception(ctx, EXCP_RI);

        }

        gen_helper_rdhwr_performance(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 5:

        check_insn(ctx, ISA_MIPS32R6);

        gen_helper_rdhwr_xnp(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 29:

#if defined(CONFIG_USER_ONLY)

        tcg_gen_ld_tl(t0, cpu_env,

                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));

        gen_store_gpr(t0, rt);

        break;

#else

        if ((ctx->hflags & MIPS_HFLAG_CP0) ||

            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {

            tcg_gen_ld_tl(t0, cpu_env,

                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));

            gen_store_gpr(t0, rt);

        } else {

            generate_exception_end(ctx, EXCP_RI);

        }

        break;

#endif

    default:            /* Invalid */

        MIPS_INVAL("rdhwr");

        generate_exception_end(ctx, EXCP_RI);

        break;

    }

    tcg_temp_free(t0);

}


static int dca_subframe_footer(DCAContext *s, int base_channel)

{

    int in, out, aux_data_count, aux_data_end, reserved;

    uint32_t nsyncaux;

    /*

     * Unpack optional information

     */

    /* presumably optional information only appears in the core? */

    if (!base_channel) {

        if (s->timestamp)

            skip_bits_long(&s->gb, 32);

        if (s->aux_data) {

            aux_data_count = get_bits(&s->gb, 6);

            // align (32-bit)

            skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);

            aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb);

            if ((nsyncaux = get_bits_long(&s->gb, 32)) != DCA_NSYNCAUX) {

                av_log(s->avctx, AV_LOG_ERROR, "nSYNCAUX mismatch %#"PRIx32"\n",

                       nsyncaux);

                return AVERROR_INVALIDDATA;

            }

            if (get_bits1(&s->gb)) { // bAUXTimeStampFlag

                avpriv_request_sample(s->avctx,

                                      "Auxiliary Decode Time Stamp Flag");

                // align (4-bit)

                skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4);

                // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4)

                skip_bits_long(&s->gb, 44);

            }

            if ((s->core_downmix = get_bits1(&s->gb))) {

                int am = get_bits(&s->gb, 3);

                switch (am) {

                case 0:

                    s->core_downmix_amode = DCA_MONO;

                    break;

                case 1:

                    s->core_downmix_amode = DCA_STEREO;

                    break;

                case 2:

                    s->core_downmix_amode = DCA_STEREO_TOTAL;

                    break;

                case 3:

                    s->core_downmix_amode = DCA_3F;

                    break;

                case 4:

                    s->core_downmix_amode = DCA_2F1R;

                    break;

                case 5:

                    s->core_downmix_amode = DCA_2F2R;

                    break;

                case 6:

                    s->core_downmix_amode = DCA_3F1R;

                    break;

                default:

                    av_log(s->avctx, AV_LOG_ERROR,

                           "Invalid mode %d for embedded downmix coefficients\n",

                           am);

                    return AVERROR_INVALIDDATA;

                }

                for (out = 0; out < ff_dca_channels[s->core_downmix_amode]; out++) {

                    for (in = 0; in < s->audio_header.prim_channels + !!s->lfe; in++) {

                        uint16_t tmp = get_bits(&s->gb, 9);

                        if ((tmp & 0xFF) > 241) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "Invalid downmix coefficient code %"PRIu16"\n",

                                   tmp);

                            return AVERROR_INVALIDDATA;

                        }

                        s->core_downmix_codes[in][out] = tmp;

                    }

                }

            }

            align_get_bits(&s->gb); // byte align

            skip_bits(&s->gb, 16);  // nAUXCRC16

            // additional data (reserved, cf. ETSI TS 102 114 V1.4.1)

            if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) {

                av_log(s->avctx, AV_LOG_ERROR,

                       "Overread auxiliary data by %d bits\n", -reserved);

                return AVERROR_INVALIDDATA;

            } else if (reserved) {

                avpriv_request_sample(s->avctx,

                                      "Core auxiliary data reserved content");

                skip_bits_long(&s->gb, reserved);

            }

        }

        if (s->crc_present && s->dynrange)

            get_bits(&s->gb, 16);

    }

    return 0;

}


static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext *sl,

                                    int *mb_type)

{

    int b8_stride = 2;

    int b4_stride = h->b_stride;

    int mb_xy = sl->mb_xy, mb_y = sl->mb_y;

    int mb_type_col[2];

    const int16_t (*l1mv0)[2], (*l1mv1)[2];

    const int8_t *l1ref0, *l1ref1;

    const int is_b8x8 = IS_8X8(*mb_type);

    unsigned int sub_mb_type;

    int i8, i4;

    assert(sl->ref_list[1][0].reference & 3);

    await_reference_mb_row(h, sl->ref_list[1][0].parent,

                           sl->mb_y + !!IS_INTERLACED(*mb_type));

    if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL

        if (!IS_INTERLACED(*mb_type)) {                    //     AFR/FR    -> AFL/FL

            mb_y  = (sl->mb_y & ~1) + sl->col_parity;

            mb_xy = sl->mb_x +

                    ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;

            b8_stride = 0;

        } else {

            mb_y  += sl->col_fieldoff;

            mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity

        }

        goto single_col;

    } else {                                        // AFL/AFR/FR/FL -> AFR/FR

        if (IS_INTERLACED(*mb_type)) {              // AFL       /FL -> AFR/FR

            mb_y           = sl->mb_y & ~1;

            mb_xy          = sl->mb_x + (sl->mb_y & ~1) * h->mb_stride;

            mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];

            mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];

            b8_stride      = 2 + 4 * h->mb_stride;

            b4_stride     *= 6;

            if (IS_INTERLACED(mb_type_col[0]) !=

                IS_INTERLACED(mb_type_col[1])) {

                mb_type_col[0] &= ~MB_TYPE_INTERLACED;

                mb_type_col[1] &= ~MB_TYPE_INTERLACED;

            }

            sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |

                          MB_TYPE_DIRECT2;                  /* B_SUB_8x8 */

            if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&

                (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&

                !is_b8x8) {

                *mb_type |= MB_TYPE_16x8 | MB_TYPE_L0L1 |

                            MB_TYPE_DIRECT2;                /* B_16x8 */

            } else {

                *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;

            }

        } else {                                    //     AFR/FR    -> AFR/FR

single_col:

            mb_type_col[0]     =

                mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];

            sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |

                          MB_TYPE_DIRECT2;                  /* B_SUB_8x8 */

            if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {

                *mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |

                            MB_TYPE_DIRECT2;                /* B_16x16 */

            } else if (!is_b8x8 &&

                       (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {

                *mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 |

                            (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));

            } else {

                if (!h->ps.sps->direct_8x8_inference_flag) {

                    /* FIXME: save sub mb types from previous frames (or derive

                     * from MVs) so we know exactly what block size to use */

                    sub_mb_type = MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |

                                  MB_TYPE_DIRECT2;          /* B_SUB_4x4 */

                }

                *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;

            }

        }

    }

    await_reference_mb_row(h, sl->ref_list[1][0].parent, mb_y);

    l1mv0  = &sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];

    l1mv1  = &sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];

    l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];

    l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];

    if (!b8_stride) {

        if (sl->mb_y & 1) {

            l1ref0 += 2;

            l1ref1 += 2;

            l1mv0  += 2 * b4_stride;

            l1mv1  += 2 * b4_stride;

        }

    }

    {

        const int *map_col_to_list0[2] = { sl->map_col_to_list0[0],

                                           sl->map_col_to_list0[1] };

        const int *dist_scale_factor = sl->dist_scale_factor;

        int ref_offset;

        if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {

            map_col_to_list0[0] = sl->map_col_to_list0_field[sl->mb_y & 1][0];

            map_col_to_list0[1] = sl->map_col_to_list0_field[sl->mb_y & 1][1];

            dist_scale_factor   = sl->dist_scale_factor_field[sl->mb_y & 1];

        }

        ref_offset = (sl->ref_list[1][0].parent->mbaff << 4) & (mb_type_col[0] >> 3);

        if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {

            int y_shift = 2 * !IS_INTERLACED(*mb_type);

            assert(h->ps.sps->direct_8x8_inference_flag);

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

                const int x8 = i8 & 1;

                const int y8 = i8 >> 1;

                int ref0, scale;

                const int16_t (*l1mv)[2] = l1mv0;

                if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))

                    continue;

                sl->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);

                if (IS_INTRA(mb_type_col[y8])) {

                    fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);

                    fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);

                    continue;

                }

                ref0 = l1ref0[x8 + y8 * b8_stride];

                if (ref0 >= 0)

                    ref0 = map_col_to_list0[0][ref0 + ref_offset];

                else {

                    ref0 = map_col_to_list0[1][l1ref1[x8 + y8 * b8_stride] +

                                               ref_offset];

                    l1mv = l1mv1;

                }

                scale = dist_scale_factor[ref0];

                fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,

                               ref0, 1);

                {

                    const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride];

                    int my_col            = (mv_col[1] << y_shift) / 2;

                    int mx                = (scale * mv_col[0] + 128) >> 8;

                    int my                = (scale * my_col    + 128) >> 8;

                    fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,

                                   pack16to32(mx, my), 4);

                    fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,

                                   pack16to32(mx - mv_col[0], my - my_col), 4);

                }

            }

            return;

        }

        /* one-to-one mv scaling */

        if (IS_16X16(*mb_type)) {

            int ref, mv0, mv1;

            fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);

            if (IS_INTRA(mb_type_col[0])) {

                ref = mv0 = mv1 = 0;

            } else {

                const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]

                                                : map_col_to_list0[1][l1ref1[0] + ref_offset];

                const int scale = dist_scale_factor[ref0];

                const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];

                int mv_l0[2];

                mv_l0[0] = (scale * mv_col[0] + 128) >> 8;

                mv_l0[1] = (scale * mv_col[1] + 128) >> 8;

                ref      = ref0;

                mv0      = pack16to32(mv_l0[0], mv_l0[1]);

                mv1      = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]);

            }

            fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);

            fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);

            fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);

        } else {

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

                const int x8 = i8 & 1;

                const int y8 = i8 >> 1;

                int ref0, scale;

                const int16_t (*l1mv)[2] = l1mv0;

                if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))

                    continue;

                sl->sub_mb_type[i8] = sub_mb_type;

                fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);

                if (IS_INTRA(mb_type_col[0])) {

                    fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);

                    fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);

                    fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);

                    continue;

                }

                assert(b8_stride == 2);

                ref0 = l1ref0[i8];

                if (ref0 >= 0)

                    ref0 = map_col_to_list0[0][ref0 + ref_offset];

                else {

                    ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];

                    l1mv = l1mv1;

                }

                scale = dist_scale_factor[ref0];

                fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,

                               ref0, 1);

                if (IS_SUB_8X8(sub_mb_type)) {

                    const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];

                    int mx                = (scale * mv_col[0] + 128) >> 8;

                    int my                = (scale * mv_col[1] + 128) >> 8;

                    fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,

                                   pack16to32(mx, my), 4);

                    fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,

                                   pack16to32(mx - mv_col[0], my - mv_col[1]), 4);

                } else {

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

                        const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +

                                                     (y8 * 2 + (i4 >> 1)) * b4_stride];

                        int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]];

                        mv_l0[0] = (scale * mv_col[0] + 128) >> 8;

                        mv_l0[1] = (scale * mv_col[1] + 128) >> 8;

                        AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]],

                                 pack16to32(mv_l0[0] - mv_col[0],

                                            mv_l0[1] - mv_col[1]));

                    }

                }

            }

        }

    }

}


static void ff_mpeg4_init_direct_mv(MpegEncContext *s){

    //FIXME table is stored in MpegEncContext for thread-safety,

    // but a static array would be faster

    static const int tab_size = sizeof(s->direct_scale_mv[0])/sizeof(int16_t);

    static const int tab_bias = (tab_size/2);

    int i;

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

        s->direct_scale_mv[0][i] = (i-tab_bias)*s->pb_time/s->pp_time;

        s->direct_scale_mv[1][i] = (i-tab_bias)*(s->pb_time-s->pp_time)/s->pp_time;

    }

}


static void video_image_display(VideoState *is)

{

    Frame *vp;

    Frame *sp;

    AVPicture pict;

    SDL_Rect rect;

    int i;

    vp = frame_queue_peek(&is->pictq);

    if (vp->bmp) {

        if (is->subtitle_st) {

            if (frame_queue_nb_remaining(&is->subpq) > 0) {

                sp = frame_queue_peek(&is->subpq);

                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {

                    SDL_LockYUVOverlay (vp->bmp);

                    pict.data[0] = vp->bmp->pixels[0];

                    pict.data[1] = vp->bmp->pixels[2];

                    pict.data[2] = vp->bmp->pixels[1];

                    pict.linesize[0] = vp->bmp->pitches[0];

                    pict.linesize[1] = vp->bmp->pitches[2];

                    pict.linesize[2] = vp->bmp->pitches[1];

                    for (i = 0; i < sp->sub.num_rects; i++)

                        blend_subrect(&pict, sp->sub.rects[i],

                                      vp->bmp->w, vp->bmp->h);

                    SDL_UnlockYUVOverlay (vp->bmp);

                }

            }

        }

        calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp->width, vp->height, vp->sar);

        SDL_DisplayYUVOverlay(vp->bmp, &rect);

        if (rect.x != is->last_display_rect.x || rect.y != is->last_display_rect.y || rect.w != is->last_display_rect.w || rect.h != is->last_display_rect.h || is->force_refresh) {

            int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);

            fill_border(is->xleft, is->ytop, is->width, is->height, rect.x, rect.y, rect.w, rect.h, bgcolor, 1);

            is->last_display_rect = rect;

        }

    }

}


static int pad_count(const AVFilterPad *pads)

{

    int count;

    if (!pads)

        return 0;

    for(count = 0; pads->name; count ++) pads ++;

    return count;

}


rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply,

                 unsigned char **content_ptr, int return_on_interleaved_data)

{

    RTSPState *rt = s->priv_data;

    char buf[4096], buf1[1024], *q;

    unsigned char ch;

    const char *p;

    int ret, content_length, line_count = 0;

    unsigned char *content = NULL;

    memset(reply, 0, sizeof(*reply));

    /* parse reply (XXX: use buffers) */

    rt->last_reply[0] = '\0';

    for(;;) {

        q = buf;

        for(;;) {

            ret = url_read_complete(rt->rtsp_hd, &ch, 1);

#ifdef DEBUG_RTP_TCP

            dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);

#endif

            if (ret != 1)

                return -1;

            if (ch == '\n')

                break;

            if (ch == '$') {

                /* XXX: only parse it if first char on line ? */

                if (return_on_interleaved_data) {

                    return 1;

                } else

                rtsp_skip_packet(s);

            } else if (ch != '\r') {

                if ((q - buf) < sizeof(buf) - 1)

                    *q++ = ch;

            }

        }

        *q = '\0';

        dprintf(s, "line='%s'\n", buf);

        /* test if last line */

        if (buf[0] == '\0')

            break;

        p = buf;

        if (line_count == 0) {

            /* get reply code */

            get_word(buf1, sizeof(buf1), &p);

            get_word(buf1, sizeof(buf1), &p);

            reply->status_code = atoi(buf1);

        } else {

            rtsp_parse_line(reply, p);

            av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));

            av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));

        }

        line_count++;

    }

    if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')

        av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));

    content_length = reply->content_length;

    if (content_length > 0) {

        /* leave some room for a trailing '\0' (useful for simple parsing) */

        content = av_malloc(content_length + 1);

        (void)url_read_complete(rt->rtsp_hd, content, content_length);

        content[content_length] = '\0';

    }

    if (content_ptr)

        *content_ptr = content;

    else

        av_free(content);

    /* EOS */

    if (reply->notice == 2101 /* End-of-Stream Reached */      ||

        reply->notice == 2104 /* Start-of-Stream Reached */    ||

        reply->notice == 2306 /* Continuous Feed Terminated */)

        rt->state = RTSP_STATE_IDLE;

    else if (reply->notice >= 4400 && reply->notice < 5500)

        return AVERROR(EIO); /* data or server error */

    else if (reply->notice == 2401 /* Ticket Expired */ ||

             (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )

        return AVERROR(EPERM);

    return 0;

}


int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))

{

    int total = size;

    do {

        int len = FFMIN(f->end - f->wptr, size);

        if (func) {

            if (func(src, f->wptr, len) <= 0)

                break;

        } else {

            memcpy(f->wptr, src, len);

            src = (uint8_t*)src + len;

        }

// Write memory barrier needed for SMP here in theory

        f->wptr += len;

        if (f->wptr >= f->end)

            f->wptr = f->buffer;

        f->wndx += len;

        size -= len;

    } while (size > 0);

    return total - size;

}


int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)

{

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);

    int max_step     [4];       /* max pixel step for each plane */

    int max_step_comp[4];       /* the component for each plane which has the max pixel step */

    if ((unsigned)pix_fmt >= AV_PIX_FMT_NB || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)

        return AVERROR(EINVAL);

    av_image_fill_max_pixsteps(max_step, max_step_comp, desc);

    return image_get_linesize(width, plane, max_step[plane], max_step_comp[plane], desc);

}


static int encode_slice(AVCodecContext *c, void *arg)

{

    FFV1Context *fs  = *(void **)arg;

    FFV1Context *f   = fs->avctx->priv_data;

    int width        = fs->slice_width;

    int height       = fs->slice_height;

    int x            = fs->slice_x;

    int y            = fs->slice_y;

    const AVFrame *const p = f->frame;

    const int ps     = (av_pix_fmt_desc_get(c->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR)

                       ? (f->bits_per_raw_sample > 8) + 1

                       : 4;

    if (f->key_frame)

        ffv1_clear_slice_state(f, fs);

    if (f->version > 2) {

        encode_slice_header(f, fs);

    }

    if (!fs->ac) {

        if (f->version > 2)

            put_rac(&fs->c, (uint8_t[]) { 129 }, 0);

        fs->ac_byte_count = f->version > 2 || (!x && !y) ? ff_rac_terminate( &fs->c) : 0;

        init_put_bits(&fs->pb, fs->c.bytestream_start + fs->ac_byte_count,

                      fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count);

    }

    if (f->colorspace == 0) {

        const int chroma_width  = -((-width) >> f->chroma_h_shift);

        const int chroma_height = -((-height) >> f->chroma_v_shift);

        const int cx            = x >> f->chroma_h_shift;

        const int cy            = y >> f->chroma_v_shift;

        encode_plane(fs, p->data[0] + ps * x + y * p->linesize[0],

                     width, height, p->linesize[0], 0);

        if (f->chroma_planes) {

            encode_plane(fs, p->data[1] + ps * cx + cy * p->linesize[1],

                         chroma_width, chroma_height, p->linesize[1], 1);

            encode_plane(fs, p->data[2] + ps * cx + cy * p->linesize[2],

                         chroma_width, chroma_height, p->linesize[2], 1);

        }

        if (fs->transparency)

            encode_plane(fs, p->data[3] + ps * x + y * p->linesize[3], width,

                         height, p->linesize[3], 2);

    } else {

        const uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0],

                                     p->data[1] + ps * x + y * p->linesize[1],

                                     p->data[2] + ps * x + y * p->linesize[2] };

        encode_rgb_frame(fs, planes, width, height, p->linesize);

    }

    emms_c();

    return 0;

}


static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)

{

    BDRVRBDState *s = bs->opaque;

    char pool[RBD_MAX_POOL_NAME_SIZE];

    char snap_buf[RBD_MAX_SNAP_NAME_SIZE];

    char conf[RBD_MAX_CONF_SIZE];

    char clientname_buf[RBD_MAX_CONF_SIZE];

    char *clientname;

    int r;

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

                           snap_buf, sizeof(snap_buf),

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

                           conf, sizeof(conf)) < 0) {

        return -EINVAL;

    }

    s->snap = NULL;

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

        s->snap = g_strdup(snap_buf);

    }

    clientname = qemu_rbd_parse_clientname(conf, clientname_buf);

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

    if (r < 0) {

        error_report("error initializing");

        return r;

    }

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

        r = rados_conf_read_file(s->cluster, NULL);

        if (r < 0) {

            error_report("error reading config file");

            rados_shutdown(s->cluster);

            return r;

        }

    }

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

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

        if (r < 0) {

            error_report("error setting config options");

            rados_shutdown(s->cluster);

            return r;

        }

    }

    r = rados_connect(s->cluster);

    if (r < 0) {

        error_report("error connecting");

        rados_shutdown(s->cluster);

        return r;

    }

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

    if (r < 0) {

        error_report("error opening pool %s", pool);

        rados_shutdown(s->cluster);

        return r;

    }

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

    if (r < 0) {

        error_report("error reading header from %s", s->name);

        rados_ioctx_destroy(s->io_ctx);

        rados_shutdown(s->cluster);

        return r;

    }

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

    s->event_reader_pos = 0;

    r = qemu_pipe(s->fds);

    if (r < 0) {

        error_report("error opening eventfd");

        goto failed;

    }

    fcntl(s->fds[0], F_SETFL, O_NONBLOCK);

    fcntl(s->fds[1], F_SETFL, O_NONBLOCK);

    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader,

                            NULL, qemu_rbd_aio_flush_cb, NULL, s);

    return 0;

failed:

    rbd_close(s->image);

    rados_ioctx_destroy(s->io_ctx);

    rados_shutdown(s->cluster);

    return r;

}


static inline int coupling_strategy(AC3DecodeContext *s, int blk,

                                    uint8_t *bit_alloc_stages)

{

    GetBitContext *bc = &s->gbc;

    int fbw_channels = s->fbw_channels;

    int channel_mode = s->channel_mode;

    int ch;

    memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);

    if (!s->eac3)

        s->cpl_in_use[blk] = get_bits1(bc);

    if (s->cpl_in_use[blk]) {

        /* coupling in use */

        int cpl_start_subband, cpl_end_subband;

        if (channel_mode < AC3_CHMODE_STEREO) {

            av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");

            return AVERROR_INVALIDDATA;

        }

        /* check for enhanced coupling */

        if (s->eac3 && get_bits1(bc)) {

            /* TODO: parse enhanced coupling strategy info */

            avpriv_request_sample(s->avctx, "Enhanced coupling");

            return AVERROR_PATCHWELCOME;

        }

        /* determine which channels are coupled */

        if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {

            s->channel_in_cpl[1] = 1;

            s->channel_in_cpl[2] = 1;

        } else {

            for (ch = 1; ch <= fbw_channels; ch++)

                s->channel_in_cpl[ch] = get_bits1(bc);

        }

        /* phase flags in use */

        if (channel_mode == AC3_CHMODE_STEREO)

            s->phase_flags_in_use = get_bits1(bc);

        /* coupling frequency range */

        cpl_start_subband = get_bits(bc, 4);

        cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 :

                                          get_bits(bc, 4) + 3;

        if (cpl_start_subband >= cpl_end_subband) {

            av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n",

                   cpl_start_subband, cpl_end_subband);

            return AVERROR_INVALIDDATA;

        }

        s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;

        s->end_freq[CPL_CH]   = cpl_end_subband   * 12 + 37;

        decode_band_structure(bc, blk, s->eac3, 0, cpl_start_subband,

                              cpl_end_subband,

                              ff_eac3_default_cpl_band_struct,

                              &s->num_cpl_bands, s->cpl_band_sizes);

    } else {

        /* coupling not in use */

        for (ch = 1; ch <= fbw_channels; ch++) {

            s->channel_in_cpl[ch] = 0;

            s->first_cpl_coords[ch] = 1;

        }

        s->first_cpl_leak = s->eac3;

        s->phase_flags_in_use = 0;

    }

    return 0;

}


static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf)

{

    int tag, type, count, off, value = 0;

    int i, j;

    uint32_t *pal;

    const uint8_t *rp, *gp, *bp;

    tag = tget_short(&buf, s->le);

    type = tget_short(&buf, s->le);

    count = tget_long(&buf, s->le);

    off = tget_long(&buf, s->le);

    if(count == 1){

        switch(type){

        case TIFF_BYTE:

        case TIFF_SHORT:

            buf -= 4;

            value = tget(&buf, type, s->le);

            buf = NULL;

            break;

        case TIFF_LONG:

            value = off;

            buf = NULL;

            break;

        case TIFF_STRING:

            if(count <= 4){

                buf -= 4;

                break;

            }

        default:

            value = -1;

            buf = start + off;

        }

    }else if(type_sizes[type] * count <= 4){

        buf -= 4;

    }else{

        buf = start + off;

    }

    if(buf && (buf < start || buf > end_buf)){

        av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");

        return -1;

    }

    switch(tag){

    case TIFF_WIDTH:

        s->width = value;

        break;

    case TIFF_HEIGHT:

        s->height = value;

        break;

    case TIFF_BPP:

        if(count == 1) s->bpp = value;

        else{

            switch(type){

            case TIFF_BYTE:

                s->bpp = (off & 0xFF) + ((off >> 8) & 0xFF) + ((off >> 16) & 0xFF) + ((off >> 24) & 0xFF);

                break;

            case TIFF_SHORT:

            case TIFF_LONG:

                s->bpp = 0;

                for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le);

                break;

            default:

                s->bpp = -1;

            }

        }

        switch(s->bpp){

        case 1:

            s->avctx->pix_fmt = PIX_FMT_MONOBLACK;

            break;

        case 8:

            s->avctx->pix_fmt = PIX_FMT_PAL8;

            break;

        case 24:

            s->avctx->pix_fmt = PIX_FMT_RGB24;

            break;

        case 16:

            if(count == 1){

                s->avctx->pix_fmt = PIX_FMT_GRAY16BE;

            }else{

                av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%i)\n", s->bpp);

                return -1;

            }

            break;

        case 32:

            if(count == 4){

                s->avctx->pix_fmt = PIX_FMT_RGBA;

            }else{

                av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count);

                return -1;

            }

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count);

            return -1;

        }

        if(s->width != s->avctx->width || s->height != s->avctx->height){

            if(avcodec_check_dimensions(s->avctx, s->width, s->height))

                return -1;

            avcodec_set_dimensions(s->avctx, s->width, s->height);

        }

        if(s->picture.data[0])

            s->avctx->release_buffer(s->avctx, &s->picture);

        if(s->avctx->get_buffer(s->avctx, &s->picture) < 0){

            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");

            return -1;

        }

        if(s->bpp == 8){

            /* make default grayscale pal */

            pal = (uint32_t *) s->picture.data[1];

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

                pal[i] = i * 0x010101;

        }

        break;

    case TIFF_COMPR:

        s->compr = value;

        s->predictor = 0;

        switch(s->compr){

        case TIFF_RAW:

        case TIFF_PACKBITS:

        case TIFF_LZW:

        case TIFF_CCITT_RLE:

            break;

        case TIFF_G3:

        case TIFF_G4:

            s->fax_opts = 0;

            break;

        case TIFF_DEFLATE:

        case TIFF_ADOBE_DEFLATE:

#if CONFIG_ZLIB

            break;

#else

            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");

            return -1;

#endif

        case TIFF_JPEG:

        case TIFF_NEWJPEG:

            av_log(s->avctx, AV_LOG_ERROR, "JPEG compression is not supported\n");

            return -1;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr);

            return -1;

        }

        break;

    case TIFF_ROWSPERSTRIP:

        if(type == TIFF_LONG && value == -1)

            value = s->avctx->height;

        if(value < 1){

            av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n");

            return -1;

        }

        s->rps = value;

        break;

    case TIFF_STRIP_OFFS:

        if(count == 1){

            s->stripdata = NULL;

            s->stripoff = value;

        }else

            s->stripdata = start + off;

        s->strips = count;

        if(s->strips == 1) s->rps = s->height;

        s->sot = type;

        if(s->stripdata > end_buf){

            av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");

            return -1;

        }

        break;

    case TIFF_STRIP_SIZE:

        if(count == 1){

            s->stripsizes = NULL;

            s->stripsize = value;

            s->strips = 1;

        }else{

            s->stripsizes = start + off;

        }

        s->strips = count;

        s->sstype = type;

        if(s->stripsizes > end_buf){

            av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n");

            return -1;

        }

        break;

    case TIFF_PREDICTOR:

        s->predictor = value;

        break;

    case TIFF_INVERT:

        switch(value){

        case 0:

            s->invert = 1;

            break;

        case 1:

            s->invert = 0;

            break;

        case 2:

        case 3:

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Color mode %d is not supported\n", value);

            return -1;

        }

        break;

    case TIFF_PAL:

        if(s->avctx->pix_fmt != PIX_FMT_PAL8){

            av_log(s->avctx, AV_LOG_ERROR, "Palette met but this is not palettized format\n");

            return -1;

        }

        pal = (uint32_t *) s->picture.data[1];

        off = type_sizes[type];

        rp = buf;

        gp = buf + count / 3 * off;

        bp = buf + count / 3 * off * 2;

        off = (type_sizes[type] - 1) << 3;

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

            j = (tget(&rp, type, s->le) >> off) << 16;

            j |= (tget(&gp, type, s->le) >> off) << 8;

            j |= tget(&bp, type, s->le) >> off;

            pal[i] = j;

        }

        break;

    case TIFF_PLANAR:

        if(value == 2){

            av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n");

            return -1;

        }

        break;

    case TIFF_T4OPTIONS:

    case TIFF_T6OPTIONS:

        s->fax_opts = value;

        break;

    }

    return 0;

}


static int slirp_hostfwd(SlirpState *s, const char *redir_str,

                         int legacy_format)

{

    struct in_addr host_addr = { .s_addr = INADDR_ANY };

    struct in_addr guest_addr = { .s_addr = 0 };

    int host_port, guest_port;

    const char *p;

    char buf[256];

    int is_udp;

    char *end;

    p = redir_str;

    if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (!strcmp(buf, "tcp") || buf[0] == '\0') {

        is_udp = 0;

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

        is_udp = 1;

    } else {

        goto fail_syntax;

    }

    if (!legacy_format) {

        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

            goto fail_syntax;

        }

        if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {

            goto fail_syntax;

        }

    }

    if (get_str_sep(buf, sizeof(buf), &p, legacy_format ? ':' : '-') < 0) {

        goto fail_syntax;

    }

    host_port = strtol(buf, &end, 0);

    if (*end != '\0' || host_port < 0 || host_port > 65535) {

        goto fail_syntax;

    }

    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {

        goto fail_syntax;

    }

    guest_port = strtol(p, &end, 0);

    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {

        goto fail_syntax;

    }

    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,

                          guest_port) < 0) {

        error_report("could not set up host forwarding rule '%s'",

                     redir_str);

        return -1;

    }

    return 0;

 fail_syntax:

    error_report("invalid host forwarding rule '%s'", redir_str);

    return -1;

}


int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
{
    if (dma_has_iommu(dma)) {
        return iommu_dma_memory_set(dma, addr, c, len);
    }
    do_dma_memory_set(addr, c, len);
    return 0;
}


static int loadvm_postcopy_handle_run(MigrationIncomingState *mis)

{

    PostcopyState ps = postcopy_state_set(POSTCOPY_INCOMING_RUNNING);

    trace_loadvm_postcopy_handle_run();

    if (ps != POSTCOPY_INCOMING_LISTENING) {

        error_report("CMD_POSTCOPY_RUN in wrong postcopy state (%d)", ps);

        return -1;

    }

    mis->bh = qemu_bh_new(loadvm_postcopy_handle_run_bh, NULL);

    qemu_bh_schedule(mis->bh);

    /* We need to finish reading the stream from the package

     * and also stop reading anything more from the stream that loaded the

     * package (since it's now being read by the listener thread).

     * LOADVM_QUIT will quit all the layers of nested loadvm loops.

     */

    return LOADVM_QUIT;

}


int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,

                                             uint8_t *buf, int buf_size,

                                             const short *samples)

{

    AVPacket pkt;

    AVFrame *frame;

    int ret, samples_size, got_packet;

    av_init_packet(&pkt);

    pkt.data = buf;

    pkt.size = buf_size;

    if (samples) {

        frame = av_frame_alloc();

        if (avctx->frame_size) {

            frame->nb_samples = avctx->frame_size;

        } else {

            /* if frame_size is not set, the number of samples must be

             * calculated from the buffer size */

            int64_t nb_samples;

            if (!av_get_bits_per_sample(avctx->codec_id)) {

                av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not "

                                            "support this codec\n");

                av_frame_free(&frame);

                return AVERROR(EINVAL);

            }

            nb_samples = (int64_t)buf_size * 8 /

                         (av_get_bits_per_sample(avctx->codec_id) *

                          avctx->channels);

            if (nb_samples >= INT_MAX) {

                av_frame_free(&frame);

                return AVERROR(EINVAL);

            }

            frame->nb_samples = nb_samples;

        }

        /* it is assumed that the samples buffer is large enough based on the

         * relevant parameters */

        samples_size = av_samples_get_buffer_size(NULL, avctx->channels,

                                                  frame->nb_samples,

                                                  avctx->sample_fmt, 1);

        if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,

                                            avctx->sample_fmt,

                                            (const uint8_t *)samples,

                                            samples_size, 1)) < 0) {

            av_frame_free(&frame);

            return ret;

        }

        /* fabricate frame pts from sample count.

         * this is needed because the avcodec_encode_audio() API does not have

         * a way for the user to provide pts */

        if (avctx->sample_rate && avctx->time_base.num)

            frame->pts = ff_samples_to_time_base(avctx,

                                                 avctx->internal->sample_count);

        else

            frame->pts = AV_NOPTS_VALUE;

        avctx->internal->sample_count += frame->nb_samples;

    } else {

        frame = NULL;

    }

    got_packet = 0;

    ret = avcodec_encode_audio2(avctx, &pkt, frame, &got_packet);

    if (!ret && got_packet && avctx->coded_frame) {

        avctx->coded_frame->pts       = pkt.pts;

        avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);

    }

    /* free any side data since we cannot return it */

    av_packet_free_side_data(&pkt);

    if (frame && frame->extended_data != frame->data)

        av_freep(&frame->extended_data);

    av_frame_free(&frame);

    return ret ? ret : pkt.size;

}


void main_loop_wait(int nonblocking)

{

    IOHandlerRecord *ioh;

    fd_set rfds, wfds, xfds;

    int ret, nfds;

    struct timeval tv;

    int timeout;

    if (nonblocking)

        timeout = 0;

    else {

        timeout = qemu_calculate_timeout();

        qemu_bh_update_timeout(&timeout);

    }

    os_host_main_loop_wait(&timeout);

    /* poll any events */

    /* XXX: separate device handlers from system ones */

    nfds = -1;

    FD_ZERO(&rfds);

    FD_ZERO(&wfds);

    FD_ZERO(&xfds);

    QLIST_FOREACH(ioh, &io_handlers, next) {

        if (ioh->deleted)

            continue;

        if (ioh->fd_read &&

            (!ioh->fd_read_poll ||

             ioh->fd_read_poll(ioh->opaque) != 0)) {

            FD_SET(ioh->fd, &rfds);

            if (ioh->fd > nfds)

                nfds = ioh->fd;

        }

        if (ioh->fd_write) {

            FD_SET(ioh->fd, &wfds);

            if (ioh->fd > nfds)

                nfds = ioh->fd;

        }

    }

    tv.tv_sec = timeout / 1000;

    tv.tv_usec = (timeout % 1000) * 1000;

    slirp_select_fill(&nfds, &rfds, &wfds, &xfds);

    qemu_mutex_unlock_iothread();

    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);

    qemu_mutex_lock_iothread();

    if (ret > 0) {

        IOHandlerRecord *pioh;

        QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {

            if (ioh->deleted) {

                QLIST_REMOVE(ioh, next);

                qemu_free(ioh);

                continue;

            }

            if (ioh->fd_read && FD_ISSET(ioh->fd, &rfds)) {

                ioh->fd_read(ioh->opaque);

            }

            if (ioh->fd_write && FD_ISSET(ioh->fd, &wfds)) {

                ioh->fd_write(ioh->opaque);

            }

        }

    }

    slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));

    qemu_run_all_timers();

    /* Check bottom-halves last in case any of the earlier events triggered

       them.  */

    qemu_bh_poll();

}


static void gen_lswx(DisasContext *ctx)

{

    TCGv t0;

    TCGv_i32 t1, t2, t3;

    gen_set_access_type(ctx, ACCESS_INT);

    /* NIP cannot be restored if the memory exception comes from an helper */

    gen_update_nip(ctx, ctx->nip - 4);

    t0 = tcg_temp_new();

    gen_addr_reg_index(ctx, t0);

    t1 = tcg_const_i32(rD(ctx->opcode));

    t2 = tcg_const_i32(rA(ctx->opcode));

    t3 = tcg_const_i32(rB(ctx->opcode));

    gen_helper_lswx(cpu_env, t0, t1, t2, t3);

    tcg_temp_free(t0);

    tcg_temp_free_i32(t1);

    tcg_temp_free_i32(t2);

    tcg_temp_free_i32(t3);

}


static void get_sensor_reading(IPMIBmcSim *ibs,

                               uint8_t *cmd, unsigned int cmd_len,

                               uint8_t *rsp, unsigned int *rsp_len,

                               unsigned int max_rsp_len)

{

    IPMISensor *sens;

    IPMI_CHECK_CMD_LEN(3);

    if ((cmd[2] > MAX_SENSORS) ||

            !IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {

        rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;

        return;

    }

    sens = ibs->sensors + cmd[2];

    IPMI_ADD_RSP_DATA(sens->reading);

    IPMI_ADD_RSP_DATA(IPMI_SENSOR_GET_RET_STATUS(sens));

    IPMI_ADD_RSP_DATA(sens->states & 0xff);

    if (IPMI_SENSOR_IS_DISCRETE(sens)) {

        IPMI_ADD_RSP_DATA((sens->states >> 8) & 0xff);

    }

}


int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, void *buf,
                       uint32_t size)
{
#ifdef DEBUG_TCE
    fprintf(stderr, "spapr_tce_dma_write taddr=0x%llx size=0x%x\n",
            (unsigned long long)taddr, size);
#endif
    while (size) {
        uint64_t tce;
        uint32_t lsize;
        uint64_t txaddr;
        /* Check if we are in bound */
        if (taddr >= dev->rtce_window_size) {
#ifdef DEBUG_TCE
            fprintf(stderr, "spapr_tce_dma_read out of bounds\n");
#endif
            return H_DEST_PARM;
        tce = dev->rtce_table[taddr >> SPAPR_VIO_TCE_PAGE_SHIFT].tce;
        /* How much til end of page ? */
        lsize = MIN(size, ((~taddr) & SPAPR_VIO_TCE_PAGE_MASK) + 1);
        /* Check TCE */
        if (!(tce & 1)) {
            return H_DEST_PARM;
        /* Translate */
        txaddr = (tce & ~SPAPR_VIO_TCE_PAGE_MASK) |
            (taddr & SPAPR_VIO_TCE_PAGE_MASK);
#ifdef DEBUG_TCE
        fprintf(stderr, " -> write to txaddr=0x%llx, size=0x%x\n",
                (unsigned long long)txaddr, lsize);
#endif
        /* Do it */
        cpu_physical_memory_read(txaddr, buf, lsize);
        buf += lsize;
        taddr += lsize;
        size -= lsize;
    return H_SUCCESS;


static inline void RENAME(rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)

{

    const uint8_t *s = src;

    const uint8_t *end;

    const uint8_t *mm_end;

    uint16_t *d = (uint16_t *)dst;

    end = s + src_size;

    __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");

    __asm__ volatile(

        "movq          %0, %%mm7    \n\t"

        "movq          %1, %%mm6    \n\t"

        ::"m"(red_15mask),"m"(green_15mask));

    mm_end = end - 15;

    while (s < mm_end) {

        __asm__ volatile(

            PREFETCH"    32%1           \n\t"

            "movd          %1, %%mm0    \n\t"

            "movd         4%1, %%mm3    \n\t"

            "punpckldq    8%1, %%mm0    \n\t"

            "punpckldq   12%1, %%mm3    \n\t"

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

            "movq       %%mm0, %%mm2    \n\t"

            "movq       %%mm3, %%mm4    \n\t"

            "movq       %%mm3, %%mm5    \n\t"

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

            "psllq         $7, %%mm3    \n\t"

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

            "pand       %%mm7, %%mm3    \n\t"

            "psrlq         $6, %%mm1    \n\t"

            "psrlq         $6, %%mm4    \n\t"

            "pand       %%mm6, %%mm1    \n\t"

            "pand       %%mm6, %%mm4    \n\t"

            "psrlq        $19, %%mm2    \n\t"

            "psrlq        $19, %%mm5    \n\t"

            "pand          %2, %%mm2    \n\t"

            "pand          %2, %%mm5    \n\t"

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

            "por        %%mm4, %%mm3    \n\t"

            "por        %%mm2, %%mm0    \n\t"

            "por        %%mm5, %%mm3    \n\t"

            "psllq        $16, %%mm3    \n\t"

            "por        %%mm3, %%mm0    \n\t"

            MOVNTQ"     %%mm0, %0       \n\t"

            :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");

        d += 4;

        s += 16;

    }

    __asm__ volatile(SFENCE:::"memory");

    __asm__ volatile(EMMS:::"memory");

    while (s < end) {

        register int rgb = *(const uint32_t*)s; s += 4;

        *d++ = ((rgb&0xF8)<<7) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>19);

    }

}


void usb_test_hotplug(const char *hcd_id, const int port,

                      void (*port_check)(void))

{

    QDict *response;

    char  *cmd;

    cmd = g_strdup_printf("{'execute': 'device_add',"

                          " 'arguments': {"

                          "   'driver': 'usb-tablet',"

                          "   'port': '%d',"

                          "   'bus': '%s.0',"

                          "   'id': 'usbdev%d'"

                          "}}", port, hcd_id, port);

    response = qmp(cmd);

    g_free(cmd);

    g_assert(response);

    g_assert(!qdict_haskey(response, "error"));

    if (port_check) {

        port_check();

    }

    cmd = g_strdup_printf("{'execute': 'device_del',"

                           " 'arguments': {"

                           "   'id': 'usbdev%d'"

                           "}}", port);

    response = qmp(cmd);

    g_free(cmd);

    g_assert(response);

    g_assert(qdict_haskey(response, "event"));

    g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));

}


static inline int target_to_host_errno(int err)

{

    if (target_to_host_errno_table[err])

        return target_to_host_errno_table[err];

    return err;

}


int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,

                        uint8_t ar)

{

    CPUS390XState *env = &cpu->env;

    S390PCIBusDevice *pbdev;

    MemoryRegion *mr;

    int i;

    uint32_t fh;

    uint8_t pcias;

    uint8_t len;

    uint8_t buffer[128];

    if (env->psw.mask & PSW_MASK_PSTATE) {

        program_interrupt(env, PGM_PRIVILEGED, 6);

        return 0;

    }

    fh = env->regs[r1] >> 32;

    pcias = (env->regs[r1] >> 16) & 0xf;

    len = env->regs[r1] & 0xff;

    if (pcias > 5) {

        DPRINTF("pcistb invalid space\n");

        setcc(cpu, ZPCI_PCI_LS_ERR);

        s390_set_status_code(env, r1, ZPCI_PCI_ST_INVAL_AS);

        return 0;

    }

    switch (len) {

    case 16:

    case 32:

    case 64:

    case 128:

        break;

    default:

        program_interrupt(env, PGM_SPECIFICATION, 6);

        return 0;

    }

    pbdev = s390_pci_find_dev_by_fh(fh);

    if (!pbdev) {

        DPRINTF("pcistb no pci dev fh 0x%x\n", fh);

        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);

        return 0;

    }

    switch (pbdev->state) {

    case ZPCI_FS_RESERVED:

    case ZPCI_FS_STANDBY:

    case ZPCI_FS_DISABLED:

    case ZPCI_FS_PERMANENT_ERROR:

        setcc(cpu, ZPCI_PCI_LS_INVAL_HANDLE);

        return 0;

    case ZPCI_FS_ERROR:

        setcc(cpu, ZPCI_PCI_LS_ERR);

        s390_set_status_code(env, r1, ZPCI_PCI_ST_BLOCKED);

        return 0;

    default:

        break;

    }

    mr = pbdev->pdev->io_regions[pcias].memory;

    if (!memory_region_access_valid(mr, env->regs[r3], len, true)) {

        program_interrupt(env, PGM_ADDRESSING, 6);

        return 0;

    }

    if (s390_cpu_virt_mem_read(cpu, gaddr, ar, buffer, len)) {

        return 0;

    }

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

        memory_region_dispatch_write(mr, env->regs[r3] + i * 8,

                                     ldq_p(buffer + i * 8), 8,

                                     MEMTXATTRS_UNSPECIFIED);

    }

    setcc(cpu, ZPCI_PCI_LS_OK);

    return 0;

}