static int compute_bit_allocation(AC3EncodeContext *s,

                                  uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],

                                  uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],

                                  uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS],

                                  int frame_bits)

{

    int i, ch;

    int csnroffst, fsnroffst;

    uint8_t bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2];

    static int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 };

    /* init default parameters */

    s->sdecaycod = 2;

    s->fdecaycod = 1;

    s->sgaincod = 1;

    s->dbkneecod = 2;

    s->floorcod = 4;

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

        s->fgaincod[ch] = 4;

    /* compute real values */

    s->bit_alloc.fscod = s->fscod;

    s->bit_alloc.halfratecod = s->halfratecod;

    s->bit_alloc.sdecay = sdecaytab[s->sdecaycod] >> s->halfratecod;

    s->bit_alloc.fdecay = fdecaytab[s->fdecaycod] >> s->halfratecod;

    s->bit_alloc.sgain = sgaintab[s->sgaincod];

    s->bit_alloc.dbknee = dbkneetab[s->dbkneecod];

    s->bit_alloc.floor = floortab[s->floorcod];

    /* header size */

    frame_bits += 65;

    // if (s->acmod == 2)

    //    frame_bits += 2;

    frame_bits += frame_bits_inc[s->acmod];

    /* audio blocks */

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

        frame_bits += s->nb_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */

        if (s->acmod == 2)

            frame_bits++; /* rematstr */

        frame_bits += 2 * s->nb_channels; /* chexpstr[2] * c */

	if (s->lfe)

	    frame_bits++; /* lfeexpstr */

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

            if (exp_strategy[i][ch] != EXP_REUSE)

                frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */

        }

        frame_bits++; /* baie */

        frame_bits++; /* snr */

        frame_bits += 2; /* delta / skip */

    }

    frame_bits++; /* cplinu for block 0 */

    /* bit alloc info */

    /* sdcycod[2], fdcycod[2], sgaincod[2], dbpbcod[2], floorcod[3] */

    /* csnroffset[6] */

    /* (fsnoffset[4] + fgaincod[4]) * c */

    frame_bits += 2*4 + 3 + 6 + s->nb_all_channels * (4 + 3);

    /* auxdatae, crcrsv */

    frame_bits += 2;

    /* CRC */

    frame_bits += 16;

    /* now the big work begins : do the bit allocation. Modify the snr

       offset until we can pack everything in the requested frame size */

    csnroffst = s->csnroffst;

    while (csnroffst >= 0 &&

	   bit_alloc(s, bap, encoded_exp, exp_strategy, frame_bits, csnroffst, 0) < 0)

	csnroffst -= SNR_INC1;

    if (csnroffst < 0) {

	av_log(NULL, AV_LOG_ERROR, "Yack, Error !!!\n");

	return -1;

    }

    while ((csnroffst + SNR_INC1) <= 63 &&

           bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits,

                     csnroffst + SNR_INC1, 0) >= 0) {

        csnroffst += SNR_INC1;

        memcpy(bap, bap1, sizeof(bap1));

    }

    while ((csnroffst + 1) <= 63 &&

           bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, csnroffst + 1, 0) >= 0) {

        csnroffst++;

        memcpy(bap, bap1, sizeof(bap1));

    }

    fsnroffst = 0;

    while ((fsnroffst + SNR_INC1) <= 15 &&

           bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits,

                     csnroffst, fsnroffst + SNR_INC1) >= 0) {

        fsnroffst += SNR_INC1;

        memcpy(bap, bap1, sizeof(bap1));

    }

    while ((fsnroffst + 1) <= 15 &&

           bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits,

                     csnroffst, fsnroffst + 1) >= 0) {

        fsnroffst++;

        memcpy(bap, bap1, sizeof(bap1));

    }

    s->csnroffst = csnroffst;

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

        s->fsnroffst[ch] = fsnroffst;

#if defined(DEBUG_BITALLOC)

    {

        int j;

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

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

                printf("Block #%d Ch%d:\n", i, ch);

                printf("bap=");

                for(j=0;j<s->nb_coefs[ch];j++) {

                    printf("%d ",bap[i][ch][j]);

                }

                printf("\n");

            }

        }

    }

#endif

    return 0;

}


static void decode_plane_bitstream(HYuvContext *s, int count, int plane)

{

    int i;

    count /= 2;

    if (s->bps <= 8) {

        OPEN_READER(re, &s->gb);

        if (count >= (get_bits_left(&s->gb)) / (32 * 2)) {

            for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {

                READ_2PIX_PLANE(s->temp[0][2 * i], s->temp[0][2 * i + 1], plane, OP8bits);

            }

        } else {

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

                READ_2PIX_PLANE(s->temp[0][2 * i], s->temp[0][2 * i + 1], plane, OP8bits);

            }

        }

        CLOSE_READER(re, &s->gb);

    } else if (s->bps <= 14) {

        OPEN_READER(re, &s->gb);

        if (count >= (get_bits_left(&s->gb)) / (32 * 2)) {

            for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {

                READ_2PIX_PLANE(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane, OP14bits);

            }

        } else {

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

                READ_2PIX_PLANE(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane, OP14bits);

            }

        }

        CLOSE_READER(re, &s->gb);

    } else {

        if (count >= (get_bits_left(&s->gb)) / (32 * 2)) {

            for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) {

                READ_2PIX_PLANE16(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane);

            }

        } else {

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

                READ_2PIX_PLANE16(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane);

            }

        }

    }

}


static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)

{

    dprint(d, 1, "%s: start%s\n", __FUNCTION__,

           loadvm ? " (loadvm)" : "");

    qemu_mutex_unlock_iothread();

    d->ssd.worker->reset_cursor(d->ssd.worker);

    d->ssd.worker->reset_image_cache(d->ssd.worker);

    qemu_mutex_lock_iothread();

    qxl_reset_surfaces(d);

    qxl_reset_memslots(d);

    /* pre loadvm reset must not touch QXLRam.  This lives in

     * device memory, is migrated together with RAM and thus

     * already loaded at this point */

    if (!loadvm) {

        qxl_reset_state(d);

    }

    qemu_spice_create_host_memslot(&d->ssd);

    qxl_soft_reset(d);

    dprint(d, 1, "%s: done\n", __FUNCTION__);

}


int ff_rv34_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    RV34DecContext *r = avctx->priv_data;

    MpegEncContext *s = &r->s;

    AVFrame *pict = data;

    SliceInfo si;

    int i;

    int slice_count;

    const uint8_t *slices_hdr = NULL;

    int last = 0;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict = *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr = NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(!avctx->slice_count){

        slice_count = (*buf++) + 1;

        slices_hdr = buf + 4;

        buf += 8 * slice_count;

        buf_size -= 1 + 8 * slice_count;

    }else

        slice_count = avctx->slice_count;

    //parse first slice header to check whether this frame can be decoded

    if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){

        av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");

        return -1;

    }

    init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);

    if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){

        av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");

        return -1;

    }

    if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B)

        return -1;

    if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)

       || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)

       ||  avctx->skip_frame >= AVDISCARD_ALL)

        return avpkt->size;

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

        int offset = get_slice_offset(avctx, slices_hdr, i);

        int size;

        if(i+1 == slice_count)

            size = buf_size - offset;

        else

            size = get_slice_offset(avctx, slices_hdr, i+1) - offset;

        if(offset > buf_size){

            av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");

            break;

        }

        r->si.end = s->mb_width * s->mb_height;

        if(i+1 < slice_count){

            init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);

            if(r->parse_slice_header(r, &r->s.gb, &si) < 0){

                if(i+2 < slice_count)

                    size = get_slice_offset(avctx, slices_hdr, i+2) - offset;

                else

                    size = buf_size - offset;

            }else

                r->si.end = si.start;

        }

        last = rv34_decode_slice(r, r->si.end, buf + offset, size);

        s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;

        if(last)

            break;

    }

    if(last && s->current_picture_ptr){

        if(r->loop_filter)

            r->loop_filter(r, s->mb_height - 1);

        ff_er_frame_end(s);

        MPV_frame_end(s);

        if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {

            *pict = *(AVFrame*)s->current_picture_ptr;

        } else if (s->last_picture_ptr != NULL) {

            *pict = *(AVFrame*)s->last_picture_ptr;

        }

        if(s->last_picture_ptr || s->low_delay){

            *data_size = sizeof(AVFrame);

            ff_print_debug_info(s, pict);

        }

        s->current_picture_ptr = NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)

    }

    return avpkt->size;

}


static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,

                          int remaining_sectors, QEMUIOVector *qiov)

{

    BDRVQcowState *s = bs->opaque;

    int index_in_cluster, n1;

    int ret;

    int cur_nr_sectors; /* number of sectors in current iteration */

    uint64_t cluster_offset = 0;

    uint64_t bytes_done = 0;

    QEMUIOVector hd_qiov;

    uint8_t *cluster_data = NULL;

    qemu_iovec_init(&hd_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    while (remaining_sectors != 0) {

        /* prepare next request */

        cur_nr_sectors = remaining_sectors;

        if (s->crypt_method) {

            cur_nr_sectors = MIN(cur_nr_sectors,

                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);

        }

        ret = qcow2_get_cluster_offset(bs, sector_num << 9,

            &cur_nr_sectors, &cluster_offset);

        if (ret < 0) {

            goto fail;

        }

        index_in_cluster = sector_num & (s->cluster_sectors - 1);

        qemu_iovec_reset(&hd_qiov);

        qemu_iovec_concat(&hd_qiov, qiov, bytes_done,

            cur_nr_sectors * 512);

        switch (ret) {

        case QCOW2_CLUSTER_UNALLOCATED:

            if (bs->backing_hd) {

                /* read from the base image */

                n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,

                    sector_num, cur_nr_sectors);

                if (n1 > 0) {

                    QEMUIOVector local_qiov;

                    qemu_iovec_init(&local_qiov, hd_qiov.niov);

                    qemu_iovec_concat(&local_qiov, &hd_qiov, 0,

                                      n1 * BDRV_SECTOR_SIZE);

                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);

                    qemu_co_mutex_unlock(&s->lock);

                    ret = bdrv_co_readv(bs->backing_hd, sector_num,

                                        n1, &local_qiov);

                    qemu_co_mutex_lock(&s->lock);

                    qemu_iovec_destroy(&local_qiov);

                    if (ret < 0) {

                        goto fail;

                    }

                }

            } else {

                /* Note: in this case, no need to wait */

                qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);

            }

            break;

        case QCOW2_CLUSTER_ZERO:

            qemu_iovec_memset(&hd_qiov, 0, 0, 512 * cur_nr_sectors);

            break;

        case QCOW2_CLUSTER_COMPRESSED:

            /* add AIO support for compressed blocks ? */

            ret = qcow2_decompress_cluster(bs, cluster_offset);

            if (ret < 0) {

                goto fail;

            }

            qemu_iovec_from_buf(&hd_qiov, 0,

                s->cluster_cache + index_in_cluster * 512,

                512 * cur_nr_sectors);

            break;

        case QCOW2_CLUSTER_NORMAL:

            if ((cluster_offset & 511) != 0) {

                ret = -EIO;

                goto fail;

            }

            if (s->crypt_method) {

                /*

                 * For encrypted images, read everything into a temporary

                 * contiguous buffer on which the AES functions can work.

                 */

                if (!cluster_data) {

                    cluster_data =

                        qemu_try_blockalign(bs->file, QCOW_MAX_CRYPT_CLUSTERS

                                                      * s->cluster_size);

                    if (cluster_data == NULL) {

                        ret = -ENOMEM;

                        goto fail;

                    }

                }

                assert(cur_nr_sectors <=

                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);

                qemu_iovec_reset(&hd_qiov);

                qemu_iovec_add(&hd_qiov, cluster_data,

                    512 * cur_nr_sectors);

            }

            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);

            qemu_co_mutex_unlock(&s->lock);

            ret = bdrv_co_readv(bs->file,

                                (cluster_offset >> 9) + index_in_cluster,

                                cur_nr_sectors, &hd_qiov);

            qemu_co_mutex_lock(&s->lock);

            if (ret < 0) {

                goto fail;

            }

            if (s->crypt_method) {

                qcow2_encrypt_sectors(s, sector_num,  cluster_data,

                    cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);

                qemu_iovec_from_buf(qiov, bytes_done,

                    cluster_data, 512 * cur_nr_sectors);

            }

            break;

        default:

            g_assert_not_reached();

            ret = -EIO;

            goto fail;

        }

        remaining_sectors -= cur_nr_sectors;

        sector_num += cur_nr_sectors;

        bytes_done += cur_nr_sectors * 512;

    }

    ret = 0;

