static void test_cancel(void)

{

    WorkerTestData data[100];

    int num_canceled;

    int i;

    /* Start more work items than there will be threads, to ensure

     * the pool is full.

     */

    test_submit_many();

    /* Start long running jobs, to ensure we can cancel some.  */

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

        data[i].n = 0;

        data[i].ret = -EINPROGRESS;

        data[i].aiocb = thread_pool_submit_aio(pool, long_cb, &data[i],

                                               done_cb, &data[i]);

    }

    /* Starting the threads may be left to a bottom half.  Let it

     * run, but do not waste too much time...

     */

    active = 100;

    aio_notify(ctx);

    aio_poll(ctx, false);

    /* Wait some time for the threads to start, with some sanity

     * testing on the behavior of the scheduler...

     */

    g_assert_cmpint(active, ==, 100);

    g_usleep(1000000);

    g_assert_cmpint(active, >, 50);

    /* Cancel the jobs that haven't been started yet.  */

    num_canceled = 0;

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

        if (atomic_cmpxchg(&data[i].n, 0, 3) == 0) {

            data[i].ret = -ECANCELED;

            bdrv_aio_cancel(data[i].aiocb);

            active--;

            num_canceled++;

        }

    }

    g_assert_cmpint(active, >, 0);

    g_assert_cmpint(num_canceled, <, 100);

    /* Canceling the others will be a blocking operation.  */

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

        if (data[i].n != 3) {

            bdrv_aio_cancel(data[i].aiocb);

        }

    }

    /* Finish execution and execute any remaining callbacks.  */

    qemu_aio_wait_all();

    g_assert_cmpint(active, ==, 0);

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

        if (data[i].n == 3) {

            g_assert_cmpint(data[i].ret, ==, -ECANCELED);

            g_assert(data[i].aiocb != NULL);

        } else {

            g_assert_cmpint(data[i].n, ==, 2);

            g_assert_cmpint(data[i].ret, ==, 0);

            g_assert(data[i].aiocb == NULL);

        }

    }

}


static void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)

{

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

        gen_io_start();

    }

    gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);

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

        gen_io_end();

        gen_stop_exception(ctx);

    }

}


static void coroutine_fn commit_run(void *opaque)

{

    CommitBlockJob *s = opaque;

    BlockDriverState *active = s->active;

    BlockDriverState *top = s->top;

    BlockDriverState *base = s->base;

    BlockDriverState *overlay_bs = NULL;

    int64_t sector_num, end;

    int ret = 0;

    int n = 0;

    void *buf;

    int bytes_written = 0;

    int64_t base_len;

    ret = s->common.len = bdrv_getlength(top);

    if (s->common.len < 0) {

        goto exit_restore_reopen;

    }

    ret = base_len = bdrv_getlength(base);

    if (base_len < 0) {

        goto exit_restore_reopen;

    }

    if (base_len < s->common.len) {

        ret = bdrv_truncate(base, s->common.len);

        if (ret) {

            goto exit_restore_reopen;

        }

    }

    overlay_bs = bdrv_find_overlay(active, top);

    end = s->common.len >> BDRV_SECTOR_BITS;

    buf = qemu_blockalign(top, COMMIT_BUFFER_SIZE);

    for (sector_num = 0; sector_num < end; sector_num += n) {

        uint64_t delay_ns = 0;

        bool copy;

wait:

        /* Note that even when no rate limit is applied we need to yield

         * with no pending I/O here so that bdrv_drain_all() returns.

         */

        block_job_sleep_ns(&s->common, rt_clock, delay_ns);

        if (block_job_is_cancelled(&s->common)) {

            break;

        }

        /* Copy if allocated above the base */

        ret = bdrv_co_is_allocated_above(top, base, sector_num,

                                         COMMIT_BUFFER_SIZE / BDRV_SECTOR_SIZE,

                                         &n);

        copy = (ret == 1);

        trace_commit_one_iteration(s, sector_num, n, ret);

        if (copy) {

            if (s->common.speed) {

                delay_ns = ratelimit_calculate_delay(&s->limit, n);

                if (delay_ns > 0) {

                    goto wait;

                }

            }

            ret = commit_populate(top, base, sector_num, n, buf);

            bytes_written += n * BDRV_SECTOR_SIZE;

        }

        if (ret < 0) {

            if (s->on_error == BLOCKDEV_ON_ERROR_STOP ||

                s->on_error == BLOCKDEV_ON_ERROR_REPORT||

                (s->on_error == BLOCKDEV_ON_ERROR_ENOSPC && ret == -ENOSPC)) {

                goto exit_free_buf;

            } else {

                n = 0;

                continue;

            }

        }

        /* Publish progress */

        s->common.offset += n * BDRV_SECTOR_SIZE;

    }

    ret = 0;

    if (!block_job_is_cancelled(&s->common) && sector_num == end) {

        /* success */

        ret = bdrv_drop_intermediate(active, top, base);

    }

exit_free_buf:

    qemu_vfree(buf);

exit_restore_reopen:

    /* restore base open flags here if appropriate (e.g., change the base back

     * to r/o). These reopens do not need to be atomic, since we won't abort

     * even on failure here */

    if (s->base_flags != bdrv_get_flags(base)) {

        bdrv_reopen(base, s->base_flags, NULL);

    }

    if (s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {

        bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);

    }

    block_job_completed(&s->common, ret);

}


static inline long double compute_read_bwidth(void)

{

    assert(block_mig_state.total_time != 0);

    return  (block_mig_state.reads * BLOCK_SIZE)/ block_mig_state.total_time;

}


size_t v9fs_unmarshal(struct iovec *out_sg, int out_num, size_t offset,

                      int bswap, const char *fmt, ...)

{

    int i;

    va_list ap;

    size_t old_offset = offset;

    va_start(ap, fmt);

    for (i = 0; fmt[i]; i++) {

        switch (fmt[i]) {

        case 'b': {

            uint8_t *valp = va_arg(ap, uint8_t *);

            offset += v9fs_unpack(valp, out_sg, out_num, offset, sizeof(*valp));

            break;

        }

        case 'w': {

            uint16_t val, *valp;

            valp = va_arg(ap, uint16_t *);

            offset += v9fs_unpack(&val, out_sg, out_num, offset, sizeof(val));

            if (bswap) {

                *valp = le16_to_cpu(val);

            } else {

                *valp = val;

            }

            break;

        }

        case 'd': {

            uint32_t val, *valp;

            valp = va_arg(ap, uint32_t *);

            offset += v9fs_unpack(&val, out_sg, out_num, offset, sizeof(val));

            if (bswap) {

                *valp = le32_to_cpu(val);

            } else {

                *valp = val;

            }

            break;

        }

        case 'q': {

            uint64_t val, *valp;

            valp = va_arg(ap, uint64_t *);

            offset += v9fs_unpack(&val, out_sg, out_num, offset, sizeof(val));

            if (bswap) {

                *valp = le64_to_cpu(val);

            } else {

                *valp = val;

            }

            break;

        }

        case 's': {

            V9fsString *str = va_arg(ap, V9fsString *);

            offset += v9fs_unmarshal(out_sg, out_num, offset, bswap,

                            "w", &str->size);

            /* FIXME: sanity check str->size */

            str->data = g_malloc(str->size + 1);

            offset += v9fs_unpack(str->data, out_sg, out_num, offset,

                            str->size);

            str->data[str->size] = 0;

            break;

        }

        case 'Q': {

            V9fsQID *qidp = va_arg(ap, V9fsQID *);

            offset += v9fs_unmarshal(out_sg, out_num, offset, bswap, "bdq",

                                     &qidp->type, &qidp->version, &qidp->path);

            break;

        }

        case 'S': {

            V9fsStat *statp = va_arg(ap, V9fsStat *);

            offset += v9fs_unmarshal(out_sg, out_num, offset, bswap,

                                    "wwdQdddqsssssddd",

                                     &statp->size, &statp->type, &statp->dev,

                                     &statp->qid, &statp->mode, &statp->atime,

                                     &statp->mtime, &statp->length,

                                     &statp->name, &statp->uid, &statp->gid,

                                     &statp->muid, &statp->extension,

                                     &statp->n_uid, &statp->n_gid,

                                     &statp->n_muid);

            break;

        }

        case 'I': {

            V9fsIattr *iattr = va_arg(ap, V9fsIattr *);

            offset += v9fs_unmarshal(out_sg, out_num, offset, bswap,

                                     "ddddqqqqq",

                                     &iattr->valid, &iattr->mode,

                                     &iattr->uid, &iattr->gid, &iattr->size,

                                     &iattr->atime_sec, &iattr->atime_nsec,

                                     &iattr->mtime_sec, &iattr->mtime_nsec);

            break;

        }

        default:

            break;

        }

    }

    va_end(ap);

    return offset - old_offset;

}


int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *func,

                                       void *arg)

{

    ThreadPoolCo tpc = { .co = qemu_coroutine_self(), .ret = -EINPROGRESS };

    assert(qemu_in_coroutine());

    thread_pool_submit_aio(pool, func, arg, thread_pool_co_cb, &tpc);

    qemu_coroutine_yield();

    return tpc.ret;

}


int qcrypto_init(Error **errp G_GNUC_UNUSED)

{

    return 0;

}


static av_cold int MPA_encode_init(AVCodecContext *avctx)

{

    MpegAudioContext *s = avctx->priv_data;

    int freq = avctx->sample_rate;

    int bitrate = avctx->bit_rate;

    int channels = avctx->channels;

    int i, v, table;

    float a;

    if (channels <= 0 || channels > 2){

        av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels);

        return AVERROR(EINVAL);

    }

    bitrate = bitrate / 1000;

    s->nb_channels = channels;

    avctx->frame_size = MPA_FRAME_SIZE;

    avctx->delay      = 512 - 32 + 1;

    /* encoding freq */

    s->lsf = 0;

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

        if (avpriv_mpa_freq_tab[i] == freq)

            break;

        if ((avpriv_mpa_freq_tab[i] / 2) == freq) {

            s->lsf = 1;

            break;

        }

    }

    if (i == 3){

        av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq);

        return AVERROR(EINVAL);

    }

    s->freq_index = i;

    /* encoding bitrate & frequency */

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

        if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate)

            break;

    }

    if (i == 15){

        av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate);

        return AVERROR(EINVAL);

    }

    s->bitrate_index = i;

    /* compute total header size & pad bit */

    a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);

    s->frame_size = ((int)a) * 8;

    /* frame fractional size to compute padding */

    s->frame_frac = 0;

    s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);

    /* select the right allocation table */

    table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf);

    /* number of used subbands */

    s->sblimit = ff_mpa_sblimit_table[table];

    s->alloc_table = ff_mpa_alloc_tables[table];

    av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",

            bitrate, freq, s->frame_size, table, s->frame_frac_incr);

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

        s->samples_offset[i] = 0;

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

        int v;

        v = ff_mpa_enwindow[i];

#if WFRAC_BITS != 16

        v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);

