static int svq1_decode_frame(AVCodecContext *avctx, void *data,

                             int *data_size, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size       = avpkt->size;

    MpegEncContext *s  = avctx->priv_data;

    uint8_t *current, *previous;

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

    AVFrame *pict = data;

    svq1_pmv *pmv;

    /* initialize bit buffer */

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

    /* decode frame header */

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

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

        return AVERROR_INVALIDDATA;

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

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

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

        if (buf_size < 36)

            return AVERROR_INVALIDDATA;

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

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

    }

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

    if (result != 0) {

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

        return result;

    }

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

    /* FIXME: This avoids some confusion for "B frames" without 2 references.

     * This should be removed after libavcodec can handle more flexible

     * picture types & ordering */

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

        return buf_size;

    if ((avctx->skip_frame >= AVDISCARD_NONREF &&

         s->pict_type == AV_PICTURE_TYPE_B)    ||

        (avctx->skip_frame >= AVDISCARD_NONKEY &&

         s->pict_type != AV_PICTURE_TYPE_I)    ||

        avctx->skip_frame >= AVDISCARD_ALL)

        return buf_size;

    if ((result = ff_MPV_frame_start(s, avctx)) < 0)

        return result;

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

    if (!pmv)

        return AVERROR(ENOMEM);

    /* decode y, u and v components */

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

        int linesize;

        if (i == 0) {

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

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

            linesize = s->linesize;

        } else {

            if (s->flags & CODEC_FLAG_GRAY)

                break;

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

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

            linesize = s->uvlinesize;

        }

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

        if (s->pict_type == AV_PICTURE_TYPE_B)

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

        else

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

        if (s->pict_type == AV_PICTURE_TYPE_I) {

            /* keyframe */

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

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

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

                                                     linesize);

                    if (result != 0) {

                        av_log(s->avctx, AV_LOG_INFO,

                               "Error in svq1_decode_block %i (keyframe)\n",

                               result);

                        goto err;

                    }

                }

                current += 16 * linesize;

            }

        } else {

            /* delta frame */

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

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

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

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

                                                     previous, linesize,

                                                     pmv, x, y);

                    if (result != 0) {

                        av_dlog(s->avctx,

                                "Error in svq1_decode_delta_block %i\n",

                                result);

                        goto err;

                    }

                }

                pmv[0].x     =

                    pmv[0].y = 0;

                current += 16 * linesize;

            }

        }

    }

    *pict = s->current_picture.f;

    ff_MPV_frame_end(s);

    *data_size = sizeof(AVFrame);

    result     = buf_size;

err:

    av_free(pmv);

    return result;

}


static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)

{

    BDRVSheepdogState *s = bs->opaque;

    BDRVSheepdogState *old_s;

    char tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid = 0;

    int ret = 0;

    old_s = g_malloc(sizeof(BDRVSheepdogState));

    memcpy(old_s, s, sizeof(BDRVSheepdogState));

    snapid = strtoul(snapshot_id, NULL, 10);

    if (snapid) {

        tag[0] = 0;

    } else {

        pstrcpy(tag, sizeof(tag), snapshot_id);

    }

    ret = reload_inode(s, snapid, tag);

    if (ret) {

        goto out;

    }

    ret = sd_create_branch(s);

    if (ret) {

        goto out;

    }

    g_free(old_s);

    return 0;

out:

    /* recover bdrv_sd_state */

    memcpy(s, old_s, sizeof(BDRVSheepdogState));

    g_free(old_s);

    error_report("failed to open. recover old bdrv_sd_state.");

    return ret;

}


static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    RMContext *rm = s->priv_data;
    AVStream *st;
    ByteIOContext *pb = &s->pb;
    unsigned int tag, v;
    int tag_size, size, codec_data_size, i;
    int64_t codec_pos;
    unsigned int h263_hack_version, start_time, duration;
    char buf[128];
    int flags = 0;
    tag = get_le32(pb);
    if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
        /* very old .ra format */
        return rm_read_header_old(s, ap);
    } else if (tag != MKTAG('.', 'R', 'M', 'F')) {
        return AVERROR_IO;
    get_be32(pb); /* header size */
    get_be16(pb);
    get_be32(pb);
    get_be32(pb); /* number of headers */
    for(;;) {
        if (url_feof(pb))
            goto fail;
        tag = get_le32(pb);
        tag_size = get_be32(pb);
        get_be16(pb);
#if 0
        printf("tag=%c%c%c%c (%08x) size=%d\n",
               (tag) & 0xff,
               (tag >> 8) & 0xff,
               (tag >> 16) & 0xff,
               (tag >> 24) & 0xff,
               tag,
               tag_size);
#endif
        if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A'))
            goto fail;
        switch(tag) {
        case MKTAG('P', 'R', 'O', 'P'):
            /* file header */
            get_be32(pb); /* max bit rate */
            get_be32(pb); /* avg bit rate */
            get_be32(pb); /* max packet size */
            get_be32(pb); /* avg packet size */
            get_be32(pb); /* nb packets */
            get_be32(pb); /* duration */
            get_be32(pb); /* preroll */
            get_be32(pb); /* index offset */
            get_be32(pb); /* data offset */
            get_be16(pb); /* nb streams */
            flags = get_be16(pb); /* flags */
            break;
        case MKTAG('C', 'O', 'N', 'T'):
            get_str(pb, s->title, sizeof(s->title));
            get_str(pb, s->author, sizeof(s->author));
            get_str(pb, s->copyright, sizeof(s->copyright));
            get_str(pb, s->comment, sizeof(s->comment));
            break;
        case MKTAG('M', 'D', 'P', 'R'):
            st = av_new_stream(s, 0);
            if (!st)
                goto fail;
            st->id = get_be16(pb);
            get_be32(pb); /* max bit rate */
            st->codec->bit_rate = get_be32(pb); /* bit rate */
            get_be32(pb); /* max packet size */
            get_be32(pb); /* avg packet size */
            start_time = get_be32(pb); /* start time */
            get_be32(pb); /* preroll */
            duration = get_be32(pb); /* duration */
            st->start_time = start_time;
            st->duration = duration;
            get_str8(pb, buf, sizeof(buf)); /* desc */
            get_str8(pb, buf, sizeof(buf)); /* mimetype */
            codec_data_size = get_be32(pb);
            codec_pos = url_ftell(pb);
            st->codec->codec_type = CODEC_TYPE_DATA;
            av_set_pts_info(st, 64, 1, 1000);
            v = get_be32(pb);
            if (v == MKTAG(0xfd, 'a', 'r', '.')) {
                /* ra type header */
                rm_read_audio_stream_info(s, st, 0);
            } else {
                int fps, fps2;
                if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
                fail1:
                    av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");
                    goto skip;
                st->codec->codec_tag = get_le32(pb);
//                av_log(NULL, AV_LOG_DEBUG, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
                if (   st->codec->codec_tag != MKTAG('R', 'V', '1', '0')
                    && st->codec->codec_tag != MKTAG('R', 'V', '2', '0')
                    && st->codec->codec_tag != MKTAG('R', 'V', '3', '0')
                    && st->codec->codec_tag != MKTAG('R', 'V', '4', '0'))
                    goto fail1;
                st->codec->width = get_be16(pb);
                st->codec->height = get_be16(pb);
                st->codec->time_base.num= 1;
                fps= get_be16(pb);
                st->codec->codec_type = CODEC_TYPE_VIDEO;
                get_be32(pb);
                fps2= get_be16(pb);
                get_be16(pb);
                st->codec->extradata_size= codec_data_size - (url_ftell(pb) - codec_pos);
                st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
//                av_log(NULL, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2);
                st->codec->time_base.den = fps * st->codec->time_base.num;
                /* modification of h263 codec version (!) */
#ifdef WORDS_BIGENDIAN
                h263_hack_version = ((uint32_t*)st->codec->extradata)[1];
#else
                h263_hack_version = bswap_32(((uint32_t*)st->codec->extradata)[1]);
#endif
                st->codec->sub_id = h263_hack_version;
                switch((h263_hack_version>>28)){
                case 1: st->codec->codec_id = CODEC_ID_RV10; break;
                case 2: st->codec->codec_id = CODEC_ID_RV20; break;
                case 3: st->codec->codec_id = CODEC_ID_RV30; break;
                case 4: st->codec->codec_id = CODEC_ID_RV40; break;
                default: goto fail1;
skip:
            /* skip codec info */
            size = url_ftell(pb) - codec_pos;
            url_fskip(pb, codec_data_size - size);
            break;
        case MKTAG('D', 'A', 'T', 'A'):
            goto header_end;
        default:
            /* unknown tag: skip it */
            url_fskip(pb, tag_size - 10);
            break;
 header_end:
    rm->nb_packets = get_be32(pb); /* number of packets */
    if (!rm->nb_packets && (flags & 4))
        rm->nb_packets = 3600 * 25;
    get_be32(pb); /* next data header */
    return 0;
 fail:
    for(i=0;i<s->nb_streams;i++) {
        av_free(s->streams[i]);
    return AVERROR_IO;


static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,

                                 int nb_sectors, int *pnum)

{

    BDRVParallelsState *s = bs->opaque;

    uint32_t idx, to_allocate, i;

    int64_t pos, space;

    pos = block_status(s, sector_num, nb_sectors, pnum);

    if (pos > 0) {

        return pos;

    }

    idx = sector_num / s->tracks;

    if (idx >= s->bat_size) {

        return -EINVAL;

    }

    to_allocate = DIV_ROUND_UP(sector_num + *pnum, s->tracks) - idx;

    space = to_allocate * s->tracks;

    if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) {

        int ret;

        space += s->prealloc_size;

        if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {

            ret = bdrv_pwrite_zeroes(bs->file,

                                     s->data_end << BDRV_SECTOR_BITS,

                                     space << BDRV_SECTOR_BITS, 0);

        } else {

            ret = bdrv_truncate(bs->file,

                                (s->data_end + space) << BDRV_SECTOR_BITS);

        }

        if (ret < 0) {

            return ret;

        }

    }

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

        s->bat_bitmap[idx + i] = cpu_to_le32(s->data_end / s->off_multiplier);

        s->data_end += s->tracks;

        bitmap_set(s->bat_dirty_bmap,

                   bat_entry_off(idx + i) / s->bat_dirty_block, 1);

    }

    return bat2sect(s, idx) + sector_num % s->tracks;

}


static void send_scsi_cdb_read10(QPCIDevice *dev, void *ide_base,

                                 uint64_t lba, int nblocks)

{

    Read10CDB pkt = { .padding = 0 };

    int i;

    g_assert_cmpint(lba, <=, UINT32_MAX);

    g_assert_cmpint(nblocks, <=, UINT16_MAX);

    g_assert_cmpint(nblocks, >=, 0);

    /* Construct SCSI CDB packet */

    pkt.opcode = 0x28;

    pkt.lba = cpu_to_be32(lba);

    pkt.nblocks = cpu_to_be16(nblocks);

    /* Send Packet */

    for (i = 0; i < sizeof(Read10CDB)/2; i++) {

        qpci_io_writew(dev, ide_base + reg_data,

                       le16_to_cpu(((uint16_t *)&pkt)[i]));

    }

}


static int vobsub_read_header(AVFormatContext *s)

{

    int i, ret = 0, header_parsed = 0, langidx = 0;

    MpegDemuxContext *vobsub = s->priv_data;

    char *sub_name = NULL;

    size_t fname_len;

    char *ext, *header_str;

    AVBPrint header;

    int64_t delay = 0;

    AVStream *st = NULL;

    sub_name = av_strdup(s->filename);

    fname_len = strlen(sub_name);

    ext = sub_name - 3 + fname_len;

    if (fname_len < 4 || *(ext - 1) != '.') {

        av_log(s, AV_LOG_ERROR, "The input index filename is too short "

               "to guess the associated .SUB file\n");

        ret = AVERROR_INVALIDDATA;

        goto end;

    }

    memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);

    av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name);

    ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL);

    if (ret < 0) {

        av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name);

        goto end;

    }

    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);

    while (!url_feof(s->pb)) {

        char line[2048];

        int len = ff_get_line(s->pb, line, sizeof(line));

        if (!len)

            break;

        line[strcspn(line, "\r\n")] = 0;

        if (!strncmp(line, "id:", 3)) {

            int n, stream_id = 0;

            char id[64] = {0};

            n = sscanf(line, "id: %63[^,], index: %u", id, &stream_id);

            if (n != 2) {

                av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "

                       "assuming 'id: und, index: 0'\n", line);

                strcpy(id, "und");

                stream_id = 0;

            }

            if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {

                av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");

                ret = AVERROR(EINVAL);

                goto end;

            }

            st = avformat_new_stream(s, NULL);

            if (!st) {

                ret = AVERROR(ENOMEM);

                goto end;

            }

            st->id = stream_id;

            st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;

            st->codec->codec_id   = AV_CODEC_ID_DVD_SUBTITLE;

            avpriv_set_pts_info(st, 64, 1, 1000);

            av_dict_set(&st->metadata, "language", id, 0);

            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);

            header_parsed = 1;

        } else if (st && !strncmp(line, "timestamp:", 10)) {

            AVPacket *sub;

            int hh, mm, ss, ms;

            int64_t pos, timestamp;

            const char *p = line + 10;

            if (!s->nb_streams) {

                av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");

                ret = AVERROR_INVALIDDATA;

                goto end;

            }

            if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,

                       &hh, &mm, &ss, &ms, &pos) != 5) {

                av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "

                       "abort parsing\n", line);

                break;

            }

            timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;

            timestamp = av_rescale_q(timestamp, av_make_q(1, 1000), st->time_base);

            sub = ff_subtitles_queue_insert(&vobsub->q[s->nb_streams - 1], "", 0, 0);

            if (!sub) {

                ret = AVERROR(ENOMEM);

                goto end;

            }

            sub->pos = pos;

            sub->pts = timestamp;

            sub->stream_index = s->nb_streams - 1;

        } else if (st && !strncmp(line, "alt:", 4)) {

            const char *p = line + 4;

            while (*p == ' ')

                p++;

            av_dict_set(&st->metadata, "title", p, 0);

            av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", st->id, p);

            header_parsed = 1;

        } else if (!strncmp(line, "delay:", 6)) {

            int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;

            const char *p = line + 6;

            while (*p == ' ')

                p++;

            if (*p == '-' || *p == '+') {

                sign = *p == '-' ? -1 : 1;

                p++;

            }

            sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);

            delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;

        } else if (!strncmp(line, "langidx:", 8)) {

            const char *p = line + 8;

            if (sscanf(p, "%d", &langidx) != 1)

                av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");

        } else if (!header_parsed) {

            if (line[0] && line[0] != '#')

                av_bprintf(&header, "%s\n", line);

        }

    }

    if (langidx < s->nb_streams)

        s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;

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

        vobsub->q[i].sort = SUB_SORT_POS_TS;

        ff_subtitles_queue_finalize(&vobsub->q[i]);

    }

    if (!av_bprint_is_complete(&header)) {

        av_bprint_finalize(&header, NULL);

        ret = AVERROR(ENOMEM);

        goto end;

    }

    av_bprint_finalize(&header, &header_str);

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

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

        sub_st->codec->extradata      = av_strdup(header_str);

        sub_st->codec->extradata_size = header.len;

    }

    av_free(header_str);