fail:

    qemu_co_mutex_unlock(&s->lock);

    qemu_iovec_destroy(&hd_qiov);

    qemu_vfree(cluster_data);

    return ret;

}


static int mov_write_udta_tag(ByteIOContext *pb, MOVMuxContext *mov,

                              AVFormatContext *s)

{

    ByteIOContext *pb_buf;

    int i, ret, size;

    uint8_t *buf;

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

        if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {

            return 0;

        }

    ret = url_open_dyn_buf(&pb_buf);

    if(ret < 0)

        return ret;

        if (mov->mode & MODE_3GP) {

            mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");

            mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");

            mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");

            mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");

            mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");

            mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");

            mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");

            mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");

        } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4

            mov_write_string_metadata(s, pb_buf, "\251nam", "title"      , 0);

            mov_write_string_metadata(s, pb_buf, "\251aut", "author"     , 0);

            mov_write_string_metadata(s, pb_buf, "\251alb", "album"      , 0);

            mov_write_string_metadata(s, pb_buf, "\251day", "date"       , 0);

            mov_write_string_tag(pb_buf, "\251enc", LIBAVFORMAT_IDENT, 0, 0);

            mov_write_string_metadata(s, pb_buf, "\251des", "comment"    , 0);

            mov_write_string_metadata(s, pb_buf, "\251gen", "genre"      , 0);

            mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright"  , 0);

        } else {

            /* iTunes meta data */

            mov_write_meta_tag(pb_buf, mov, s);

        }

        if (s->nb_chapters)

            mov_write_chpl_tag(pb_buf, s);

    if ((size = url_close_dyn_buf(pb_buf, &buf)) > 0) {

        put_be32(pb, size+8);

        put_tag(pb, "udta");

        put_buffer(pb, buf, size);

        av_free(buf);

    }

    return 0;

}


static void gen_tlbwe_booke206(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

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

    gen_helper_booke206_tlbwe(cpu_env);

#endif

}


static void serial_xmit(SerialState *s)

{

    do {

        assert(!(s->lsr & UART_LSR_TEMT));

        if (s->tsr_retry == 0) {

            assert(!(s->lsr & UART_LSR_THRE));

            if (s->fcr & UART_FCR_FE) {

                assert(!fifo8_is_empty(&s->xmit_fifo));

                s->tsr = fifo8_pop(&s->xmit_fifo);

                if (!s->xmit_fifo.num) {

                    s->lsr |= UART_LSR_THRE;

                }

            } else {

                s->tsr = s->thr;

                s->lsr |= UART_LSR_THRE;

            }

            if ((s->lsr & UART_LSR_THRE) && !s->thr_ipending) {

                s->thr_ipending = 1;

                serial_update_irq(s);

            }

        }

        if (s->mcr & UART_MCR_LOOP) {

            /* in loopback mode, say that we just received a char */

            serial_receive1(s, &s->tsr, 1);

        } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {

            if (s->tsr_retry < MAX_XMIT_RETRY &&

                qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,

                                      serial_watch_cb, s) > 0) {

                s->tsr_retry++;

                return;

            }

        }

        s->tsr_retry = 0;

        /* Transmit another byte if it is already available. It is only

           possible when FIFO is enabled and not empty. */

    } while (!(s->lsr & UART_LSR_THRE));

    s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

    s->lsr |= UART_LSR_TEMT;

}


void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict)

{

    struct in_addr host_addr = { .s_addr = INADDR_ANY };

    int host_port;

    char buf[256] = "";

    const char *src_str, *p;

    SlirpState *s;

    int is_udp = 0;

    int err;

    const char *arg1 = qdict_get_str(qdict, "arg1");

    const char *arg2 = qdict_get_try_str(qdict, "arg2");

    const char *arg3 = qdict_get_try_str(qdict, "arg3");

    if (arg2) {

        s = slirp_lookup(mon, arg1, arg2);

        src_str = arg3;

    } else {

        s = slirp_lookup(mon, NULL, NULL);

        src_str = arg1;

    }

    if (!s) {

        return;

    }

    if (!src_str || !src_str[0])

        goto fail_syntax;

    p = src_str;

    get_str_sep(buf, sizeof(buf), &p, ':');

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

        is_udp = 0;

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

        is_udp = 1;

    } else {

        goto fail_syntax;

    }

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

        goto fail_syntax;

    }

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

        goto fail_syntax;

    }

    host_port = atoi(p);

    err = slirp_remove_hostfwd(QTAILQ_FIRST(&slirp_stacks)->slirp, is_udp,

                               host_addr, host_port);

    monitor_printf(mon, "host forwarding rule for %s %s\n", src_str,

                   err ? "removed" : "not found");

    return;

 fail_syntax:

    monitor_printf(mon, "invalid format\n");

}


static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    AVStream *st;

    MOVStreamContext *sc;

    unsigned int i, entries;

    int64_t duration=0;

    int64_t total_sample_count=0;

    if (c->fc->nb_streams < 1)

        return 0;

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

    sc = st->priv_data;

    avio_r8(pb); /* version */

    avio_rb24(pb); /* flags */

    entries = avio_rb32(pb);

    av_dlog(c->fc, "track[%i].stts.entries = %i\n",

            c->fc->nb_streams-1, entries);

    if (entries >= UINT_MAX / sizeof(*sc->stts_data))

        return -1;

    sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));

    if (!sc->stts_data)

        return AVERROR(ENOMEM);

    sc->stts_count = entries;

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

        int sample_duration;

        int sample_count;

        sample_count=avio_rb32(pb);

        sample_duration = avio_rb32(pb);

        sc->stts_data[i].count= sample_count;

        sc->stts_data[i].duration= sample_duration;

        av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",

                sample_count, sample_duration);

        duration+=(int64_t)sample_duration*sample_count;

        total_sample_count+=sample_count;

    }

    st->nb_frames= total_sample_count;

    if (duration)

        st->duration= duration;

    return 0;

}


static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)

{

    AVPacket pkt1, *pkt = &pkt1;

    ASFStream *asf_st;

    int64_t pts;

    int64_t pos= *ppos;

    int i;

    int64_t start_pos[ASF_MAX_STREAMS];

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

        start_pos[i]= pos;

    }

    if (s->packet_size > 0)

        pos= (pos+s->packet_size-1-s->data_offset)/s->packet_size*s->packet_size+ s->data_offset;

    *ppos= pos;

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

//printf("asf_read_pts\n");

    asf_reset_header(s);

    for(;;){

        if (av_read_frame(s, pkt) < 0){

            av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");

            return AV_NOPTS_VALUE;

        }

        pts= pkt->pts;

        av_free_packet(pkt);

        if(pkt->flags&AV_PKT_FLAG_KEY){

            i= pkt->stream_index;

            asf_st= s->streams[i]->priv_data;

//            assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0);

            pos= asf_st->packet_pos;

            av_add_index_entry(s->streams[i], pos, pts, pkt->size, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);

            start_pos[i]= asf_st->packet_pos + 1;

            if(pkt->stream_index == stream_index)

               break;

        }

    }

    *ppos= pos;

//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts);

    return pts;

}


static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,

                               Jpeg2000Component *comp,

                               Jpeg2000T1Context *t1, Jpeg2000Band *band)

{

    int i, j;

    int w = cblk->coord[0][1] - cblk->coord[0][0];

    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {

        int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];

        int *src = t1->data[j];

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

            datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<14)) >> 15;

    }

}


static void vmxnet3_update_features(VMXNET3State *s)

{

    uint32_t guest_features;

    int rxcso_supported;

    guest_features = VMXNET3_READ_DRV_SHARED32(s->drv_shmem,

                                               devRead.misc.uptFeatures);

    rxcso_supported = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_RXCSUM);

    s->rx_vlan_stripping = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_RXVLAN);

    s->lro_supported = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_LRO);

    VMW_CFPRN("Features configuration: LRO: %d, RXCSUM: %d, VLANSTRIP: %d",

              s->lro_supported, rxcso_supported,

              s->rx_vlan_stripping);

    if (s->peer_has_vhdr) {

        qemu_set_offload(qemu_get_queue(s->nic)->peer,

                         rxcso_supported,

                         s->lro_supported,

                         s->lro_supported,

                         0,

                         0);

    }

}


int object_property_get_enum(Object *obj, const char *name,

                             const char *typename, Error **errp)

{

    StringOutputVisitor *sov;

    StringInputVisitor *siv;

    char *str;

    int ret;

    ObjectProperty *prop = object_property_find(obj, name, errp);

    EnumProperty *enumprop;

    if (prop == NULL) {

        return 0;

    }

    if (!g_str_equal(prop->type, typename)) {

        error_setg(errp, "Property %s on %s is not '%s' enum type",

                   name, object_class_get_name(

                       object_get_class(obj)), typename);

        return 0;

    }

    enumprop = prop->opaque;

    sov = string_output_visitor_new(false);

    object_property_get(obj, string_output_get_visitor(sov), name, errp);

    str = string_output_get_string(sov);

    siv = string_input_visitor_new(str);

    string_output_visitor_cleanup(sov);

    visit_type_enum(string_input_get_visitor(siv),

                    &ret, enumprop->strings, NULL, name, errp);

    g_free(str);

    string_input_visitor_cleanup(siv);

    return ret;

}