#endif

        s->filter_bank[i] = v;

        if ((i & 63) != 0)

            v = -v;

        if (i != 0)

            s->filter_bank[512 - i] = v;

    }

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

        v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20));

        if (v <= 0)

            v = 1;

        s->scale_factor_table[i] = v;

        s->scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);

    }

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

        v = i - 64;

        if (v <= -3)

            v = 0;

        else if (v < 0)

            v = 1;

        else if (v == 0)

            v = 2;

        else if (v < 3)

            v = 3;

        else

            v = 4;

        s->scale_diff_table[i] = v;

    }

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

        v = ff_mpa_quant_bits[i];

        if (v < 0)

            v = -v;

        else

            v = v * 3;

        s->total_quant_bits[i] = 12 * v;

    }

    return 0;

}


BlockDriverState *check_to_replace_node(const char *node_name, Error **errp)

{

    BlockDriverState *to_replace_bs = bdrv_find_node(node_name);

    AioContext *aio_context;

    if (!to_replace_bs) {

        error_setg(errp, "Node name '%s' not found", node_name);

        return NULL;

    }

    aio_context = bdrv_get_aio_context(to_replace_bs);

    aio_context_acquire(aio_context);

    if (bdrv_op_is_blocked(to_replace_bs, BLOCK_OP_TYPE_REPLACE, errp)) {

        to_replace_bs = NULL;

        goto out;

    }

    /* We don't want arbitrary node of the BDS chain to be replaced only the top

     * most non filter in order to prevent data corruption.

     * Another benefit is that this tests exclude backing files which are

     * blocked by the backing blockers.

     */

    if (!bdrv_is_first_non_filter(to_replace_bs)) {

        error_setg(errp, "Only top most non filter can be replaced");

        to_replace_bs = NULL;

        goto out;

    }

out:

    aio_context_release(aio_context);

    return to_replace_bs;

}


static uint32_t ecc_mem_readb(void *opaque, target_phys_addr_t addr)

{

    printf("ECC: Unsupported read 0x" TARGET_FMT_plx " 00\n", addr);

    return 0;

}


static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0)

{

    switch(ot) {

    case OT_BYTE:

        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {

            tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8);

        } else {

            tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8);

        }

        break;

    case OT_WORD:

        tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16);

        break;

    default: /* XXX this shouldn't be reached;  abort? */

    case OT_LONG:

        /* For x86_64, this sets the higher half of register to zero.

           For i386, this is equivalent to a mov. */

        tcg_gen_ext32u_tl(cpu_regs[reg], t0);

        break;

#ifdef TARGET_X86_64

    case OT_QUAD:

        tcg_gen_mov_tl(cpu_regs[reg], t0);

        break;

#endif

    }

}


static int local_symlink(FsContext *fs_ctx, const char *oldpath,

                         V9fsPath *dir_path, const char *name, FsCred *credp)

{

    int err = -1;

    int serrno = 0;

    char *newpath;

    V9fsString fullname;

    char buffer[PATH_MAX];

    v9fs_string_init(&fullname);

    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);

    newpath = fullname.data;

    /* Determine the security model */

    if (fs_ctx->fs_sm == SM_MAPPED) {

        int fd;

        ssize_t oldpath_size, write_size;

        fd = open(rpath(fs_ctx, newpath, buffer), O_CREAT|O_EXCL|O_RDWR,

                SM_LOCAL_MODE_BITS);

        if (fd == -1) {

            err = fd;

            goto out;

        }

        /* Write the oldpath (target) to the file. */

        oldpath_size = strlen(oldpath);

        do {

            write_size = write(fd, (void *)oldpath, oldpath_size);

        } while (write_size == -1 && errno == EINTR);

        if (write_size != oldpath_size) {

            serrno = errno;

            close(fd);

            err = -1;

            goto err_end;

        }

        close(fd);

        /* Set cleint credentials in symlink's xattr */

        credp->fc_mode = credp->fc_mode|S_IFLNK;

        err = local_set_xattr(rpath(fs_ctx, newpath, buffer), credp);

        if (err == -1) {

            serrno = errno;

            goto err_end;

        }

    } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) ||

               (fs_ctx->fs_sm == SM_NONE)) {

        err = symlink(oldpath, rpath(fs_ctx, newpath, buffer));

        if (err) {

            goto out;

        }

        err = lchown(rpath(fs_ctx, newpath, buffer), credp->fc_uid,

                     credp->fc_gid);

        if (err == -1) {

            /*

             * If we fail to change ownership and if we are

             * using security model none. Ignore the error

             */

            if (fs_ctx->fs_sm != SM_NONE) {

                serrno = errno;

                goto err_end;

            } else

                err = 0;

        }

    }

    goto out;

err_end:

    remove(rpath(fs_ctx, newpath, buffer));

    errno = serrno;

out:

    v9fs_string_free(&fullname);

    return err;

}


int socket_listen(SocketAddress *addr, Error **errp)

{

    QemuOpts *opts;

    int fd;

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

    switch (addr->kind) {

    case SOCKET_ADDRESS_KIND_INET:

        inet_addr_to_opts(opts, addr->inet);

        fd = inet_listen_opts(opts, 0, errp);

        break;

    case SOCKET_ADDRESS_KIND_UNIX:

        qemu_opt_set(opts, "path", addr->q_unix->path, &error_abort);

        fd = unix_listen_opts(opts, errp);

        break;

    case SOCKET_ADDRESS_KIND_FD:

        fd = monitor_get_fd(cur_mon, addr->fd->str, errp);

        break;

    default:

        abort();

    }

    qemu_opts_del(opts);

    return fd;

}


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

                     Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    unsigned int len, i, shift;

    int ret;

    QCowHeader header;

    Error *local_err = NULL;

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,

                               false, errp);

    if (!bs->file) {

        return -EINVAL;

    }

    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));

    if (ret < 0) {

        goto fail;

    }

    be32_to_cpus(&header.magic);

    be32_to_cpus(&header.version);

    be64_to_cpus(&header.backing_file_offset);

    be32_to_cpus(&header.backing_file_size);

    be32_to_cpus(&header.mtime);

    be64_to_cpus(&header.size);

    be32_to_cpus(&header.crypt_method);

    be64_to_cpus(&header.l1_table_offset);

    if (header.magic != QCOW_MAGIC) {

        error_setg(errp, "Image not in qcow format");

        ret = -EINVAL;

        goto fail;

    }

    if (header.version != QCOW_VERSION) {

        error_setg(errp, "Unsupported qcow version %" PRIu32, header.version);

        ret = -ENOTSUP;

        goto fail;

    }

    if (header.size <= 1) {

        error_setg(errp, "Image size is too small (must be at least 2 bytes)");

        ret = -EINVAL;

        goto fail;

    }

    if (header.cluster_bits < 9 || header.cluster_bits > 16) {

        error_setg(errp, "Cluster size must be between 512 and 64k");

        ret = -EINVAL;

        goto fail;

    }

    /* l2_bits specifies number of entries; storing a uint64_t in each entry,

     * so bytes = num_entries << 3. */

    if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) {

        error_setg(errp, "L2 table size must be between 512 and 64k");

        ret = -EINVAL;

        goto fail;

    }

    if (header.crypt_method > QCOW_CRYPT_AES) {

        error_setg(errp, "invalid encryption method in qcow header");

        ret = -EINVAL;

        goto fail;

    }

    if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128,

                                 QCRYPTO_CIPHER_MODE_CBC)) {

        error_setg(errp, "AES cipher not available");

        ret = -EINVAL;

        goto fail;

    }

    s->crypt_method_header = header.crypt_method;

    if (s->crypt_method_header) {

        if (bdrv_uses_whitelist() &&

            s->crypt_method_header == QCOW_CRYPT_AES) {

            error_setg(errp,

                       "Use of AES-CBC encrypted qcow images is no longer "

                       "supported in system emulators");

            error_append_hint(errp,

                              "You can use 'qemu-img convert' to convert your "

                              "image to an alternative supported format, such "

                              "as unencrypted qcow, or raw with the LUKS "

                              "format instead.\n");

            ret = -ENOSYS;

            goto fail;

        }

        bs->encrypted = true;

    }

    s->cluster_bits = header.cluster_bits;

    s->cluster_size = 1 << s->cluster_bits;

    s->cluster_sectors = 1 << (s->cluster_bits - 9);

    s->l2_bits = header.l2_bits;

    s->l2_size = 1 << s->l2_bits;

    bs->total_sectors = header.size / 512;

    s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;

    /* read the level 1 table */

    shift = s->cluster_bits + s->l2_bits;

    if (header.size > UINT64_MAX - (1LL << shift)) {

        error_setg(errp, "Image too large");

        ret = -EINVAL;

        goto fail;

    } else {

        uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift;

        if (l1_size > INT_MAX / sizeof(uint64_t)) {

            error_setg(errp, "Image too large");

            ret = -EINVAL;

            goto fail;

        }

        s->l1_size = l1_size;

    }

    s->l1_table_offset = header.l1_table_offset;

    s->l1_table = g_try_new(uint64_t, s->l1_size);

    if (s->l1_table == NULL) {

        error_setg(errp, "Could not allocate memory for L1 table");

        ret = -ENOMEM;

        goto fail;

    }

    ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,

               s->l1_size * sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }

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

        be64_to_cpus(&s->l1_table[i]);

    }

    /* alloc L2 cache (max. 64k * 16 * 8 = 8 MB) */

    s->l2_cache =

        qemu_try_blockalign(bs->file->bs,

                            s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));

    if (s->l2_cache == NULL) {

        error_setg(errp, "Could not allocate L2 table cache");

        ret = -ENOMEM;

        goto fail;

    }

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

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

    s->cluster_cache_offset = -1;

    /* read the backing file name */

    if (header.backing_file_offset != 0) {

        len = header.backing_file_size;

        if (len > 1023 || len >= sizeof(bs->backing_file)) {

            error_setg(errp, "Backing file name too long");

            ret = -EINVAL;

            goto fail;

        }

        ret = bdrv_pread(bs->file, header.backing_file_offset,

                   bs->backing_file, len);

        if (ret < 0) {

            goto fail;

        }

        bs->backing_file[len] = '\0';

    }

    /* Disable migration when qcow images are used */

    error_setg(&s->migration_blocker, "The qcow format used by node '%s' "

               "does not support live migration",

               bdrv_get_device_or_node_name(bs));

    ret = migrate_add_blocker(s->migration_blocker, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        error_free(s->migration_blocker);

        goto fail;

    }

    qemu_co_mutex_init(&s->lock);

    return 0;

 fail:

    g_free(s->l1_table);

    qemu_vfree(s->l2_cache);

    g_free(s->cluster_cache);

    g_free(s->cluster_data);

    return ret;

}


static void sigp_restart(CPUState *cs, run_on_cpu_data arg)

{

    S390CPU *cpu = S390_CPU(cs);

    SigpInfo *si = arg.host_ptr;

    struct kvm_s390_irq irq = {

        .type = KVM_S390_RESTART,

    };

    switch (s390_cpu_get_state(cpu)) {

    case CPU_STATE_STOPPED:

        /* the restart irq has to be delivered prior to any other pending irq */

        cpu_synchronize_state(cs);

        do_restart_interrupt(&cpu->env);

        s390_cpu_set_state(CPU_STATE_OPERATING, cpu);

        break;

    case CPU_STATE_OPERATING:

        kvm_s390_vcpu_interrupt(cpu, &irq);

        break;

    }

    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;

}