end:

    av_free(sub_name);

    return ret;

}


QBool *qobject_to_qbool(const QObject *obj)

{

    if (qobject_type(obj) != QTYPE_QBOOL)

        return NULL;

    return container_of(obj, QBool, base);

}


static av_always_inline int mvd_decode(HEVCContext *s)

{

    int ret = 2;

    int k = 1;

    while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) {

        ret += 1 << k;

        k++;

    }

    if (k == CABAC_MAX_BIN)

        av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k);

    while (k--)

        ret += get_cabac_bypass(&s->HEVClc->cc) << k;

    return get_cabac_bypass_sign(&s->HEVClc->cc, -ret);

}


static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)

{

    CPUS390XState *env = &cpu->env;

    cpu_synchronize_state(CPU(cpu));

    env->regs[2] = s390_virtio_hypercall(env);

    return 0;

}


av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v)

{

    MpegEncContext *s = &v->s;

    int i;

    int mb_height = FFALIGN(s->mb_height, 2);

    /* Allocate mb bitplanes */

    v->mv_type_mb_plane = av_malloc (s->mb_stride * mb_height);

    v->direct_mb_plane  = av_malloc (s->mb_stride * mb_height);

    v->forward_mb_plane = av_malloc (s->mb_stride * mb_height);

    v->fieldtx_plane    = av_mallocz(s->mb_stride * mb_height);

    v->acpred_plane     = av_malloc (s->mb_stride * mb_height);

    v->over_flags_plane = av_malloc (s->mb_stride * mb_height);

    v->n_allocated_blks = s->mb_width + 2;

    v->block            = av_malloc(sizeof(*v->block) * v->n_allocated_blks);

    v->cbp_base         = av_malloc(sizeof(v->cbp_base[0]) * 2 * s->mb_stride);

    v->cbp              = v->cbp_base + s->mb_stride;

    v->ttblk_base       = av_malloc(sizeof(v->ttblk_base[0]) * 2 * s->mb_stride);

    v->ttblk            = v->ttblk_base + s->mb_stride;

    v->is_intra_base    = av_mallocz(sizeof(v->is_intra_base[0]) * 2 * s->mb_stride);

    v->is_intra         = v->is_intra_base + s->mb_stride;

    v->luma_mv_base     = av_malloc(sizeof(v->luma_mv_base[0]) * 2 * s->mb_stride);

    v->luma_mv          = v->luma_mv_base + s->mb_stride;

    /* allocate block type info in that way so it could be used with s->block_index[] */

    v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);

    v->mb_type[0]   = v->mb_type_base + s->b8_stride + 1;

    v->mb_type[1]   = v->mb_type_base + s->b8_stride * (mb_height * 2 + 1) + s->mb_stride + 1;

    v->mb_type[2]   = v->mb_type[1] + s->mb_stride * (mb_height + 1);

    /* allocate memory to store block level MV info */

    v->blk_mv_type_base = av_mallocz(     s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);

    v->blk_mv_type      = v->blk_mv_type_base + s->b8_stride + 1;

    v->mv_f_base        = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));

    v->mv_f[0]          = v->mv_f_base + s->b8_stride + 1;

    v->mv_f[1]          = v->mv_f[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);

    v->mv_f_next_base   = av_mallocz(2 * (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2));

    v->mv_f_next[0]     = v->mv_f_next_base + s->b8_stride + 1;

    v->mv_f_next[1]     = v->mv_f_next[0] + (s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2);

    ff_intrax8_common_init(&v->x8,s);

    if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {

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

            if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) return -1;

    }

    if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane ||

        !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base ||

        !v->mb_type_base) {

        goto error;

    }

    return 0;

error:

    ff_vc1_decode_end(s->avctx);

    return AVERROR(ENOMEM);

}


static int vapic_prepare(VAPICROMState *s)

{

    vapic_map_rom_writable(s);

    if (patch_hypercalls(s) < 0) {

        return -1;

    }

    vapic_enable_tpr_reporting(true);

    return 0;

}


void ahci_uninit(AHCIState *s)

{

    int i, j;

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

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

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

            IDEState *s = &ad->port.ifs[j];

            ide_exit(s);

        }

    }

    g_free(s->dev);

}


int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)

{

    int ret, size;

    size = RAW_PACKET_SIZE;

    if (av_new_packet(pkt, size) < 0)

        return AVERROR(ENOMEM);

    pkt->pos= avio_tell(s->pb);

    pkt->stream_index = 0;

    ret = ffio_read_partial(s->pb, pkt->data, size);

    if (ret < 0) {

        av_free_packet(pkt);

        return ret;

    }

    pkt->size = ret;

    return ret;

}


static inline struct rgbvec interp_tetrahedral(const LUT3DContext *lut3d,

                                               const struct rgbvec *s)