void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)

{

    qemu_irq *irqs;

    int i;

    s->as = as;

    s->ports = ports;

    s->dev = g_malloc0(sizeof(AHCIDevice) * ports);

    ahci_reg_init(s);

    /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */

    memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,

                          "ahci", AHCI_MEM_BAR_SIZE);

    memory_region_init_io(&s->idp, OBJECT(qdev), &ahci_idp_ops, s,

                          "ahci-idp", 32);

    irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);

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

        AHCIDevice *ad = &s->dev[i];

        ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);

        ide_init2(&ad->port, irqs[i]);

        ad->hba = s;

        ad->port_no = i;

        ad->port.dma = &ad->dma;

        ad->port.dma->ops = &ahci_dma_ops;

    }

}


static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, int (*read_child)(), int ctx_size, enum MXFMetadataSetType type)

{

    ByteIOContext *pb = mxf->fc->pb;

    MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf;

    uint64_t klv_end = url_ftell(pb) + klv->length;

    if (!ctx)

        return -1;

    while (url_ftell(pb) + 4 < klv_end) {

        int tag = get_be16(pb);

        int size = get_be16(pb); /* KLV specified by 0x53 */

        uint64_t next = url_ftell(pb) + size;

        UID uid = {0};

        dprintf(mxf->fc, "local tag %#04x size %d\n", tag, size);

        if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */

            av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x with 0 size\n", tag);

            continue;

        }

        if (tag > 0x7FFF) { /* dynamic tag */

            int i;

            for (i = 0; i < mxf->local_tags_count; i++) {

                int local_tag = AV_RB16(mxf->local_tags+i*18);

                if (local_tag == tag) {

                    memcpy(uid, mxf->local_tags+i*18+2, 16);

                    dprintf(mxf->fc, "local tag %#04x\n", local_tag);

                    PRINT_KEY(mxf->fc, "uid", uid);

                }

            }

        }

        if (ctx_size && tag == 0x3C0A)

            get_buffer(pb, ctx->uid, 16);

        else if (read_child(ctx, pb, tag, size, uid) < 0)

            return -1;

        url_fseek(pb, next, SEEK_SET);

    }

    if (ctx_size) ctx->type = type;

    return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0;

}


void do_ddiv (void)

{

    if (T1 != 0) {

        lldiv_t res = lldiv((int64_t)T0, (int64_t)T1);

        env->LO[0][env->current_tc] = res.quot;

        env->HI[0][env->current_tc] = res.rem;

    }

}


static int flush_packet(AVFormatContext *ctx, int stream_index,

                         int64_t pts, int64_t dts, int64_t scr, int trailer_size)

{

    MpegMuxContext *s = ctx->priv_data;

    StreamInfo *stream = ctx->streams[stream_index]->priv_data;

    uint8_t *buf_ptr;

    int size, payload_size, startcode, id, stuffing_size, i, header_len;

    int packet_size;

    uint8_t buffer[128];

    int zero_trail_bytes = 0;

    int pad_packet_bytes = 0;

    int pes_flags;

    int general_pack = 0;  /*"general" pack without data specific to one stream?*/

    int nb_frames;

    id = stream->id;

#if 0

    printf("packet ID=%2x PTS=%0.3f\n",

           id, pts / 90000.0);

#endif

    buf_ptr = buffer;

    if ((s->packet_number % s->pack_header_freq) == 0 || s->last_scr != scr) {

        /* output pack and systems header if needed */

        size = put_pack_header(ctx, buf_ptr, scr);

        buf_ptr += size;

        s->last_scr= scr;

        if (s->is_vcd) {

            /* there is exactly one system header for each stream in a VCD MPEG,

               One in the very first video packet and one in the very first

               audio packet (see VCD standard p. IV-7 and IV-8).*/

            if (stream->packet_number==0) {

                size = put_system_header(ctx, buf_ptr, id);

                buf_ptr += size;

            }

        } else if (s->is_dvd) {

            if (stream->align_iframe || s->packet_number == 0){

                int PES_bytes_to_fill = s->packet_size - size - 10;

                if (pts != AV_NOPTS_VALUE) {

                    if (dts != pts)

                        PES_bytes_to_fill -= 5 + 5;

                    else

                        PES_bytes_to_fill -= 5;

                }

                if (stream->bytes_to_iframe == 0 || s->packet_number == 0) {

                    size = put_system_header(ctx, buf_ptr, 0);

                    buf_ptr += size;

                    size = buf_ptr - buffer;

                    put_buffer(ctx->pb, buffer, size);

                    put_be32(ctx->pb, PRIVATE_STREAM_2);

                    put_be16(ctx->pb, 0x03d4);         // length

                    put_byte(ctx->pb, 0x00);           // substream ID, 00=PCI

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

                        put_byte(ctx->pb, 0x00);

                    put_be32(ctx->pb, PRIVATE_STREAM_2);

                    put_be16(ctx->pb, 0x03fa);         // length

                    put_byte(ctx->pb, 0x01);           // substream ID, 01=DSI

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

                        put_byte(ctx->pb, 0x00);

                    memset(buffer, 0, 128);

                    buf_ptr = buffer;

                    s->packet_number++;

                    stream->align_iframe = 0;

                    scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet

                    size = put_pack_header(ctx, buf_ptr, scr);

                    s->last_scr= scr;

                    buf_ptr += size;

                    /* GOP Start */

                } else if (stream->bytes_to_iframe < PES_bytes_to_fill) {

                    pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe;

                }

            }

        } else {

            if ((s->packet_number % s->system_header_freq) == 0) {

                size = put_system_header(ctx, buf_ptr, 0);

                buf_ptr += size;

            }

        }

    }

    size = buf_ptr - buffer;

    put_buffer(ctx->pb, buffer, size);

    packet_size = s->packet_size - size;

    if (s->is_vcd && id == AUDIO_ID)

        /* The VCD standard demands that 20 zero bytes follow

           each audio pack (see standard p. IV-8).*/

        zero_trail_bytes += 20;

    if ((s->is_vcd && stream->packet_number==0)

        || (s->is_svcd && s->packet_number==0)) {

        /* for VCD the first pack of each stream contains only the pack header,

           the system header and lots of padding (see VCD standard p. IV-6).

           In the case of an audio pack, 20 zero bytes are also added at

           the end.*/

        /* For SVCD we fill the very first pack to increase compatibility with

           some DVD players. Not mandated by the standard.*/

        if (s->is_svcd)

            general_pack = 1;    /* the system header refers to both streams and no stream data*/

        pad_packet_bytes = packet_size - zero_trail_bytes;

    }

    packet_size -= pad_packet_bytes + zero_trail_bytes;

    if (packet_size > 0) {

        /* packet header size */

        packet_size -= 6;

        /* packet header */

        if (s->is_mpeg2) {

            header_len = 3;

            if (stream->packet_number==0)

                header_len += 3; /* PES extension */

            header_len += 1; /* obligatory stuffing byte */

        } else {

            header_len = 0;

        }

        if (pts != AV_NOPTS_VALUE) {

            if (dts != pts)

                header_len += 5 + 5;

            else

                header_len += 5;

        } else {

            if (!s->is_mpeg2)

                header_len++;

        }

        payload_size = packet_size - header_len;

        if (id < 0xc0) {

            startcode = PRIVATE_STREAM_1;

            payload_size -= 1;

            if (id >= 0x40) {

                payload_size -= 3;

                if (id >= 0xa0)

                    payload_size -= 3;

            }

        } else {

            startcode = 0x100 + id;

        }

        stuffing_size = payload_size - av_fifo_size(&stream->fifo);

        // first byte does not fit -> reset pts/dts + stuffing

        if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){

            int timestamp_len=0;

            if(dts != pts)

                timestamp_len += 5;

            if(pts != AV_NOPTS_VALUE)

                timestamp_len += s->is_mpeg2 ? 5 : 4;

            pts=dts= AV_NOPTS_VALUE;

            header_len -= timestamp_len;

            if (s->is_dvd && stream->align_iframe) {

                pad_packet_bytes += timestamp_len;

                packet_size -= timestamp_len;

            } else {

                payload_size += timestamp_len;

            }

            stuffing_size += timestamp_len;

            if(payload_size > trailer_size)

                stuffing_size += payload_size - trailer_size;

        }

        if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing

            packet_size += pad_packet_bytes;

            payload_size += pad_packet_bytes; // undo the previous adjustment

            if (stuffing_size < 0) {

                stuffing_size = pad_packet_bytes;

            } else {

                stuffing_size += pad_packet_bytes;

            }

            pad_packet_bytes = 0;

        }

        if (stuffing_size < 0)

            stuffing_size = 0;

        if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/

            pad_packet_bytes += stuffing_size;

            packet_size -= stuffing_size;

            payload_size -= stuffing_size;

            stuffing_size = 0;

        }

        nb_frames= get_nb_frames(ctx, stream, payload_size - stuffing_size);

        put_be32(ctx->pb, startcode);

        put_be16(ctx->pb, packet_size);

        if (!s->is_mpeg2)

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

                put_byte(ctx->pb, 0xff);

        if (s->is_mpeg2) {

            put_byte(ctx->pb, 0x80); /* mpeg2 id */

            pes_flags=0;

            if (pts != AV_NOPTS_VALUE) {

                pes_flags |= 0x80;

                if (dts != pts)

                    pes_flags |= 0x40;

            }

            /* Both the MPEG-2 and the SVCD standards demand that the

               P-STD_buffer_size field be included in the first packet of

               every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2

               and MPEG-2 standard 2.7.7) */

            if (stream->packet_number == 0)

                pes_flags |= 0x01;

            put_byte(ctx->pb, pes_flags); /* flags */

            put_byte(ctx->pb, header_len - 3 + stuffing_size);

            if (pes_flags & 0x80)  /*write pts*/

                put_timestamp(ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts);

            if (pes_flags & 0x40)  /*write dts*/

                put_timestamp(ctx->pb, 0x01, dts);

            if (pes_flags & 0x01) {  /*write pes extension*/

                put_byte(ctx->pb, 0x10); /* flags */

                /* P-STD buffer info */

                if (id == AUDIO_ID)

                    put_be16(ctx->pb, 0x4000 | stream->max_buffer_size/128);

                else

                    put_be16(ctx->pb, 0x6000 | stream->max_buffer_size/1024);

            }

        } else {

            if (pts != AV_NOPTS_VALUE) {

                if (dts != pts) {

                    put_timestamp(ctx->pb, 0x03, pts);

                    put_timestamp(ctx->pb, 0x01, dts);

                } else {

                    put_timestamp(ctx->pb, 0x02, pts);

                }

            } else {

                put_byte(ctx->pb, 0x0f);

            }

        }

        if (s->is_mpeg2) {

            /* special stuffing byte that is always written

               to prevent accidental generation of start codes. */

            put_byte(ctx->pb, 0xff);

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

                put_byte(ctx->pb, 0xff);

        }

        if (startcode == PRIVATE_STREAM_1) {

            put_byte(ctx->pb, id);

            if (id >= 0xa0) {

                /* LPCM (XXX: check nb_frames) */

                put_byte(ctx->pb, 7);

                put_be16(ctx->pb, 4); /* skip 3 header bytes */

                put_byte(ctx->pb, stream->lpcm_header[0]);

                put_byte(ctx->pb, stream->lpcm_header[1]);

                put_byte(ctx->pb, stream->lpcm_header[2]);

            } else if (id >= 0x40) {

                /* AC3 */

                put_byte(ctx->pb, nb_frames);

                put_be16(ctx->pb, trailer_size+1);

            }

        }

        /* output data */

        if(av_fifo_generic_read(&stream->fifo, payload_size - stuffing_size, &put_buffer, ctx->pb) < 0)

            return -1;

        stream->bytes_to_iframe -= payload_size - stuffing_size;

    }else{

        payload_size=

        stuffing_size= 0;

    }

    if (pad_packet_bytes > 0)

        put_padding_packet(ctx,ctx->pb, pad_packet_bytes);

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

        put_byte(ctx->pb, 0x00);

    put_flush_packet(ctx->pb);

    s->packet_number++;

    /* only increase the stream packet number if this pack actually contains

       something that is specific to this stream! I.e. a dedicated header

       or some data.*/

    if (!general_pack)

        stream->packet_number++;

    return payload_size - stuffing_size;

}