void qemu_purge_queued_packets(VLANClientState *vc)

{

    VLANPacket *packet, *next;

    TAILQ_FOREACH_SAFE(packet, &vc->vlan->send_queue, entry, next) {

        if (packet->sender == vc) {

            TAILQ_REMOVE(&vc->vlan->send_queue, packet, entry);

            qemu_free(packet);

        }

    }

}


static void mips_tlb_flush_extra (CPUState *env, int first)

{

    /* Discard entries from env->tlb[first] onwards.  */

    while (env->tlb_in_use > first) {

        invalidate_tlb(--env->tlb_in_use, 0);

    }

}


void ff_avg_h264_qpel8_mc32_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_midh_qrt_and_aver_dst_8w_msa(src - (2 * stride) - 2,

                                          stride, dst, stride, 8, 1);

}


DeviceState *exynos4210_uart_create(target_phys_addr_t addr,

                                 int fifo_size,

                                 int channel,

                                 CharDriverState *chr,

                                 qemu_irq irq)

{

    DeviceState  *dev;

    SysBusDevice *bus;

    const char chr_name[] = "serial";

    char label[ARRAY_SIZE(chr_name) + 1];

    dev = qdev_create(NULL, "exynos4210.uart");

    if (!chr) {

        if (channel >= MAX_SERIAL_PORTS) {

            hw_error("Only %d serial ports are supported by QEMU.\n",

                     MAX_SERIAL_PORTS);

        }

        chr = serial_hds[channel];

        if (!chr) {

            snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, channel);

            chr = qemu_chr_new(label, "null", NULL);

            if (!(chr)) {

                hw_error("Can't assign serial port to UART%d.\n", channel);

            }

        }

    }

    qdev_prop_set_chr(dev, "chardev", chr);

    qdev_prop_set_uint32(dev, "channel", channel);

    qdev_prop_set_uint32(dev, "rx-size", fifo_size);

    qdev_prop_set_uint32(dev, "tx-size", fifo_size);

    bus = sysbus_from_qdev(dev);

    qdev_init_nofail(dev);

    if (addr != (target_phys_addr_t)-1) {

        sysbus_mmio_map(bus, 0, addr);

    }

    sysbus_connect_irq(bus, 0, irq);

    return dev;

}


static VncClientInfo *qmp_query_vnc_client(const VncState *client)

{

    struct sockaddr_storage sa;

    socklen_t salen = sizeof(sa);

    char host[NI_MAXHOST];

    char serv[NI_MAXSERV];

    VncClientInfo *info;

    if (getpeername(client->csock, (struct sockaddr *)&sa, &salen) < 0) {

        return NULL;

    }

    if (getnameinfo((struct sockaddr *)&sa, salen,

                    host, sizeof(host),

                    serv, sizeof(serv),

                    NI_NUMERICHOST | NI_NUMERICSERV) < 0) {

        return NULL;

    }

    info = g_malloc0(sizeof(*info));

    info->base = g_malloc0(sizeof(*info->base));

    info->base->host = g_strdup(host);

    info->base->service = g_strdup(serv);

    info->base->family = inet_netfamily(sa.ss_family);

    info->base->websocket = client->websocket;

    if (client->tls) {

        info->x509_dname = qcrypto_tls_session_get_peer_name(client->tls);

        info->has_x509_dname = info->x509_dname != NULL;

    }

#ifdef CONFIG_VNC_SASL

    if (client->sasl.conn && client->sasl.username) {

        info->has_sasl_username = true;

        info->sasl_username = g_strdup(client->sasl.username);

    }

#endif

    return info;

}


static void deblocking_filter_CTB(HEVCContext *s, int x0, int y0)

{

    uint8_t *src;

    int x, y, x_end, y_end, chroma;

    int c_tc[2], beta[2], tc[2];

    uint8_t no_p[2] = { 0 };

    uint8_t no_q[2] = { 0 };

    int log2_ctb_size = s->sps->log2_ctb_size;

    int ctb_size        = 1 << log2_ctb_size;

    int ctb             = (x0 >> log2_ctb_size) +

                          (y0 >> log2_ctb_size) * s->sps->ctb_width;

    int cur_tc_offset   = s->deblock[ctb].tc_offset;

    int cur_beta_offset = s->deblock[ctb].beta_offset;

    int tc_offset, left_tc_offset, beta_offset, left_beta_offset;

    int pcmf = (s->sps->pcm_enabled_flag &&

                s->sps->pcm.loop_filter_disable_flag) ||

               s->pps->transquant_bypass_enable_flag;

    if (x0) {

        left_tc_offset   = s->deblock[ctb - 1].tc_offset;

        left_beta_offset = s->deblock[ctb - 1].beta_offset;

    }

    x_end = x0 + ctb_size;

    if (x_end > s->sps->width)

        x_end = s->sps->width;

    y_end = y0 + ctb_size;

    if (y_end > s->sps->height)

        y_end = s->sps->height;

    tc_offset   = cur_tc_offset;

    beta_offset = cur_beta_offset;

    // vertical filtering luma

    for (y = y0; y < y_end; y += 8) {

        for (x = x0 ? x0 : 8; x < x_end; x += 8) {

            const int bs0 = s->vertical_bs[(x >> 3) + (y       >> 2) * s->bs_width];

            const int bs1 = s->vertical_bs[(x >> 3) + ((y + 4) >> 2) * s->bs_width];

            if (bs0 || bs1) {

                const int qp0 = (get_qPy(s, x - 1, y)     + get_qPy(s, x, y)     + 1) >> 1;

                const int qp1 = (get_qPy(s, x - 1, y + 4) + get_qPy(s, x, y + 4) + 1) >> 1;

                beta[0] = betatable[av_clip(qp0 + beta_offset, 0, MAX_QP)];

                beta[1] = betatable[av_clip(qp1 + beta_offset, 0, MAX_QP)];

                tc[0]   = bs0 ? TC_CALC(qp0, bs0) : 0;

                tc[1]   = bs1 ? TC_CALC(qp1, bs1) : 0;

                src     = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];

                if (pcmf) {

                    no_p[0] = get_pcm(s, x - 1, y);

                    no_p[1] = get_pcm(s, x - 1, y + 4);

                    no_q[0] = get_pcm(s, x, y);

                    no_q[1] = get_pcm(s, x, y + 4);

                    s->hevcdsp.hevc_v_loop_filter_luma_c(src,

                                                         s->frame->linesize[LUMA],

                                                         beta, tc, no_p, no_q);

                } else

                    s->hevcdsp.hevc_v_loop_filter_luma(src,

                                                       s->frame->linesize[LUMA],

                                                       beta, tc, no_p, no_q);

            }

        }

    }

    // vertical filtering chroma

    for (chroma = 1; chroma <= 2; chroma++) {

        for (y = y0; y < y_end; y += 16) {

            for (x = x0 ? x0 : 16; x < x_end; x += 16) {

                const int bs0 = s->vertical_bs[(x >> 3) + (y       >> 2) * s->bs_width];

                const int bs1 = s->vertical_bs[(x >> 3) + ((y + 8) >> 2) * s->bs_width];

                if ((bs0 == 2) || (bs1 == 2)) {

                    const int qp0 = (get_qPy(s, x - 1, y)     + get_qPy(s, x, y)     + 1) >> 1;

                    const int qp1 = (get_qPy(s, x - 1, y + 8) + get_qPy(s, x, y + 8) + 1) >> 1;

                    c_tc[0] = (bs0 == 2) ? chroma_tc(s, qp0, chroma, tc_offset) : 0;

                    c_tc[1] = (bs1 == 2) ? chroma_tc(s, qp1, chroma, tc_offset) : 0;

                    src     = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];

                    if (pcmf) {

                        no_p[0] = get_pcm(s, x - 1, y);

                        no_p[1] = get_pcm(s, x - 1, y + 8);

                        no_q[0] = get_pcm(s, x, y);

                        no_q[1] = get_pcm(s, x, y + 8);

                        s->hevcdsp.hevc_v_loop_filter_chroma_c(src,

                                                               s->frame->linesize[chroma],

                                                               c_tc, no_p, no_q);

                    } else

                        s->hevcdsp.hevc_v_loop_filter_chroma(src,

                                                             s->frame->linesize[chroma],

                                                             c_tc, no_p, no_q);

                }

            }

        }

    }

    // horizontal filtering luma

    if (x_end != s->sps->width)

        x_end -= 8;

    for (y = y0 ? y0 : 8; y < y_end; y += 8) {

        for (x = x0 ? x0 - 8 : 0; x < x_end; x += 8) {

            const int bs0 = s->horizontal_bs[(x +     y * s->bs_width) >> 2];

            const int bs1 = s->horizontal_bs[(x + 4 + y * s->bs_width) >> 2];

            if (bs0 || bs1) {

                const int qp0 = (get_qPy(s, x, y - 1)     + get_qPy(s, x, y)     + 1) >> 1;

                const int qp1 = (get_qPy(s, x + 4, y - 1) + get_qPy(s, x + 4, y) + 1) >> 1;

                tc_offset   = x >= x0 ? cur_tc_offset : left_tc_offset;

                beta_offset = x >= x0 ? cur_beta_offset : left_beta_offset;

                beta[0] = betatable[av_clip(qp0 + beta_offset, 0, MAX_QP)];

                beta[1] = betatable[av_clip(qp1 + beta_offset, 0, MAX_QP)];

                tc[0]   = bs0 ? TC_CALC(qp0, bs0) : 0;

                tc[1]   = bs1 ? TC_CALC(qp1, bs1) : 0;

                src     = &s->frame->data[LUMA][y * s->frame->linesize[LUMA] + (x << s->sps->pixel_shift)];

                if (pcmf) {

                    no_p[0] = get_pcm(s, x, y - 1);

                    no_p[1] = get_pcm(s, x + 4, y - 1);

                    no_q[0] = get_pcm(s, x, y);

                    no_q[1] = get_pcm(s, x + 4, y);

                    s->hevcdsp.hevc_h_loop_filter_luma_c(src,

                                                         s->frame->linesize[LUMA],

                                                         beta, tc, no_p, no_q);

                } else

                    s->hevcdsp.hevc_h_loop_filter_luma(src,

                                                       s->frame->linesize[LUMA],

                                                       beta, tc, no_p, no_q);

            }

        }

    }

    // horizontal filtering chroma

    for (chroma = 1; chroma <= 2; chroma++) {

        for (y = y0 ? y0 : 16; y < y_end; y += 16) {

            for (x = x0 - 8; x < x_end; x += 16) {

                int bs0, bs1;

                // to make sure no memory access over boundary when x = -8

                // TODO: simplify with row based deblocking

                if (x < 0) {

                    bs0 = 0;

                    bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];

                } else if (x >= x_end - 8) {

                    bs0 = s->horizontal_bs[(x +     y * s->bs_width) >> 2];

                    bs1 = 0;

                } else {

                    bs0 = s->horizontal_bs[(x + y     * s->bs_width) >> 2];

                    bs1 = s->horizontal_bs[(x + 8 + y * s->bs_width) >> 2];

                }

                if ((bs0 == 2) || (bs1 == 2)) {

                    const int qp0 = bs0 == 2 ? (get_qPy(s, x,     y - 1) + get_qPy(s, x,     y) + 1) >> 1 : 0;

                    const int qp1 = bs1 == 2 ? (get_qPy(s, x + 8, y - 1) + get_qPy(s, x + 8, y) + 1) >> 1 : 0;

                    tc_offset = x >= x0 ? cur_tc_offset : left_tc_offset;

                    c_tc[0]   = bs0 == 2 ? chroma_tc(s, qp0, chroma, tc_offset)     : 0;

                    c_tc[1]   = bs1 == 2 ? chroma_tc(s, qp1, chroma, cur_tc_offset) : 0;

                    src       = &s->frame->data[chroma][y / 2 * s->frame->linesize[chroma] + ((x / 2) << s->sps->pixel_shift)];

                    if (pcmf) {

                        no_p[0] = get_pcm(s, x, y - 1);

                        no_p[1] = get_pcm(s, x + 8, y - 1);

                        no_q[0] = get_pcm(s, x, y);

                        no_q[1] = get_pcm(s, x + 8, y);

                        s->hevcdsp.hevc_h_loop_filter_chroma_c(src,

                                                               s->frame->linesize[chroma],

                                                               c_tc, no_p, no_q);

                    } else

                        s->hevcdsp.hevc_h_loop_filter_chroma(src,

                                                             s->frame->linesize[chroma],

                                                             c_tc, no_p, no_q);

                }

            }

        }

    }

}