{

    const struct rgbvec d = {s->r - PREV(s->r), s->g - PREV(s->g), s->b - PREV(s->b)};

    const struct rgbvec c000 = lut3d->lut[PREV(s->r)][PREV(s->g)][PREV(s->b)];

    const struct rgbvec c001 = lut3d->lut[PREV(s->r)][PREV(s->g)][NEXT(s->b)];

    const struct rgbvec c010 = lut3d->lut[PREV(s->r)][NEXT(s->g)][PREV(s->b)];

    const struct rgbvec c011 = lut3d->lut[PREV(s->r)][NEXT(s->g)][NEXT(s->b)];

    const struct rgbvec c100 = lut3d->lut[NEXT(s->r)][PREV(s->g)][PREV(s->b)];

    const struct rgbvec c101 = lut3d->lut[NEXT(s->r)][PREV(s->g)][NEXT(s->b)];

    const struct rgbvec c110 = lut3d->lut[NEXT(s->r)][NEXT(s->g)][PREV(s->b)];

    const struct rgbvec c111 = lut3d->lut[NEXT(s->r)][NEXT(s->g)][NEXT(s->b)];

    struct rgbvec c;

    if (d.r > d.g) {

        if (d.g > d.b) {

            c.r = (1-d.r) * c000.r + (d.r-d.g) * c100.r + (d.g-d.b) * c110.r + (d.b) * c111.r;

            c.g = (1-d.r) * c000.g + (d.r-d.g) * c100.g + (d.g-d.b) * c110.g + (d.b) * c111.g;

            c.b = (1-d.r) * c000.b + (d.r-d.g) * c100.b + (d.g-d.b) * c110.b + (d.b) * c111.b;

        } else if (d.r > d.b) {

            c.r = (1-d.r) * c000.r + (d.r-d.b) * c100.r + (d.b-d.g) * c101.r + (d.g) * c111.r;

            c.g = (1-d.r) * c000.g + (d.r-d.b) * c100.g + (d.b-d.g) * c101.g + (d.g) * c111.g;

            c.b = (1-d.r) * c000.b + (d.r-d.b) * c100.b + (d.b-d.g) * c101.b + (d.g) * c111.b;

        } else {

            c.r = (1-d.b) * c000.r + (d.b-d.r) * c001.r + (d.r-d.g) * c101.r + (d.g) * c111.r;

            c.g = (1-d.b) * c000.g + (d.b-d.r) * c001.g + (d.r-d.g) * c101.g + (d.g) * c111.g;

            c.b = (1-d.b) * c000.b + (d.b-d.r) * c001.b + (d.r-d.g) * c101.b + (d.g) * c111.b;

        }

    } else {

        if (d.b > d.g) {

            c.r = (1-d.b) * c000.r + (d.b-d.g) * c001.r + (d.g-d.r) * c011.r + (d.r) * c111.r;

            c.g = (1-d.b) * c000.g + (d.b-d.g) * c001.g + (d.g-d.r) * c011.g + (d.r) * c111.g;

            c.b = (1-d.b) * c000.b + (d.b-d.g) * c001.b + (d.g-d.r) * c011.b + (d.r) * c111.b;

        } else if (d.b > d.r) {

            c.r = (1-d.g) * c000.r + (d.g-d.b) * c010.r + (d.b-d.r) * c011.r + (d.r) * c111.r;

            c.g = (1-d.g) * c000.g + (d.g-d.b) * c010.g + (d.b-d.r) * c011.g + (d.r) * c111.g;

            c.b = (1-d.g) * c000.b + (d.g-d.b) * c010.b + (d.b-d.r) * c011.b + (d.r) * c111.b;

        } else {

            c.r = (1-d.g) * c000.r + (d.g-d.r) * c010.r + (d.r-d.b) * c110.r + (d.b) * c111.r;

            c.g = (1-d.g) * c000.g + (d.g-d.r) * c010.g + (d.r-d.b) * c110.g + (d.b) * c111.g;

            c.b = (1-d.g) * c000.b + (d.g-d.r) * c010.b + (d.r-d.b) * c110.b + (d.b) * c111.b;

        }

    }

    return c;

}


static av_cold int nvenc_setup_device(AVCodecContext *avctx)

{

    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    CUresult cu_res;

    CUcontext cu_context_curr;

    switch (avctx->codec->id) {

    case AV_CODEC_ID_H264:

        ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_H264_GUID;

        break;

    case AV_CODEC_ID_HEVC:

        ctx->init_encode_params.encodeGUID = NV_ENC_CODEC_HEVC_GUID;

        break;

    default:

        return AVERROR_BUG;

    }

    ctx->data_pix_fmt = avctx->pix_fmt;

#if CONFIG_CUDA

    if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {

        AVHWFramesContext *frames_ctx;

        AVCUDADeviceContext *device_hwctx;

        if (!avctx->hw_frames_ctx) {

            av_log(avctx, AV_LOG_ERROR, "hw_frames_ctx must be set when using GPU frames as input\n");

            return AVERROR(EINVAL);

        }

        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;

        device_hwctx = frames_ctx->device_ctx->hwctx;

        ctx->cu_context = device_hwctx->cuda_ctx;

        ctx->data_pix_fmt = frames_ctx->sw_format;

        return 0;

    }

#endif

    if (ctx->gpu >= dl_fn->nvenc_device_count) {

        av_log(avctx, AV_LOG_FATAL, "Requested GPU %d, but only %d GPUs are available!\n", ctx->gpu, dl_fn->nvenc_device_count);

        return AVERROR(EINVAL);

    }

    ctx->cu_context = NULL;

    cu_res = dl_fn->cu_ctx_create(&ctx->cu_context_internal, 4, dl_fn->nvenc_devices[ctx->gpu]); // CU_CTX_SCHED_BLOCKING_SYNC=4, avoid CPU spins

    if (cu_res != CUDA_SUCCESS) {

        av_log(avctx, AV_LOG_FATAL, "Failed creating CUDA context for NVENC: 0x%x\n", (int)cu_res);

        return AVERROR_EXTERNAL;

    }

    cu_res = dl_fn->cu_ctx_pop_current(&cu_context_curr);

    if (cu_res != CUDA_SUCCESS) {

        av_log(avctx, AV_LOG_FATAL, "Failed popping CUDA context: 0x%x\n", (int)cu_res);

        return AVERROR_EXTERNAL;

    }

    ctx->cu_context = ctx->cu_context_internal;

    return 0;

}


static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c)

{

    GetBitContext *gb       = &ctx->gb;

    ALSChannelData *current = cd;

    unsigned int channels   = ctx->avctx->channels;

    int entries             = 0;

    while (entries < channels && !(current->stop_flag = get_bits1(gb))) {

        current->master_channel = get_bits_long(gb, av_ceil_log2(channels));

        if (current->master_channel >= channels) {

            av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel!\n");

            return -1;

        }

        if (current->master_channel != c) {

            current->time_diff_flag = get_bits1(gb);

            current->weighting[0]   = als_weighting(gb, 1, 16);

            current->weighting[1]   = als_weighting(gb, 2, 14);

            current->weighting[2]   = als_weighting(gb, 1, 16);

            if (current->time_diff_flag) {

                current->weighting[3] = als_weighting(gb, 1, 16);

                current->weighting[4] = als_weighting(gb, 1, 16);

                current->weighting[5] = als_weighting(gb, 1, 16);

                current->time_diff_sign  = get_bits1(gb);

                current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3;

            }

        }

        current++;

        entries++;

    }

    if (entries == channels) {

        av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data!\n");

        return -1;

    }

    align_get_bits(gb);

    return 0;

}


static void cpu_unregister_map_client(void *_client)

{

    MapClient *client = (MapClient *)_client;

    QLIST_REMOVE(client, link);

    g_free(client);

}


static int rv34_decoder_alloc(RV34DecContext *r)

{

    r->intra_types_stride = r->s.mb_width * 4 + 4;

    r->cbp_chroma       = av_malloc(r->s.mb_stride * r->s.mb_height *

                                    sizeof(*r->cbp_chroma));

    r->cbp_luma         = av_malloc(r->s.mb_stride * r->s.mb_height *

                                    sizeof(*r->cbp_luma));

    r->deblock_coefs    = av_malloc(r->s.mb_stride * r->s.mb_height *

                                    sizeof(*r->deblock_coefs));

    r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 *

                                    sizeof(*r->intra_types_hist));

    r->mb_type          = av_mallocz(r->s.mb_stride * r->s.mb_height *

                                     sizeof(*r->mb_type));

    if (!(r->cbp_chroma       && r->cbp_luma && r->deblock_coefs &&

          r->intra_types_hist && r->mb_type)) {

        rv34_decoder_free(r);

        return AVERROR(ENOMEM);

    }

    r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;

    return 0;

}


static int dvbsub_parse(AVCodecParserContext *s,

                        AVCodecContext *avctx,

                        const uint8_t **poutbuf, int *poutbuf_size,

                        const uint8_t *buf, int buf_size)

{

    DVBSubParseContext *pc = s->priv_data;

    uint8_t *p, *p_end;

    int i, len, buf_pos = 0;

    av_dlog(avctx, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n",

            s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);

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

    {

        av_dlog(avctx, "%02x ", buf[i]);

        if (i % 16 == 15)

            av_dlog(avctx, "\n");

    }

    if (i % 16 != 0)

        av_dlog(avctx, "\n");

    *poutbuf = NULL;

    *poutbuf_size = 0;

    s->fetch_timestamp = 1;

    if (s->last_pts != s->pts && s->pts != AV_NOPTS_VALUE) /* Start of a new packet */

    {

        if (pc->packet_index != pc->packet_start)

        {

            av_dlog(avctx, "Discarding %d bytes\n",

                    pc->packet_index - pc->packet_start);

        }

        pc->packet_start = 0;

        pc->packet_index = 0;

        if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {

            av_dlog(avctx, "Bad packet header\n");

            return -1;

        }

        buf_pos = 2;

        pc->in_packet = 1;

    } else {

        if (pc->packet_start != 0)

        {

            if (pc->packet_index != pc->packet_start)

            {

                memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,

                            pc->packet_index - pc->packet_start);

                pc->packet_index -= pc->packet_start;

                pc->packet_start = 0;

            } else {

                pc->packet_start = 0;

                pc->packet_index = 0;

            }

        }

    }

    if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)

        return -1;

/* if not currently in a packet, discard data */

    if (pc->in_packet == 0)

        return buf_size;

    memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);

    pc->packet_index += buf_size - buf_pos;

    p = pc->packet_buf;

    p_end = pc->packet_buf + pc->packet_index;

    while (p < p_end)

    {

        if (*p == 0x0f)

        {

            if (p + 6 <= p_end)

            {

                len = AV_RB16(p + 4);

                if (p + len + 6 <= p_end)

                {

                    *poutbuf_size += len + 6;

                    p += len + 6;

                } else

                    break;

            } else

                break;

        } else if (*p == 0xff) {

            if (p + 1 < p_end)

            {

                av_dlog(avctx, "Junk at end of packet\n");

            }

            pc->packet_index = p - pc->packet_buf;

            pc->in_packet = 0;

            break;

        } else {

            av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");

            pc->packet_index = p - pc->packet_buf;

            pc->in_packet = 0;

            break;

        }

    }

    if (*poutbuf_size > 0)

    {

        *poutbuf = pc->packet_buf;

        pc->packet_start = *poutbuf_size;

    }

    if (s->pts == AV_NOPTS_VALUE)

        s->pts = s->last_pts;

    return buf_size;

}


static void id3v2_parse(AVFormatContext *s, int len, uint8_t version,

                        uint8_t flags, ID3v2ExtraMeta **extra_meta)