static void mux_chr_update_read_handler(CharDriverState *chr,

                                        GMainContext *context)

{

    MuxDriver *d = chr->opaque;

    int idx;

    if (d->mux_cnt >= MAX_MUX) {

        fprintf(stderr, "Cannot add I/O handlers, MUX array is full\n");

        return;

    }

    if (chr->mux_idx == -1) {

        chr->mux_idx = d->mux_cnt++;

    }

    idx = chr->mux_idx;

    d->ext_opaque[idx] = chr->handler_opaque;

    d->chr_can_read[idx] = chr->chr_can_read;

    d->chr_read[idx] = chr->chr_read;

    d->chr_event[idx] = chr->chr_event;

    /* Fix up the real driver with mux routines */

    if (d->mux_cnt == 1) {

        qemu_chr_add_handlers_full(d->drv, mux_chr_can_read,

                                   mux_chr_read,

                                   mux_chr_event,

                                   chr, context);

    }

    if (d->focus != -1) {

        mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_OUT);

    }

    d->focus = idx;

    mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);

}


static inline void RENAME(yuv2packed2)(SwsContext *c, uint16_t *buf0, uint16_t *buf1, uint16_t *uvbuf0, uint16_t *uvbuf1,

                          uint8_t *dest, int dstW, int yalpha, int uvalpha, int y)

{

    int yalpha1=yalpha^4095;

    int uvalpha1=uvalpha^4095;

    int i;

#if 0 //isn't used

    if (flags&SWS_FULL_CHR_H_INT)

    {

        switch(dstFormat)

        {

#ifdef HAVE_MMX

        case PIX_FMT_RGB32:

            asm volatile(

FULL_YSCALEYUV2RGB

            "punpcklbw %%mm1, %%mm3    \n\t" // BGBGBGBG

            "punpcklbw %%mm7, %%mm0    \n\t" // R0R0R0R0

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

            "punpcklwd %%mm0, %%mm3    \n\t" // BGR0BGR0

            "punpckhwd %%mm0, %%mm1    \n\t" // BGR0BGR0

            MOVNTQ(%%mm3,  (%4, %%REGa, 4))

            MOVNTQ(%%mm1, 8(%4, %%REGa, 4))

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

            "cmp %5, %%"REG_a"  \n\t"

            " jb 1b             \n\t"

            :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" ((long)dstW),

            "m" (yalpha1), "m" (uvalpha1)

            : "%"REG_a

            );

            break;

        case PIX_FMT_BGR24:

            asm volatile(

FULL_YSCALEYUV2RGB

                                              // lsb ... msb

            "punpcklbw %%mm1, %%mm3     \n\t" // BGBGBGBG

            "punpcklbw %%mm7, %%mm0     \n\t" // R0R0R0R0

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

            "punpcklwd %%mm0, %%mm3     \n\t" // BGR0BGR0

            "punpckhwd %%mm0, %%mm1     \n\t" // BGR0BGR0

            "movq      %%mm3, %%mm2     \n\t" // BGR0BGR0

            "psrlq        $8, %%mm3     \n\t" // GR0BGR00

            "pand "MANGLE(bm00000111)", %%mm2   \n\t" // BGR00000

            "pand "MANGLE(bm11111000)", %%mm3   \n\t" // 000BGR00

            "por       %%mm2, %%mm3     \n\t" // BGRBGR00

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

            "psllq       $48, %%mm1     \n\t" // 000000BG

            "por       %%mm1, %%mm3     \n\t" // BGRBGRBG

            "movq      %%mm2, %%mm1     \n\t" // BGR0BGR0

            "psrld       $16, %%mm2     \n\t" // R000R000

            "psrlq       $24, %%mm1     \n\t" // 0BGR0000

            "por       %%mm2, %%mm1     \n\t" // RBGRR000

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

            "add   %%"REG_a", %%"REG_b" \n\t"

#ifdef HAVE_MMX2

            //FIXME Alignment

            "movntq %%mm3,  (%%"REG_b", %%"REG_a", 2)   \n\t"

            "movntq %%mm1, 8(%%"REG_b", %%"REG_a", 2)   \n\t"

#else

            "movd %%mm3,  (%%"REG_b", %%"REG_a", 2)     \n\t"

            "psrlq  $32, %%mm3                          \n\t"

            "movd %%mm3, 4(%%"REG_b", %%"REG_a", 2)     \n\t"

            "movd %%mm1, 8(%%"REG_b", %%"REG_a", 2)     \n\t"

#endif

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

            "cmp     %5, %%"REG_a"                      \n\t"

            " jb     1b                                 \n\t"

            :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "m" (dest), "m" (dstW),

            "m" (yalpha1), "m" (uvalpha1)

            : "%"REG_a, "%"REG_b

            );

            break;

        case PIX_FMT_BGR555:

            asm volatile(

FULL_YSCALEYUV2RGB

#ifdef DITHER1XBPP

            "paddusb "MANGLE(g5Dither)", %%mm1  \n\t"

            "paddusb "MANGLE(r5Dither)", %%mm0  \n\t"

            "paddusb "MANGLE(b5Dither)", %%mm3  \n\t"

#endif

            "punpcklbw            %%mm7, %%mm1  \n\t" // 0G0G0G0G

            "punpcklbw            %%mm7, %%mm3  \n\t" // 0B0B0B0B

            "punpcklbw            %%mm7, %%mm0  \n\t" // 0R0R0R0R

            "psrlw                   $3, %%mm3  \n\t"

            "psllw                   $2, %%mm1  \n\t"

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

            "pand     "MANGLE(g15Mask)", %%mm1  \n\t"

            "pand     "MANGLE(r15Mask)", %%mm0  \n\t"

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

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

            MOVNTQ(%%mm0, (%4, %%REGa, 2))

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

            "cmp %5, %%"REG_a"  \n\t"

            " jb 1b             \n\t"

            :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),

            "m" (yalpha1), "m" (uvalpha1)

            : "%"REG_a

            );

            break;

        case PIX_FMT_BGR565:

            asm volatile(

FULL_YSCALEYUV2RGB

#ifdef DITHER1XBPP

            "paddusb "MANGLE(g6Dither)", %%mm1  \n\t"

            "paddusb "MANGLE(r5Dither)", %%mm0  \n\t"

            "paddusb "MANGLE(b5Dither)", %%mm3  \n\t"

#endif

            "punpcklbw            %%mm7, %%mm1  \n\t" // 0G0G0G0G

            "punpcklbw            %%mm7, %%mm3  \n\t" // 0B0B0B0B

            "punpcklbw            %%mm7, %%mm0  \n\t" // 0R0R0R0R

            "psrlw                   $3, %%mm3  \n\t"

            "psllw                   $3, %%mm1  \n\t"

            "psllw                   $8, %%mm0  \n\t"

            "pand     "MANGLE(g16Mask)", %%mm1  \n\t"

            "pand     "MANGLE(r16Mask)", %%mm0  \n\t"

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

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

            MOVNTQ(%%mm0, (%4, %%REGa, 2))

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

            "cmp %5, %%"REG_a"  \n\t"

            " jb 1b             \n\t"

            :: "r" (buf0), "r" (buf1), "r" (uvbuf0), "r" (uvbuf1), "r" (dest), "m" (dstW),

            "m" (yalpha1), "m" (uvalpha1)

            : "%"REG_a

            );

            break;

#endif /* HAVE_MMX */

        case PIX_FMT_BGR32:

#ifndef HAVE_MMX

        case PIX_FMT_RGB32:

#endif

            if (dstFormat==PIX_FMT_RGB32)

            {

                int i;

#ifdef WORDS_BIGENDIAN

                dest++;

#endif

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

                    // vertical linear interpolation && yuv2rgb in a single step:

                    int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];

                    int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);

                    int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);

                    dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];

                    dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];

                    dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];

                    dest+= 4;

                }

            }

            else if (dstFormat==PIX_FMT_BGR24)

            {

                int i;

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

                    // vertical linear interpolation && yuv2rgb in a single step:

                    int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];

                    int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);

                    int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);

                    dest[0]=clip_table[((Y + yuvtab_40cf[U]) >>13)];

                    dest[1]=clip_table[((Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13)];

                    dest[2]=clip_table[((Y + yuvtab_3343[V]) >>13)];

                    dest+= 3;

                }

            }

            else if (dstFormat==PIX_FMT_BGR565)

            {

                int i;

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

                    // vertical linear interpolation && yuv2rgb in a single step:

                    int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];

                    int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);

                    int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);

                    ((uint16_t*)dest)[i] =

                        clip_table16b[(Y + yuvtab_40cf[U]) >>13] |

                        clip_table16g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |

                        clip_table16r[(Y + yuvtab_3343[V]) >>13];

                }

            }

            else if (dstFormat==PIX_FMT_BGR555)

            {

                int i;

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

                    // vertical linear interpolation && yuv2rgb in a single step:

                    int Y=yuvtab_2568[((buf0[i]*yalpha1+buf1[i]*yalpha)>>19)];

                    int U=((uvbuf0[i]*uvalpha1+uvbuf1[i]*uvalpha)>>19);

                    int V=((uvbuf0[i+2048]*uvalpha1+uvbuf1[i+2048]*uvalpha)>>19);

                    ((uint16_t*)dest)[i] =

                        clip_table15b[(Y + yuvtab_40cf[U]) >>13] |

                        clip_table15g[(Y + yuvtab_1a1e[V] + yuvtab_0c92[U]) >>13] |

                        clip_table15r[(Y + yuvtab_3343[V]) >>13];

                }

            }

        }//FULL_UV_IPOL

    else

    {

#endif // if 0

#ifdef HAVE_MMX

        switch(c->dstFormat)

        {

            //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :(

            case PIX_FMT_RGB32:

                asm volatile(

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

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

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

                YSCALEYUV2RGB(%%REGBP, %5)

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

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

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

                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),

                "a" (&c->redDither)

                );

                return;

            case PIX_FMT_BGR24:

                asm volatile(

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

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

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

                YSCALEYUV2RGB(%%REGBP, %5)

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

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

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

                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),

                "a" (&c->redDither)

                );

                return;

            case PIX_FMT_BGR555:

                asm volatile(

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

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

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

                YSCALEYUV2RGB(%%REGBP, %5)

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

#ifdef DITHER1XBPP

                "paddusb "MANGLE(b5Dither)", %%mm2      \n\t"

                "paddusb "MANGLE(g5Dither)", %%mm4      \n\t"

                "paddusb "MANGLE(r5Dither)", %%mm5      \n\t"

#endif

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

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

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

                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),

                "a" (&c->redDither)

                );

                return;

            case PIX_FMT_BGR565:

                asm volatile(

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

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

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

                YSCALEYUV2RGB(%%REGBP, %5)

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

#ifdef DITHER1XBPP

                "paddusb "MANGLE(b5Dither)", %%mm2      \n\t"

                "paddusb "MANGLE(g6Dither)", %%mm4      \n\t"

                "paddusb "MANGLE(r5Dither)", %%mm5      \n\t"

#endif

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

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

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

                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),

                "a" (&c->redDither)

                );

                return;

            case PIX_FMT_YUYV422:

                asm volatile(

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

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

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

                YSCALEYUV2PACKED(%%REGBP, %5)

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

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

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

                :: "c" (buf0), "d" (buf1), "S" (uvbuf0), "D" (uvbuf1), "m" (dest),

                "a" (&c->redDither)

                );

                return;

            default: break;

        }