static inline void mix_2f_2r_to_dolby(AC3DecodeContext *ctx)

{

    int i;

    float (*output)[256] = ctx->audio_block.block_output;

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

        output[1][i] -= output[3][i];

        output[2][i] += output[4][i];

    }

    memset(output[3], 0, sizeof(output[3]));

    memset(output[4], 0, sizeof(output[4]));

}


int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)

{

    QSVFrame *cur;

    MFXVideoENCODE_Close(q->session);

    if (q->internal_session)

        MFXClose(q->internal_session);

    q->session          = NULL;

    q->internal_session = NULL;

    cur = q->work_frames;

    while (cur) {

        q->work_frames = cur->next;

        av_frame_free(&cur->frame);

        av_freep(&cur);

        cur = q->work_frames;

    }

    while (q->async_fifo && av_fifo_size(q->async_fifo)) {

        AVPacket pkt;

        mfxSyncPoint sync;

        mfxBitstream *bs;

        av_fifo_generic_read(q->async_fifo, &pkt,  sizeof(pkt),  NULL);

        av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL);

        av_fifo_generic_read(q->async_fifo, &bs,   sizeof(bs),   NULL);

        av_freep(&bs);

        av_packet_unref(&pkt);

    }

    av_fifo_free(q->async_fifo);

    q->async_fifo = NULL;

    av_frame_free(&avctx->coded_frame);

    return 0;

}


static av_cold int raw_encode_init(AVCodecContext *avctx)

{

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);

    avctx->coded_frame            = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc);

    if(!avctx->codec_tag)

        avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);

    return 0;

}


int ff_audio_mix(AudioMix *am, AudioData *src)

{

    int use_generic = 1;

    int len = src->nb_samples;

    int i, j;

    /* determine whether to use the optimized function based on pointer and

       samples alignment in both the input and output */

    if (am->has_optimized_func) {

        int aligned_len = FFALIGN(len, am->samples_align);

        if (!(src->ptr_align % am->ptr_align) &&

            src->samples_align >= aligned_len) {

            len = aligned_len;

            use_generic = 0;

        }

    }

    av_dlog(am->avr, "audio_mix: %d samples - %d to %d channels (%s)\n",

            src->nb_samples, am->in_channels, am->out_channels,

            use_generic ? am->func_descr_generic : am->func_descr);

    if (am->in_matrix_channels && am->out_matrix_channels) {

        uint8_t **data;

        uint8_t *data0[AVRESAMPLE_MAX_CHANNELS];

        if (am->out_matrix_channels < am->out_channels ||

             am->in_matrix_channels <  am->in_channels) {

            for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {

                if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])

                    continue;

                data0[j++] = src->data[i];

            }

            data = data0;

        } else {

            data = src->data;

        }

        if (use_generic)

            am->mix_generic(data, am->matrix, len, am->out_matrix_channels,

                            am->in_matrix_channels);

        else

            am->mix(data, am->matrix, len, am->out_matrix_channels,

                    am->in_matrix_channels);

    }

    if (am->out_matrix_channels < am->out_channels) {

        for (i = 0; i < am->out_channels; i++)

            if (am->output_zero[i])

                av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);

    }

    ff_audio_data_set_channels(src, am->out_channels);

    return 0;

}


static int ahci_dma_set_inactive(IDEDMA *dma)

{

    AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);

    DPRINTF(ad->port_no, "dma done\n");

    /* update d2h status */

    ahci_write_fis_d2h(ad, NULL);

    ad->dma_cb = NULL;

    /* maybe we still have something to process, check later */

    ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);

    qemu_bh_schedule(ad->check_bh);

    return 0;

}


DriveInfo *drive_init(QemuOpts *opts, void *opaque,

                      int *fatal_error)

{

    const char *buf;

    const char *file = NULL;

    char devname[128];

    const char *serial;

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriver *drv = NULL;

    QEMUMachine *machine = opaque;

    int max_devs;

    int index;

    int ro = 0;

    int bdrv_flags = 0;

    int on_read_error, on_write_error;

    const char *devaddr;

    DriveInfo *dinfo;

    int snapshot = 0;

    *fatal_error = 1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    if (machine && machine->use_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

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

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

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

    }

    media = MEDIA_DISK;

    /* extract parameters */

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

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

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

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

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

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

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

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

    file = qemu_opt_get(opts, "file");

    serial = qemu_opt_get(opts, "serial");

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

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

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

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

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

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

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

	    type = IF_FLOPPY;

            max_devs = 0;

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

	    type = IF_PFLASH;

            max_devs = 0;

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

	    type = IF_MTD;

            max_devs = 0;

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

	    type = IF_SD;

            max_devs = 0;

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

            type = IF_VIRTIO;

            max_devs = 0;

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

	    type = IF_XEN;

            max_devs = 0;

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

	    type = IF_NONE;

            max_devs = 0;

	} else {

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

            return NULL;

	}

    }

    if (cyls || heads || secs) {

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

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

	    return NULL;

	}

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

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

	    return NULL;

	}

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

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

	    return NULL;

	}

    }

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

        if (!cyls) {

            fprintf(stderr,

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

                    buf);

            return NULL;

        }

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

            translation = BIOS_ATA_TRANSLATION_NONE;

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

            translation = BIOS_ATA_TRANSLATION_LBA;

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

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

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

	    return NULL;

	}

    }

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

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

	    media = MEDIA_DISK;

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

            if (cyls || secs || heads) {

                fprintf(stderr,

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

	        return NULL;

            }

	    media = MEDIA_CDROM;

	} else {

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

	    return NULL;

	}

    }

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

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

            bdrv_flags |= BDRV_O_NOCACHE;

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

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

            /* this is the default */

        } else {

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

           return NULL;

        }

    }

#ifdef CONFIG_LINUX_AIO

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

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

            bdrv_flags |= BDRV_O_NATIVE_AIO;

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

            /* this is the default */

        } else {

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

           return NULL;

        }

    }

#endif

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

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

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

            bdrv_iterate_format(bdrv_format_print, NULL);

            fprintf(stderr, "\n");

	    return NULL;

        }

        drv = bdrv_find_whitelisted_format(buf);

        if (!drv) {

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

            return NULL;

        }

    }

    on_write_error = BLOCK_ERR_STOP_ENOSPC;

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

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

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

            return NULL;

        }

        on_write_error = parse_block_error_action(buf, 0);

        if (on_write_error < 0) {

            return NULL;

        }

    }

    on_read_error = BLOCK_ERR_REPORT;

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

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

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

            return NULL;

        }

        on_read_error = parse_block_error_action(buf, 1);

        if (on_read_error < 0) {

            return NULL;

        }

    }

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

        if (type != IF_VIRTIO) {

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

            return NULL;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

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

            fprintf(stderr,

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

            return NULL;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

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

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

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

                unit_id, max_devs - 1);

        return NULL;

    }

    /*

     * ignore multiple definitions

     */

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

        *fatal_error = 0;

        return NULL;

    }

    /* init */

    dinfo = qemu_mallocz(sizeof(*dinfo));

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

        dinfo->id = qemu_strdup(buf);

    } else {

        /* no id supplied -> create one */

        dinfo->id = qemu_mallocz(32);

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

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

        if (max_devs)

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

                     devname, bus_id, mediastr, unit_id);

        else

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

                     devname, mediastr, unit_id);

    }

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

    dinfo->devaddr = devaddr;

    dinfo->type = type;

    dinfo->bus = bus_id;

    dinfo->unit = unit_id;

    dinfo->on_read_error = on_read_error;

    dinfo->on_write_error = on_write_error;

    dinfo->opts = opts;

    if (serial)

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

    QTAILQ_INSERT_TAIL(&drives, dinfo, next);

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

    case IF_NONE:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

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

                bdrv_set_translation_hint(dinfo->bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

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

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

        break;

    case IF_VIRTIO:

        /* add virtio block device */

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

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

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

        if (devaddr)

            qemu_opt_set(opts, "addr", devaddr);

        break;

    case IF_COUNT:

        abort();

    }

    if (!file) {

        *fatal_error = 0;

        return NULL;

    }

    if (snapshot) {

        /* always use write-back with snapshot */

        bdrv_flags &= ~BDRV_O_CACHE_MASK;

        bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB);

    }

    if (media == MEDIA_CDROM) {

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

        ro = 1;

    } else if (ro == 1) {

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

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

            return NULL;

        }

    }

    bdrv_flags |= ro ? 0 : BDRV_O_RDWR;

    if (bdrv_open(dinfo->bdrv, file, bdrv_flags, drv) < 0) {

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

                        file, strerror(errno));

        return NULL;

    }

    if (bdrv_key_required(dinfo->bdrv))

        autostart = 0;

    *fatal_error = 0;

    return dinfo;

}


static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size)

{

    int i, x, y;

    i=0; x=0; y=0;

    while(i<buf_size) {

        int run_length, color;

        if (buf[i] & 0x80) {

            run_length = 1;

            color = buf[i];

            i++;

        }else{

            run_length = (buf[i] & 0x7f) + 2;

            color = buf[i+1];

            i+=2;

        }

        if (half_horiz)

            run_length *=2;

        if (color) {

            memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length);

            if (half_vert)

                memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length);

        }

        x+= run_length;

        if (x >= s->avctx->width) {

            x=0;

            y += half_vert ? 2 : 1;

        }

    }

}