{

    int isv34, unsync;

    unsigned tlen;

    char tag[5];

    int64_t next, end = avio_tell(s->pb) + len;

    int taghdrlen;

    const char *reason = NULL;

    AVIOContext pb;

    AVIOContext *pbx;

    unsigned char *buffer = NULL;

    int buffer_size       = 0;

    const ID3v2EMFunc *extra_func = NULL;

    unsigned char *uncompressed_buffer = NULL;

    int uncompressed_buffer_size = 0;

    av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len);

    switch (version) {

    case 2:

        if (flags & 0x40) {

            reason = "compression";

            goto error;

        }

        isv34     = 0;

        taghdrlen = 6;

        break;

    case 3:

    case 4:

        isv34     = 1;

        taghdrlen = 10;

        break;

    default:

        reason = "version";

        goto error;

    }

    unsync = flags & 0x80;

    if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */

        int extlen = get_size(s->pb, 4);

        if (version == 4)

            /* In v2.4 the length includes the length field we just read. */

            extlen -= 4;

        if (extlen < 0) {

            reason = "invalid extended header length";

            goto error;

        }

        avio_skip(s->pb, extlen);

        len -= extlen + 4;

        if (len < 0) {

            reason = "extended header too long.";

            goto error;

        }

    }

    while (len >= taghdrlen) {

        unsigned int tflags = 0;

        int tunsync         = 0;

        int tcomp           = 0;

        int tencr           = 0;

        unsigned long dlen;

        if (isv34) {

            avio_read(s->pb, tag, 4);

            tag[4] = 0;

            if (version == 3) {

                tlen = avio_rb32(s->pb);

            } else

                tlen = get_size(s->pb, 4);

            tflags  = avio_rb16(s->pb);

            tunsync = tflags & ID3v2_FLAG_UNSYNCH;

        } else {

            avio_read(s->pb, tag, 3);

            tag[3] = 0;

            tlen   = avio_rb24(s->pb);

        }

        if (tlen > (1<<28))

            break;

        len -= taghdrlen + tlen;

        if (len < 0)

            break;

        next = avio_tell(s->pb) + tlen;

        if (!tlen) {

            if (tag[0])

                av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",

                       tag);

            continue;

        }

        if (tflags & ID3v2_FLAG_DATALEN) {

            if (tlen < 4)

                break;

            dlen = avio_rb32(s->pb);

            tlen -= 4;

        } else

            dlen = tlen;

        tcomp = tflags & ID3v2_FLAG_COMPRESSION;

        tencr = tflags & ID3v2_FLAG_ENCRYPTION;

        /* skip encrypted tags and, if no zlib, compressed tags */

        if (tencr || (!CONFIG_ZLIB && tcomp)) {

            const char *type;

            if (!tcomp)

                type = "encrypted";

            else if (!tencr)

                type = "compressed";

            else

                type = "encrypted and compressed";

            av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);

            avio_skip(s->pb, tlen);

        /* check for text tag or supported special meta tag */

        } else if (tag[0] == 'T' ||

                   (extra_meta &&

                    (extra_func = get_extra_meta_func(tag, isv34)))) {

            pbx = s->pb;

            if (unsync || tunsync || tcomp) {

                av_fast_malloc(&buffer, &buffer_size, tlen);

                if (!buffer) {

                    av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);

                    goto seek;

                }

            }

            if (unsync || tunsync) {

                int64_t end = avio_tell(s->pb) + tlen;

                uint8_t *b;

                b = buffer;

                while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) {

                    *b++ = avio_r8(s->pb);

                    if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 &&

                        b - buffer < tlen &&

                        !s->pb->eof_reached ) {

                        uint8_t val = avio_r8(s->pb);

                        *b++ = val ? val : avio_r8(s->pb);

                    }

                }

                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL,

                                  NULL);

                tlen = b - buffer;

                pbx  = &pb; // read from sync buffer

            }

#if CONFIG_ZLIB

                if (tcomp) {

                    int err;

                    av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);

                    av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);

                    if (!uncompressed_buffer) {

                        av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);

                        goto seek;

                    }

                    if (!(unsync || tunsync)) {

                        err = avio_read(s->pb, buffer, tlen);

                        if (err < 0) {

                            av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");

                            goto seek;

                        }

                        tlen = err;

                    }

                    err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);

                    if (err != Z_OK) {

                        av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);

                        goto seek;

                    }

                    ffio_init_context(&pb, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL);

                    tlen = dlen;

                    pbx = &pb; // read from sync buffer

                }

#endif

            if (tag[0] == 'T')

                /* parse text tag */

                read_ttag(s, pbx, tlen, &s->metadata, tag);

            else

                /* parse special meta tag */

                extra_func->read(s, pbx, tlen, tag, extra_meta);

        } else if (!tag[0]) {

            if (tag[1])

                av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");

            avio_skip(s->pb, tlen);

            break;

        }

        /* Skip to end of tag */

seek:

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

    }

    /* Footer preset, always 10 bytes, skip over it */

    if (version == 4 && flags & 0x10)

        end += 10;

error:

    if (reason)

        av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",

               version, reason);

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

    av_free(buffer);

    av_free(uncompressed_buffer);

    return;

}


static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,

                                  int ecpl, int start_subband, int end_subband,

                                  const uint8_t *default_band_struct,

                                  uint8_t *band_struct, int *num_subbands,

                                  int *num_bands, uint8_t *band_sizes)

{

    int subbnd, bnd, n_subbands, n_bands;

    uint8_t bnd_sz[22];

    n_subbands = end_subband - start_subband;

    /* decode band structure from bitstream or use default */

    if (!eac3 || get_bits1(gbc)) {

        for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) {

            band_struct[subbnd] = get_bits1(gbc);

        }

    } else if (!blk) {

        memcpy(band_struct,

               &default_band_struct[start_subband+1],

               n_subbands-1);

    }

    band_struct[n_subbands-1] = 0;

    /* calculate number of bands and band sizes based on band structure.

       note that the first 4 subbands in enhanced coupling span only 6 bins

       instead of 12. */

    if (num_bands || band_sizes ) {

        n_bands = n_subbands;

        bnd_sz[0] = ecpl ? 6 : 12;

        for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {

            int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;

            if (band_struct[subbnd-1]) {

                n_bands--;

                bnd_sz[bnd] += subbnd_size;

            } else {

                bnd_sz[++bnd] = subbnd_size;

            }

        }

    }

    /* set optional output params */

    if (num_subbands)

        *num_subbands = n_subbands;

    if (num_bands)

        *num_bands = n_bands;

    if (band_sizes)

        memcpy(band_sizes, bnd_sz, n_bands);

}


static void dump_iterate(DumpState *s, Error **errp)

{

    GuestPhysBlock *block;

    int64_t size;

    int ret;

    Error *local_err = NULL;

    while (1) {

        block = s->next_block;

        size = block->target_end - block->target_start;

        if (s->has_filter) {

            size -= s->start;

            if (s->begin + s->length < block->target_end) {

                size -= block->target_end - (s->begin + s->length);

            }

        }

        write_memory(s, block, s->start, size, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return;

        }

        ret = get_next_block(s, block);

        if (ret == 1) {

            dump_completed(s);

        }

    }

}


fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,

                             target_phys_addr_t mmio_base,

                             DriveInfo **fds)

{

    fdctrl_t *fdctrl;

    DeviceState *dev;

    fdctrl_sysbus_t *sys;

    dev = qdev_create(NULL, "sysbus-fdc");

    sys = DO_UPCAST(fdctrl_sysbus_t, busdev.qdev, dev);

    fdctrl = &sys->state;

    fdctrl->dma_chann = dma_chann; /* FIXME */

    qdev_prop_set_drive(dev, "driveA", fds[0]);

    qdev_prop_set_drive(dev, "driveB", fds[1]);

    if (qdev_init(dev) != 0)

        return NULL;

    sysbus_connect_irq(&sys->busdev, 0, irq);

    sysbus_mmio_map(&sys->busdev, 0, mmio_base);

    return fdctrl;

}


static void uhci_async_complete(USBPort *port, USBPacket *packet)

{

    UHCIAsync *async = container_of(packet, UHCIAsync, packet);

    UHCIState *s = async->queue->uhci;

    if (async->isoc) {

        UHCI_TD td;

        uint32_t link = async->td;

        uint32_t int_mask = 0, val;

        pci_dma_read(&s->dev, link & ~0xf, &td, sizeof(td));

        le32_to_cpus(&td.link);

        le32_to_cpus(&td.ctrl);

        le32_to_cpus(&td.token);

        le32_to_cpus(&td.buffer);

        uhci_async_unlink(async);

        uhci_complete_td(s, &td, async, &int_mask);

        s->pending_int_mask |= int_mask;

        /* update the status bits of the TD */

        val = cpu_to_le32(td.ctrl);

        pci_dma_write(&s->dev, (link & ~0xf) + 4, &val, sizeof(val));

        uhci_async_free(async);

    } else {

        async->done = 1;

        uhci_process_frame(s);

    }

}


int coroutine_fn thread_pool_submit_co(ThreadPoolFunc *func, void *arg)

{

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

    assert(qemu_in_coroutine());

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

    qemu_coroutine_yield();

    return tpc.ret;

}


static void uhci_process_frame(UHCIState *s)