#endif //HAVE_MMX

YSCALE_YUV_2_ANYRGB_C(YSCALE_YUV_2_RGB2_C, YSCALE_YUV_2_PACKED2_C)

}


static void apply_delogo(uint8_t *dst, int dst_linesize,

                         uint8_t *src, int src_linesize,

                         int w, int h, AVRational sar,

                         int logo_x, int logo_y, int logo_w, int logo_h,

                         unsigned int band, int show, int direct)

{

    int x, y;

    uint64_t interp, weightl, weightr, weightt, weightb;

    uint8_t *xdst, *xsrc;

    uint8_t *topleft, *botleft, *topright;

    unsigned int left_sample, right_sample;

    int xclipl, xclipr, yclipt, yclipb;

    int logo_x1, logo_x2, logo_y1, logo_y2;

    xclipl = FFMAX(-logo_x, 0);

    xclipr = FFMAX(logo_x+logo_w-w, 0);

    yclipt = FFMAX(-logo_y, 0);

    yclipb = FFMAX(logo_y+logo_h-h, 0);

    logo_x1 = logo_x + xclipl;

    logo_x2 = logo_x + logo_w - xclipr;

    logo_y1 = logo_y + yclipt;

    logo_y2 = logo_y + logo_h - yclipb;

    topleft  = src+logo_y1     * src_linesize+logo_x1;

    topright = src+logo_y1     * src_linesize+logo_x2-1;

    botleft  = src+(logo_y2-1) * src_linesize+logo_x1;

    if (!direct)

        av_image_copy_plane(dst, dst_linesize, src, src_linesize, w, h);

    dst += (logo_y1 + 1) * dst_linesize;

    src += (logo_y1 + 1) * src_linesize;

    for (y = logo_y1+1; y < logo_y2-1; y++) {

        left_sample = topleft[src_linesize*(y-logo_y1)]   +

                      topleft[src_linesize*(y-logo_y1-1)] +

                      topleft[src_linesize*(y-logo_y1+1)];

        right_sample = topright[src_linesize*(y-logo_y1)]   +

                       topright[src_linesize*(y-logo_y1-1)] +

                       topright[src_linesize*(y-logo_y1+1)];

        for (x = logo_x1+1,

             xdst = dst+logo_x1+1,

             xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) {

            /* Weighted interpolation based on relative distances, taking SAR into account */

            weightl = (uint64_t)              (logo_x2-1-x) * (y-logo_y1) * (logo_y2-1-y) * sar.den;

            weightr = (uint64_t)(x-logo_x1)                 * (y-logo_y1) * (logo_y2-1-y) * sar.den;

            weightt = (uint64_t)(x-logo_x1) * (logo_x2-1-x)               * (logo_y2-1-y) * sar.num;

            weightb = (uint64_t)(x-logo_x1) * (logo_x2-1-x) * (y-logo_y1)                 * sar.num;

            interp =

                left_sample * weightl

                +

                right_sample * weightr

                +

                (topleft[x-logo_x1]    +

                 topleft[x-logo_x1-1]  +

                 topleft[x-logo_x1+1]) * weightt

                +

                (botleft[x-logo_x1]    +

                 botleft[x-logo_x1-1]  +

                 botleft[x-logo_x1+1]) * weightb;

            interp /= (weightl + weightr + weightt + weightb) * 3U;

            if (y >= logo_y+band && y < logo_y+logo_h-band &&

                x >= logo_x+band && x < logo_x+logo_w-band) {

                *xdst = interp;

            } else {

                unsigned dist = 0;

                if      (x < logo_x+band)

                    dist = FFMAX(dist, logo_x-x+band);

                else if (x >= logo_x+logo_w-band)

                    dist = FFMAX(dist, x-(logo_x+logo_w-1-band));

                if      (y < logo_y+band)

                    dist = FFMAX(dist, logo_y-y+band);

                else if (y >= logo_y+logo_h-band)

                    dist = FFMAX(dist, y-(logo_y+logo_h-1-band));

                *xdst = (*xsrc*dist + interp*(band-dist))/band;

                if (show && (dist == band-1))

                    *xdst = 0;

            }

        }

        dst += dst_linesize;

        src += src_linesize;

    }

}


static long getrampagesize(void)

{

    long hpsize = LONG_MAX;

    Object *memdev_root;

    if (mem_path) {

        return gethugepagesize(mem_path);

    }

    /* it's possible we have memory-backend objects with

     * hugepage-backed RAM. these may get mapped into system

     * address space via -numa parameters or memory hotplug

     * hooks. we want to take these into account, but we

     * also want to make sure these supported hugepage

     * sizes are applicable across the entire range of memory

     * we may boot from, so we take the min across all

     * backends, and assume normal pages in cases where a

     * backend isn't backed by hugepages.

     */

    memdev_root = object_resolve_path("/objects", NULL);

    if (!memdev_root) {

        return getpagesize();

    }

    object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);

    if (hpsize == LONG_MAX) {

        return getpagesize();

    }

    if (nb_numa_nodes == 0 && hpsize > getpagesize()) {

        /* No NUMA nodes and normal RAM without -mem-path ==> no huge pages! */

        static bool warned;

        if (!warned) {

            error_report("Huge page support disabled (n/a for main memory).");

            warned = true;

        }

        return getpagesize();

    }

    return hpsize;

}


static int kvm_put_xsave(CPUState *env)

{

#ifdef KVM_CAP_XSAVE

    int i;

    struct kvm_xsave* xsave;

    uint16_t cwd, swd, twd, fop;

    if (!kvm_has_xsave())

        return kvm_put_fpu(env);

    xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));

    memset(xsave, 0, sizeof(struct kvm_xsave));

    cwd = swd = twd = fop = 0;

    swd = env->fpus & ~(7 << 11);

    swd |= (env->fpstt & 7) << 11;

    cwd = env->fpuc;

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

        twd |= (!env->fptags[i]) << i;

    xsave->region[0] = (uint32_t)(swd << 16) + cwd;

    xsave->region[1] = (uint32_t)(fop << 16) + twd;

    memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,

            sizeof env->fpregs);

    memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs,

            sizeof env->xmm_regs);

    xsave->region[XSAVE_MXCSR] = env->mxcsr;

    *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;

    memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,

            sizeof env->ymmh_regs);

    return kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);

#else

    return kvm_put_fpu(env);

#endif

}


static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc,

                      int step)

{

    int i, j;

    int offset = avctx->width * step;

    uint8_t *outdata = p->data[0];

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

        int size, left, code, pix;

        uint8_t *out = outdata;

        int pos = 0;

        /* size of packed line */

        size = left = bytestream2_get_be16(gbc);

        if (bytestream2_get_bytes_left(gbc) < size)

        /* decode line */

        while (left > 0) {

            code = bytestream2_get_byte(gbc);

            if (code & 0x80 ) { /* run */

                pix = bytestream2_get_byte(gbc);

                for (j = 0; j < 257 - code; j++) {

                    out[pos] = pix;

                    pos += step;

                    if (pos >= offset) {

                        pos -= offset;

                        pos++;

                    }

                }

                left  -= 2;

            } else { /* copy */

                for (j = 0; j < code + 1; j++) {

                    out[pos] = bytestream2_get_byte(gbc);

                    pos += step;

                    if (pos >= offset) {

                        pos -= offset;

                        pos++;

                    }

                }

                left  -= 2 + code;

            }

        }

        outdata += p->linesize[0];

    }

    return 0;

}


uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,

                              uint32_t r3, uint32_t n)

{

    int64_t t1 = (int64_t)r1;

    int64_t t2 = sextract64(r2, 0, 32);

    int64_t t3 = sextract64(r3, 0, 32);

    int64_t result, mul;

    int64_t ovf;

    mul = (t2 * t3) << n;

    result = t1 - mul;

    env->PSW_USB_AV = (result ^ result * 2u) >> 32;

    env->PSW_USB_SAV |= env->PSW_USB_AV;

    ovf = (result ^ t1) & (t1 ^ mul);

    /* we do the saturation by hand, since we produce an overflow on the host

       if the mul before was (0x80000000 * 0x80000000) << 1). If this is the

       case, we flip the saturated value. */

    if (mul == 0x8000000000000000LL) {

        if (ovf >= 0) {

            env->PSW_USB_V = (1 << 31);

            env->PSW_USB_SV = (1 << 31);

            /* ext_ret > MAX_INT */

            if (mul >= 0) {

                result = INT64_MAX;

            /* ext_ret < MIN_INT */

               result = INT64_MIN;

            }

        }

        if (ovf < 0) {

            env->PSW_USB_V = (1 << 31);

            env->PSW_USB_SV = (1 << 31);

            /* ext_ret > MAX_INT */

            if (mul < 0) {

                result = INT64_MAX;

            /* ext_ret < MIN_INT */

               result = INT64_MIN;

            }

        }

    }

    return (uint64_t)result;

}


static void mtree_print_mr(fprintf_function mon_printf, void *f,

                           const MemoryRegion *mr, unsigned int level,

                           hwaddr base,

                           MemoryRegionListHead *alias_print_queue)