milkymist_init(QEMUMachineInitArgs *args)
{
    const char *cpu_model = args->cpu_model;
    const char *kernel_filename = args->kernel_filename;
    const char *kernel_cmdline = args->kernel_cmdline;
    const char *initrd_filename = args->initrd_filename;
    LM32CPU *cpu;
    CPULM32State *env;
    int kernel_size;
    DriveInfo *dinfo;
    MemoryRegion *address_space_mem = get_system_memory();
    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
    qemu_irq irq[32], *cpu_irq;
    int i;
    char *bios_filename;
    ResetInfo *reset_info;
    /* memory map */
    hwaddr flash_base   = 0x00000000;
    size_t flash_sector_size        = 128 * 1024;
    size_t flash_size               = 32 * 1024 * 1024;
    hwaddr sdram_base   = 0x40000000;
    size_t sdram_size               = 128 * 1024 * 1024;
    hwaddr initrd_base  = sdram_base + 0x1002000;
    hwaddr cmdline_base = sdram_base + 0x1000000;
    size_t initrd_max = sdram_size - 0x1002000;
    reset_info = g_malloc0(sizeof(ResetInfo));
    if (cpu_model == NULL) {
        cpu_model = "lm32-full";
    cpu = cpu_lm32_init(cpu_model);
    env = &cpu->env;
    reset_info->cpu = cpu;
    cpu_lm32_set_phys_msb_ignore(env, 1);
    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
    vmstate_register_ram_global(phys_sdram);
    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
    dinfo = drive_get(IF_PFLASH, 0, 0);
    /* Numonyx JS28F256J3F105 */
    pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size,
                          dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                          flash_size / flash_sector_size, 2,
                          0x00, 0x89, 0x00, 0x1d, 1);
    /* create irq lines */
    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);
    env->pic_state = lm32_pic_init(*cpu_irq);
    for (i = 0; i < 32; i++) {
        irq[i] = qdev_get_gpio_in(env->pic_state, i);
    /* load bios rom */
    if (bios_name == NULL) {
        bios_name = BIOS_FILENAME;
    bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
    if (bios_filename) {
        load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE);
    reset_info->bootstrap_pc = BIOS_OFFSET;
    /* if no kernel is given no valid bios rom is a fatal error */
    if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) {
        fprintf(stderr, "qemu: could not load Milkymist One bios '%s'\n",
                bios_name);
    milkymist_uart_create(0x60000000, irq[0]);
    milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
            80000000, 0x10014d31, 0x0000041f, 0x00000001);
    milkymist_hpdmc_create(0x60002000);
    milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff);
    milkymist_memcard_create(0x60004000);
    milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]);
    milkymist_pfpu_create(0x60006000, irq[8]);
    milkymist_tmu2_create(0x60007000, irq[9]);
    milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]);
    milkymist_softusb_create(0x6000f000, irq[15],
            0x20000000, 0x1000, 0x20020000, 0x2000);
    /* make sure juart isn't the first chardev */
    env->juart_state = lm32_juart_init();
    if (kernel_filename) {
        uint64_t entry;
        /* Boots a kernel elf binary.  */
        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,
                               1, ELF_MACHINE, 0);
        reset_info->bootstrap_pc = entry;
        if (kernel_size < 0) {
            kernel_size = load_image_targphys(kernel_filename, sdram_base,
                                              sdram_size);
            reset_info->bootstrap_pc = sdram_base;
        if (kernel_size < 0) {
            fprintf(stderr, "qemu: could not load kernel '%s'\n",
                    kernel_filename);
    if (kernel_cmdline && strlen(kernel_cmdline)) {
        pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE,
                kernel_cmdline);
        reset_info->cmdline_base = (uint32_t)cmdline_base;
    if (initrd_filename) {
        size_t initrd_size;
        initrd_size = load_image_targphys(initrd_filename, initrd_base,
                initrd_max);
        reset_info->initrd_base = (uint32_t)initrd_base;
        reset_info->initrd_size = (uint32_t)initrd_size;
    qemu_register_reset(main_cpu_reset, reset_info);


void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)

{

    static int print_prefix=1;

    static int count;

    static char line[1024], prev[1024];

    static int is_atty;

    AVClass* avc= ptr ? *(AVClass**)ptr : NULL;

    if(level>av_log_level)

        return;

    line[0]=0;

#undef fprintf

    if(print_prefix && avc) {

        if (avc->parent_log_context_offset) {

            AVClass** parent= *(AVClass***)(((uint8_t*)ptr) + avc->parent_log_context_offset);

            if(parent && *parent){

                snprintf(line, sizeof(line), "[%s @ %p] ", (*parent)->item_name(parent), parent);

            }

        }

        snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ", avc->item_name(ptr), ptr);

    }

    vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl);

    print_prefix= line[strlen(line)-1] == '\n';

#if HAVE_ISATTY

    if(!is_atty) is_atty= isatty(2) ? 1 : -1;

#endif

    if(print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){

        count++;

        if(is_atty==1)

            fprintf(stderr, "    Last message repeated %d times\r", count);

        return;

    }

    if(count>0){

        fprintf(stderr, "    Last message repeated %d times\n", count);

        count=0;

    }

    colored_fputs(av_clip(level>>3, 0, 6), line);

    strcpy(prev, line);

}


static int bt_hci_name_req(struct bt_hci_s *hci, bdaddr_t *bdaddr)

{

    struct bt_device_s *slave;

    evt_remote_name_req_complete params;

    int len;

    for (slave = hci->device.net->slave; slave; slave = slave->next)

        if (slave->page_scan && !bacmp(&slave->bd_addr, bdaddr))

            break;

    if (!slave)

        return -ENODEV;

    bt_hci_event_status(hci, HCI_SUCCESS);

    params.status       = HCI_SUCCESS;

    bacpy(&params.bdaddr, &slave->bd_addr);

    len = snprintf(params.name, sizeof(params.name),

                    "%s", slave->lmp_name ?: "");

    memset(params.name + len, 0, sizeof(params.name) - len);

    bt_hci_event(hci, EVT_REMOTE_NAME_REQ_COMPLETE,

                    &params, EVT_REMOTE_NAME_REQ_COMPLETE_SIZE);

    return 0;

}


int av_opt_is_set_to_default(void *obj, const AVOption *o)

{

    int64_t i64;

    double d, d2;

    float f;

    AVRational q;

    int ret, w, h;

    char *str;

    void *dst;

    if (!o || !obj)

        return AVERROR(EINVAL);

    dst = ((uint8_t*)obj) + o->offset;

    switch (o->type) {

    case AV_OPT_TYPE_CONST:

        return 1;

    case AV_OPT_TYPE_FLAGS:

    case AV_OPT_TYPE_PIXEL_FMT:

    case AV_OPT_TYPE_SAMPLE_FMT:

    case AV_OPT_TYPE_INT:

    case AV_OPT_TYPE_CHANNEL_LAYOUT:

    case AV_OPT_TYPE_DURATION:

    case AV_OPT_TYPE_INT64:

        read_number(o, dst, NULL, NULL, &i64);

        return o->default_val.i64 == i64;

    case AV_OPT_TYPE_STRING:

        str = *(char **)dst;

        if (str == o->default_val.str) //2 NULLs

            return 1;

        if (!str || !o->default_val.str) //1 NULL

            return 0;

        return !strcmp(str, o->default_val.str);

    case AV_OPT_TYPE_DOUBLE:

        read_number(o, dst, &d, NULL, NULL);

        return o->default_val.dbl == d;

    case AV_OPT_TYPE_FLOAT:

        read_number(o, dst, &d, NULL, NULL);

        f = o->default_val.dbl;

        d2 = f;

        return d2 == d;

    case AV_OPT_TYPE_RATIONAL:

        q = av_d2q(o->default_val.dbl, INT_MAX);

        return !av_cmp_q(*(AVRational*)dst, q);

    case AV_OPT_TYPE_BINARY: {

        struct {

            uint8_t *data;

            int size;

        } tmp = {0};

        int opt_size = *(int *)((void **)dst + 1);

        void *opt_ptr = *(void **)dst;

        if (!opt_ptr && (!o->default_val.str || !strlen(o->default_val.str)))

            return 1;

        if (opt_ptr && o->default_val.str && !strlen(o->default_val.str))

            return 0;

        if (opt_size != strlen(o->default_val.str) / 2)

            return 0;

        ret = set_string_binary(NULL, NULL, o->default_val.str, &tmp.data);

        if (!ret)

            ret = !memcmp(opt_ptr, tmp.data, tmp.size);

        av_free(tmp.data);

        return ret;

    }

    case AV_OPT_TYPE_DICT:

        /* Binary and dict have not default support yet. Any pointer is not default. */

        return !!(*(void **)dst);

    case AV_OPT_TYPE_IMAGE_SIZE:

        if (!o->default_val.str || !strcmp(o->default_val.str, "none"))

            w = h = 0;

        else if ((ret = av_parse_video_size(&w, &h, o->default_val.str)) < 0)

            return ret;

        return (w == *(int *)dst) && (h == *((int *)dst+1));

    case AV_OPT_TYPE_VIDEO_RATE:

        q = (AVRational){0, 0};

        if (o->default_val.str)

            av_parse_video_rate(&q, o->default_val.str);

        return !av_cmp_q(*(AVRational*)dst, q);

    case AV_OPT_TYPE_COLOR: {

        uint8_t color[4] = {0, 0, 0, 0};

        if (o->default_val.str)

            av_parse_color(color, o->default_val.str, -1, NULL);

        return !memcmp(color, dst, sizeof(color));

    }

    default:

        av_log(obj, AV_LOG_WARNING, "Not supported option type: %d, option name: %s\n", o->type, o->name);

        break;

    }

    return AVERROR_PATCHWELCOME;

}


static int indeo3_decode_frame(AVCodecContext *avctx,

                               void *data, int *data_size,

                               unsigned char *buf, int buf_size)

{

    Indeo3DecodeContext *s=avctx->priv_data;

    unsigned char *src, *dest;

    int y;

    /* no supplementary picture */

    if (buf_size == 0) {

        return 0;

    }

    iv_decode_frame(s, buf, buf_size);

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

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

    s->frame.reference = 0;

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

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

        return -1;

    }

    src = s->cur_frame->Ybuf;

    dest = s->frame.data[0];

    for (y = 0; y < s->height; y++) {

      memcpy(dest, src, s->cur_frame->y_w);

      src += s->cur_frame->y_w;

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

    }

    if (!(s->avctx->flags & CODEC_FLAG_GRAY))

    {

    src = s->cur_frame->Ubuf;

    dest = s->frame.data[1];

    for (y = 0; y < s->height / 4; y++) {

      memcpy(dest, src, s->cur_frame->uv_w);

      src += s->cur_frame->uv_w;

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

    }

    src = s->cur_frame->Vbuf;

    dest = s->frame.data[2];

    for (y = 0; y < s->height / 4; y++) {

      memcpy(dest, src, s->cur_frame->uv_w);

      src += s->cur_frame->uv_w;

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

    }

    }

    *data_size=sizeof(AVFrame);

    *(AVFrame*)data= s->frame;

    return buf_size;

}