{

    uint32_t frame_addr, link, old_td_ctrl, val, int_mask;

    uint32_t curr_qh;

    int cnt, ret;

    UHCI_TD td;

    UHCI_QH qh;

    QhDb qhdb;

    frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);

    DPRINTF("uhci: processing frame %d addr 0x%x\n" , s->frnum, frame_addr);

    cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);

    le32_to_cpus(&link);

    int_mask = 0;

    curr_qh  = 0;

    qhdb_reset(&qhdb);

    for (cnt = FRAME_MAX_LOOPS; is_valid(link) && cnt; cnt--) {

        if (is_qh(link)) {

            /* QH */

            if (qhdb_insert(&qhdb, link)) {

                /*

                 * We're going in circles. Which is not a bug because

                 * HCD is allowed to do that as part of the BW management.

                 * In our case though it makes no sense to spin here. Sync transations

                 * are already done, and async completion handler will re-process

                 * the frame when something is ready.

                 */

                DPRINTF("uhci: detected loop. qh 0x%x\n", link);

                break;

            }

            cpu_physical_memory_read(link & ~0xf, (uint8_t *) &qh, sizeof(qh));

            le32_to_cpus(&qh.link);

            le32_to_cpus(&qh.el_link);

            DPRINTF("uhci: QH 0x%x load. link 0x%x elink 0x%x\n",

                    link, qh.link, qh.el_link);

            if (!is_valid(qh.el_link)) {

                /* QH w/o elements */

                curr_qh = 0;

                link = qh.link;

            } else {

                /* QH with elements */

            	curr_qh = link;

            	link = qh.el_link;

            }

            continue;

        }

        /* TD */

        cpu_physical_memory_read(link & ~0xf, (uint8_t *) &td, sizeof(td));

        le32_to_cpus(&td.link);

        le32_to_cpus(&td.ctrl);

        le32_to_cpus(&td.token);

        le32_to_cpus(&td.buffer);

        DPRINTF("uhci: TD 0x%x load. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",

                link, td.link, td.ctrl, td.token, curr_qh);

        old_td_ctrl = td.ctrl;

        ret = uhci_handle_td(s, link, &td, &int_mask);

        if (old_td_ctrl != td.ctrl) {

            /* update the status bits of the TD */

            val = cpu_to_le32(td.ctrl);

            cpu_physical_memory_write((link & ~0xf) + 4,

                                      (const uint8_t *)&val, sizeof(val));

        }

        if (ret < 0) {

            /* interrupted frame */

            break;

        }

        if (ret == 2 || ret == 1) {

            DPRINTF("uhci: TD 0x%x %s. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",

                    link, ret == 2 ? "pend" : "skip",

                    td.link, td.ctrl, td.token, curr_qh);

            link = curr_qh ? qh.link : td.link;

            continue;

        }

        /* completed TD */

        DPRINTF("uhci: TD 0x%x done. link 0x%x ctrl 0x%x token 0x%x qh 0x%x\n",

                link, td.link, td.ctrl, td.token, curr_qh);

        link = td.link;

        if (curr_qh) {

	    /* update QH element link */

            qh.el_link = link;

            val = cpu_to_le32(qh.el_link);

            cpu_physical_memory_write((curr_qh & ~0xf) + 4,

                                          (const uint8_t *)&val, sizeof(val));

            if (!depth_first(link)) {

               /* done with this QH */

               DPRINTF("uhci: QH 0x%x done. link 0x%x elink 0x%x\n",

                       curr_qh, qh.link, qh.el_link);

               curr_qh = 0;

               link    = qh.link;

            }

        }

        /* go to the next entry */

    }

    s->pending_int_mask |= int_mask;

}


int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx,

                                              AVPacket *avpkt,

                                              const AVFrame *frame,

                                              int *got_packet_ptr)

{

    AVFrame tmp;

    AVFrame *padded_frame = NULL;

    int ret;

    AVPacket user_pkt = *avpkt;

    int needs_realloc = !user_pkt.data;

    *got_packet_ptr = 0;

    if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) {

        av_free_packet(avpkt);

        av_init_packet(avpkt);

        return 0;

    }

    /* ensure that extended_data is properly set */

    if (frame && !frame->extended_data) {

        if (av_sample_fmt_is_planar(avctx->sample_fmt) &&

            avctx->channels > AV_NUM_DATA_POINTERS) {

            av_log(avctx, AV_LOG_ERROR, "Encoding to a planar sample format, "

                                        "with more than %d channels, but extended_data is not set.\n",

                   AV_NUM_DATA_POINTERS);

            return AVERROR(EINVAL);

        }

        av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n");

        tmp = *frame;

        tmp.extended_data = tmp.data;

        frame = &tmp;

    }

    /* check for valid frame size */

    if (frame) {

        if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {

            if (frame->nb_samples > avctx->frame_size) {

                av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n");

                return AVERROR(EINVAL);

            }

        } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {

            if (frame->nb_samples < avctx->frame_size &&

                !avctx->internal->last_audio_frame) {

                ret = pad_last_frame(avctx, &padded_frame, frame);

                if (ret < 0)

                    return ret;

                frame = padded_frame;

                avctx->internal->last_audio_frame = 1;

            }

            if (frame->nb_samples != avctx->frame_size) {

                av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size);

                ret = AVERROR(EINVAL);

                goto end;

            }

        }

    }

    ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);

    if (!ret) {

        if (*got_packet_ptr) {

            if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) {

                if (avpkt->pts == AV_NOPTS_VALUE)

                    avpkt->pts = frame->pts;

                if (!avpkt->duration)

                    avpkt->duration = ff_samples_to_time_base(avctx,

                                                              frame->nb_samples);

            }

            avpkt->dts = avpkt->pts;

        } else {

            avpkt->size = 0;

        }

    }

    if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {

        needs_realloc = 0;

        if (user_pkt.data) {

            if (user_pkt.size >= avpkt->size) {

                memcpy(user_pkt.data, avpkt->data, avpkt->size);

            } else {

                av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);

                avpkt->size = user_pkt.size;

                ret = -1;

            }

            avpkt->buf      = user_pkt.buf;

            avpkt->data     = user_pkt.data;

            avpkt->destruct = user_pkt.destruct;

        } else {

            if (av_dup_packet(avpkt) < 0) {

                ret = AVERROR(ENOMEM);

            }

        }

    }

    if (!ret) {

        if (needs_realloc && avpkt->data) {

            ret = av_buffer_realloc(&avpkt->buf, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);

            if (ret >= 0)

                avpkt->data = avpkt->buf->data;

        }

        avctx->frame_number++;

    }

    if (ret < 0 || !*got_packet_ptr) {

        av_free_packet(avpkt);

        av_init_packet(avpkt);

        goto end;

    }

    /* NOTE: if we add any audio encoders which output non-keyframe packets,

     *       this needs to be moved to the encoders, but for now we can do it

     *       here to simplify things */

    avpkt->flags |= AV_PKT_FLAG_KEY;

end:

    av_frame_free(&padded_frame);

    return ret;

}


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

{

    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);

    VirtIOInput *vinput = VIRTIO_INPUT(vdev);

    virtio_input_event event;

    VirtQueueElement elem;

    int len;

    while (virtqueue_pop(vinput->sts, &elem)) {

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

        len = iov_to_buf(elem.out_sg, elem.out_num,

                         0, &event, sizeof(event));

        if (vic->handle_status) {

            vic->handle_status(vinput, &event);

        }

        virtqueue_push(vinput->sts, &elem, len);

    }

    virtio_notify(vdev, vinput->sts);

}


void qmp_guest_file_close(int64_t handle, Error **err)

{

    GuestFileHandle *gfh = guest_file_handle_find(handle, err);

    int ret;

    slog("guest-file-close called, handle: %ld", handle);

    if (!gfh) {

        return;

    }

    ret = fclose(gfh->fh);

    if (ret == -1) {

        error_set(err, QERR_QGA_COMMAND_FAILED, "fclose() failed");

        return;

    }

    QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);

    g_free(gfh);

}


static int convert_read(ImgConvertState *s, int64_t sector_num, int nb_sectors,

                        uint8_t *buf)

{

    int n;

    int ret;

    if (s->status == BLK_ZERO || s->status == BLK_BACKING_FILE) {

        return 0;

    }

    assert(nb_sectors <= s->buf_sectors);

    while (nb_sectors > 0) {

        BlockBackend *blk;

        int64_t bs_sectors;

        /* In the case of compression with multiple source files, we can get a

         * nb_sectors that spreads into the next part. So we must be able to

         * read across multiple BDSes for one convert_read() call. */

        convert_select_part(s, sector_num);

        blk = s->src[s->src_cur];

        bs_sectors = s->src_sectors[s->src_cur];

        n = MIN(nb_sectors, bs_sectors - (sector_num - s->src_cur_offset));

        ret = blk_read(blk, sector_num - s->src_cur_offset, buf, n);

        if (ret < 0) {

            return ret;

        }

        sector_num += n;

        nb_sectors -= n;

        buf += n * BDRV_SECTOR_SIZE;

    }

    return 0;

}


static void qemu_announce_self_once(void *opaque)

{

    static int count = SELF_ANNOUNCE_ROUNDS;

    QEMUTimer *timer = *(QEMUTimer **)opaque;

    qemu_foreach_nic(qemu_announce_self_iter, NULL);

    if (--count) {

        /* delay 50ms, 150ms, 250ms, ... */

        qemu_mod_timer(timer, qemu_get_clock(rt_clock) +

                       50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);

    } else {

	    qemu_del_timer(timer);

	    qemu_free_timer(timer);

    }

}


static int nvme_init(PCIDevice *pci_dev)

{

    NvmeCtrl *n = NVME(pci_dev);

    NvmeIdCtrl *id = &n->id_ctrl;

    int i;

    int64_t bs_size;

    uint8_t *pci_conf;

    if (!(n->conf.bs)) {

        return -1;

    }

    bs_size = bdrv_getlength(n->conf.bs);

    if (bs_size < 0) {

        return -1;

    }

    blkconf_serial(&n->conf, &n->serial);

    if (!n->serial) {

        return -1;

    }

    pci_conf = pci_dev->config;

    pci_conf[PCI_INTERRUPT_PIN] = 1;

    pci_config_set_prog_interface(pci_dev->config, 0x2);

    pci_config_set_class(pci_dev->config, PCI_CLASS_STORAGE_EXPRESS);

    pcie_endpoint_cap_init(&n->parent_obj, 0x80);

    n->num_namespaces = 1;

    n->num_queues = 64;

    n->reg_size = 1 << qemu_fls(0x1004 + 2 * (n->num_queues + 1) * 4);

    n->ns_size = bs_size / (uint64_t)n->num_namespaces;

    n->namespaces = g_new0(NvmeNamespace, n->num_namespaces);

    n->sq = g_new0(NvmeSQueue *, n->num_queues);

    n->cq = g_new0(NvmeCQueue *, n->num_queues);

    memory_region_init_io(&n->iomem, OBJECT(n), &nvme_mmio_ops, n,

                          "nvme", n->reg_size);

    pci_register_bar(&n->parent_obj, 0,

        PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64,

        &n->iomem);

    msix_init_exclusive_bar(&n->parent_obj, n->num_queues, 4);

    id->vid = cpu_to_le16(pci_get_word(pci_conf + PCI_VENDOR_ID));

    id->ssvid = cpu_to_le16(pci_get_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID));

    strpadcpy((char *)id->mn, sizeof(id->mn), "QEMU NVMe Ctrl", ' ');

    strpadcpy((char *)id->fr, sizeof(id->fr), "1.0", ' ');

    strpadcpy((char *)id->sn, sizeof(id->sn), n->serial, ' ');

    id->rab = 6;

    id->ieee[0] = 0x00;

    id->ieee[1] = 0x02;

    id->ieee[2] = 0xb3;

    id->oacs = cpu_to_le16(0);

    id->frmw = 7 << 1;

    id->lpa = 1 << 0;

    id->sqes = (0x6 << 4) | 0x6;

    id->cqes = (0x4 << 4) | 0x4;

    id->nn = cpu_to_le32(n->num_namespaces);

    id->psd[0].mp = cpu_to_le16(0x9c4);

    id->psd[0].enlat = cpu_to_le32(0x10);

    id->psd[0].exlat = cpu_to_le32(0x4);

    n->bar.cap = 0;

    NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);

    NVME_CAP_SET_CQR(n->bar.cap, 1);

    NVME_CAP_SET_AMS(n->bar.cap, 1);

    NVME_CAP_SET_TO(n->bar.cap, 0xf);

    NVME_CAP_SET_CSS(n->bar.cap, 1);

    n->bar.vs = 0x00010001;

    n->bar.intmc = n->bar.intms = 0;

    for (i = 0; i < n->num_namespaces; i++) {

        NvmeNamespace *ns = &n->namespaces[i];

        NvmeIdNs *id_ns = &ns->id_ns;

        id_ns->nsfeat = 0;

        id_ns->nlbaf = 0;

        id_ns->flbas = 0;

        id_ns->mc = 0;

        id_ns->dpc = 0;

        id_ns->dps = 0;

        id_ns->lbaf[0].ds = BDRV_SECTOR_BITS;

        id_ns->ncap  = id_ns->nuse = id_ns->nsze =

            cpu_to_le64(n->ns_size >>

                id_ns->lbaf[NVME_ID_NS_FLBAS_INDEX(ns->id_ns.flbas)].ds);

    }

    return 0;

}