{

    MemoryRegionList *new_ml, *ml, *next_ml;

    MemoryRegionListHead submr_print_queue;

    const MemoryRegion *submr;

    unsigned int i;

    if (!mr) {

        return;

    }

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

        mon_printf(f, MTREE_INDENT);

    }

    if (mr->alias) {

        MemoryRegionList *ml;

        bool found = false;

        /* check if the alias is already in the queue */

        QTAILQ_FOREACH(ml, alias_print_queue, queue) {

            if (ml->mr == mr->alias) {

                found = true;

            }

        }

        if (!found) {

            ml = g_new(MemoryRegionList, 1);

            ml->mr = mr->alias;

            QTAILQ_INSERT_TAIL(alias_print_queue, ml, queue);

        }

        mon_printf(f, TARGET_FMT_plx "-" TARGET_FMT_plx

                   " (prio %d, %s): alias %s @%s " TARGET_FMT_plx

                   "-" TARGET_FMT_plx "%s\n",

                   base + mr->addr,

                   base + mr->addr + MR_SIZE(mr->size),

                   mr->priority,

                   memory_region_type((MemoryRegion *)mr),

                   memory_region_name(mr),

                   memory_region_name(mr->alias),

                   mr->alias_offset,

                   mr->alias_offset + MR_SIZE(mr->size),

                   mr->enabled ? "" : " [disabled]");

    } else {

        mon_printf(f,

                   TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %s): %s%s\n",

                   base + mr->addr,

                   base + mr->addr + MR_SIZE(mr->size),

                   mr->priority,

                   memory_region_type((MemoryRegion *)mr),

                   memory_region_name(mr),

                   mr->enabled ? "" : " [disabled]");

    }

    QTAILQ_INIT(&submr_print_queue);

    QTAILQ_FOREACH(submr, &mr->subregions, subregions_link) {

        new_ml = g_new(MemoryRegionList, 1);

        new_ml->mr = submr;

        QTAILQ_FOREACH(ml, &submr_print_queue, queue) {

            if (new_ml->mr->addr < ml->mr->addr ||

                (new_ml->mr->addr == ml->mr->addr &&

                 new_ml->mr->priority > ml->mr->priority)) {

                QTAILQ_INSERT_BEFORE(ml, new_ml, queue);

                new_ml = NULL;

                break;

            }

        }

        if (new_ml) {

            QTAILQ_INSERT_TAIL(&submr_print_queue, new_ml, queue);

        }

    }

    QTAILQ_FOREACH(ml, &submr_print_queue, queue) {

        mtree_print_mr(mon_printf, f, ml->mr, level + 1, base + mr->addr,

                       alias_print_queue);

    }

    QTAILQ_FOREACH_SAFE(ml, &submr_print_queue, queue, next_ml) {

        g_free(ml);

    }

}


static uint64_t bonito_cop_readl(void *opaque, hwaddr addr,
                                 unsigned size)
{
    uint32_t val;
    PCIBonitoState *s = opaque;
    val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)];
    return val;


static int vmdk_snapshot_create(const char *filename, const char *backing_file)

{

    int snp_fd, p_fd;

    int ret;

    uint32_t p_cid;

    char *p_name, *gd_buf, *rgd_buf;

    const char *real_filename, *temp_str;

    VMDK4Header header;

    uint32_t gde_entries, gd_size;

    int64_t gd_offset, rgd_offset, capacity, gt_size;

    char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];

    static const char desc_template[] =

    "# Disk DescriptorFile\n"

    "version=1\n"

    "CID=%x\n"

    "parentCID=%x\n"

    "createType=\"monolithicSparse\"\n"

    "parentFileNameHint=\"%s\"\n"

    "\n"

    "# Extent description\n"

    "RW %u SPARSE \"%s\"\n"

    "\n"

    "# The Disk Data Base \n"

    "#DDB\n"

    "\n";

    snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);

    if (snp_fd < 0)

        return -errno;

    p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);

    if (p_fd < 0) {

        close(snp_fd);

        return -errno;

    }

    /* read the header */

    if (lseek(p_fd, 0x0, SEEK_SET) == -1) {

        ret = -errno;

        goto fail;

    }

    if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {

        ret = -errno;

        goto fail;

    }

    /* write the header */

    if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {

        ret = -errno;

        goto fail;

    }

    if (write(snp_fd, hdr, HEADER_SIZE) == -1) {

        ret = -errno;

        goto fail;

    }

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

    memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC

    if (ftruncate(snp_fd, header.grain_offset << 9)) {

        ret = -errno;

        goto fail;

    }

    /* the descriptor offset = 0x200 */

    if (lseek(p_fd, 0x200, SEEK_SET) == -1) {

        ret = -errno;

        goto fail;

    }

    if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {

        ret = -errno;

        goto fail;

    }

    if ((p_name = strstr(p_desc,"CID")) != NULL) {

        p_name += sizeof("CID");

        sscanf(p_name,"%x",&p_cid);

    }

    real_filename = filename;

    if ((temp_str = strrchr(real_filename, '\\')) != NULL)

        real_filename = temp_str + 1;

    if ((temp_str = strrchr(real_filename, '/')) != NULL)

        real_filename = temp_str + 1;

    if ((temp_str = strrchr(real_filename, ':')) != NULL)

        real_filename = temp_str + 1;

    snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,

             (uint32_t)header.capacity, real_filename);

    /* write the descriptor */

    if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {

        ret = -errno;

        goto fail;

    }

    if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {

        ret = -errno;

        goto fail;

    }

    gd_offset = header.gd_offset * SECTOR_SIZE;     // offset of GD table

    rgd_offset = header.rgd_offset * SECTOR_SIZE;   // offset of RGD table

    capacity = header.capacity * SECTOR_SIZE;       // Extent size

    /*

     * Each GDE span 32M disk, means:

     * 512 GTE per GT, each GTE points to grain

     */

    gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;

    if (!gt_size) {

        ret = -EINVAL;

        goto fail;

    }

    gde_entries = (uint32_t)(capacity / gt_size);  // number of gde/rgde

    gd_size = gde_entries * sizeof(uint32_t);

    /* write RGD */

    rgd_buf = qemu_malloc(gd_size);

    if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {

        ret = -errno;

        goto fail_rgd;

    }

    if (read(p_fd, rgd_buf, gd_size) != gd_size) {

        ret = -errno;

        goto fail_rgd;

    }

    if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {

        ret = -errno;

        goto fail_rgd;

    }

    if (write(snp_fd, rgd_buf, gd_size) == -1) {

        ret = -errno;

        goto fail_rgd;

    }

    qemu_free(rgd_buf);

    /* write GD */

    gd_buf = qemu_malloc(gd_size);

    if (lseek(p_fd, gd_offset, SEEK_SET) == -1) {

        ret = -errno;

        goto fail_gd;

    }

    if (read(p_fd, gd_buf, gd_size) != gd_size) {

        ret = -errno;

        goto fail_gd;

    }

    if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) {

        ret = -errno;

        goto fail_gd;

    }

    if (write(snp_fd, gd_buf, gd_size) == -1) {

        ret = -errno;

        goto fail_gd;

    }

    qemu_free(gd_buf);

    close(p_fd);

    close(snp_fd);

    return 0;

    fail_gd:

    qemu_free(gd_buf);

    fail_rgd:

    qemu_free(rgd_buf);

    fail:

    close(p_fd);

    close(snp_fd);

    return ret;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->init = pci_piix_ide_initfn;

    k->vendor_id = PCI_VENDOR_ID_INTEL;

    k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;

    k->class_id = PCI_CLASS_STORAGE_IDE;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

    dc->no_user = 1;

    dc->unplug = pci_piix3_xen_ide_unplug;

}


static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src)
{
    SAMIContext *sami = avctx->priv_data;
    int ret = 0;
    char *tag = NULL;
    char *dupsrc = av_strdup(src);
    char *p = dupsrc;
    AVBPrint *dst_content = &sami->encoded_content;
    AVBPrint *dst_source = &sami->encoded_source;
    av_bprint_clear(&sami->encoded_content);
    av_bprint_clear(&sami->content);
    av_bprint_clear(&sami->encoded_source);
    for (;;) {
        char *saveptr = NULL;
        int prev_chr_is_space = 0;
        AVBPrint *dst = &sami->content;
        /* parse & extract paragraph tag */
        p = av_stristr(p, "<P");
        if (!p)
            break;
        if (p[2] != '>' && !av_isspace(p[2])) { // avoid confusion with tags such as <PRE>
            p++;
            continue;
        }
        if (dst->len) // add a separator with the previous paragraph if there was one
            av_bprintf(dst, "\\N");
        tag = av_strtok(p, ">", &saveptr);
        if (!tag || !saveptr)
            break;
        p = saveptr;
        /* check if the current paragraph is the "source" (speaker name) */
        if (av_stristr(tag, "ID=Source") || av_stristr(tag, "ID=\"Source\"")) {
            dst = &sami->source;
            av_bprint_clear(dst);
        }
        /* if empty event -> skip subtitle */
        while (av_isspace(*p))
            p++;
        if (!strncmp(p, " ", 6)) {
            ret = -1;
            goto end;
        }
        /* extract the text, stripping most of the tags */
        while (*p) {
            if (*p == '<') {
                if (!av_strncasecmp(p, "<P", 2) && (p[2] == '>' || av_isspace(p[2])))
                    break;
            }
            if (!av_strncasecmp(p, "<BR", 3)) {
                av_bprintf(dst, "\\N");
                p++;
                while (*p && *p != '>')
                    p++;
                if (!*p)
                    break;
                if (*p == '>')
                    p++;
                continue;
            }
            if (!av_isspace(*p))
                av_bprint_chars(dst, *p, 1);
            else if (!prev_chr_is_space)
                av_bprint_chars(dst, ' ', 1);
            prev_chr_is_space = av_isspace(*p);
            p++;
        }
    }
    av_bprint_clear(&sami->full);
    if (sami->source.len) {
        ret = ff_htmlmarkup_to_ass(avctx, dst_source, sami->source.str);
        if (ret < 0)
            goto end;
        av_bprintf(&sami->full, "{\\i1}%s{\\i0}\\N", sami->encoded_source.str);
    }
    ret = ff_htmlmarkup_to_ass(avctx, dst_content, sami->content.str);
    if (ret < 0)
        goto end;
    av_bprintf(&sami->full, "%s", sami->encoded_content.str);
end:
    av_free(dupsrc);
    return ret;
}


static void reset_codec(WmallDecodeCtx *s)

{

    int ich, ilms;

    s->mclms_recent = s->mclms_order * s->num_channels;

    for (ich = 0; ich < s->num_channels; ich++) {

        for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++)

            s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order;

        /* first sample of a seekable subframe is considered as the starting of

           a transient area which is samples_per_frame samples long */

        s->channel[ich].transient_counter = s->samples_per_frame;

        s->transient[ich] = 1;

    }

}