void ff_h261_loop_filter(MpegEncContext *s){

    H261Context * h= (H261Context*)s;

    const int linesize  = s->linesize;

    const int uvlinesize= s->uvlinesize;

    uint8_t *dest_y = s->dest[0];

    uint8_t *dest_cb= s->dest[1];

    uint8_t *dest_cr= s->dest[2];

    if(!(IS_FIL (h->mtype)))

        return;

    s->dsp.h261_loop_filter(dest_y                   , linesize);

    s->dsp.h261_loop_filter(dest_y                + 8, linesize);

    s->dsp.h261_loop_filter(dest_y + 8 * linesize    , linesize);

    s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize);

    s->dsp.h261_loop_filter(dest_cb, uvlinesize);

    s->dsp.h261_loop_filter(dest_cr, uvlinesize);

}


static gboolean check_old_packet_regular(void *opaque)

{

    CompareState *s = opaque;

    /* if have old packet we will notify checkpoint */

    colo_old_packet_check(s);

    return TRUE;

}


float64 helper_fsqrtd(CPUSPARCState *env, float64 src)

{

    float64 ret;

    clear_float_exceptions(env);

    ret = float64_sqrt(src, &env->fp_status);

    check_ieee_exceptions(env);

    return ret;

}


static int local_mknod(FsContext *ctx, const char *path, mode_t mode, dev_t dev)

{

    return mknod(rpath(ctx, path), mode, dev);

}


int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)

{

    int cssid, ssid, schid, m;

    SubchDev *sch;

    SCHIB *schib;

    uint64_t addr;

    int ret = -ENODEV;

    int cc;

    hwaddr len = sizeof(*schib);

    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {

        program_interrupt(env, PGM_OPERAND, 2);

        return -EIO;

    }

    trace_ioinst_sch_id("msch", cssid, ssid, schid);

    addr = decode_basedisp_s(env, ipb);

    if (addr & 3) {

        program_interrupt(env, PGM_SPECIFICATION, 2);

        return -EIO;

    }

    schib = s390_cpu_physical_memory_map(env, addr, &len, 0);

    if (!schib || len != sizeof(*schib)) {

        program_interrupt(env, PGM_ADDRESSING, 2);

        cc = -EIO;

        goto out;

    }

    if (!ioinst_schib_valid(schib)) {

        program_interrupt(env, PGM_OPERAND, 2);

        cc = -EIO;

        goto out;

    }

    sch = css_find_subch(m, cssid, ssid, schid);

    if (sch && css_subch_visible(sch)) {

        ret = css_do_msch(sch, schib);

    }

    switch (ret) {

    case -ENODEV:

        cc = 3;

        break;

    case -EBUSY:

        cc = 2;

        break;

    case 0:

        cc = 0;

        break;

    default:

        cc = 1;

        break;

    }

out:

    s390_cpu_physical_memory_unmap(env, schib, len, 0);

    return cc;

}


static void v9fs_readlink(void *opaque)

{

    V9fsPDU *pdu = opaque;

    size_t offset = 7;

    V9fsString target;

    int32_t fid;

    int err = 0;

    V9fsFidState *fidp;

    pdu_unmarshal(pdu, offset, "d", &fid);

    trace_v9fs_readlink(pdu->tag, pdu->id, fid);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    v9fs_string_init(&target);

    err = v9fs_co_readlink(pdu, &fidp->path, &target);

    if (err < 0) {

        goto out;

    }

    offset += pdu_marshal(pdu, offset, "s", &target);

    err = offset;

    trace_v9fs_readlink_return(pdu->tag, pdu->id, target.data);

    v9fs_string_free(&target);

out:

    put_fid(pdu, fidp);

out_nofid:

    complete_pdu(pdu->s, pdu, err);

}


static void gt64120_write_config(PCIDevice *d, uint32_t address, uint32_t val,

                                 int len)

{

#ifdef TARGET_WORDS_BIGENDIAN

    val = bswap32(val);

#endif

    pci_default_write_config(d, address, val, len);

}


static void arm_thiswdog_write(void *opaque, target_phys_addr_t addr,

                               uint64_t value, unsigned size)

{

    arm_mptimer_state *s = (arm_mptimer_state *)opaque;

    int id = get_current_cpu(s);

    timerblock_write(&s->timerblock[id * 2 + 1], addr, value, size);

}


static void rtc_save_td(QEMUFile *f, void *opaque)

{

    RTCState *s = opaque;

    qemu_put_be32(f, s->irq_coalesced);

    qemu_put_be32(f, s->period);

}


static void scsi_realize(SCSIDevice *dev, Error **errp)

{

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);

    Error *err = NULL;

    if (!s->qdev.conf.bs) {

        error_setg(errp, "drive property not set");

        return;

    }

    if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&

        !bdrv_is_inserted(s->qdev.conf.bs)) {

        error_setg(errp, "Device needs media, but drive is empty");

        return;

    }

    blkconf_serial(&s->qdev.conf, &s->serial);

    if (dev->type == TYPE_DISK) {

        blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);

        if (err) {

            error_propagate(errp, err);

            return;

        }

    }

    if (s->qdev.conf.discard_granularity == -1) {

        s->qdev.conf.discard_granularity =

            MAX(s->qdev.conf.logical_block_size, DEFAULT_DISCARD_GRANULARITY);

    }

    if (!s->version) {

        s->version = g_strdup(qemu_get_version());

    }

    if (!s->vendor) {

        s->vendor = g_strdup("QEMU");

    }

    if (bdrv_is_sg(s->qdev.conf.bs)) {

        error_setg(errp, "unwanted /dev/sg*");

        return;

    }

    if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&

            !(s->features & (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS))) {

        bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_removable_block_ops, s);

    } else {

        bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_disk_block_ops, s);

    }

    bdrv_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);

    bdrv_iostatus_enable(s->qdev.conf.bs);

}


static void ahci_shutdown(AHCIQState *ahci)

{

    QOSState *qs = ahci->parent;

    ahci_clean_mem(ahci);

    free_ahci_device(ahci->dev);

    g_free(ahci);

    qtest_shutdown(qs);

}


int udp_set_remote_url(URLContext *h, const char *uri)

{

    UDPContext *s = h->priv_data;

    char hostname[256];

    int port;

    url_split(NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);

    /* set the destination address */

    if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0)

        return AVERROR_IO;

    s->dest_addr.sin_family = AF_INET;

    s->dest_addr.sin_port = htons(port);

    return 0;

}


int cpu_signal_handler(int host_signum, void *pinfo,

                       void *puc)

{

    siginfo_t *info = pinfo;

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)

    ucontext_t *uc = puc;

#else

    ucontext_t *uc = puc;

#endif

    unsigned long pc;

    int is_write;

    pc = IAR_sig(uc);

    is_write = 0;

#if 0

    /* ppc 4xx case */

    if (DSISR_sig(uc) & 0x00800000) {

        is_write = 1;

    }

#else

    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) {

        is_write = 1;

    }

#endif

    return handle_cpu_signal(pc, (unsigned long)info->si_addr,

                             is_write, &uc->uc_sigmask);

}


static void net_socket_connected(int fd, Error *err, void *opaque)

{

    socket_connect_data *c = opaque;

    NetSocketState *s;

    char *addr_str = NULL;

    Error *local_error = NULL;

    addr_str = socket_address_to_string(c->saddr, &local_error);

    if (addr_str == NULL) {

        error_report_err(local_error);

        closesocket(fd);

        goto end;

    }

    s = net_socket_fd_init(c->peer, c->model, c->name, fd, true);

    if (!s) {

        closesocket(fd);

        goto end;

    }

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

             "socket: connect to %s", addr_str);

end:

    g_free(addr_str);

    socket_connect_data_free(c);

}


void OPPROTO op_decw_ECX(void)

{

    ECX = (ECX & ~0xffff) | ((ECX - 1) & 0xffff);

}


static int vnc_auth_sasl_check_access(VncState *vs)

{

    const void *val;

    int err;

    err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);

    if (err != SASL_OK) {

	VNC_DEBUG("cannot query SASL username on connection %d (%s)\n",

		  err, sasl_errstring(err, NULL, NULL));

	return -1;

    }

    if (val == NULL) {

	VNC_DEBUG("no client username was found\n");

	return -1;

    }

    VNC_DEBUG("SASL client username %s\n", (const char *)val);

    vs->sasl.username = qemu_strdup((const char*)val);

    return 0;

}


ssize_t nbd_send_request(QIOChannel *ioc, struct nbd_request *request)

{

    uint8_t buf[NBD_REQUEST_SIZE];

    ssize_t ret;

    TRACE("Sending request to server: "

          "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64

          ", .type=%" PRIu32 " }",

          request->from, request->len, request->handle, request->type);

    stl_be_p(buf, NBD_REQUEST_MAGIC);

    stl_be_p(buf + 4, request->type);

    stq_be_p(buf + 8, request->handle);

    stq_be_p(buf + 16, request->from);

    stl_be_p(buf + 24, request->len);

    ret = write_sync(ioc, buf, sizeof(buf));

    if (ret < 0) {

        return ret;

    }

    if (ret != sizeof(buf)) {

        LOG("writing to socket failed");

        return -EINVAL;

    }

    return 0;

}


static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTokenType type, int x, int y)

{

    JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);

    QDict *dict;

    if (type == JSON_OPERATOR) {

        switch (qstring_get_str(token)[0]) {

        case '{':

            parser->brace_count++;

            break;

        case '}':

            parser->brace_count--;

            break;

        case '[':

            parser->bracket_count++;

            break;

        case ']':

            parser->bracket_count--;

            break;

        default:

            break;

        }

    }

    dict = qdict_new();

    qdict_put(dict, "type", qint_from_int(type));

    QINCREF(token);

    qdict_put(dict, "token", token);

    qdict_put(dict, "x", qint_from_int(x));

    qdict_put(dict, "y", qint_from_int(y));

    parser->token_size += token->length;

    qlist_append(parser->tokens, dict);

    if (type == JSON_ERROR) {

        goto out_emit_bad;

    } else if (parser->brace_count < 0 ||

        parser->bracket_count < 0 ||

        (parser->brace_count == 0 &&

         parser->bracket_count == 0)) {

        goto out_emit;

    } else if (parser->token_size > MAX_TOKEN_SIZE ||

               parser->bracket_count > MAX_NESTING ||

               parser->brace_count > MAX_NESTING) {

        /* Security consideration, we limit total memory allocated per object

         * and the maximum recursion depth that a message can force.

         */

        goto out_emit;

    }

    return;

out_emit_bad:

    /* clear out token list and tell the parser to emit and error

     * indication by passing it a NULL list

     */

    QDECREF(parser->tokens);

    parser->tokens = NULL;

out_emit:

    /* send current list of tokens to parser and reset tokenizer */

    parser->brace_count = 0;

    parser->bracket_count = 0;

    parser->emit(parser, parser->tokens);

    if (parser->tokens) {

        QDECREF(parser->tokens);

    }

    parser->tokens = qlist_new();

    parser->token_size = 0;

}


static bool gen_wsr_ccompare(DisasContext *dc, uint32_t sr, TCGv_i32 v)