int blk_get_max_transfer_length(BlockBackend *blk)

{

    BlockDriverState *bs = blk_bs(blk);

    if (bs) {

        return bs->bl.max_transfer_length;

    } else {

        return 0;

    }

}


START_TEST(qstring_append_chr_test)

{

    int i;

    QString *qstring;

    const char *str = "qstring append char unit-test";

    qstring = qstring_new();

    for (i = 0; str[i]; i++)

        qstring_append_chr(qstring, str[i]);

    fail_unless(strcmp(str, qstring_get_str(qstring)) == 0);

    QDECREF(qstring);

}


static int ftp_get_line(FTPContext *s, char *line, int line_size)

{

    int ch;

    char *q = line;

    int ori_block_flag = s->conn_control_block_flag;

    for (;;) {

        ch = ftp_getc(s);

        if (ch < 0) {

            s->conn_control_block_flag = ori_block_flag;

            return ch;

        }

        if (ch == '\n') {

            /* process line */

            if (q > line && q[-1] == '\r')

                q--;

            *q = '\0';

            s->conn_control_block_flag = ori_block_flag;

            return 0;

        } else {

            s->conn_control_block_flag = 0; /* line need to be finished */

            if ((q - line) < line_size - 1)

                *q++ = ch;

        }

    }

}


static int raw_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)

{

    BDRVRawState *s = bs->opaque;

    if (s->offset || s->has_size) {

        return -ENOTSUP;

    }

    return bdrv_co_ioctl(bs->file->bs, req, buf);

}


static void lsi_io_write(void *opaque, target_phys_addr_t addr,

                         uint64_t val, unsigned size)

{

    LSIState *s = opaque;

    lsi_reg_writeb(s, addr & 0xff, val);

}


void input_type_enum(Visitor *v, int *obj, const char *strings[],

                     const char *kind, const char *name,

                     Error **errp)

{

    int64_t value = 0;

    char *enum_str;

    assert(strings);

    visit_type_str(v, &enum_str, name, errp);

    if (error_is_set(errp)) {

        return;

    }

    while (strings[value] != NULL) {

        if (strcmp(strings[value], enum_str) == 0) {

            break;

        }

        value++;

    }

    if (strings[value] == NULL) {

        error_set(errp, QERR_INVALID_PARAMETER, name ? name : "null");

        g_free(enum_str);

        return;

    }

    g_free(enum_str);

    *obj = value;

}


int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)

{

    CPUState *cpu = ENV_GET_CPU(env);

    TaskState *ts = cpu->opaque;

    struct emulated_sigtable *k;

    struct sigqueue *q, **pq;

    abi_ulong handler;

    int queue;

    trace_user_queue_signal(env, sig);

    k = &ts->sigtab[sig - 1];

    queue = gdb_queuesig ();

    handler = sigact_table[sig - 1]._sa_handler;

    if (sig == TARGET_SIGSEGV && sigismember(&ts->signal_mask, SIGSEGV)) {

        /* Guest has blocked SIGSEGV but we got one anyway. Assume this

         * is a forced SIGSEGV (ie one the kernel handles via force_sig_info

         * because it got a real MMU fault). A blocked SIGSEGV in that

         * situation is treated as if using the default handler. This is

         * not correct if some other process has randomly sent us a SIGSEGV

         * via kill(), but that is not easy to distinguish at this point,

         * so we assume it doesn't happen.

         */

        handler = TARGET_SIG_DFL;

    }

    if (!queue && handler == TARGET_SIG_DFL) {

        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {

            kill(getpid(),SIGSTOP);

            return 0;

        } else

        /* default handler : ignore some signal. The other are fatal */

        if (sig != TARGET_SIGCHLD &&

            sig != TARGET_SIGURG &&

            sig != TARGET_SIGWINCH &&

            sig != TARGET_SIGCONT) {

            force_sig(sig);

        } else {

            return 0; /* indicate ignored */

        }

    } else if (!queue && handler == TARGET_SIG_IGN) {

        /* ignore signal */

        return 0;

    } else if (!queue && handler == TARGET_SIG_ERR) {

        force_sig(sig);

    } else {

        pq = &k->first;

        if (sig < TARGET_SIGRTMIN) {

            /* if non real time signal, we queue exactly one signal */

            if (!k->pending)

                q = &k->info;

            else

                return 0;

        } else {

            if (!k->pending) {

                /* first signal */

                q = &k->info;

            } else {

                q = alloc_sigqueue(env);

                if (!q)

                    return -EAGAIN;

                while (*pq != NULL)

                    pq = &(*pq)->next;

            }

        }

        *pq = q;

        q->info = *info;

        q->next = NULL;

        k->pending = 1;

        /* signal that a new signal is pending */

        atomic_set(&ts->signal_pending, 1);

        return 1; /* indicates that the signal was queued */

    }

}


int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){
    int i;
    int w= s->width;
    int h= s->height;
    InternalBuffer *buf;
    int *picture_number;
    if(pic->data[0]!=NULL) {
        av_log(s, AV_LOG_ERROR, "pic->data[0]!=NULL in avcodec_default_get_buffer\n");
        return -1;
    }
    if(s->internal_buffer_count >= INTERNAL_BUFFER_SIZE) {
        av_log(s, AV_LOG_ERROR, "internal_buffer_count overflow (missing release_buffer?)\n");
        return -1;
    }
    if(avcodec_check_dimensions(s,w,h))
        return -1;
    if(s->internal_buffer==NULL){
        s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer));
    }
#if 0
    s->internal_buffer= av_fast_realloc(
        s->internal_buffer,
        &s->internal_buffer_size,
        sizeof(InternalBuffer)*FFMAX(99,  s->internal_buffer_count+1)/*FIXME*/
        );
#endif
    buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count];
    picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE-1]).last_pic_num; //FIXME ugly hack
    (*picture_number)++;
    if(buf->base[0]){
        pic->age= *picture_number - buf->last_pic_num;
        buf->last_pic_num= *picture_number;
    }else{
        int h_chroma_shift, v_chroma_shift;
        int pixel_size, size[3];
        AVPicture picture;
        avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
        if(!(s->flags&CODEC_FLAG_EMU_EDGE)){
            w+= EDGE_WIDTH*2;
            h+= EDGE_WIDTH*2;
        }
        avpicture_fill(&picture, NULL, s->pix_fmt, w, h);
        pixel_size= picture.linesize[0]*8 / w;
//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", (int)picture.data[1], w, h, s->pix_fmt);
        assert(pixel_size>=1);
            //FIXME next ensures that linesize= 2^x uvlinesize, thats needed because some MC code assumes it
        if(pixel_size == 3*8)
            w= ALIGN(w, STRIDE_ALIGN<<h_chroma_shift);
        else
            w= ALIGN(pixel_size*w, STRIDE_ALIGN<<(h_chroma_shift+3)) / pixel_size;
        size[1] = avpicture_fill(&picture, NULL, s->pix_fmt, w, h);
        size[0] = picture.linesize[0] * h;
        size[1] -= size[0];
        if(picture.data[2])
            size[1]= size[2]= size[1]/2;
        else
            size[2]= 0;
        buf->last_pic_num= -256*256*256*64;
        memset(buf->base, 0, sizeof(buf->base));
        memset(buf->data, 0, sizeof(buf->data));
        for(i=0; i<3 && size[i]; i++){
            const int h_shift= i==0 ? 0 : h_chroma_shift;
            const int v_shift= i==0 ? 0 : v_chroma_shift;
            buf->linesize[i]= picture.linesize[i];
            buf->base[i]= av_malloc(size[i]+16); //FIXME 16
            if(buf->base[i]==NULL) return -1;
            memset(buf->base[i], 128, size[i]);
            // no edge if EDEG EMU or not planar YUV, we check for PAL8 redundantly to protect against a exploitable bug regression ...
            if((s->flags&CODEC_FLAG_EMU_EDGE) || (s->pix_fmt == PIX_FMT_PAL8) || !size[2])
                buf->data[i] = buf->base[i];
            else
                buf->data[i] = buf->base[i] + ALIGN((buf->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), STRIDE_ALIGN);
        }
        pic->age= 256*256*256*64;
    }
    pic->type= FF_BUFFER_TYPE_INTERNAL;
    for(i=0; i<4; i++){
        pic->base[i]= buf->base[i];
        pic->data[i]= buf->data[i];
        pic->linesize[i]= buf->linesize[i];
    }
    s->internal_buffer_count++;
    return 0;
}


static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)