static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) {

    AVCodecContext *vcodec = vstream->codec;

    switch(flv_codecid) {

        case FLV_CODECID_H263  : vcodec->codec_id = AV_CODEC_ID_FLV1   ; break;

        case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break;

        case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break;

        case FLV_CODECID_VP6   : vcodec->codec_id = AV_CODEC_ID_VP6F   ;

        case FLV_CODECID_VP6A  :

            if(flv_codecid == FLV_CODECID_VP6A)

                vcodec->codec_id = AV_CODEC_ID_VP6A;

            if (read) {

                if (vcodec->extradata_size != 1) {

                    vcodec->extradata_size = 1;

                    vcodec->extradata = av_malloc(1);

                }

                vcodec->extradata[0] = avio_r8(s->pb);

            }

            return 1; // 1 byte body size adjustment for flv_read_packet()

        case FLV_CODECID_H264:

            vcodec->codec_id = AV_CODEC_ID_H264;

            return 3; // not 4, reading packet type will consume one byte

        default:

            av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);

            vcodec->codec_tag = flv_codecid;

    }

    return 0;

}


float64 float64_scalbn( float64 a, int n STATUS_PARAM )

{

    flag aSign;

    int16 aExp;

    uint64_t aSig;

    a = float64_squash_input_denormal(a STATUS_VAR);

    aSig = extractFloat64Frac( a );

    aExp = extractFloat64Exp( a );

    aSign = extractFloat64Sign( a );

    if ( aExp == 0x7FF ) {

        return a;

    }

    if ( aExp != 0 )

        aSig |= LIT64( 0x0010000000000000 );

    else if ( aSig == 0 )

        return a;

    aExp += n - 1;

    aSig <<= 10;

    return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );

}


static int postcopy_start(MigrationState *ms, bool *old_vm_running)

{

    int ret;

    QIOChannelBuffer *bioc;

    QEMUFile *fb;

    int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);

    bool restart_block = false;

    int cur_state = MIGRATION_STATUS_ACTIVE;

    if (!migrate_pause_before_switchover()) {

        migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,

                          MIGRATION_STATUS_POSTCOPY_ACTIVE);

    }

    trace_postcopy_start();

    qemu_mutex_lock_iothread();

    trace_postcopy_start_set_run();

    qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);

    *old_vm_running = runstate_is_running();

    global_state_store();

    ret = vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);

    if (ret < 0) {

        goto fail;

    }

    ret = migration_maybe_pause(ms, &cur_state,

                                MIGRATION_STATUS_POSTCOPY_ACTIVE);

    if (ret < 0) {

        goto fail;

    }

    ret = bdrv_inactivate_all();

    if (ret < 0) {

        goto fail;

    }

    restart_block = true;

    /*

     * Cause any non-postcopiable, but iterative devices to

     * send out their final data.

     */

    qemu_savevm_state_complete_precopy(ms->to_dst_file, true, false);

    /*

     * in Finish migrate and with the io-lock held everything should

     * be quiet, but we've potentially still got dirty pages and we

     * need to tell the destination to throw any pages it's already received

     * that are dirty

     */

    if (migrate_postcopy_ram()) {

        if (ram_postcopy_send_discard_bitmap(ms)) {

            error_report("postcopy send discard bitmap failed");

            goto fail;

        }

    }

    /*

     * send rest of state - note things that are doing postcopy

     * will notice we're in POSTCOPY_ACTIVE and not actually

     * wrap their state up here

     */

    qemu_file_set_rate_limit(ms->to_dst_file, INT64_MAX);

    if (migrate_postcopy_ram()) {

        /* Ping just for debugging, helps line traces up */

        qemu_savevm_send_ping(ms->to_dst_file, 2);

    }

    /*

     * While loading the device state we may trigger page transfer

     * requests and the fd must be free to process those, and thus

     * the destination must read the whole device state off the fd before

     * it starts processing it.  Unfortunately the ad-hoc migration format

     * doesn't allow the destination to know the size to read without fully

     * parsing it through each devices load-state code (especially the open

     * coded devices that use get/put).

     * So we wrap the device state up in a package with a length at the start;

     * to do this we use a qemu_buf to hold the whole of the device state.

     */

    bioc = qio_channel_buffer_new(4096);

    qio_channel_set_name(QIO_CHANNEL(bioc), "migration-postcopy-buffer");

    fb = qemu_fopen_channel_output(QIO_CHANNEL(bioc));

    object_unref(OBJECT(bioc));

    /*

     * Make sure the receiver can get incoming pages before we send the rest

     * of the state

     */

    qemu_savevm_send_postcopy_listen(fb);

    qemu_savevm_state_complete_precopy(fb, false, false);

    if (migrate_postcopy_ram()) {

        qemu_savevm_send_ping(fb, 3);

    }

    qemu_savevm_send_postcopy_run(fb);

    /* <><> end of stuff going into the package */

    /* Last point of recovery; as soon as we send the package the destination

     * can open devices and potentially start running.

     * Lets just check again we've not got any errors.

     */

    ret = qemu_file_get_error(ms->to_dst_file);

    if (ret) {

        error_report("postcopy_start: Migration stream errored (pre package)");

        goto fail_closefb;

    }

    restart_block = false;

    /* Now send that blob */

    if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {

        goto fail_closefb;

    }

    qemu_fclose(fb);

    /* Send a notify to give a chance for anything that needs to happen

     * at the transition to postcopy and after the device state; in particular

     * spice needs to trigger a transition now

     */

    ms->postcopy_after_devices = true;

    notifier_list_notify(&migration_state_notifiers, ms);

    ms->downtime =  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) - time_at_stop;

    qemu_mutex_unlock_iothread();

    if (migrate_postcopy_ram()) {

        /*

         * Although this ping is just for debug, it could potentially be

         * used for getting a better measurement of downtime at the source.

         */

        qemu_savevm_send_ping(ms->to_dst_file, 4);

    }

    if (migrate_release_ram()) {

        ram_postcopy_migrated_memory_release(ms);

    }

    ret = qemu_file_get_error(ms->to_dst_file);

    if (ret) {

        error_report("postcopy_start: Migration stream errored");

        migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,

                              MIGRATION_STATUS_FAILED);

    }

    return ret;

fail_closefb:

    qemu_fclose(fb);

fail:

    migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,

                          MIGRATION_STATUS_FAILED);

    if (restart_block) {

        /* A failure happened early enough that we know the destination hasn't

         * accessed block devices, so we're safe to recover.

         */

        Error *local_err = NULL;

        bdrv_invalidate_cache_all(&local_err);

        if (local_err) {

            error_report_err(local_err);

        }

    }

    qemu_mutex_unlock_iothread();

    return -1;

}


static BusState *qbus_find(const char *path)

{

    DeviceState *dev;

    BusState *bus;

    char elem[128];

    int pos, len;

    /* find start element */

    if (path[0] == '/') {

        bus = sysbus_get_default();

        pos = 0;

    } else {

        if (sscanf(path, "%127[^/]%n", elem, &len) != 1) {

            assert(!path[0]);

            elem[0] = len = 0;

        }

        bus = qbus_find_recursive(sysbus_get_default(), elem, NULL);

        if (!bus) {

            qerror_report(QERR_BUS_NOT_FOUND, elem);

            return NULL;

        } else if (qbus_is_full(bus)) {

            qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",

                          elem);

            return NULL;

        }

        pos = len;

    }

    for (;;) {

        assert(path[pos] == '/' || !path[pos]);

        while (path[pos] == '/') {

            pos++;

        }

        if (path[pos] == '\0') {

            return bus;

        }

        /* find device */

        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {

            g_assert_not_reached();

            elem[0] = len = 0;

        }

        pos += len;

        dev = qbus_find_dev(bus, elem);

        if (!dev) {

            qerror_report(QERR_DEVICE_NOT_FOUND, elem);

            if (!monitor_cur_is_qmp()) {

                qbus_list_dev(bus);

            }

            return NULL;

        }

        assert(path[pos] == '/' || !path[pos]);

        while (path[pos] == '/') {

            pos++;

        }

        if (path[pos] == '\0') {

            /* last specified element is a device.  If it has exactly

             * one child bus accept it nevertheless */

            switch (dev->num_child_bus) {

            case 0:

                qerror_report(ERROR_CLASS_GENERIC_ERROR,

                              "Device '%s' has no child bus", elem);

                return NULL;

            case 1:

                return QLIST_FIRST(&dev->child_bus);

            default:

                qerror_report(ERROR_CLASS_GENERIC_ERROR,

                              "Device '%s' has multiple child busses", elem);

                if (!monitor_cur_is_qmp()) {

                    qbus_list_bus(dev);

                }

                return NULL;

            }

        }

        /* find bus */

        if (sscanf(path+pos, "%127[^/]%n", elem, &len) != 1) {

            g_assert_not_reached();

            elem[0] = len = 0;

        }

        pos += len;

        bus = qbus_find_bus(dev, elem);

        if (!bus) {

            qerror_report(QERR_BUS_NOT_FOUND, elem);

            if (!monitor_cur_is_qmp()) {

                qbus_list_bus(dev);

            }

            return NULL;

        }

    }

}


void bdrv_init(void)

{

    bdrv_register(&bdrv_raw);

    bdrv_register(&bdrv_host_device);

    bdrv_register(&bdrv_cow);

    bdrv_register(&bdrv_qcow);

    bdrv_register(&bdrv_vmdk);

    bdrv_register(&bdrv_cloop);

    bdrv_register(&bdrv_dmg);

    bdrv_register(&bdrv_bochs);

    bdrv_register(&bdrv_vpc);

    bdrv_register(&bdrv_vvfat);

    bdrv_register(&bdrv_qcow2);

    bdrv_register(&bdrv_parallels);

    bdrv_register(&bdrv_nbd);

}


void ff_h264_direct_dist_scale_factor(H264Context * const h){

    const int poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];

    const int poc1 = h->ref_list[1][0].poc;

    int i, field;

    if (FRAME_MBAFF(h))

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

            const int poc  = h->cur_pic_ptr->field_poc[field];

            const int poc1 = h->ref_list[1][0].field_poc[field];

            for (i = 0; i < 2 * h->ref_count[0]; i++)

                h->dist_scale_factor_field[field][i^field] =

                    get_scale_factor(h, poc, poc1, i+16);

        }

    for (i = 0; i < h->ref_count[0]; i++){

        h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);

    }

}


static void virtio_net_handle_tx_bh(VirtIODevice *vdev, VirtQueue *vq)

{

    VirtIONet *n = to_virtio_net(vdev);

    if (unlikely(n->tx_waiting)) {

        return;

    }

    virtio_queue_set_notification(vq, 0);

    qemu_bh_schedule(n->tx_bh);

    n->tx_waiting = 1;

}


static int net_dump_init(NetClientState *peer, const char *device,

                         const char *name, const char *filename, int len)