{

    uint32_t id = sr - CCOMPARE;

    bool ret = false;

    if (id < dc->config->nccompare) {

        uint32_t int_bit = 1 << dc->config->timerint[id];

        TCGv_i32 tmp = tcg_const_i32(id);

        tcg_gen_mov_i32(cpu_SR[sr], v);

        tcg_gen_andi_i32(cpu_SR[INTSET], cpu_SR[INTSET], ~int_bit);

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

            gen_io_start();

        }

        gen_helper_update_ccompare(cpu_env, tmp);

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

            gen_io_end();

            gen_jumpi_check_loop_end(dc, 0);

            ret = true;

        }

        tcg_temp_free(tmp);

    }

    return ret;

}


static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size)

{

    uint8_t buf[4];

    if (vs->depth == 4) {

        uint32_t *pixels = pixels1;

        int n, i;

        n = size >> 2;

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

            vnc_convert_pixel(vs, buf, pixels[i]);

            vnc_write(vs, buf, vs->pix_bpp);

        }

    } else if (vs->depth == 2) {

        uint16_t *pixels = pixels1;

        int n, i;

        n = size >> 1;

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

            vnc_convert_pixel(vs, buf, pixels[i]);

            vnc_write(vs, buf, vs->pix_bpp);

        }

    } else if (vs->depth == 1) {

        uint8_t *pixels = pixels1;

        int n, i;

        n = size;

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

            vnc_convert_pixel(vs, buf, pixels[i]);

            vnc_write(vs, buf, vs->pix_bpp);

        }

    } else {

        fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");

    }

}


static int parse_tonal(DCALbrDecoder *s, int group)

{

    unsigned int amp[DCA_LBR_CHANNELS_TOTAL];

    unsigned int phs[DCA_LBR_CHANNELS_TOTAL];

    unsigned int diff, main_amp, shift;

    int sf, sf_idx, ch, main_ch, freq;

    int ch_nbits = av_ceil_log2(s->nchannels_total);

    // Parse subframes for this group

    for (sf = 0; sf < 1 << group; sf += diff ? 8 : 1) {

        sf_idx = ((s->framenum << group) + sf) & 31;

        s->tonal_bounds[group][sf_idx][0] = s->ntones;

        // Parse tones for this subframe

        for (freq = 1;; freq++) {

            if (get_bits_left(&s->gb) < 1) {

                av_log(s->avctx, AV_LOG_ERROR, "Tonal group chunk too short\n");

                return -1;

            }

            diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], 2);

            if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n");

                return -1;

            }

            diff = get_bitsz(&s->gb, diff >> 2) + ff_dca_fst_amp[diff];

            if (diff <= 1)

                break;  // End of subframe

            freq += diff - 2;

            if (freq >> (5 - group) > s->nsubbands * 4 - 5) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid spectral line offset\n");

                return -1;

            }

            // Main channel

            main_ch = get_bitsz(&s->gb, ch_nbits);

            main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, 2)

                + s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]]

                + s->limited_range - 2;

            amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0;

            phs[main_ch] = get_bits(&s->gb, 3);

            // Secondary channels

            for (ch = 0; ch < s->nchannels_total; ch++) {

                if (ch == main_ch)

                    continue;

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

                    amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, 1);

                    phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph,  1);

                } else {

                    amp[ch] = 0;

                    phs[ch] = 0;

                }

            }

            if (amp[main_ch]) {

                // Allocate new tone

                DCALbrTone *t = &s->tones[s->ntones];

                s->ntones = (s->ntones + 1) & (DCA_LBR_TONES - 1);

                t->x_freq = freq >> (5 - group);

                t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group;

                t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4;

                shift = ff_dca_ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)]

                    - ((t->ph_rot << (5 - group)) - t->ph_rot);

                for (ch = 0; ch < s->nchannels; ch++) {

                    t->amp[ch] = amp[ch] < AMP_MAX ? amp[ch] : 0;

                    t->phs[ch] = 128 - phs[ch] * 32 + shift;

                }

            }

        }

        s->tonal_bounds[group][sf_idx][1] = s->ntones;

    }

    return 0;

}


static uint64_t mv88w8618_eth_read(void *opaque, hwaddr offset,

                                   unsigned size)

{

    mv88w8618_eth_state *s = opaque;

    switch (offset) {

    case MP_ETH_SMIR:

        if (s->smir & MP_ETH_SMIR_OPCODE) {

            switch (s->smir & MP_ETH_SMIR_ADDR) {

            case MP_ETH_PHY1_BMSR:

                return MP_PHY_BMSR_LINK | MP_PHY_BMSR_AUTONEG |

                       MP_ETH_SMIR_RDVALID;

            case MP_ETH_PHY1_PHYSID1:

                return (MP_PHY_88E3015 >> 16) | MP_ETH_SMIR_RDVALID;

            case MP_ETH_PHY1_PHYSID2:

                return (MP_PHY_88E3015 & 0xFFFF) | MP_ETH_SMIR_RDVALID;

            default:

                return MP_ETH_SMIR_RDVALID;

            }

        }

        return 0;

    case MP_ETH_ICR:

        return s->icr;

    case MP_ETH_IMR:

        return s->imr;

    case MP_ETH_FRDP0 ... MP_ETH_FRDP3:

        return s->frx_queue[(offset - MP_ETH_FRDP0)/4];

    case MP_ETH_CRDP0 ... MP_ETH_CRDP3:

        return s->rx_queue[(offset - MP_ETH_CRDP0)/4];

    case MP_ETH_CTDP0 ... MP_ETH_CTDP3:

        return s->tx_queue[(offset - MP_ETH_CTDP0)/4];

    default:

        return 0;

    }

}


static int make_cdt16_entry(int p1, int p2, int16_t *cdt)

{

    int r, b, lo;

    b = cdt[p2];

    r = cdt[p1] << 11;

    lo = b + r;

    return (lo + (lo << 16)) << 1;

}


static void monitor_call_handler(Monitor *mon, const mon_cmd_t *cmd,

                                 const QDict *params)

{

    QObject *data = NULL;

    cmd->mhandler.cmd_new(mon, params, &data);

    if (is_async_return(data)) {

        /*

         * Asynchronous commands have no initial return data but they can

         * generate errors.  Data is returned via the async completion handler.

         */

        if (monitor_ctrl_mode(mon) && monitor_has_error(mon)) {

            monitor_protocol_emitter(mon, NULL);

        }

    } else if (monitor_ctrl_mode(mon)) {

        /* Monitor Protocol */

        monitor_protocol_emitter(mon, data);

    } else {

        /* User Protocol */

         if (data)

            cmd->user_print(mon, data);

    }

    qobject_decref(data);

}


static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,

                                       bool write)

{

    BDRVVPCState *s = bs->opaque;

    uint64_t bitmap_offset, block_offset;

    uint32_t pagetable_index, offset_in_block;

    pagetable_index = offset / s->block_size;

    offset_in_block = offset % s->block_size;

    if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)

        return -1; /* not allocated */

    bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];

    block_offset = bitmap_offset + s->bitmap_size + offset_in_block;

    /* We must ensure that we don't write to any sectors which are marked as

       unused in the bitmap. We get away with setting all bits in the block

       bitmap each time we write to a new block. This might cause Virtual PC to

       miss sparse read optimization, but it's not a problem in terms of

       correctness. */

    if (write && (s->last_bitmap_offset != bitmap_offset)) {

        uint8_t bitmap[s->bitmap_size];

        s->last_bitmap_offset = bitmap_offset;

        memset(bitmap, 0xff, s->bitmap_size);

        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);

    }

    return block_offset;

}


static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,

                                unsigned len)

{

    OpenPICState *opp = opaque;

    int idx;

    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);

    if (addr & 0xF)

        return;

    idx = (addr >> 6) & 0x3;

    addr = addr & 0x30;

    if (addr == 0x0) {

        /* TIFR (TFRR) */

        opp->tifr = val;

        return;

    }

    switch (addr & 0x30) {

    case 0x00: /* TICC (GTCCR) */

        break;

    case 0x10: /* TIBC (GTBCR) */

        if ((opp->timers[idx].ticc & TICC_TOG) != 0 &&

            (val & TIBC_CI) == 0 &&

            (opp->timers[idx].tibc & TIBC_CI) != 0) {

            opp->timers[idx].ticc &= ~TICC_TOG;

        }

        opp->timers[idx].tibc = val;

        break;

    case 0x20: /* TIVP (GTIVPR) */

        write_IRQreg_ipvp(opp, opp->irq_tim0 + idx, val);

        break;

    case 0x30: /* TIDE (GTIDR) */

        write_IRQreg_ide(opp, opp->irq_tim0 + idx, val);

        break;

    }

}


int load_vmstate(const char *name, Error **errp)

{

    BlockDriverState *bs, *bs_vm_state;

    QEMUSnapshotInfo sn;

    QEMUFile *f;

    int ret;

    AioContext *aio_context;

    MigrationIncomingState *mis = migration_incoming_get_current();

    if (!bdrv_all_can_snapshot(&bs)) {

        error_setg(errp,

                   "Device '%s' is writable but does not support snapshots",

                   bdrv_get_device_name(bs));

        return -ENOTSUP;

    }

    ret = bdrv_all_find_snapshot(name, &bs);

    if (ret < 0) {

        error_setg(errp,

                   "Device '%s' does not have the requested snapshot '%s'",

                   bdrv_get_device_name(bs), name);

        return ret;

    }

    bs_vm_state = bdrv_all_find_vmstate_bs();

    if (!bs_vm_state) {

        error_setg(errp, "No block device supports snapshots");

        return -ENOTSUP;

    }

    aio_context = bdrv_get_aio_context(bs_vm_state);

    /* Don't even try to load empty VM states */

    aio_context_acquire(aio_context);

    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);

    aio_context_release(aio_context);

    if (ret < 0) {

        return ret;

    } else if (sn.vm_state_size == 0) {

        error_setg(errp, "This is a disk-only snapshot. Revert to it "

                   " offline using qemu-img");

        return -EINVAL;

    }

    /* Flush all IO requests so they don't interfere with the new state.  */

    bdrv_drain_all();

    ret = bdrv_all_goto_snapshot(name, &bs);

    if (ret < 0) {

        error_setg(errp, "Error %d while activating snapshot '%s' on '%s'",

                     ret, name, bdrv_get_device_name(bs));

        return ret;

    }

    /* restore the VM state */

    f = qemu_fopen_bdrv(bs_vm_state, 0);

    if (!f) {

        error_setg(errp, "Could not open VM state file");

        return -EINVAL;

    }

    qemu_system_reset(VMRESET_SILENT);

    mis->from_src_file = f;

    aio_context_acquire(aio_context);

    ret = qemu_loadvm_state(f);

    qemu_fclose(f);

    aio_context_release(aio_context);

    migration_incoming_state_destroy();

    if (ret < 0) {

        error_setg(errp, "Error %d while loading VM state", ret);

        return ret;

    }

    return 0;

}


CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,

                                    void (*init)(struct CharDriverState *s),

                                    Error **errp)