{

    TM2Huff huff;

    int res = 0;

    huff.val_bits = get_bits(&ctx->gb, 5);

    huff.max_bits = get_bits(&ctx->gb, 5);

    huff.min_bits = get_bits(&ctx->gb, 5);

    huff.nodes = get_bits_long(&ctx->gb, 17);

    huff.num = 0;

    /* check for correct codes parameters */

    if((huff.val_bits < 1) || (huff.val_bits > 32) ||

       (huff.max_bits < 0) || (huff.max_bits > 32)) {

        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n",

               huff.val_bits, huff.max_bits);

        return -1;

    }

    if((huff.nodes <= 0) || (huff.nodes > 0x10000)) {

        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes);

        return -1;

    }

    /* one-node tree */

    if(huff.max_bits == 0)

        huff.max_bits = 1;

    /* allocate space for codes - it is exactly ceil(nodes / 2) entries */

    huff.max_num = (huff.nodes + 1) >> 1;

    huff.nums = av_mallocz(huff.max_num * sizeof(int));

    huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));

    huff.lens = av_mallocz(huff.max_num * sizeof(int));

    if(tm2_read_tree(ctx, 0, 0, &huff) == -1)

        res = -1;

    if(huff.num != huff.max_num) {

        av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",

               huff.num, huff.max_num);

        res = -1;

    }

    /* convert codes to vlc_table */

    if(res != -1) {

        int i;

        res = init_vlc(&code->vlc, huff.max_bits, huff.max_num,

                    huff.lens, sizeof(int), sizeof(int),

                    huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);

        if(res < 0) {

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

            res = -1;

        } else

            res = 0;

        if(res != -1) {

            code->bits = huff.max_bits;

            code->length = huff.max_num;

            code->recode = av_malloc(code->length * sizeof(int));

            for(i = 0; i < code->length; i++)

                code->recode[i] = huff.nums[i];

        }

    }

    /* free allocated memory */

    av_free(huff.nums);

    av_free(huff.bits);

    av_free(huff.lens);

    return res;

}


void gen_intermediate_code_internal(XtensaCPU *cpu,

                                    TranslationBlock *tb, bool search_pc)

{

    CPUState *cs = CPU(cpu);

    CPUXtensaState *env = &cpu->env;

    DisasContext dc;

    int insn_count = 0;

    int j, lj = -1;

    uint16_t *gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    int max_insns = tb->cflags & CF_COUNT_MASK;

    uint32_t pc_start = tb->pc;

    uint32_t next_page_start =

        (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    dc.config = env->config;

    dc.singlestep_enabled = cs->singlestep_enabled;

    dc.tb = tb;

    dc.pc = pc_start;

    dc.ring = tb->flags & XTENSA_TBFLAG_RING_MASK;

    dc.cring = (tb->flags & XTENSA_TBFLAG_EXCM) ? 0 : dc.ring;

    dc.lbeg = env->sregs[LBEG];

    dc.lend = env->sregs[LEND];

    dc.is_jmp = DISAS_NEXT;

    dc.ccount_delta = 0;

    dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;

    dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;

    dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>

        XTENSA_TBFLAG_CPENABLE_SHIFT;

    init_litbase(&dc);

    init_sar_tracker(&dc);

    reset_used_window(&dc);

    if (dc.icount) {

        dc.next_icount = tcg_temp_local_new_i32();

    }

    gen_tb_start();

    if (tb->flags & XTENSA_TBFLAG_EXCEPTION) {

        tcg_gen_movi_i32(cpu_pc, dc.pc);

        gen_exception(&dc, EXCP_DEBUG);

    }

    do {

        check_breakpoint(env, &dc);

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j) {

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

                }

            }

            tcg_ctx.gen_opc_pc[lj] = dc.pc;

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = insn_count;

        }

        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {

            tcg_gen_debug_insn_start(dc.pc);

        }

        ++dc.ccount_delta;

        if (insn_count + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {

            gen_io_start();

        }

        if (dc.icount) {

            int label = gen_new_label();

            tcg_gen_addi_i32(dc.next_icount, cpu_SR[ICOUNT], 1);

            tcg_gen_brcondi_i32(TCG_COND_NE, dc.next_icount, 0, label);

            tcg_gen_mov_i32(dc.next_icount, cpu_SR[ICOUNT]);

            if (dc.debug) {

                gen_debug_exception(&dc, DEBUGCAUSE_IC);

            }

            gen_set_label(label);

        }

        if (dc.debug) {

            gen_ibreak_check(env, &dc);

        }

        disas_xtensa_insn(env, &dc);

        ++insn_count;

        if (dc.icount) {

            tcg_gen_mov_i32(cpu_SR[ICOUNT], dc.next_icount);

        }

        if (cs->singlestep_enabled) {

            tcg_gen_movi_i32(cpu_pc, dc.pc);

            gen_exception(&dc, EXCP_DEBUG);

            break;

        }

    } while (dc.is_jmp == DISAS_NEXT &&

            insn_count < max_insns &&

            dc.pc < next_page_start &&

            dc.pc + xtensa_insn_len(env, &dc) <= next_page_start &&

            tcg_ctx.gen_opc_ptr < gen_opc_end);

    reset_litbase(&dc);

    reset_sar_tracker(&dc);

    if (dc.icount) {

        tcg_temp_free(dc.next_icount);

    }

    if (tb->cflags & CF_LAST_IO) {

        gen_io_end();

    }

    if (dc.is_jmp == DISAS_NEXT) {

        gen_jumpi(&dc, dc.pc, 0);

    }

    gen_tb_end(tb, insn_count);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log("----------------\n");

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

        log_target_disas(env, pc_start, dc.pc - pc_start, 0);

        qemu_log("\n");

    }

#endif

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        memset(tcg_ctx.gen_opc_instr_start + lj + 1, 0,

                (j - lj) * sizeof(tcg_ctx.gen_opc_instr_start[0]));

    } else {

        tb->size = dc.pc - pc_start;

        tb->icount = insn_count;

    }

}


static void dump_map_entry(OutputFormat output_format, MapEntry *e,

                           MapEntry *next)

{

    switch (output_format) {

    case OFORMAT_HUMAN:

        if ((e->flags & BDRV_BLOCK_DATA) &&

            !(e->flags & BDRV_BLOCK_OFFSET_VALID)) {

            error_report("File contains external, encrypted or compressed clusters.");

            exit(1);

        }

        if ((e->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) == BDRV_BLOCK_DATA) {

            printf("%#-16"PRIx64"%#-16"PRIx64"%#-16"PRIx64"%s\n",

                   e->start, e->length, e->offset, e->bs->filename);

        }

        /* This format ignores the distinction between 0, ZERO and ZERO|DATA.

         * Modify the flags here to allow more coalescing.

         */

        if (next &&

            (next->flags & (BDRV_BLOCK_DATA|BDRV_BLOCK_ZERO)) != BDRV_BLOCK_DATA) {

            next->flags &= ~BDRV_BLOCK_DATA;

            next->flags |= BDRV_BLOCK_ZERO;

        }

        break;

    case OFORMAT_JSON:

        printf("%s{ \"start\": %"PRId64", \"length\": %"PRId64", \"depth\": %d,"

               " \"zero\": %s, \"data\": %s",

               (e->start == 0 ? "[" : ",\n"),

               e->start, e->length, e->depth,

               (e->flags & BDRV_BLOCK_ZERO) ? "true" : "false",

               (e->flags & BDRV_BLOCK_DATA) ? "true" : "false");

        if (e->flags & BDRV_BLOCK_OFFSET_VALID) {

            printf(", 'offset': %"PRId64"", e->offset);

        }

        putchar('}');

        if (!next) {

            printf("]\n");

        }

        break;

    }

}


int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,

              CharDriverState *chrA, CharDriverState *chrB,

              int clock, int it_shift)

{

    DeviceState *dev;

    SysBusDevice *s;

    SerialState *d;

    dev = qdev_create(NULL, "escc");

    qdev_prop_set_uint32(dev, "disabled", 0);

    qdev_prop_set_uint32(dev, "frequency", clock);

    qdev_prop_set_uint32(dev, "it_shift", it_shift);

    qdev_prop_set_chr(dev, "chrB", chrB);

    qdev_prop_set_chr(dev, "chrA", chrA);

    qdev_prop_set_uint32(dev, "chnBtype", ser);

    qdev_prop_set_uint32(dev, "chnAtype", ser);

    qdev_init(dev);

    s = sysbus_from_qdev(dev);

    sysbus_connect_irq(s, 0, irqB);

    sysbus_connect_irq(s, 1, irqA);

    if (base) {

        sysbus_mmio_map(s, 0, base);

    }

    d = FROM_SYSBUS(SerialState, s);

    return d->mmio_index;

}


static void init_dev(tc58128_dev * dev, const char *filename)

{

    int ret, blocks;

    dev->state = WAIT;

    dev->flash_contents = g_malloc0(FLASH_SIZE);

    memset(dev->flash_contents, 0xff, FLASH_SIZE);

    if (!dev->flash_contents) {

	fprintf(stderr, "could not alloc memory for flash\n");

	exit(1);

    }

    if (filename) {

	/* Load flash image skipping the first block */

	ret = load_image(filename, dev->flash_contents + 528 * 32);

	if (ret < 0) {

	    fprintf(stderr, "ret=%d\n", ret);

	    fprintf(stderr, "qemu: could not load flash image %s\n",

		    filename);

	    exit(1);

	} else {

	    /* Build first block with number of blocks */

	    blocks = (ret + 528 * 32 - 1) / (528 * 32);

	    dev->flash_contents[0] = blocks & 0xff;

	    dev->flash_contents[1] = (blocks >> 8) & 0xff;

	    dev->flash_contents[2] = (blocks >> 16) & 0xff;

	    dev->flash_contents[3] = (blocks >> 24) & 0xff;

	    fprintf(stderr, "loaded %d bytes for %s into flash\n", ret,

		    filename);

	}

    }

}