{

    struct pcap_file_hdr hdr;

    NetClientState *nc;

    DumpState *s;

    struct tm tm;

    int fd;

    fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644);

    if (fd < 0) {

        error_report("-net dump: can't open %s", filename);

        return -1;

    }

    hdr.magic = PCAP_MAGIC;

    hdr.version_major = 2;

    hdr.version_minor = 4;

    hdr.thiszone = 0;

    hdr.sigfigs = 0;

    hdr.snaplen = len;

    hdr.linktype = 1;

    if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {

        error_report("-net dump write error: %s", strerror(errno));

        close(fd);

        return -1;

    }

    nc = qemu_new_net_client(&net_dump_info, peer, device, name);

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

             "dump to %s (len=%d)", filename, len);

    s = DO_UPCAST(DumpState, nc, nc);

    s->fd = fd;

    s->pcap_caplen = len;

    qemu_get_timedate(&tm, 0);

    s->start_ts = mktime(&tm);

    return 0;

}


AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,

                                                     enum AVSampleFormat sample_fmt, int size,

                                                     int64_t channel_layout, int planar)

{

    AVFilterBuffer *samples = av_mallocz(sizeof(AVFilterBuffer));

    AVFilterBufferRef *ref = NULL;

    int i, sample_size, chans_nb, bufsize, per_channel_size, step_size = 0;

    char *buf;

    if (!samples || !(ref = av_mallocz(sizeof(AVFilterBufferRef))))

        goto fail;

    ref->buf                   = samples;

    ref->format                = sample_fmt;

    ref->audio = av_mallocz(sizeof(AVFilterBufferRefAudioProps));

    if (!ref->audio)

        goto fail;

    ref->audio->channel_layout = channel_layout;

    ref->audio->size           = size;

    ref->audio->planar         = planar;

    /* make sure the buffer gets read permission or it's useless for output */

    ref->perms = perms | AV_PERM_READ;

    samples->refcount   = 1;

    samples->free       = ff_avfilter_default_free_buffer;

    sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3;

    chans_nb = av_get_channel_layout_nb_channels(channel_layout);

    per_channel_size = size/chans_nb;

    ref->audio->nb_samples = per_channel_size/sample_size;

    /* Set the number of bytes to traverse to reach next sample of a particular channel:

     * For planar, this is simply the sample size.

     * For packed, this is the number of samples * sample_size.

     */

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

        samples->linesize[i] = planar > 0 ? per_channel_size : sample_size;

    memset(&samples->linesize[chans_nb], 0, (8-chans_nb) * sizeof(samples->linesize[0]));

    /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */

    bufsize = (size + 15)&~15;

    buf = av_malloc(bufsize);

    if (!buf)

        goto fail;

    /* For planar, set the start point of each channel's data within the buffer

     * For packed, set the start point of the entire buffer only

     */

    samples->data[0] = buf;

    if (buf && planar) {

        for (i = 1; i < chans_nb; i++) {

            step_size += per_channel_size;

            samples->data[i] = buf + step_size;

        }

    } else {

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

            samples->data[i] = buf;

    }

    memset(&samples->data[chans_nb], 0, (8-chans_nb) * sizeof(samples->data[0]));

    memcpy(ref->data,     samples->data,     sizeof(ref->data));

    memcpy(ref->linesize, samples->linesize, sizeof(ref->linesize));

    return ref;

fail:

    av_free(buf);

    if (ref && ref->audio)

        av_free(ref->audio);

    av_free(ref);

    av_free(samples);

    return NULL;

}


static void test_keyval_visit_any(void)

{

    Visitor *v;

    QDict *qdict;

    QObject *any;

    QList *qlist;

    QString *qstr;

    qdict = keyval_parse("a.0=null,a.1=1", NULL, &error_abort);

    v = qobject_input_visitor_new_keyval(QOBJECT(qdict));

    QDECREF(qdict);

    visit_start_struct(v, NULL, NULL, 0, &error_abort);

    visit_type_any(v, "a", &any, &error_abort);

    qlist = qobject_to_qlist(any);

    g_assert(qlist);

    qstr = qobject_to_qstring(qlist_pop(qlist));

    g_assert_cmpstr(qstring_get_str(qstr), ==, "null");

    qstr = qobject_to_qstring(qlist_pop(qlist));

    g_assert_cmpstr(qstring_get_str(qstr), ==, "1");

    g_assert(qlist_empty(qlist));

    visit_check_struct(v, &error_abort);

    visit_end_struct(v, NULL);

    visit_free(v);

}


static int vc1_decode_i_block_adv(VC1Context *v, int16_t block[64], int n,

                                  int coded, int codingset, int mquant)

{

    GetBitContext *gb = &v->s.gb;

    MpegEncContext *s = &v->s;

    int dc_pred_dir = 0; /* Direction of the DC prediction used */

    int i;

    int16_t *dc_val;

    int16_t *ac_val, *ac_val2;

    int dcdiff;

    int a_avail = v->a_avail, c_avail = v->c_avail;

    int use_pred = s->ac_pred;

    int scale;

    int q1, q2 = 0;

    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;

    /* Get DC differential */

    if (n < 4) {

        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);

    } else {

        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);

    }

    if (dcdiff < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");

        return -1;

    }

    if (dcdiff) {

        if (dcdiff == 119 /* ESC index value */) {

            /* TODO: Optimize */

            if (mquant == 1)      dcdiff = get_bits(gb, 10);

            else if (mquant == 2) dcdiff = get_bits(gb, 9);

            else                  dcdiff = get_bits(gb, 8);

        } else {

            if (mquant == 1)

                dcdiff = (dcdiff << 2) + get_bits(gb, 2) - 3;

            else if (mquant == 2)

                dcdiff = (dcdiff << 1) + get_bits1(gb)   - 1;

        }

        if (get_bits1(gb))

            dcdiff = -dcdiff;

    }

    /* Prediction */

    dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, v->a_avail, v->c_avail, &dc_val, &dc_pred_dir);

    *dc_val = dcdiff;

    /* Store the quantized DC coeff, used for prediction */

    if (n < 4) {

        block[0] = dcdiff * s->y_dc_scale;

    } else {

        block[0] = dcdiff * s->c_dc_scale;

    }

    //AC Decoding

    i = 1;

    /* check if AC is needed at all */

    if (!a_avail && !c_avail)

        use_pred = 0;

    ac_val  = s->ac_val[0][0] + s->block_index[n] * 16;

    ac_val2 = ac_val;

    scale = mquant * 2 + ((mquant == v->pq) ? v->halfpq : 0);

    if (dc_pred_dir) // left

        ac_val -= 16;

    else // top

        ac_val -= 16 * s->block_wrap[n];

    q1 = s->current_picture.f.qscale_table[mb_pos];

    if ( dc_pred_dir && c_avail && mb_pos)

        q2 = s->current_picture.f.qscale_table[mb_pos - 1];

    if (!dc_pred_dir && a_avail && mb_pos >= s->mb_stride)

        q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride];

    if ( dc_pred_dir && n == 1)

        q2 = q1;

    if (!dc_pred_dir && n == 2)

        q2 = q1;

    if (n == 3)

        q2 = q1;

    if (coded) {

        int last = 0, skip, value;

        const uint8_t *zz_table;

        int k;

        if (v->s.ac_pred) {

            if (!use_pred && v->fcm == ILACE_FRAME) {

                zz_table = v->zzi_8x8;

            } else {

                if (!dc_pred_dir) // top

                    zz_table = v->zz_8x8[2];

                else // left

                    zz_table = v->zz_8x8[3];

            }

        } else {

            if (v->fcm != ILACE_FRAME)

                zz_table = v->zz_8x8[1];

            else

                zz_table = v->zzi_8x8;

        }

        while (!last) {

            vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);

            i += skip;

            if (i > 63)

                break;

            block[zz_table[i++]] = value;

        }

        /* apply AC prediction if needed */

        if (use_pred) {

            /* scale predictors if needed*/

            if (q2 && q1 != q2) {

                q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;

                q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;

                if (q1 < 1)

                    return AVERROR_INVALIDDATA;

                if (dc_pred_dir) { // left

                    for (k = 1; k < 8; k++)

                        block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;

                } else { // top

                    for (k = 1; k < 8; k++)

                        block[k << v->top_blk_sh] += (ac_val[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;

                }

            } else {

                if (dc_pred_dir) { //left

                    for (k = 1; k < 8; k++)

                        block[k << v->left_blk_sh] += ac_val[k];

                } else { //top

                    for (k = 1; k < 8; k++)

                        block[k << v->top_blk_sh] += ac_val[k + 8];

                }

            }

        }

        /* save AC coeffs for further prediction */

        for (k = 1; k < 8; k++) {

            ac_val2[k    ] = block[k << v->left_blk_sh];

            ac_val2[k + 8] = block[k << v->top_blk_sh];

        }

        /* scale AC coeffs */

        for (k = 1; k < 64; k++)

            if (block[k]) {

                block[k] *= scale;

                if (!v->pquantizer)

                    block[k] += (block[k] < 0) ? -mquant : mquant;

            }

        if (use_pred) i = 63;

    } else { // no AC coeffs

        int k;

        memset(ac_val2, 0, 16 * 2);

        if (dc_pred_dir) { // left

            if (use_pred) {

                memcpy(ac_val2, ac_val, 8 * 2);

                if (q2 && q1 != q2) {

                    q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;

                    q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;

                    if (q1 < 1)

                        return AVERROR_INVALIDDATA;

                    for (k = 1; k < 8; k++)

                        ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;

                }

            }

        } else { // top

            if (use_pred) {

                memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);

                if (q2 && q1 != q2) {

                    q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1;

                    q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1;

                    if (q1 < 1)

                        return AVERROR_INVALIDDATA;

                    for (k = 1; k < 8; k++)

                        ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18;

                }

            }

        }

        /* apply AC prediction if needed */

        if (use_pred) {

            if (dc_pred_dir) { // left

                for (k = 1; k < 8; k++) {

                    block[k << v->left_blk_sh] = ac_val2[k] * scale;

                    if (!v->pquantizer && block[k << v->left_blk_sh])

                        block[k << v->left_blk_sh] += (block[k << v->left_blk_sh] < 0) ? -mquant : mquant;

                }

            } else { // top

                for (k = 1; k < 8; k++) {

                    block[k << v->top_blk_sh] = ac_val2[k + 8] * scale;

                    if (!v->pquantizer && block[k << v->top_blk_sh])

                        block[k << v->top_blk_sh] += (block[k << v->top_blk_sh] < 0) ? -mquant : mquant;

                }

            }

            i = 63;

        }

    }

    s->block_last_index[n] = i;

    return 0;

}


static int crc_write_packet(struct AVFormatContext *s,

                            int stream_index,

                            const uint8_t *buf, int size, int64_t pts)

{

    CRCState *crc = s->priv_data;

    crc->crcval = adler32(crc->crcval, buf, size);

    return 0;

}


void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)

{

}