{

    CharDriver *cd;

    CharDriverState *chr;

    GSList *i;

    if (qemu_opts_id(opts) == NULL) {

        error_setg(errp, "chardev: no id specified");

        goto err;

    }

    if (qemu_opt_get(opts, "backend") == NULL) {

        error_setg(errp, "chardev: \"%s\" missing backend",

                   qemu_opts_id(opts));

        goto err;

    }

    for (i = backends; i; i = i->next) {

        cd = i->data;

        if (strcmp(cd->name, qemu_opt_get(opts, "backend")) == 0) {

            break;

        }

    }

    if (i == NULL) {

        error_setg(errp, "chardev: backend \"%s\" not found",

                   qemu_opt_get(opts, "backend"));

        goto err;

    }

    if (!cd->open) {

        /* using new, qapi init */

        ChardevBackend *backend = g_new0(ChardevBackend, 1);

        ChardevReturn *ret = NULL;

        const char *id = qemu_opts_id(opts);

        const char *bid = NULL;

        if (qemu_opt_get_bool(opts, "mux", 0)) {

            bid = g_strdup_printf("%s-base", id);

        }

        chr = NULL;

        backend->kind = cd->kind;

        if (cd->parse) {

            cd->parse(opts, backend, errp);

            if (error_is_set(errp)) {

                goto qapi_out;

            }

        }

        ret = qmp_chardev_add(bid ? bid : id, backend, errp);

        if (error_is_set(errp)) {

            goto qapi_out;

        }

        if (bid) {

            qapi_free_ChardevBackend(backend);

            qapi_free_ChardevReturn(ret);

            backend = g_new0(ChardevBackend, 1);

            backend->mux = g_new0(ChardevMux, 1);

            backend->kind = CHARDEV_BACKEND_KIND_MUX;

            backend->mux->chardev = g_strdup(bid);

            ret = qmp_chardev_add(id, backend, errp);

            if (error_is_set(errp)) {

                goto qapi_out;

            }

        }

        chr = qemu_chr_find(id);

    qapi_out:

        qapi_free_ChardevBackend(backend);

        qapi_free_ChardevReturn(ret);

        return chr;

    }

    chr = cd->open(opts);

    if (!chr) {

        error_setg(errp, "chardev: opening backend \"%s\" failed",

                   qemu_opt_get(opts, "backend"));

        goto err;

    }

    if (!chr->filename)

        chr->filename = g_strdup(qemu_opt_get(opts, "backend"));

    chr->init = init;

    /* if we didn't create the chardev via qmp_chardev_add, we

     * need to send the OPENED event here

     */

    if (!chr->explicit_be_open) {

        qemu_chr_be_event(chr, CHR_EVENT_OPENED);

    }

    QTAILQ_INSERT_TAIL(&chardevs, chr, next);

    if (qemu_opt_get_bool(opts, "mux", 0)) {

        CharDriverState *base = chr;

        int len = strlen(qemu_opts_id(opts)) + 6;

        base->label = g_malloc(len);

        snprintf(base->label, len, "%s-base", qemu_opts_id(opts));

        chr = qemu_chr_open_mux(base);

        chr->filename = base->filename;

        chr->avail_connections = MAX_MUX;

        QTAILQ_INSERT_TAIL(&chardevs, chr, next);

    } else {

        chr->avail_connections = 1;

    }

    chr->label = g_strdup(qemu_opts_id(opts));

    chr->opts = opts;

    return chr;

err:

    qemu_opts_del(opts);

    return NULL;

}


void ff_estimate_p_frame_motion(MpegEncContext * s,

                                int mb_x, int mb_y)

{

    MotionEstContext * const c= &s->me;

    uint8_t *pix, *ppix;

    int sum, mx, my, dmin;

    int varc;            ///< the variance of the block (sum of squared (p[y][x]-average))

    int vard;            ///< sum of squared differences with the estimated motion vector

    int P[10][2];

    const int shift= 1+s->quarter_sample;

    int mb_type=0;

    Picture * const pic= &s->current_picture;

    init_ref(c, s->new_picture.f.data, s->last_picture.f.data, NULL, 16*mb_x, 16*mb_y, 0);

    assert(s->quarter_sample==0 || s->quarter_sample==1);

    assert(s->linesize == c->stride);

    assert(s->uvlinesize == c->uvstride);

    c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);

    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);

    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);

    c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;

    get_limits(s, 16*mb_x, 16*mb_y);

    c->skip=0;

    /* intra / predictive decision */

    pix = c->src[0][0];

    sum = s->dsp.pix_sum(pix, s->linesize);

    varc = s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500;

    pic->mb_mean[s->mb_stride * mb_y + mb_x] = (sum+128)>>8;

    pic->mb_var [s->mb_stride * mb_y + mb_x] = (varc+128)>>8;

    c->mb_var_sum_temp += (varc+128)>>8;

    if(c->avctx->me_threshold){

        vard= check_input_motion(s, mb_x, mb_y, 1);

        if((vard+128)>>8 < c->avctx->me_threshold){

            int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);

            int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;

            pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;

            c->mc_mb_var_sum_temp += (vard+128)>>8;

            c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);

            return;

        }

        if((vard+128)>>8 < c->avctx->mb_threshold)

            mb_type= s->mb_type[mb_x + mb_y*s->mb_stride];

    }

    switch(s->me_method) {

    case ME_ZERO:

    default:

        no_motion_search(s, &mx, &my);

        mx-= mb_x*16;

        my-= mb_y*16;

        dmin = 0;

        break;

    case ME_X1:

    case ME_EPZS:

       {

            const int mot_stride = s->b8_stride;

            const int mot_xy = s->block_index[0];

            P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];

            P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];

            if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);

            if(!s->first_slice_line) {

                P_TOP[0]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][0];

                P_TOP[1]      = s->current_picture.f.motion_val[0][mot_xy - mot_stride    ][1];

                P_TOPRIGHT[0] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][0];

                P_TOPRIGHT[1] = s->current_picture.f.motion_val[0][mot_xy - mot_stride + 2][1];

                if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);

                if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);

                if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);

                P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);

                P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);

                if(s->out_format == FMT_H263){

                    c->pred_x = P_MEDIAN[0];

                    c->pred_y = P_MEDIAN[1];

                }else { /* mpeg1 at least */

                    c->pred_x= P_LEFT[0];

                    c->pred_y= P_LEFT[1];

                }

            }else{

                c->pred_x= P_LEFT[0];

                c->pred_y= P_LEFT[1];

            }

        }

        dmin = ff_epzs_motion_search(s, &mx, &my, P, 0, 0, s->p_mv_table, (1<<16)>>shift, 0, 16);

        break;

    }

    /* At this point (mx,my) are full-pell and the relative displacement */

    ppix = c->ref[0][0] + (my * s->linesize) + mx;

    vard = s->dsp.sse[0](NULL, pix, ppix, s->linesize, 16);

    pic->mc_mb_var[s->mb_stride * mb_y + mb_x] = (vard+128)>>8;

//    pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;

    c->mc_mb_var_sum_temp += (vard+128)>>8;

    if(mb_type){

        int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);

        int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;

        c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);

        if(mb_type == CANDIDATE_MB_TYPE_INTER){

            c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);

            set_p_mv_tables(s, mx, my, 1);

        }else{

            mx <<=shift;

            my <<=shift;

        }

        if(mb_type == CANDIDATE_MB_TYPE_INTER4V){

            h263_mv4_search(s, mx, my, shift);

            set_p_mv_tables(s, mx, my, 0);

        }

        if(mb_type == CANDIDATE_MB_TYPE_INTER_I){

            interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 1);

        }

    }else if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){

        int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);

        int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;

        c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);

        if (vard*2 + 200*256 > varc)

            mb_type|= CANDIDATE_MB_TYPE_INTRA;

        if (varc*2 + 200*256 > vard || s->qscale > 24){

//        if (varc*2 + 200*256 + 50*(s->lambda2>>FF_LAMBDA_SHIFT) > vard){

            mb_type|= CANDIDATE_MB_TYPE_INTER;

            c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);

            if(s->flags&CODEC_FLAG_MV0)

                if(mx || my)

                    mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference

        }else{

            mx <<=shift;

            my <<=shift;

        }

        if((s->flags&CODEC_FLAG_4MV)

           && !c->skip && varc>50<<8 && vard>10<<8){

            if(h263_mv4_search(s, mx, my, shift) < INT_MAX)

                mb_type|=CANDIDATE_MB_TYPE_INTER4V;

            set_p_mv_tables(s, mx, my, 0);

        }else

            set_p_mv_tables(s, mx, my, 1);

        if((s->flags&CODEC_FLAG_INTERLACED_ME)

           && !c->skip){ //FIXME varc/d checks

            if(interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0) < INT_MAX)

                mb_type |= CANDIDATE_MB_TYPE_INTER_I;

        }

    }else{

        int intra_score, i;

        mb_type= CANDIDATE_MB_TYPE_INTER;

        dmin= c->sub_motion_search(s, &mx, &my, dmin, 0, 0, 0, 16);

        if(c->avctx->me_sub_cmp != c->avctx->mb_cmp && !c->skip)

            dmin= ff_get_mb_score(s, mx, my, 0, 0, 0, 16, 1);

        if((s->flags&CODEC_FLAG_4MV)

           && !c->skip && varc>50<<8 && vard>10<<8){

            int dmin4= h263_mv4_search(s, mx, my, shift);

            if(dmin4 < dmin){

                mb_type= CANDIDATE_MB_TYPE_INTER4V;

                dmin=dmin4;

            }

        }

        if((s->flags&CODEC_FLAG_INTERLACED_ME)

           && !c->skip){ //FIXME varc/d checks

            int dmin_i= interlaced_search(s, 0, s->p_field_mv_table, s->p_field_select_table, mx, my, 0);

            if(dmin_i < dmin){

                mb_type = CANDIDATE_MB_TYPE_INTER_I;

                dmin= dmin_i;

            }

        }

//        pic->mb_cmp_score[s->mb_stride * mb_y + mb_x] = dmin;

        set_p_mv_tables(s, mx, my, mb_type!=CANDIDATE_MB_TYPE_INTER4V);

        /* get intra luma score */

        if((c->avctx->mb_cmp&0xFF)==FF_CMP_SSE){

            intra_score= varc - 500;

        }else{

            int mean= (sum+128)>>8;

            mean*= 0x01010101;

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

                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 0]) = mean;

                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 4]) = mean;

                *(uint32_t*)(&c->scratchpad[i*s->linesize+ 8]) = mean;

                *(uint32_t*)(&c->scratchpad[i*s->linesize+12]) = mean;

            }

            intra_score= s->dsp.mb_cmp[0](s, c->scratchpad, pix, s->linesize, 16);

        }

        intra_score += c->mb_penalty_factor*16;

        if(intra_score < dmin){

            mb_type= CANDIDATE_MB_TYPE_INTRA;

            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = CANDIDATE_MB_TYPE_INTRA; //FIXME cleanup

        }else

            s->current_picture.f.mb_type[mb_y*s->mb_stride + mb_x] = 0;

        {

            int p_score= FFMIN(vard, varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*100);

            int i_score= varc-500+(s->lambda2>>FF_LAMBDA_SHIFT)*20;

            c->scene_change_score+= ff_sqrt(p_score) - ff_sqrt(i_score);

        }

    }

    s->mb_type[mb_y*s->mb_stride + mb_x]= mb_type;

}