int ff_h264_decode_mb_cavlc(H264Context *h){

    MpegEncContext * const s = &h->s;

    int mb_xy;

    int partition_count;

    unsigned int mb_type, cbp;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;

    const int pixel_shift = h->pixel_shift;

    mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;

    tprintf(s->avctx, "pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);

    cbp = 0; /* avoid warning. FIXME: find a solution without slowing

                down the code */

    if(h->slice_type_nos != AV_PICTURE_TYPE_I){

        if(s->mb_skip_run==-1)

            s->mb_skip_run= get_ue_golomb(&s->gb);

        if (s->mb_skip_run--) {

            if(FRAME_MBAFF && (s->mb_y&1) == 0){

                if(s->mb_skip_run==0)

                    h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);

            }

            decode_mb_skip(h);

            return 0;

        }

    }

    if(FRAME_MBAFF){

        if( (s->mb_y&1) == 0 )

            h->mb_mbaff = h->mb_field_decoding_flag = get_bits1(&s->gb);

    }

    h->prev_mb_skipped= 0;

    mb_type= get_ue_golomb(&s->gb);

    if(h->slice_type_nos == AV_PICTURE_TYPE_B){

        if(mb_type < 23){

            partition_count= b_mb_type_info[mb_type].partition_count;

            mb_type=         b_mb_type_info[mb_type].type;

        }else{

            mb_type -= 23;

            goto decode_intra_mb;

        }

    }else if(h->slice_type_nos == AV_PICTURE_TYPE_P){

        if(mb_type < 5){

            partition_count= p_mb_type_info[mb_type].partition_count;

            mb_type=         p_mb_type_info[mb_type].type;

        }else{

            mb_type -= 5;

            goto decode_intra_mb;

        }

    }else{

       assert(h->slice_type_nos == AV_PICTURE_TYPE_I);

        if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)

            mb_type--;

decode_intra_mb:

        if(mb_type > 25){

            av_log(h->s.avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(h->slice_type), s->mb_x, s->mb_y);

            return -1;

        }

        partition_count=0;

        cbp= i_mb_type_info[mb_type].cbp;

        h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;

        mb_type= i_mb_type_info[mb_type].type;

    }

    if(MB_FIELD)

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[ mb_xy ]= h->slice_num;

    if(IS_INTRA_PCM(mb_type)){

        unsigned int x;

        static const uint16_t mb_sizes[4] = {256,384,512,768};

        const int mb_size = mb_sizes[h->sps.chroma_format_idc]*h->sps.bit_depth_luma >> 3;

        // We assume these blocks are very rare so we do not optimize it.

        align_get_bits(&s->gb);

        // The pixels are stored in the same order as levels in h->mb array.

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

            ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);

        }

        // In deblocking, the quantizer is 0

        s->current_picture.f.qscale_table[mb_xy] = 0;

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 48);

        s->current_picture.f.mb_type[mb_xy] = mb_type;

        return 0;

    }

    if(MB_MBAFF){

        h->ref_count[0] <<= 1;

        h->ref_count[1] <<= 1;

    }

    fill_decode_neighbors(h, mb_type);

    fill_decode_caches(h, mb_type);

    //mb_pred

    if(IS_INTRA(mb_type)){

        int pred_mode;

//            init_top_left_availability(h);

        if(IS_INTRA4x4(mb_type)){

            int i;

            int di = 1;

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

                mb_type |= MB_TYPE_8x8DCT;

                di = 4;

            }

//                fill_intra4x4_pred_table(h);

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

                int mode= pred_intra_mode(h, i);

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

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

                    mode = rem_mode + (rem_mode >= mode);

                }

                if(di==4)

                    fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );

                else

                    h->intra4x4_pred_mode_cache[ scan8[i] ] = mode;

            }

            write_back_intra_pred_mode(h);

            if( ff_h264_check_intra4x4_pred_mode(h) < 0)

                return -1;

        }else{

            h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode);

            if(h->intra16x16_pred_mode < 0)

                return -1;

        }

        if(decode_chroma){

            pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb));

            if(pred_mode < 0)

                return -1;

            h->chroma_pred_mode= pred_mode;

        } else {

            h->chroma_pred_mode = DC_128_PRED8x8;

        }

    }else if(partition_count==4){

        int i, j, sub_partition_count[4], list, ref[2][4];

        if(h->slice_type_nos == AV_PICTURE_TYPE_B){

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

                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);

                if(h->sub_mb_type[i] >=13){

                    av_log(h->s.avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);

                    return -1;

                }

                sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      b_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

            if( IS_DIRECT(h->sub_mb_type[0]|h->sub_mb_type[1]|h->sub_mb_type[2]|h->sub_mb_type[3])) {

                ff_h264_pred_direct_motion(h, &mb_type);

                h->ref_cache[0][scan8[4]] =

                h->ref_cache[1][scan8[4]] =

                h->ref_cache[0][scan8[12]] =

                h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;

            }

        }else{

            assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?

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

                h->sub_mb_type[i]= get_ue_golomb_31(&s->gb);

                if(h->sub_mb_type[i] >=4){

                    av_log(h->s.avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", h->sub_mb_type[i], s->mb_x, s->mb_y);

                    return -1;

                }

                sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      p_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

        }

        for(list=0; list<h->list_count; list++){

            int ref_count= IS_REF0(mb_type) ? 1 : h->ref_count[list];

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

                if(IS_DIRECT(h->sub_mb_type[i])) continue;

                if(IS_DIR(h->sub_mb_type[i], 0, list)){

                    unsigned int tmp;

                    if(ref_count == 1){

                        tmp= 0;

                    }else if(ref_count == 2){

                        tmp= get_bits1(&s->gb)^1;

                    }else{

                        tmp= get_ue_golomb_31(&s->gb);

                        if(tmp>=ref_count){

                            av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);

                            return -1;

                        }

                    }

                    ref[list][i]= tmp;

                }else{

                 //FIXME

                    ref[list][i] = -1;

                }

            }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h);

        for(list=0; list<h->list_count; list++){

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

                if(IS_DIRECT(h->sub_mb_type[i])) {

                    h->ref_cache[list][ scan8[4*i] ] = h->ref_cache[list][ scan8[4*i]+1 ];

                    continue;

                }

                h->ref_cache[list][ scan8[4*i]   ]=h->ref_cache[list][ scan8[4*i]+1 ]=

                h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                if(IS_DIR(h->sub_mb_type[i], 0, list)){

                    const int sub_mb_type= h->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];

                        pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                    }

                }else{

                    uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];

                    p[0] = p[1]=

                    p[8] = p[9]= 0;

                }

            }

        }

    }else if(IS_DIRECT(mb_type)){

        ff_h264_pred_direct_motion(h, &mb_type);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    }else{

        int list, mx, my, i;

         //FIXME we should set ref_idx_l? to 0 if we use that later ...

        if(IS_16X16(mb_type)){

            for(list=0; list<h->list_count; list++){

                    unsigned int val;

                    if(IS_DIR(mb_type, 0, list)){

                        if(h->ref_count[list]==1){

                            val= 0;

                        }else if(h->ref_count[list]==2){

                            val= get_bits1(&s->gb)^1;

                        }else{

                            val= get_ue_golomb_31(&s->gb);

                            if(val >= h->ref_count[list]){

                                av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                return -1;

                            }

                        }

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

                    }

            }

            for(list=0; list<h->list_count; list++){

                if(IS_DIR(mb_type, 0, list)){

                    pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mx, &my);

                    mx += get_se_golomb(&s->gb);

                    my += get_se_golomb(&s->gb);

                    tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }

            }

        }

        else if(IS_16X8(mb_type)){

            for(list=0; list<h->list_count; list++){

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){

                            if(h->ref_count[list] == 1){

                                val= 0;

                            }else if(h->ref_count[list] == 2){

                                val= get_bits1(&s->gb)^1;

                            }else{

                                val= get_ue_golomb_31(&s->gb);

                                if(val >= h->ref_count[list]){

                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                    return -1;

                                }

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for(list=0; list<h->list_count; list++){

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            if(h->ref_count[list]==1){

                                val= 0;

                            }else if(h->ref_count[list]==2){

                                val= get_bits1(&s->gb)^1;

                            }else{

                                val= get_ue_golomb_31(&s->gb);

                                if(val >= h->ref_count[list]){

                                    av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                    return -1;

                                }

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);

                        mx += get_se_golomb(&s->gb);

                        my += get_se_golomb(&s->gb);

                        tprintf(s->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);

                }

            }

        }

    }

    if(IS_INTER(mb_type))

        write_back_motion(h, mb_type);

    if(!IS_INTRA16x16(mb_type)){

        cbp= get_ue_golomb(&s->gb);

        if(decode_chroma){

            if(cbp > 47){

                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);

                return -1;

            }

            if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];

            else                     cbp= golomb_to_inter_cbp   [cbp];

        }else{

            if(cbp > 15){

                av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);

                return -1;

            }

            if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];

            else                     cbp= golomb_to_inter_cbp_gray[cbp];

        }

    }

    if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){

        mb_type |= MB_TYPE_8x8DCT*get_bits1(&s->gb);

    }

    h->cbp=

    h->cbp_table[mb_xy]= cbp;

    s->current_picture.f.mb_type[mb_xy] = mb_type;

    if(cbp || IS_INTRA16x16(mb_type)){

        int i4x4, i8x8, chroma_idx;

        int dquant;

        int ret;

        GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;

        const uint8_t *scan, *scan8x8;

        const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);

        if(IS_INTERLACED(mb_type)){

            scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;

            scan= s->qscale ? h->field_scan : h->field_scan_q0;

        }else{

            scan8x8= s->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;

            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

        }

        dquant= get_se_golomb(&s->gb);

        s->qscale += dquant;

        if(((unsigned)s->qscale) > max_qp){

            if(s->qscale<0) s->qscale+= max_qp+1;

            else            s->qscale-= max_qp+1;

            if(((unsigned)s->qscale) > max_qp){

                av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);

                return -1;

            }

        }

        h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);

        h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);

        if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){

            return -1;

        }

        h->cbp_table[mb_xy] |= ret << 12;

        if(CHROMA444){

            if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){

                return -1;

            }

            if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){

                return -1;

            }

        } else if (CHROMA422) {

            if(cbp&0x30){

                for(chroma_idx=0; chroma_idx<2; chroma_idx++)

                    if (decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift),

                                        CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma422_dc_scan,

                                        NULL, 8) < 0) {

                        return -1;

                    }

            }

            if(cbp&0x20){

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

                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];

                    DCTELEM *mb = h->mb + (16*(16 + 16*chroma_idx) << pixel_shift);

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

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

                            const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;

                            if (decode_residual(h, gb, mb, index, scan + 1, qmul, 15) < 0)

                                return -1;

                            mb += 16 << pixel_shift;

                        }

                    }

                }

            }else{

                fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        } else /* yuv420 */ {

            if(cbp&0x30){

                for(chroma_idx=0; chroma_idx<2; chroma_idx++)

                    if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){

                        return -1;

                    }

            }

            if(cbp&0x20){

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

                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];

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

                        const int index= 16 + 16*chroma_idx + i4x4;

                        if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){

                            return -1;

                        }

                    }

                }

            }else{

                fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        }

    }else{

        fill_rectangle(&h->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);

        fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

        fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

    }

    s->current_picture.f.qscale_table[mb_xy] = s->qscale;

    write_back_non_zero_count(h);

    if(MB_MBAFF){

        h->ref_count[0] >>= 1;

        h->ref_count[1] >>= 1;

    }

    return 0;

}


static void d3d11va_frames_uninit(AVHWFramesContext *ctx)

{

    AVD3D11VAFramesContext *frames_hwctx = ctx->hwctx;

    D3D11VAFramesContext *s = ctx->internal->priv;

    if (frames_hwctx->texture)

        ID3D11Texture2D_Release(frames_hwctx->texture);

    if (s->staging_texture)

        ID3D11Texture2D_Release(s->staging_texture);

}