static av_cold int svq3_decode_init(AVCodecContext *avctx)

{

    SVQ3Context *svq3 = avctx->priv_data;

    H264Context *h = &svq3->h;

    MpegEncContext *s = &h->s;

    int m;

    unsigned char *extradata;

    unsigned char *extradata_end;

    unsigned int size;

    int marker_found = 0;

    if (ff_h264_decode_init(avctx) < 0)

        return -1;

    s->flags  = avctx->flags;

    s->flags2 = avctx->flags2;

    s->unrestricted_mv = 1;

    h->is_complex=1;

    h->sps.chroma_format_idc = 1;

    avctx->pix_fmt = avctx->codec->pix_fmts[0];

    if (!s->context_initialized) {

        h->chroma_qp[0] = h->chroma_qp[1] = 4;

        svq3->halfpel_flag  = 1;

        svq3->thirdpel_flag = 1;

        svq3->unknown_flag  = 0;

        /* prowl for the "SEQH" marker in the extradata */

        extradata = (unsigned char *)avctx->extradata;

        extradata_end = avctx->extradata + avctx->extradata_size;

        if (extradata) {

            for (m = 0; m + 8 < avctx->extradata_size; m++) {

                if (!memcmp(extradata, "SEQH", 4)) {

                    marker_found = 1;

                    break;

                }

                extradata++;

            }

        }

        /* if a match was found, parse the extra data */

        if (marker_found) {

            GetBitContext gb;

            int frame_size_code;

            size = AV_RB32(&extradata[4]);

            if (size > extradata_end - extradata - 8)

                return AVERROR_INVALIDDATA;

            init_get_bits(&gb, extradata + 8, size*8);

            /* 'frame size code' and optional 'width, height' */

            frame_size_code = get_bits(&gb, 3);

            switch (frame_size_code) {

                case 0: avctx->width = 160; avctx->height = 120; break;

                case 1: avctx->width = 128; avctx->height =  96; break;

                case 2: avctx->width = 176; avctx->height = 144; break;

                case 3: avctx->width = 352; avctx->height = 288; break;

                case 4: avctx->width = 704; avctx->height = 576; break;

                case 5: avctx->width = 240; avctx->height = 180; break;

                case 6: avctx->width = 320; avctx->height = 240; break;

                case 7:

                    avctx->width  = get_bits(&gb, 12);

                    avctx->height = get_bits(&gb, 12);

                    break;

            }

            svq3->halfpel_flag  = get_bits1(&gb);

            svq3->thirdpel_flag = get_bits1(&gb);

            /* unknown fields */

            skip_bits1(&gb);

            skip_bits1(&gb);

            skip_bits1(&gb);

            skip_bits1(&gb);

            s->low_delay = get_bits1(&gb);

            /* unknown field */

            skip_bits1(&gb);

            while (get_bits1(&gb)) {

                skip_bits(&gb, 8);

            }

            svq3->unknown_flag = get_bits1(&gb);

            avctx->has_b_frames = !s->low_delay;

            if (svq3->unknown_flag) {

#if CONFIG_ZLIB

                unsigned watermark_width  = svq3_get_ue_golomb(&gb);

                unsigned watermark_height = svq3_get_ue_golomb(&gb);

                int u1 = svq3_get_ue_golomb(&gb);

                int u2 = get_bits(&gb, 8);

                int u3 = get_bits(&gb, 2);

                int u4 = svq3_get_ue_golomb(&gb);

                unsigned long buf_len = watermark_width*watermark_height*4;

                int offset = (get_bits_count(&gb)+7)>>3;

                uint8_t *buf;

                if ((uint64_t)watermark_width*4 > UINT_MAX/watermark_height)

                    return -1;

                buf = av_malloc(buf_len);

                av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n", watermark_width, watermark_height);

                av_log(avctx, AV_LOG_DEBUG, "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n", u1, u2, u3, u4, offset);

                if (uncompress(buf, &buf_len, extradata + 8 + offset, size - offset) != Z_OK) {

                    av_log(avctx, AV_LOG_ERROR, "could not uncompress watermark logo\n");

                    av_free(buf);

                    return -1;

                }

                svq3->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);

                svq3->watermark_key = svq3->watermark_key << 16 | svq3->watermark_key;

                av_log(avctx, AV_LOG_DEBUG, "watermark key %#x\n", svq3->watermark_key);

                av_free(buf);

#else

                av_log(avctx, AV_LOG_ERROR, "this svq3 file contains watermark which need zlib support compiled in\n");

                return -1;

#endif

            }

        }

        s->width  = avctx->width;

        s->height = avctx->height;

        if (ff_MPV_common_init(s) < 0)

            return -1;

        h->b_stride = 4*s->mb_width;

        if (ff_h264_alloc_tables(h) < 0) {

            av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");

            return AVERROR(ENOMEM);

        }

    }

    return 0;

}


int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,

                         AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    VP56Context *s = avctx->priv_data;

    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];

    int remaining_buf_size = avpkt->size;

    int is_alpha, av_uninit(alpha_offset);

    if (s->has_alpha) {

        if (remaining_buf_size < 3)

            return -1;

        alpha_offset = bytestream_get_be24(&buf);

        remaining_buf_size -= 3;

        if (remaining_buf_size < alpha_offset)

            return -1;

    }

    for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) {

        int mb_row, mb_col, mb_row_flip, mb_offset = 0;

        int block, y, uv, stride_y, stride_uv;

        int golden_frame = 0;

        int res;

        s->modelp = &s->models[is_alpha];

        res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);

        if (!res)

            return -1;

        if (res == 2) {

            int i;

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

                if (s->frames[i].data[0])

                    avctx->release_buffer(avctx, &s->frames[i]);

            }

            if (is_alpha)

                return -1;

        }

        if (!is_alpha) {

            p->reference = 1;

            if (avctx->get_buffer(avctx, p) < 0) {

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

                return -1;

            }

            if (res == 2)

                if (vp56_size_changed(avctx)) {

                    avctx->release_buffer(avctx, p);

                    return -1;

                }

        }

        if (p->key_frame) {

            p->pict_type = AV_PICTURE_TYPE_I;

            s->default_models_init(s);

            for (block=0; block<s->mb_height*s->mb_width; block++)

                s->macroblocks[block].type = VP56_MB_INTRA;

        } else {

            p->pict_type = AV_PICTURE_TYPE_P;

            vp56_parse_mb_type_models(s);

            s->parse_vector_models(s);

            s->mb_type = VP56_MB_INTER_NOVEC_PF;

        }

        s->parse_coeff_models(s);

        memset(s->prev_dc, 0, sizeof(s->prev_dc));

        s->prev_dc[1][VP56_FRAME_CURRENT] = 128;

        s->prev_dc[2][VP56_FRAME_CURRENT] = 128;

        for (block=0; block < 4*s->mb_width+6; block++) {

            s->above_blocks[block].ref_frame = VP56_FRAME_NONE;

            s->above_blocks[block].dc_coeff = 0;

            s->above_blocks[block].not_null_dc = 0;

        }

        s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;

        s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;

        stride_y  = p->linesize[0];

        stride_uv = p->linesize[1];

        if (s->flip < 0)

            mb_offset = 7;

        /* main macroblocks loop */

        for (mb_row=0; mb_row<s->mb_height; mb_row++) {

            if (s->flip < 0)

                mb_row_flip = s->mb_height - mb_row - 1;

            else

                mb_row_flip = mb_row;

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

                s->left_block[block].ref_frame = VP56_FRAME_NONE;

                s->left_block[block].dc_coeff = 0;

                s->left_block[block].not_null_dc = 0;

            }

            memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));

            memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));

            s->above_block_idx[0] = 1;

            s->above_block_idx[1] = 2;

            s->above_block_idx[2] = 1;

            s->above_block_idx[3] = 2;

            s->above_block_idx[4] = 2*s->mb_width + 2 + 1;

            s->above_block_idx[5] = 3*s->mb_width + 4 + 1;

            s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;

            s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;

            s->block_offset[1] = s->block_offset[0] + 8;

            s->block_offset[3] = s->block_offset[2] + 8;

            s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;

            s->block_offset[5] = s->block_offset[4];

            for (mb_col=0; mb_col<s->mb_width; mb_col++) {

                vp56_decode_mb(s, mb_row, mb_col, is_alpha);

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

                    s->above_block_idx[y] += 2;

                    s->block_offset[y] += 16;

                }

                for (uv=4; uv<6; uv++) {

                    s->above_block_idx[uv] += 1;

                    s->block_offset[uv] += 8;

                }

            }

        }

        if (p->key_frame || golden_frame) {

            if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&

                s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])

                avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);

            s->framep[VP56_FRAME_GOLDEN] = p;

        }

        if (s->has_alpha) {

            FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],

                              s->framep[VP56_FRAME_GOLDEN2]);

            buf += alpha_offset;

            remaining_buf_size -= alpha_offset;

        }

    }

    if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||

        s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {

        if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&

            s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])

            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],

                              s->framep[VP56_FRAME_UNUSED]);

        else

            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],

                              s->framep[VP56_FRAME_UNUSED2]);

    } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])

        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);

    FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],

                      s->framep[VP56_FRAME_PREVIOUS]);

    p->qstride = 0;

    p->qscale_table = s->qscale_table;

    p->qscale_type = FF_QSCALE_TYPE_VP56;

    *(AVFrame*)data = *p;

    *data_size = sizeof(AVFrame);

    return avpkt->size;

}


static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

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

    int tag, len;

    get_be32(pb); /* version + flags */

    len = mp4_read_descr(c, pb, &tag);

    if (tag == MP4ESDescrTag) {

        get_be16(pb); /* ID */

        get_byte(pb); /* priority */

    } else

        get_be16(pb); /* ID */

    len = mp4_read_descr(c, pb, &tag);

    if (tag == MP4DecConfigDescrTag) {

        int object_type_id = get_byte(pb);

        get_byte(pb); /* stream type */

        get_be24(pb); /* buffer size db */

        get_be32(pb); /* max bitrate */

        get_be32(pb); /* avg bitrate */

        st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);

        dprintf(c->fc, "esds object type id %d\n", object_type_id);

        len = mp4_read_descr(c, pb, &tag);

        if (tag == MP4DecSpecificDescrTag) {

            dprintf(c->fc, "Specific MPEG4 header len=%d\n", len);

            if((uint64_t)len > (1<<30))

                return -1;

            st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

            get_buffer(pb, st->codec->extradata, len);

            st->codec->extradata_size = len;

            if (st->codec->codec_id == CODEC_ID_AAC) {

                MPEG4AudioConfig cfg;

                ff_mpeg4audio_get_config(&cfg, st->codec->extradata,

                                         st->codec->extradata_size);

                if (cfg.chan_config > 7)

                    return -1;

                st->codec->channels = ff_mpeg4audio_channels[cfg.chan_config];

                if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4

                    st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];

                else

                    st->codec->sample_rate = cfg.sample_rate; // ext sample rate ?

                dprintf(c->fc, "mp4a config channels %d obj %d ext obj %d "

                        "sample rate %d ext sample rate %d\n", st->codec->channels,

                        cfg.object_type, cfg.ext_object_type,

                        cfg.sample_rate, cfg.ext_sample_rate);

                if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,

                                                            cfg.object_type)))

                    st->codec->codec_id = CODEC_ID_AAC;

            }

        }

    }

    return 0;

}


av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)

{

    NVENCContext *ctx               = avctx->priv_data;

    NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;

    int i;

    av_frame_free(&avctx->coded_frame);

    if (ctx->in) {

        for (i = 0; i < ctx->nb_surfaces; ++i) {

            nv->nvEncDestroyInputBuffer(ctx->nvenc_ctx, ctx->in[i].in);

            nv->nvEncDestroyBitstreamBuffer(ctx->nvenc_ctx, ctx->out[i].out);

        }

    }

    av_freep(&ctx->in);

    av_freep(&ctx->out);

    if (ctx->nvenc_ctx)

        nv->nvEncDestroyEncoder(ctx->nvenc_ctx);

    if (ctx->cu_context)

        ctx->nvel.cu_ctx_destroy(ctx->cu_context);

    if (ctx->nvel.nvenc)

        dlclose(ctx->nvel.nvenc);

    if (ctx->nvel.cuda)

        dlclose(ctx->nvel.cuda);

    return 0;

}


static QDM2SubPNode *qdm2_search_subpacket_type_in_list(QDM2SubPNode *list,

                                                        int type)

{

    while (list != NULL && list->packet != NULL) {

        if (list->packet->type == type)

            return list;

        list = list->next;

    }

    return NULL;

}


static int segment_end(AVFormatContext *s, int write_trailer, int is_last)

{

    SegmentContext *seg = s->priv_data;

    AVFormatContext *oc = seg->avf;

    int ret = 0;

    av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */

    if (write_trailer)

        ret = av_write_trailer(oc);

    if (ret < 0)

        av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n",

               oc->filename);

    if (seg->list) {

        if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) {

            SegmentListEntry *entry = av_mallocz(sizeof(*entry));

            if (!entry) {

                ret = AVERROR(ENOMEM);

                goto end;

            }

            /* append new element */

            memcpy(entry, &seg->cur_entry, sizeof(*entry));

            if (!seg->segment_list_entries)

                seg->segment_list_entries = seg->segment_list_entries_end = entry;

            else

                seg->segment_list_entries_end->next = entry;

            seg->segment_list_entries_end = entry;

            /* drop first item */

            if (seg->list_size && seg->segment_count > seg->list_size) {

                entry = seg->segment_list_entries;

                seg->segment_list_entries = seg->segment_list_entries->next;

                av_free(entry->filename);

                av_freep(&entry);

            }

            avio_close(seg->list_pb);

            if ((ret = segment_list_open(s)) < 0)

                goto end;

            for (entry = seg->segment_list_entries; entry; entry = entry->next)

                segment_list_print_entry(seg->list_pb, seg->list_type, entry, s);

            if (seg->list_type == LIST_TYPE_M3U8 && is_last)

                avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n");

        } else {

            segment_list_print_entry(seg->list_pb, seg->list_type, &seg->cur_entry, s);

        }

        avio_flush(seg->list_pb);

    }

    av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",

           seg->avf->filename, seg->segment_count);

    seg->segment_count++;

end:

    avio_close(oc->pb);

    return ret;

}


static void get_default_channel_layouts(OutputStream *ost, InputStream *ist)

{

    char layout_name[256];

    AVCodecContext *enc = ost->st->codec;

    AVCodecContext *dec = ist->st->codec;

    if (dec->channel_layout &&

        av_get_channel_layout_nb_channels(dec->channel_layout) != dec->channels) {

        av_get_channel_layout_string(layout_name, sizeof(layout_name),

                                     dec->channels, dec->channel_layout);

        av_log(NULL, AV_LOG_ERROR, "New channel layout (%s) is invalid\n",

               layout_name);

        dec->channel_layout = 0;

    }

    if (!dec->channel_layout) {

        if (enc->channel_layout && dec->channels == enc->channels) {

            dec->channel_layout = enc->channel_layout;

        } else {

            dec->channel_layout = av_get_default_channel_layout(dec->channels);

            if (!dec->channel_layout) {

                av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "

                       "layout for Input Stream #%d.%d\n", ist->file_index,

                       ist->st->index);

                exit_program(1);

            }

        }

        av_get_channel_layout_string(layout_name, sizeof(layout_name),

                                     dec->channels, dec->channel_layout);

        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for  Input Stream "

               "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);

    }

    if (!enc->channel_layout) {

        if (dec->channels == enc->channels) {

            enc->channel_layout = dec->channel_layout;

            return;

        } else {

            enc->channel_layout = av_get_default_channel_layout(enc->channels);

        }

        if (!enc->channel_layout) {

            av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout "

                   "for Output Stream #%d.%d\n", ost->file_index,

                   ost->st->index);

            exit_program(1);

        }

        av_get_channel_layout_string(layout_name, sizeof(layout_name),

                                     enc->channels, enc->channel_layout);

        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream "

               "#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name);

    }

}


int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata)

{

    CacheItem *it = NULL;

    g_assert(cache);

    g_assert(cache->page_cache);

    /* actual update of entry */

    it = cache_get_by_addr(cache, addr);

    /* allocate page */

    if (!it->it_data) {

        it->it_data = g_try_malloc(cache->page_size);

        if (!it->it_data) {

            DPRINTF("Error allocating page\n");

            return -1;

        }

        cache->num_items++;

    }

    memcpy(it->it_data, pdata, cache->page_size);

    it->it_age = ++cache->max_item_age;

    it->it_addr = addr;

    return 0;

}


static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)

{

    #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL + CONFIG_HEVC_VAAPI_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL)

    enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;

    switch (sps->pix_fmt) {

    case AV_PIX_FMT_YUV420P:

    case AV_PIX_FMT_YUVJ420P:

#if CONFIG_HEVC_DXVA2_HWACCEL

        *fmt++ = AV_PIX_FMT_DXVA2_VLD;

#endif

#if CONFIG_HEVC_D3D11VA_HWACCEL

        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;

#endif

#if CONFIG_HEVC_VAAPI_HWACCEL

        *fmt++ = AV_PIX_FMT_VAAPI;

#endif

#if CONFIG_HEVC_VDPAU_HWACCEL

        *fmt++ = AV_PIX_FMT_VDPAU;

#endif

        break;

    case AV_PIX_FMT_YUV420P10:

#if CONFIG_HEVC_DXVA2_HWACCEL

        *fmt++ = AV_PIX_FMT_DXVA2_VLD;

#endif

#if CONFIG_HEVC_D3D11VA_HWACCEL

        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;

#endif

#if CONFIG_HEVC_VAAPI_HWACCEL

        *fmt++ = AV_PIX_FMT_VAAPI;

#endif

        break;

    }

    *fmt++ = sps->pix_fmt;

    *fmt = AV_PIX_FMT_NONE;

    return ff_get_format(s->avctx, pix_fmts);

}


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

{

    int ret, fd;

    uint32_t vid = 0;

    BDRVSheepdogState *s = bs->opaque;

    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];

    uint32_t snapid;

    char *buf = NULL;

    strstart(filename, "sheepdog:", (const char **)&filename);

    QLIST_INIT(&s->inflight_aio_head);

    QLIST_INIT(&s->pending_aio_head);

    s->fd = -1;

    memset(vdi, 0, sizeof(vdi));

    memset(tag, 0, sizeof(tag));

    if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {

        ret = -EINVAL;

        goto out;

    }

    s->fd = get_sheep_fd(s);

    if (s->fd < 0) {

        ret = s->fd;

        goto out;

    }

    ret = find_vdi_name(s, vdi, snapid, tag, &vid, 0);

    if (ret) {

        goto out;

    }

    s->cache_enabled = 1;

    s->flush_fd = connect_to_sdog(s->addr, s->port);

    if (s->flush_fd < 0) {

        error_report("failed to connect");

        ret = s->flush_fd;

        goto out;

    }

    if (snapid || tag[0] != '\0') {

        dprintf("%" PRIx32 " snapshot inode was open.\n", vid);

        s->is_snapshot = 1;

    }

    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }

    buf = g_malloc(SD_INODE_SIZE);

    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,

                      s->cache_enabled);

    closesocket(fd);

    if (ret) {

        goto out;

    }

    memcpy(&s->inode, buf, sizeof(s->inode));

    s->min_dirty_data_idx = UINT32_MAX;

    s->max_dirty_data_idx = 0;

    bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE;

    strncpy(s->name, vdi, sizeof(s->name));

    qemu_co_mutex_init(&s->lock);

    g_free(buf);

    return 0;

out:

    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);

    if (s->fd >= 0) {

        closesocket(s->fd);

    }

    g_free(buf);

    return ret;

}


static void qvirtio_9p_pci_stop(QVirtIO9P *v9p)

{

    qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc);

    qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));

    g_free(v9p->dev);

    qvirtio_9p_stop(v9p);

}


static av_cold int pnm_encode_init(AVCodecContext *avctx)

{

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    return 0;

}


static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,

                                 int point_transform, int nb_components)

{

    int i, mb_x, mb_y, mask;

    int bits= (s->bits+7)&~7;

    int resync_mb_y = 0;

    int resync_mb_x = 0;

    point_transform += bits - s->bits;

    mask = ((1 << s->bits) - 1) << point_transform;

    av_assert0(nb_components>=1 && nb_components<=4);

    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

            if (s->restart_interval && !s->restart_count){

                s->restart_count = s->restart_interval;

                resync_mb_x = mb_x;

                resync_mb_y = mb_y;

            }

            if(!mb_x || mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || s->interlaced){

                int toprow  = mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x;

                int leftcol = !mb_x || mb_y == resync_mb_y && mb_x == resync_mb_x;

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

                    uint8_t *ptr;

                    uint16_t *ptr16;

                    int n, h, v, x, y, c, j, linesize;

                    n = s->nb_blocks[i];

                    c = s->comp_index[i];

                    h = s->h_scount[i];

                    v = s->v_scount[i];

                    x = 0;

                    y = 0;

                    linesize= s->linesize[c];

                    if(bits>8) linesize /= 2;

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

                        int pred, dc;

                        dc = mjpeg_decode_dc(s, s->dc_index[i]);

                        if(dc == 0xFFFFF)

                            return -1;

                        if(bits<=8){

                        ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap

                        if(y==0 && toprow){

                            if(x==0 && leftcol){

                                pred= 1 << (bits - 1);

                            }else{

                                pred= ptr[-1];

                            }

                        }else{

                            if(x==0 && leftcol){

                                pred= ptr[-linesize];

                            }else{

                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                            }

                        }

                        if (s->interlaced && s->bottom_field)

                            ptr += linesize >> 1;

                        pred &= mask;

                        *ptr= pred + (dc << point_transform);

                        }else{

                            ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap

                            if(y==0 && toprow){

                                if(x==0 && leftcol){

                                    pred= 1 << (bits - 1);

                                }else{

                                    pred= ptr16[-1];

                                }

                            }else{

                                if(x==0 && leftcol){

                                    pred= ptr16[-linesize];

                                }else{

                                    PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);

                                }

                            }

                            if (s->interlaced && s->bottom_field)

                                ptr16 += linesize >> 1;

                            pred &= mask;

                            *ptr16= pred + (dc << point_transform);

                        }

                        if (++x == h) {

                            x = 0;

                            y++;

                        }

                    }

                }

            } else {

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

                    uint8_t *ptr;

                    uint16_t *ptr16;

                    int n, h, v, x, y, c, j, linesize, dc;

                    n        = s->nb_blocks[i];

                    c        = s->comp_index[i];

                    h        = s->h_scount[i];

                    v        = s->v_scount[i];

                    x        = 0;

                    y        = 0;

                    linesize = s->linesize[c];

                    if(bits>8) linesize /= 2;

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

                        int pred;

                        dc = mjpeg_decode_dc(s, s->dc_index[i]);

                        if(dc == 0xFFFFF)

                            return -1;

                        if(bits<=8){

                            ptr = s->picture_ptr->data[c] +

                              (linesize * (v * mb_y + y)) +

                              (h * mb_x + x); //FIXME optimize this crap

                            PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

                            pred &= mask;

                            *ptr = pred + (dc << point_transform);

                        }else{

                            ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap

                            PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);

                            pred &= mask;

                            *ptr16= pred + (dc << point_transform);

                        }

                        if (++x == h) {

                            x = 0;

                            y++;

                        }

                    }

                }

            }

            if (s->restart_interval && !--s->restart_count) {

                align_get_bits(&s->gb);

                skip_bits(&s->gb, 16); /* skip RSTn */

            }

        }

    }

    return 0;

}


static void virtio_blk_dma_restart_cb(void *opaque, int running,

                                      RunState state)

{

    VirtIOBlock *s = opaque;

    if (!running) {

        return;

    }

    if (!s->bh) {

        s->bh = qemu_bh_new(virtio_blk_dma_restart_bh, s);

        qemu_bh_schedule(s->bh);

    }

}


int parse_debug_env(const char *name, int max, int initial)

{

    char *debug_env = getenv(name);

    char *inv = NULL;

    int debug;

    if (!debug_env) {

        return initial;

    }

    debug = strtol(debug_env, &inv, 10);

    if (inv == debug_env) {

        return initial;

    }

    if (debug < 0 || debug > max) {

        fprintf(stderr, "warning: %s not in [0, %d]", name, max);

        return initial;

    }

    return debug;

}


static void vfio_listener_region_del(MemoryListener *listener,

                                     MemoryRegionSection *section)

{

    VFIOContainer *container = container_of(listener, VFIOContainer, listener);

    hwaddr iova, end;

    Int128 llend, llsize;

    int ret;

    if (vfio_listener_skipped_section(section)) {

        trace_vfio_listener_region_del_skip(

                section->offset_within_address_space,

                section->offset_within_address_space +

                int128_get64(int128_sub(section->size, int128_one())));

        return;

    }

    if (unlikely((section->offset_within_address_space & ~TARGET_PAGE_MASK) !=

                 (section->offset_within_region & ~TARGET_PAGE_MASK))) {

        error_report("%s received unaligned region", __func__);

        return;

    }

    if (memory_region_is_iommu(section->mr)) {

        VFIOGuestIOMMU *giommu;

        QLIST_FOREACH(giommu, &container->giommu_list, giommu_next) {

            if (giommu->iommu == section->mr) {

                memory_region_unregister_iommu_notifier(giommu->iommu,

                                                        &giommu->n);

                QLIST_REMOVE(giommu, giommu_next);

                g_free(giommu);

                break;

            }

        }

        /*

         * FIXME: We assume the one big unmap below is adequate to

         * remove any individual page mappings in the IOMMU which

         * might have been copied into VFIO. This works for a page table

         * based IOMMU where a big unmap flattens a large range of IO-PTEs.

         * That may not be true for all IOMMU types.

         */

    }

    iova = TARGET_PAGE_ALIGN(section->offset_within_address_space);

    llend = int128_make64(section->offset_within_address_space);

    llend = int128_add(llend, section->size);

    llend = int128_and(llend, int128_exts64(TARGET_PAGE_MASK));

    if (int128_ge(int128_make64(iova), llend)) {

        return;

    }

    end = int128_get64(int128_sub(llend, int128_one()));

    llsize = int128_sub(llend, int128_make64(iova));

    trace_vfio_listener_region_del(iova, end);

    ret = vfio_dma_unmap(container, iova, int128_get64(llsize));

    memory_region_unref(section->mr);

    if (ret) {

        error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", "

                     "0x%"HWADDR_PRIx") = %d (%m)",

                     container, iova, int128_get64(llsize), ret);

    }

    if (container->iommu_type == VFIO_SPAPR_TCE_v2_IOMMU) {

        vfio_spapr_remove_window(container,

                                 section->offset_within_address_space);

        if (vfio_host_win_del(container,

                              section->offset_within_address_space,

                              section->offset_within_address_space +

                              int128_get64(section->size) - 1) < 0) {

            hw_error("%s: Cannot delete missing window at %"HWADDR_PRIx,

                     __func__, section->offset_within_address_space);

        }

    }

}


VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq)

{

    VirtIOSCSIReq *req;

    VirtIOSCSICommon *vs = (VirtIOSCSICommon *)s;

    const size_t zero_skip = offsetof(VirtIOSCSIReq, vring);

    req = g_malloc(sizeof(*req) + vs->cdb_size);

    req->vq = vq;

    req->dev = s;

    qemu_sglist_init(&req->qsgl, DEVICE(s), 8, &address_space_memory);

    qemu_iovec_init(&req->resp_iov, 1);

    memset((uint8_t *)req + zero_skip, 0, sizeof(*req) - zero_skip);

    return req;

}


static void qemu_cpu_kick_thread(CPUState *cpu)

{

#ifndef _WIN32

    int err;

    err = pthread_kill(cpu->thread->thread, SIG_IPI);

    if (err) {

        fprintf(stderr, "qemu:%s: %s", __func__, strerror(err));

        exit(1);

    }

#else /* _WIN32 */

    if (!qemu_cpu_is_self(cpu)) {

        SuspendThread(cpu->hThread);

        cpu_signal(0);

        ResumeThread(cpu->hThread);

    }

#endif

}


bool bdrv_unallocated_blocks_are_zero(BlockDriverState *bs)

{

    BlockDriverInfo bdi;

    if (bs->backing_hd) {

        return false;

    }

    if (bdrv_get_info(bs, &bdi) == 0) {

        return bdi.unallocated_blocks_are_zero;

    }

    return false;

}


static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,

                                        Error **errp)

{

    VirtIONet *n = VIRTIO_NET(vdev);

    NetClientState *nc = qemu_get_queue(n->nic);

    /* Firstly sync all virtio-net possible supported features */

    features |= n->host_features;

    virtio_add_feature(&features, VIRTIO_NET_F_MAC);

    if (!peer_has_vnet_hdr(n)) {

        virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);

        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);

        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);

        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);

        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);

        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);

        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);

        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);

    }

    if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {

        virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);

        virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);

    }

    if (!get_vhost_net(nc->peer)) {

        return features;

    }

    return vhost_net_get_features(get_vhost_net(nc->peer), features);

}


PXA2xxState *pxa270_init(MemoryRegion *address_space,

                         unsigned int sdram_size, const char *revision)

{

    PXA2xxState *s;

    int i;

    DriveInfo *dinfo;

    s = (PXA2xxState *) g_malloc0(sizeof(PXA2xxState));

    if (revision && strncmp(revision, "pxa27", 5)) {

        fprintf(stderr, "Machine requires a PXA27x processor.\n");

        exit(1);

    }

    if (!revision)

        revision = "pxa270";

    s->cpu = cpu_arm_init(revision);

    if (s->cpu == NULL) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0);

    /* SDRAM & Internal Memory Storage */

    memory_region_init_ram(&s->sdram, NULL, "pxa270.sdram", sdram_size,

                           &error_abort);

    vmstate_register_ram_global(&s->sdram);

    memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram);

    memory_region_init_ram(&s->internal, NULL, "pxa270.internal", 0x40000,

                           &error_abort);

    vmstate_register_ram_global(&s->internal);

    memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE,

                                &s->internal);

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

    s->dma = pxa27x_dma_init(0x40000000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA));

    sysbus_create_varargs("pxa27x-timer", 0x40a00000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0),

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1),

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2),

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3),

                    qdev_get_gpio_in(s->pic, PXA27X_PIC_OST_4_11),

                    NULL);

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

    dinfo = drive_get(IF_SD, 0, 0);

    if (!dinfo) {

        fprintf(stderr, "qemu: missing SecureDigital device\n");

        exit(1);

    }

    s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,

                    blk_bs(blk_by_legacy_dinfo(dinfo)),

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),

                    qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),

                    qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));

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

        if (serial_hds[i]) {

            serial_mm_init(address_space, pxa270_serial[i].io_base, 2,

                           qdev_get_gpio_in(s->pic, pxa270_serial[i].irqn),

                           14857000 / 16, serial_hds[i],

                           DEVICE_NATIVE_ENDIAN);

        } else {

            break;

        }

    }

    if (serial_hds[i])

        s->fir = pxa2xx_fir_init(address_space, 0x40800000,

                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP),

                        qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP),

                        qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP),

                        serial_hds[i]);

    s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD));

    s->cm_base = 0x41300000;

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

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

    memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000);

    memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem);

    vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s);

    pxa2xx_setup_cp14(s);

    s->mm_base = 0x48000000;

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

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

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

    memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000);

    memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem);

    vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s);

    s->pm_base = 0x40f00000;

    memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100);

    memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem);

    vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);

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

    s->ssp = (SSIBus **)g_malloc0(sizeof(SSIBus *) * i);

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

        DeviceState *dev;

        dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa27x_ssp[i].io_base,

                        qdev_get_gpio_in(s->pic, pxa27x_ssp[i].irqn));

        s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");

    }

    if (usb_enabled(false)) {

        sysbus_create_simple("sysbus-ohci", 0x4c000000,

                        qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));

    }

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

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

    sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));

    s->i2c[0] = pxa2xx_i2c_init(0x40301600,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff);

    s->i2c[1] = pxa2xx_i2c_init(0x40f00100,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff);

    s->i2s = pxa2xx_i2s_init(address_space, 0x40400000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S),

                    qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S),

                    qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S));

    s->kp = pxa27x_keypad_init(address_space, 0x41500000,

                    qdev_get_gpio_in(s->pic, PXA2XX_PIC_KEYPAD));

    /* GPIO1 resets the processor */

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

    qdev_connect_gpio_out(s->gpio, 1, s->reset);

    return s;

}


static gboolean pty_chr_timer(gpointer opaque)

{

    struct CharDriverState *chr = opaque;

    PtyCharDriver *s = chr->opaque;

    if (s->connected) {

        goto out;

    }

    if (s->polling) {

        /* If we arrive here without polling being cleared due

         * read returning -EIO, then we are (re-)connected */

        pty_chr_state(chr, 1);

        goto out;

    }

    /* Next poll ... */

    pty_chr_update_read_handler(chr);

out:

    return FALSE;

}


static void virtio_scsi_reset(VirtIODevice *vdev)

{

    VirtIOSCSI *s = VIRTIO_SCSI(vdev);

    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);

    if (s->ctx) {

        virtio_scsi_dataplane_stop(s);

    }

    s->resetting++;

    qbus_reset_all(&s->bus.qbus);

    s->resetting--;

    vs->sense_size = VIRTIO_SCSI_SENSE_DEFAULT_SIZE;

    vs->cdb_size = VIRTIO_SCSI_CDB_DEFAULT_SIZE;

    s->events_dropped = false;

}


int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data)

{

    BlockDriverState *bs;

    int force = qdict_get_int(qdict, "force");

    const char *filename = qdict_get_str(qdict, "device");

    bs = bdrv_find(filename);

    if (!bs) {

        qerror_report(QERR_DEVICE_NOT_FOUND, filename);

        return -1;

    }

    return eject_device(mon, bs, force);

}


static int qxl_post_load(void *opaque, int version)

{

    PCIQXLDevice* d = opaque;

    uint8_t *ram_start = d->vga.vram_ptr;

    QXLCommandExt *cmds;

    int in, out, i, newmode;

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

    assert(d->last_release_offset < d->vga.vram_size);

    if (d->last_release_offset == 0) {

        d->last_release = NULL;

    } else {

        d->last_release = (QXLReleaseInfo *)(ram_start + d->last_release_offset);

    }

    d->modes = (QXLModes*)((uint8_t*)d->rom + d->rom->modes_offset);

    dprint(d, 1, "%s: restore mode (%s)\n", __FUNCTION__,

        qxl_mode_to_string(d->mode));

    newmode = d->mode;

    d->mode = QXL_MODE_UNDEFINED;

    switch (newmode) {

    case QXL_MODE_UNDEFINED:

        break;

    case QXL_MODE_VGA:

        qxl_enter_vga_mode(d);

        break;

    case QXL_MODE_NATIVE:

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

            if (!d->guest_slots[i].active) {

                continue;

            }

            qxl_add_memslot(d, i, 0, QXL_SYNC);

        }

        qxl_create_guest_primary(d, 1, QXL_SYNC);

        /* replay surface-create and cursor-set commands */

        cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));

        for (in = 0, out = 0; in < NUM_SURFACES; in++) {

            if (d->guest_surfaces.cmds[in] == 0) {

                continue;

            }

            cmds[out].cmd.data = d->guest_surfaces.cmds[in];

            cmds[out].cmd.type = QXL_CMD_SURFACE;

            cmds[out].group_id = MEMSLOT_GROUP_GUEST;

            out++;

        }

        cmds[out].cmd.data = d->guest_cursor;

        cmds[out].cmd.type = QXL_CMD_CURSOR;

        cmds[out].group_id = MEMSLOT_GROUP_GUEST;

        out++;

        qxl_spice_loadvm_commands(d, cmds, out);

        g_free(cmds);

        break;

    case QXL_MODE_COMPAT:

        qxl_set_mode(d, d->shadow_rom.mode, 1);

        break;

    }

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

    return 0;

}


static void musicpal_init(MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    ARMCPU *cpu;

    qemu_irq pic[32];

    DeviceState *dev;

    DeviceState *i2c_dev;

    DeviceState *lcd_dev;

    DeviceState *key_dev;

    DeviceState *wm8750_dev;

    SysBusDevice *s;

    I2CBus *i2c;

    int i;

    unsigned long flash_size;

    DriveInfo *dinfo;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *sram = g_new(MemoryRegion, 1);

    if (!cpu_model) {

        cpu_model = "arm926";

    }

    cpu = cpu_arm_init(cpu_model);

    if (!cpu) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    /* For now we use a fixed - the original - RAM size */

    memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE,

                           &error_abort);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(address_space_mem, 0, ram);

    memory_region_init_ram(sram, NULL, "musicpal.sram", MP_SRAM_SIZE,

                           &error_abort);

    vmstate_register_ram_global(sram);

    memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);

    dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,

                               qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));

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

        pic[i] = qdev_get_gpio_in(dev, i);

    }

    sysbus_create_varargs(TYPE_MV88W8618_PIT, MP_PIT_BASE, pic[MP_TIMER1_IRQ],

                          pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],

                          pic[MP_TIMER4_IRQ], NULL);

    if (serial_hds[0]) {

        serial_mm_init(address_space_mem, MP_UART1_BASE, 2, pic[MP_UART1_IRQ],

                       1825000, serial_hds[0], DEVICE_NATIVE_ENDIAN);

    }

    if (serial_hds[1]) {

        serial_mm_init(address_space_mem, MP_UART2_BASE, 2, pic[MP_UART2_IRQ],

                       1825000, serial_hds[1], DEVICE_NATIVE_ENDIAN);

    }

    /* Register flash */

    dinfo = drive_get(IF_PFLASH, 0, 0);

    if (dinfo) {

        BlockDriverState *bs = blk_bs(blk_by_legacy_dinfo(dinfo));

        flash_size = bdrv_getlength(bs);

        if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&

            flash_size != 32*1024*1024) {

            fprintf(stderr, "Invalid flash image size\n");

            exit(1);

        }

        /*

         * The original U-Boot accesses the flash at 0xFE000000 instead of

         * 0xFF800000 (if there is 8 MB flash). So remap flash access if the

         * image is smaller than 32 MB.

         */

#ifdef TARGET_WORDS_BIGENDIAN

        pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,

                              "musicpal.flash", flash_size,

                              bs, 0x10000, (flash_size + 0xffff) >> 16,

                              MP_FLASH_SIZE_MAX / flash_size,

                              2, 0x00BF, 0x236D, 0x0000, 0x0000,

                              0x5555, 0x2AAA, 1);

#else

        pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,

                              "musicpal.flash", flash_size,

                              bs, 0x10000, (flash_size + 0xffff) >> 16,

                              MP_FLASH_SIZE_MAX / flash_size,

                              2, 0x00BF, 0x236D, 0x0000, 0x0000,

                              0x5555, 0x2AAA, 0);

#endif

    }

    sysbus_create_simple(TYPE_MV88W8618_FLASHCFG, MP_FLASHCFG_BASE, NULL);

    qemu_check_nic_model(&nd_table[0], "mv88w8618");

    dev = qdev_create(NULL, TYPE_MV88W8618_ETH);

    qdev_set_nic_properties(dev, &nd_table[0]);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MP_ETH_BASE);

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[MP_ETH_IRQ]);

    sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL);

    sysbus_create_simple(TYPE_MUSICPAL_MISC, MP_MISC_BASE, NULL);

    dev = sysbus_create_simple(TYPE_MUSICPAL_GPIO, MP_GPIO_BASE,

                               pic[MP_GPIO_IRQ]);

    i2c_dev = sysbus_create_simple("gpio_i2c", -1, NULL);

    i2c = (I2CBus *)qdev_get_child_bus(i2c_dev, "i2c");

    lcd_dev = sysbus_create_simple(TYPE_MUSICPAL_LCD, MP_LCD_BASE, NULL);

    key_dev = sysbus_create_simple(TYPE_MUSICPAL_KEY, -1, NULL);

    /* I2C read data */

    qdev_connect_gpio_out(i2c_dev, 0,

                          qdev_get_gpio_in(dev, MP_GPIO_I2C_DATA_BIT));

    /* I2C data */

    qdev_connect_gpio_out(dev, 3, qdev_get_gpio_in(i2c_dev, 0));

    /* I2C clock */

    qdev_connect_gpio_out(dev, 4, qdev_get_gpio_in(i2c_dev, 1));

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

        qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(lcd_dev, i));

    }

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

        qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 8));

    }

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

        qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));

    }

    wm8750_dev = i2c_create_slave(i2c, "wm8750", MP_WM_ADDR);

    dev = qdev_create(NULL, "mv88w8618_audio");

    s = SYS_BUS_DEVICE(dev);

    qdev_prop_set_ptr(dev, "wm8750", wm8750_dev);

    qdev_init_nofail(dev);

    sysbus_mmio_map(s, 0, MP_AUDIO_BASE);

    sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);

    musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE;

    musicpal_binfo.kernel_filename = kernel_filename;

    musicpal_binfo.kernel_cmdline = kernel_cmdline;

    musicpal_binfo.initrd_filename = initrd_filename;

    arm_load_kernel(cpu, &musicpal_binfo);

}


static int read_table(AVFormatContext *avctx, AVStream *st,

                       int (*parse)(AVFormatContext *avctx, AVStream *st,

                                    const char *name, int size))

{

    int count, i;

    AVIOContext *pb = avctx->pb;

    avio_skip(pb, 4);

    count = avio_rb32(pb);

    avio_skip(pb, 4);

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

        char name[17];

        int size;

        avio_read(pb, name, 16);

        name[sizeof(name) - 1] = 0;

        size = avio_rb32(pb);

        if (size < 0) {

            av_log(avctx, AV_LOG_ERROR, "entry size %d is invalid\n", size);

            return AVERROR_INVALIDDATA;

        }

        if (parse(avctx, st, name, size) < 0) {

            avpriv_request_sample(avctx, "Variable %s", name);

            avio_skip(pb, size);

        }

    }

    return 0;

}


int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)

{

    uint8_t buf[4096];

    target_phys_addr_t dst_begin = dst_addr;

    size_t want, did;

    while (nbytes) {

	want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;

	did = fread(buf, 1, want, f);

	cpu_physical_memory_write_rom(dst_addr, buf, did);

	dst_addr += did;

	nbytes -= did;

	if (did != want)

	    break;

    }

    return dst_addr - dst_begin;

}


void avpriv_do_elbg(int *points, int dim, int numpoints, int *codebook,

                int numCB, int max_steps, int *closest_cb,

                AVLFG *rand_state)

{

    int dist;

    elbg_data elbg_d;

    elbg_data *elbg = &elbg_d;

    int i, j, k, last_error, steps=0;

    int *dist_cb = av_malloc(numpoints*sizeof(int));

    int *size_part = av_malloc(numCB*sizeof(int));

    cell *list_buffer = av_malloc(numpoints*sizeof(cell));

    cell *free_cells;

    int best_dist, best_idx = 0;

    elbg->error = INT_MAX;

    elbg->dim = dim;

    elbg->numCB = numCB;

    elbg->codebook = codebook;

    elbg->cells = av_malloc(numCB*sizeof(cell *));

    elbg->utility = av_malloc(numCB*sizeof(int));

    elbg->nearest_cb = closest_cb;

    elbg->points = points;

    elbg->utility_inc = av_malloc(numCB*sizeof(int));

    elbg->scratchbuf = av_malloc(5*dim*sizeof(int));

    elbg->rand_state = rand_state;

    do {

        free_cells = list_buffer;

        last_error = elbg->error;

        steps++;

        memset(elbg->utility, 0, numCB*sizeof(int));

        memset(elbg->cells, 0, numCB*sizeof(cell *));

        elbg->error = 0;

        /* This loop evaluate the actual Voronoi partition. It is the most

           costly part of the algorithm. */

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

            best_dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + best_idx*elbg->dim, dim, INT_MAX);

            for (k=0; k < elbg->numCB; k++) {

                dist = distance_limited(elbg->points + i*elbg->dim, elbg->codebook + k*elbg->dim, dim, best_dist);

                if (dist < best_dist) {

                    best_dist = dist;

                    best_idx = k;

                }

            }

            elbg->nearest_cb[i] = best_idx;

            dist_cb[i] = best_dist;

            elbg->error += dist_cb[i];

            elbg->utility[elbg->nearest_cb[i]] += dist_cb[i];

            free_cells->index = i;

            free_cells->next = elbg->cells[elbg->nearest_cb[i]];

            elbg->cells[elbg->nearest_cb[i]] = free_cells;

            free_cells++;

        }

        do_shiftings(elbg);

        memset(size_part, 0, numCB*sizeof(int));

        memset(elbg->codebook, 0, elbg->numCB*dim*sizeof(int));

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

            size_part[elbg->nearest_cb[i]]++;

            for (j=0; j < elbg->dim; j++)

                elbg->codebook[elbg->nearest_cb[i]*elbg->dim + j] +=

                    elbg->points[i*elbg->dim + j];

        }

        for (i=0; i < elbg->numCB; i++)

            vect_division(elbg->codebook + i*elbg->dim,

                          elbg->codebook + i*elbg->dim, size_part[i], elbg->dim);

    } while(((last_error - elbg->error) > DELTA_ERR_MAX*elbg->error) &&

            (steps < max_steps));

    av_free(dist_cb);

    av_free(size_part);

    av_free(elbg->utility);

    av_free(list_buffer);

    av_free(elbg->cells);

    av_free(elbg->utility_inc);

    av_free(elbg->scratchbuf);

}


void qmp_blockdev_change_medium(const char *device, const char *filename,

                                bool has_format, const char *format,

                                bool has_read_only,

                                BlockdevChangeReadOnlyMode read_only,

                                Error **errp)

{

    BlockBackend *blk;

    BlockDriverState *medium_bs = NULL;

    int bdrv_flags, ret;

    QDict *options = NULL;

    Error *err = NULL;

    blk = blk_by_name(device);

    if (!blk) {

        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,

                  "Device '%s' not found", device);

        goto fail;

    }

    if (blk_bs(blk)) {

        blk_update_root_state(blk);

    }

    bdrv_flags = blk_get_open_flags_from_root_state(blk);

    if (!has_read_only) {

        read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;

    }

    switch (read_only) {

    case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:

        break;

    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:

        bdrv_flags &= ~BDRV_O_RDWR;

        break;

    case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:

        bdrv_flags |= BDRV_O_RDWR;

        break;

    default:

        abort();

    }

    if (has_format) {

        options = qdict_new();

        qdict_put(options, "driver", qstring_from_str(format));

    }

    assert(!medium_bs);

    ret = bdrv_open(&medium_bs, filename, NULL, options, bdrv_flags, errp);

    if (ret < 0) {

        goto fail;

    }

    blk_apply_root_state(blk, medium_bs);

    bdrv_add_key(medium_bs, NULL, &err);

    if (err) {

        error_propagate(errp, err);

        goto fail;

    }

    qmp_blockdev_open_tray(device, false, false, &err);

    if (err) {

        error_propagate(errp, err);

        goto fail;

    }

    qmp_x_blockdev_remove_medium(device, &err);

    if (err) {

        error_propagate(errp, err);

        goto fail;

    }

    qmp_blockdev_insert_anon_medium(device, medium_bs, &err);

    if (err) {

        error_propagate(errp, err);

        goto fail;

    }

    qmp_blockdev_close_tray(device, errp);

fail:

    /* If the medium has been inserted, the device has its own reference, so

     * ours must be relinquished; and if it has not been inserted successfully,

     * the reference must be relinquished anyway */

    bdrv_unref(medium_bs);

}


static void v9fs_link(void *opaque)
{
    V9fsPDU *pdu = opaque;
    int32_t dfid, oldfid;
    V9fsFidState *dfidp, *oldfidp;
    V9fsString name;
    size_t offset = 7;
    int err = 0;
    v9fs_string_init(&name);
    err = pdu_unmarshal(pdu, offset, "dds", &dfid, &oldfid, &name);
    if (err < 0) {
    trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data);
    if (name_is_illegal(name.data)) {
        err = -ENOENT;
    dfidp = get_fid(pdu, dfid);
    if (dfidp == NULL) {
        err = -ENOENT;
    oldfidp = get_fid(pdu, oldfid);
    if (oldfidp == NULL) {
        err = -ENOENT;
        goto out;
    err = v9fs_co_link(pdu, oldfidp, dfidp, &name);
    if (!err) {
        err = offset;
out:
    put_fid(pdu, dfidp);
out_nofid:
    v9fs_string_free(&name);
    pdu_complete(pdu, err);


static PCIDevice *nic_init(PCIBus * bus, NICInfo * nd, uint32_t device)

{

    PCIEEPRO100State *d;

    EEPRO100State *s;

    logout("\n");

    d = (PCIEEPRO100State *) pci_register_device(bus, nd->model,

                                                 sizeof(PCIEEPRO100State), -1,

                                                 NULL, NULL);

    s = &d->eepro100;

    s->device = device;

    s->pci_dev = &d->dev;

    pci_reset(s);

    /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,

     * i82559 and later support 64 or 256 word EEPROM. */

    s->eeprom = eeprom93xx_new(EEPROM_SIZE);

    /* Handler for memory-mapped I/O */

    d->eepro100.mmio_index =

        cpu_register_io_memory(0, pci_mmio_read, pci_mmio_write, s);

    pci_register_io_region(&d->dev, 0, PCI_MEM_SIZE,

                           PCI_ADDRESS_SPACE_MEM |

                           PCI_ADDRESS_SPACE_MEM_PREFETCH, pci_mmio_map);

    pci_register_io_region(&d->dev, 1, PCI_IO_SIZE, PCI_ADDRESS_SPACE_IO,

                           pci_map);

    pci_register_io_region(&d->dev, 2, PCI_FLASH_SIZE, PCI_ADDRESS_SPACE_MEM,

                           pci_mmio_map);

    memcpy(s->macaddr, nd->macaddr, 6);

    logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6));

    assert(s->region[1] == 0);

    nic_reset(s);

    s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name,

                                 nic_receive, nic_can_receive, s);

    qemu_format_nic_info_str(s->vc, s->macaddr);

    qemu_register_reset(nic_reset, s);

    register_savevm(s->vc->model, -1, 3, nic_save, nic_load, s);

    return (PCIDevice *)d;

}


void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type,
                                  int64_t ns)
{
    CoSleepCB sleep_cb = {
        .co = qemu_coroutine_self(),
    };
    sleep_cb.ts = aio_timer_new(ctx, type, SCALE_NS, co_sleep_cb, &sleep_cb);
    timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
    qemu_coroutine_yield();
    timer_del(sleep_cb.ts);
    timer_free(sleep_cb.ts);


void cpu_set_log(int log_flags)

{

    loglevel = log_flags;

    if (loglevel && !logfile) {

        logfile = fopen(logfilename, log_append ? "a" : "w");

        if (!logfile) {

            perror(logfilename);

            _exit(1);

        }

#if !defined(CONFIG_SOFTMMU)

        /* must avoid mmap() usage of glibc by setting a buffer "by hand" */

        {

            static char logfile_buf[4096];

            setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));

        }

#elif !defined(_WIN32)

        /* Win32 doesn't support line-buffering and requires size >= 2 */

        setvbuf(logfile, NULL, _IOLBF, 0);

#endif

        log_append = 1;

    }

    if (!loglevel && logfile) {

        fclose(logfile);

        logfile = NULL;

    }

}


void helper_ocbi(CPUSH4State *env, uint32_t address)

{

    memory_content **current = &(env->movcal_backup);

    while (*current)

    {

	uint32_t a = (*current)->address;

	if ((a & ~0x1F) == (address & ~0x1F))

	{

	    memory_content *next = (*current)->next;

            cpu_stl_data(env, a, (*current)->value);

	    if (next == NULL)

	    {

		env->movcal_backup_tail = current;

	    }

	    free (*current);

	    *current = next;

	    break;

	}

    }

}


static int xmv_read_packet(AVFormatContext *s,

                           AVPacket *pkt)

{

    XMVDemuxContext *xmv = s->priv_data;

    int result;

    if (xmv->video.current_frame == xmv->video.frame_count) {

        /* No frames left in this packet, so we fetch a new one */

        result = xmv_fetch_new_packet(s);

        if (result)

            return result;

    }

    if (xmv->current_stream == 0) {

        /* Fetch a video frame */

        result = xmv_fetch_video_packet(s, pkt);

    } else {

        /* Fetch an audio frame */

        result = xmv_fetch_audio_packet(s, pkt, xmv->current_stream - 1);

    }

    if (result)

        return result;

    /* Increase our counters */

    if (++xmv->current_stream >= xmv->stream_count) {

        xmv->current_stream       = 0;

        xmv->video.current_frame += 1;

    }

    return 0;

}


static void render_memory_region(FlatView *view,

                                 MemoryRegion *mr,

                                 target_phys_addr_t base,

                                 AddrRange clip)

{

    MemoryRegion *subregion;

    unsigned i;

    target_phys_addr_t offset_in_region;

    uint64_t remain;

    uint64_t now;

    FlatRange fr;

    AddrRange tmp;

    base += mr->addr;

    tmp = addrrange_make(base, mr->size);

    if (!addrrange_intersects(tmp, clip)) {

        return;

    }

    clip = addrrange_intersection(tmp, clip);

    if (mr->alias) {

        base -= mr->alias->addr;

        base -= mr->alias_offset;

        render_memory_region(view, mr->alias, base, clip);

        return;

    }

    /* Render subregions in priority order. */

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

        render_memory_region(view, subregion, base, clip);

    }

    if (!mr->terminates) {

        return;

    }

    offset_in_region = clip.start - base;

    base = clip.start;

    remain = clip.size;

    /* Render the region itself into any gaps left by the current view. */

    for (i = 0; i < view->nr && remain; ++i) {

        if (base >= addrrange_end(view->ranges[i].addr)) {

            continue;

        }

        if (base < view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.start - base);

            fr.mr = mr;

            fr.offset_in_region = offset_in_region;

            fr.addr = addrrange_make(base, now);

            fr.dirty_log_mask = mr->dirty_log_mask;

            flatview_insert(view, i, &fr);

            ++i;

            base += now;

            offset_in_region += now;

            remain -= now;

        }

        if (base == view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.size);

            base += now;

            offset_in_region += now;

            remain -= now;

        }

    }

    if (remain) {

        fr.mr = mr;

        fr.offset_in_region = offset_in_region;

        fr.addr = addrrange_make(base, remain);

        fr.dirty_log_mask = mr->dirty_log_mask;

        flatview_insert(view, i, &fr);

    }

}


void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)

{

    uint32_t *copy;

    copy = g_malloc(sizeof(value));

    *copy = cpu_to_le32(value);

    fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));

}


struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,

                                        hwaddr base,

                                        qemu_irq irq,

                                        struct omap_dma_lcd_channel_s *dma,

                                        omap_clk clk)

{

    struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *)

            g_malloc0(sizeof(struct omap_lcd_panel_s));

    s->irq = irq;

    s->dma = dma;

    s->sysmem = sysmem;

    omap_lcdc_reset(s);

    memory_region_init_io(&s->iomem, NULL, &omap_lcdc_ops, s, "omap.lcdc", 0x100);

    memory_region_add_subregion(sysmem, base, &s->iomem);

    s->con = graphic_console_init(NULL, 0, &omap_ops, s);

    return s;

}


static void virtio_crypto_free_request(VirtIOCryptoReq *req)

{

    if (req) {

        if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {

            g_free(req->u.sym_op_info);

        }

        g_free(req);

    }

}


void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,

                          int unused, int size)

{

    if (is_exec)

        helper_raise_exception(EXCP_IBE);

    else

        helper_raise_exception(EXCP_DBE);

}


static void qemu_aio_complete(void *opaque, int ret)

{

    struct ioreq *ioreq = opaque;

    if (ret != 0) {

        xen_be_printf(&ioreq->blkdev->xendev, 0, "%s I/O error\n",

                      ioreq->req.operation == BLKIF_OP_READ ? "read" : "write");

        ioreq->aio_errors++;

    }

    ioreq->aio_inflight--;

    if (ioreq->presync) {

        ioreq->presync = 0;

        ioreq_runio_qemu_aio(ioreq);

        return;

    }

    if (ioreq->aio_inflight > 0) {

        return;

    }

    if (ioreq->postsync) {

        ioreq->postsync = 0;

        ioreq->aio_inflight++;

        blk_aio_flush(ioreq->blkdev->blk, qemu_aio_complete, ioreq);

        return;

    }

    ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;

    ioreq_unmap(ioreq);

    ioreq_finish(ioreq);

    switch (ioreq->req.operation) {

    case BLKIF_OP_WRITE:

    case BLKIF_OP_FLUSH_DISKCACHE:

        if (!ioreq->req.nr_segments) {

            break;

        }

    case BLKIF_OP_READ:

        block_acct_done(blk_get_stats(ioreq->blkdev->blk), &ioreq->acct);

        break;

    case BLKIF_OP_DISCARD:

    default:

        break;

    }

    qemu_bh_schedule(ioreq->blkdev->bh);

}


static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,

                             unsigned first_irq, unsigned req_num)

{

    unsigned i;

    MSIMessage msg = { .address = addr, .data = first_irq };

    if (!msix) {

        msi_set_message(pdev, msg);

        trace_spapr_pci_msi_setup(pdev->name, 0, msg.address);

        return;

    }

    for (i = 0; i < req_num; ++i, ++msg.data) {

        msix_set_message(pdev, i, msg);

        trace_spapr_pci_msi_setup(pdev->name, i, msg.address);

    }

}


static void spapr_reset_htab(sPAPRMachineState *spapr)

{

    long shift;

    int index;

    shift = kvmppc_reset_htab(spapr->htab_shift);

    if (shift > 0) {

        if (shift != spapr->htab_shift) {

            error_setg(&error_abort, "Requested HTAB allocation failed during reset");

        }

        /* Tell readers to update their file descriptor */

        if (spapr->htab_fd >= 0) {

            spapr->htab_fd_stale = true;

        }

    } else {

        memset(spapr->htab, 0, HTAB_SIZE(spapr));

        for (index = 0; index < HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; index++) {

            DIRTY_HPTE(HPTE(spapr->htab, index));

        }

    }

    /* Update the RMA size if necessary */

    if (spapr->vrma_adjust) {

        spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),

                                          spapr->htab_shift);

    }

}


void raise_irq_cpu_hotplug(void)

{

    qemu_irq_raise(irq_cpu_hotplug);

}


static void uhci_queue_free(UHCIQueue *queue)

{

    UHCIState *s = queue->uhci;

    UHCIAsync *async;

    while (!QTAILQ_EMPTY(&queue->asyncs)) {

        async = QTAILQ_FIRST(&queue->asyncs);

        uhci_async_cancel(async);

    }

    trace_usb_uhci_queue_del(queue->token);

    QTAILQ_REMOVE(&s->queues, queue, next);

    g_free(queue);

}


static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,

                        SBRData *ch_data, int e_a[2])

{

    int e, i, m;

    memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1]));

    for (e = 0; e < ch_data->bs_num_env; e++) {

        const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]];

        uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;

        int k;

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

            for (m = table[i]; m < table[i + 1]; m++)

                sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i];

        // ch_data->bs_num_noise > 1 => 2 noise floors

        k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]);

        for (i = 0; i < sbr->n_q; i++)

            for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++)

                sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i];

        for (i = 0; i < sbr->n[1]; i++) {

            if (ch_data->bs_add_harmonic_flag) {

                const unsigned int m_midpoint =

                    (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1;

                ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] *

                    (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1));

            }

        }

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

            int additional_sinusoid_present = 0;

            for (m = table[i]; m < table[i + 1]; m++) {

                if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) {

                    additional_sinusoid_present = 1;

                    break;

                }

            }

            memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present,

                   (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0]));

        }

    }

    memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));

}


static void draw_mandelbrot(AVFilterContext *ctx, uint32_t *color, int linesize, int64_t pts)

{

    MBContext *mb = ctx->priv;

    int x,y,i, in_cidx=0, next_cidx=0, tmp_cidx;

    double scale= mb->start_scale*pow(mb->end_scale/mb->start_scale, pts/mb->end_pts);

    int use_zyklus=0;

    fill_from_cache(ctx, NULL, &in_cidx, NULL, mb->start_y+scale*(-mb->h/2-0.5), scale);

    tmp_cidx= in_cidx;

    memset(color, 0, sizeof(*color)*mb->w);

    for(y=0; y<mb->h; y++){

        int y1= y+1;

        const double ci=mb->start_y+scale*(y-mb->h/2);

        fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci, scale);

        if(y1<mb->h){

            memset(color+linesize*y1, 0, sizeof(*color)*mb->w);

            fill_from_cache(ctx, color+linesize*y1, &tmp_cidx, NULL, ci + 3*scale/2, scale);

        }

        for(x=0; x<mb->w; x++){

            float epsilon;

            const double cr=mb->start_x+scale*(x-mb->w/2);

            double zr=cr;

            double zi=ci;

            uint32_t c=0;

            double dv= mb->dither / (double)(1LL<<32);

            mb->dither= mb->dither*1664525+1013904223;

            if(color[x + y*linesize] & 0xFF000000)

                continue;

            if(interpol(mb, color, x, y, linesize)){

                if(next_cidx < mb->cache_allocated){

                    mb->next_cache[next_cidx  ].p[0]= cr;

                    mb->next_cache[next_cidx  ].p[1]= ci;

                    mb->next_cache[next_cidx++].val = color[x + y*linesize];

                }

                continue;

            }

            use_zyklus= (x==0 || mb->inner!=BLACK ||color[x-1 + y*linesize] == 0xFF000000);

            if(use_zyklus)

                epsilon= scale*1*sqrt(SQR(x-mb->w/2) + SQR(y-mb->h/2))/mb->w;

#define Z_Z2_C(outr,outi,inr,ini)\

            outr= inr*inr - ini*ini + cr;\

            outi= 2*inr*ini + ci;

#define Z_Z2_C_ZYKLUS(outr,outi,inr,ini, Z)\

            Z_Z2_C(outr,outi,inr,ini)\

            if(use_zyklus){\

                if(Z && fabs(mb->zyklus[i>>1][0]-outr)+fabs(mb->zyklus[i>>1][1]-outi) <= epsilon)\

                    break;\

            }\

            mb->zyklus[i][0]= outr;\

            mb->zyklus[i][1]= outi;\

            for(i=0; i<mb->maxiter-8; i++){

                double t;

                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)

                i++;

                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)

                i++;

                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)

                i++;

                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)

                i++;

                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)

                i++;

                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)

                i++;

                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)

                i++;

                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)

                if(zr*zr + zi*zi > mb->bailout){

                    i-= FFMIN(7, i);

                    for(; i<mb->maxiter; i++){

                        zr= mb->zyklus[i][0];

                        zi= mb->zyklus[i][1];

                        if(zr*zr + zi*zi > mb->bailout){

                            switch(mb->outer){

                            case            ITERATION_COUNT: zr = i; break;

                            case NORMALIZED_ITERATION_COUNT: zr= i + log2(log(mb->bailout) / log(zr*zr + zi*zi)); break;

                            }

                            c= lrintf((sin(zr)+1)*127) + lrintf((sin(zr/1.234)+1)*127)*256*256 + lrintf((sin(zr/100)+1)*127)*256;

                            break;

                        }

                    }

                    break;

                }

            }

            if(!c){

                if(mb->inner==PERIOD){

                int j;

                for(j=i-1; j; j--)

                    if(SQR(mb->zyklus[j][0]-zr) + SQR(mb->zyklus[j][1]-zi) < epsilon*epsilon*10)

                        break;

                if(j){

                    c= i-j;

                    c= ((c<<5)&0xE0) + ((c<<16)&0xE000) + ((c<<27)&0xE00000);

                }

                }else if(mb->inner==CONVTIME){

                    c= floor(i*255.0/mb->maxiter+dv)*0x010101;

                } else if(mb->inner==MINCOL){

                    int j;

                    double closest=9999;

                    int closest_index=0;

                    for(j=i-1; j>=0; j--)

                        if(SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]) < closest){

                            closest= SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]);

                            closest_index= j;

                        }

                    closest = sqrt(closest);

                    c= lrintf((mb->zyklus[closest_index][0]/closest+1)*127+dv) + lrintf((mb->zyklus[closest_index][1]/closest+1)*127+dv)*256;

                }

            }

            c |= 0xFF000000;

            color[x + y*linesize]= c;

            if(next_cidx < mb->cache_allocated){

                mb->next_cache[next_cidx  ].p[0]= cr;

                mb->next_cache[next_cidx  ].p[1]= ci;

                mb->next_cache[next_cidx++].val = c;

            }

        }

        fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci + scale/2, scale);

    }

    FFSWAP(void*, mb->next_cache, mb->point_cache);

    mb->cache_used = next_cidx;

    if(mb->cache_used == mb->cache_allocated)

        av_log(0, AV_LOG_INFO, "Mandelbrot cache is too small!\n");

}


static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb,

                                   RMDemuxContext *rm, RMStream *vst,

                                   AVPacket *pkt, int len, int *pseq,

                                   int64_t *timestamp)

{

    int hdr, seq, pic_num, len2, pos;

    int type;

    hdr = avio_r8(pb); len--;

    type = hdr >> 6;

    if(type != 3){  // not frame as a part of packet

        seq = avio_r8(pb); len--;

    }

    if(type != 1){  // not whole frame

        len2 = get_num(pb, &len);

        pos  = get_num(pb, &len);

        pic_num = avio_r8(pb); len--;

    }

    if(len<0)

        return -1;

    rm->remaining_len = len;

    if(type&1){     // frame, not slice

        if(type == 3){  // frame as a part of packet

            len= len2;

            *timestamp = pos;

        }

        if(rm->remaining_len < len)

            return -1;

        rm->remaining_len -= len;

        if(av_new_packet(pkt, len + 9) < 0)

            return AVERROR(EIO);

        pkt->data[0] = 0;

        AV_WL32(pkt->data + 1, 1);

        AV_WL32(pkt->data + 5, 0);

        avio_read(pb, pkt->data + 9, len);

        return 0;

    }

    //now we have to deal with single slice

    *pseq = seq;

    if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){

        vst->slices = ((hdr & 0x3F) << 1) + 1;

        vst->videobufsize = len2 + 8*vst->slices + 1;

        av_free_packet(&vst->pkt); //FIXME this should be output.

        if(av_new_packet(&vst->pkt, vst->videobufsize) < 0)

            return AVERROR(ENOMEM);

        vst->videobufpos = 8*vst->slices + 1;

        vst->cur_slice = 0;

        vst->curpic_num = pic_num;

        vst->pktpos = avio_tell(pb);

    }

    if(type == 2)

        len = FFMIN(len, pos);

    if(++vst->cur_slice > vst->slices)

        return 1;

    AV_WL32(vst->pkt.data - 7 + 8*vst->cur_slice, 1);

    AV_WL32(vst->pkt.data - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);

    if(vst->videobufpos + len > vst->videobufsize)

        return 1;

    if (avio_read(pb, vst->pkt.data + vst->videobufpos, len) != len)

        return AVERROR(EIO);

    vst->videobufpos += len;

    rm->remaining_len-= len;

    if (type == 2 || vst->videobufpos == vst->videobufsize) {

        vst->pkt.data[0] = vst->cur_slice-1;

        *pkt= vst->pkt;

        vst->pkt.data= NULL;

        vst->pkt.size= 0;

        if(vst->slices != vst->cur_slice) //FIXME find out how to set slices correct from the begin

            memmove(pkt->data + 1 + 8*vst->cur_slice, pkt->data + 1 + 8*vst->slices,

                vst->videobufpos - 1 - 8*vst->slices);

        pkt->size = vst->videobufpos + 8*(vst->cur_slice - vst->slices);

        pkt->pts = AV_NOPTS_VALUE;

        pkt->pos = vst->pktpos;

        vst->slices = 0;

        return 0;

    }

    return 1;

}


aio_write_f(int argc, char **argv)

{

	int nr_iov, c;

	int pattern = 0xcd;

	struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx));

	BlockDriverAIOCB *acb;

	while ((c = getopt(argc, argv, "CqP:")) != EOF) {

		switch (c) {

		case 'C':

			ctx->Cflag = 1;

			break;

		case 'q':

			ctx->qflag = 1;

			break;

		case 'P':

			pattern = atoi(optarg);

			break;

		default:

			return command_usage(&aio_write_cmd);

		}

	}

	if (optind > argc - 2)

		return command_usage(&aio_write_cmd);

	ctx->offset = cvtnum(argv[optind]);

	if (ctx->offset < 0) {

		printf("non-numeric length argument -- %s\n", argv[optind]);

		return 0;

	}

	optind++;

	if (ctx->offset & 0x1ff) {

		printf("offset %lld is not sector aligned\n",

			(long long)ctx->offset);

		return 0;

	}

	nr_iov = argc - optind;

	ctx->buf = create_iovec(&ctx->qiov, &argv[optind], nr_iov, pattern);

	gettimeofday(&ctx->t1, NULL);

	acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov,

			      ctx->qiov.size >> 9, aio_write_done, ctx);

	if (!acb)

		return -EIO;

	return 0;

}


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

                                  unsigned width)

{

    DebugconState *s = opaque;

    unsigned char ch = val;

#ifdef DEBUG_DEBUGCON

    printf(" [debugcon: write addr=0x%04" HWADDR_PRIx " val=0x%02" PRIx64 "]\n", addr, val);

#endif

    qemu_chr_fe_write(s->chr, &ch, 1);

}


static void nal_send(AVFormatContext *s1, const uint8_t *buf, int size, int last)

{

    RTPMuxContext *s = s1->priv_data;

    av_log(s1, AV_LOG_DEBUG, "Sending NAL %x of len %d M=%d\n", buf[0] & 0x1F, size, last);

    if (size <= s->max_payload_size) {

        int buffered_size = s->buf_ptr - s->buf;

        // Flush buffered NAL units if the current unit doesn't fit

        if (buffered_size + 2 + size > s->max_payload_size) {

            flush_buffered(s1, 0);

            buffered_size = 0;

        }

        // If we aren't using mode 0, and the NAL unit fits including the

        // framing (2 bytes length, plus 1 byte for the STAP-A marker),

        // write the unit to the buffer as a STAP-A packet, otherwise flush

        // and send as single NAL.

        if (buffered_size + 3 + size <= s->max_payload_size &&

            !(s->flags & FF_RTP_FLAG_H264_MODE0)) {

            if (buffered_size == 0)

                *s->buf_ptr++ = 24;

            AV_WB16(s->buf_ptr, size);

            s->buf_ptr += 2;

            memcpy(s->buf_ptr, buf, size);

            s->buf_ptr += size;

            s->buffered_nals++;

        } else {

            flush_buffered(s1, 0);

            ff_rtp_send_data(s1, buf, size, last);

        }

    } else {

        uint8_t type = buf[0] & 0x1F;

        uint8_t nri = buf[0] & 0x60;

        flush_buffered(s1, 0);

        if (s->flags & FF_RTP_FLAG_H264_MODE0) {

            av_log(s1, AV_LOG_ERROR,

                   "NAL size %d > %d, try -slice-max-size %d\n", size,

                   s->max_payload_size, s->max_payload_size);

            return;

        }

        av_log(s1, AV_LOG_DEBUG, "NAL size %d > %d\n", size, s->max_payload_size);

        s->buf[0] = 28;        /* FU Indicator; Type = 28 ---> FU-A */

        s->buf[0] |= nri;

        s->buf[1] = type;

        s->buf[1] |= 1 << 7;

        buf += 1;

        size -= 1;

        while (size + 2 > s->max_payload_size) {

            memcpy(&s->buf[2], buf, s->max_payload_size - 2);

            ff_rtp_send_data(s1, s->buf, s->max_payload_size, 0);

            buf += s->max_payload_size - 2;

            size -= s->max_payload_size - 2;

            s->buf[1] &= ~(1 << 7);

        }

        s->buf[1] |= 1 << 6;

        memcpy(&s->buf[2], buf, size);

        ff_rtp_send_data(s1, s->buf, size + 2, last);

    }

}


static av_always_inline int vmnc_get_pixel(const uint8_t *buf, int bpp, int be)

{

    switch (bpp * 2 + be) {

    case 2:

    case 3:

        return *buf;

    case 4:

        return AV_RL16(buf);

    case 5:

        return AV_RB16(buf);

    case 8:

        return AV_RL32(buf);

    case 9:

        return AV_RB32(buf);

    default:

        return 0;

    }

}


static void test_wait_event_notifier(void)

{

    EventNotifierTestData data = { .n = 0, .active = 1 };

    event_notifier_init(&data.e, false);

    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);

    g_assert(aio_poll(ctx, false));

    g_assert_cmpint(data.n, ==, 0);

    g_assert_cmpint(data.active, ==, 1);

    event_notifier_set(&data.e);

    g_assert(aio_poll(ctx, false));

    g_assert_cmpint(data.n, ==, 1);

    g_assert_cmpint(data.active, ==, 0);

    g_assert(!aio_poll(ctx, false));

    g_assert_cmpint(data.n, ==, 1);

    g_assert_cmpint(data.active, ==, 0);

    aio_set_event_notifier(ctx, &data.e, NULL, NULL);

    g_assert(!aio_poll(ctx, false));

    g_assert_cmpint(data.n, ==, 1);

    event_notifier_cleanup(&data.e);

}


target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)

{

    check_hwrena(env, 1);

    return env->SYNCI_Step;

}


static int get_moov_size(AVFormatContext *s)

{

    int ret;

    AVIOContext *moov_buf;

    MOVMuxContext *mov = s->priv_data;

    if ((ret = ffio_open_null_buf(&moov_buf)) < 0)

        return ret;

    mov_write_moov_tag(moov_buf, mov, s);

    return ffio_close_null_buf(moov_buf);

}


static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir, int avg)

{

    MpegEncContext *s = &v->s;

    uint8_t *srcY;

    int dxy, mx, my, src_x, src_y;

    int off;

    int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0;

    int v_edge_pos = s->v_edge_pos >> v->field_mode;

    uint8_t (*luty)[256];

    int use_ic;

    if ((!v->field_mode ||

         (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) &&

        !v->s.last_picture.f.data[0])

        return;

    mx = s->mv[dir][n][0];

    my = s->mv[dir][n][1];

    if (!dir) {

        if (v->field_mode && (v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {

            srcY = s->current_picture.f.data[0];

            luty = v->curr_luty;

            use_ic = v->curr_use_ic;

        } else {

            srcY = s->last_picture.f.data[0];

            luty = v->last_luty;

            use_ic = v->last_use_ic;

        }

    } else {

        srcY = s->next_picture.f.data[0];

        luty = v->next_luty;

        use_ic = v->next_use_ic;

    }

    if (!srcY) {

        av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n");

        return;

    }

    if (v->field_mode) {

        if (v->cur_field_type != v->ref_field_type[dir])

            my = my - 2 + 4 * v->cur_field_type;

    }

    if (s->pict_type == AV_PICTURE_TYPE_P && n == 3 && v->field_mode) {

        int same_count = 0, opp_count = 0, k;

        int chosen_mv[2][4][2], f;

        int tx, ty;

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

            f = v->mv_f[0][s->block_index[k] + v->blocks_off];

            chosen_mv[f][f ? opp_count : same_count][0] = s->mv[0][k][0];

            chosen_mv[f][f ? opp_count : same_count][1] = s->mv[0][k][1];

            opp_count  += f;

            same_count += 1 - f;

        }

        f = opp_count > same_count;

        switch (f ? opp_count : same_count) {

        case 4:

            tx = median4(chosen_mv[f][0][0], chosen_mv[f][1][0],

                         chosen_mv[f][2][0], chosen_mv[f][3][0]);

            ty = median4(chosen_mv[f][0][1], chosen_mv[f][1][1],

                         chosen_mv[f][2][1], chosen_mv[f][3][1]);

            break;

        case 3:

            tx = mid_pred(chosen_mv[f][0][0], chosen_mv[f][1][0], chosen_mv[f][2][0]);

            ty = mid_pred(chosen_mv[f][0][1], chosen_mv[f][1][1], chosen_mv[f][2][1]);

            break;

        case 2:

            tx = (chosen_mv[f][0][0] + chosen_mv[f][1][0]) / 2;

            ty = (chosen_mv[f][0][1] + chosen_mv[f][1][1]) / 2;

            break;

        }

        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx;

        s->current_picture.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty;

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

            v->mv_f[1][s->block_index[k] + v->blocks_off] = f;

    }

    if (v->fcm == ILACE_FRAME) {  // not sure if needed for other types of picture

        int qx, qy;

        int width  = s->avctx->coded_width;

        int height = s->avctx->coded_height >> 1;

        if (s->pict_type == AV_PICTURE_TYPE_P) {

            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][0] = mx;

            s->current_picture.motion_val[1][s->block_index[n] + v->blocks_off][1] = my;

        }

        qx = (s->mb_x * 16) + (mx >> 2);

        qy = (s->mb_y *  8) + (my >> 3);

        if (qx < -17)

            mx -= 4 * (qx + 17);

        else if (qx > width)

            mx -= 4 * (qx - width);

        if (qy < -18)

            my -= 8 * (qy + 18);

        else if (qy > height + 1)

            my -= 8 * (qy - height - 1);

    }

    if ((v->fcm == ILACE_FRAME) && fieldmv)

        off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;

    else

        off = s->linesize * 4 * (n & 2) + (n & 1) * 8;

    src_x = s->mb_x * 16 + (n & 1) * 8 + (mx >> 2);

    if (!fieldmv)

        src_y = s->mb_y * 16 + (n & 2) * 4 + (my >> 2);

    else

        src_y = s->mb_y * 16 + ((n > 1) ? 1 : 0) + (my >> 2);

    if (v->profile != PROFILE_ADVANCED) {

        src_x = av_clip(src_x, -16, s->mb_width  * 16);

        src_y = av_clip(src_y, -16, s->mb_height * 16);

    } else {

        src_x = av_clip(src_x, -17, s->avctx->coded_width);

        if (v->fcm == ILACE_FRAME) {

            if (src_y & 1)

                src_y = av_clip(src_y, -17, s->avctx->coded_height + 1);

            else

                src_y = av_clip(src_y, -18, s->avctx->coded_height);

        } else {

            src_y = av_clip(src_y, -18, s->avctx->coded_height + 1);

        }

    }

    srcY += src_y * s->linesize + src_x;

    if (v->field_mode && v->ref_field_type[dir])

        srcY += s->current_picture_ptr->f.linesize[0];

    if (fieldmv && !(src_y & 1))

        v_edge_pos--;

    if (fieldmv && (src_y & 1) && src_y < 4)

        src_y--;

    if (v->rangeredfrm || use_ic

        || s->h_edge_pos < 13 || v_edge_pos < 23

        || (unsigned)(src_x - s->mspel) > s->h_edge_pos - (mx & 3) - 8 - s->mspel * 2

        || (unsigned)(src_y - (s->mspel << fieldmv)) > v_edge_pos - (my & 3) - ((8 + s->mspel * 2) << fieldmv)) {

        srcY -= s->mspel * (1 + (s->linesize << fieldmv));

        /* check emulate edge stride and offset */

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, srcY,

                                 s->linesize, s->linesize,

                                 9 + s->mspel * 2, (9 + s->mspel * 2) << fieldmv,

                                 src_x - s->mspel, src_y - (s->mspel << fieldmv),

                                 s->h_edge_pos, v_edge_pos);

        srcY = s->edge_emu_buffer;

        /* if we deal with range reduction we need to scale source blocks */

        if (v->rangeredfrm) {

            int i, j;

            uint8_t *src;

            src = srcY;

            for (j = 0; j < 9 + s->mspel * 2; j++) {

                for (i = 0; i < 9 + s->mspel * 2; i++)

                    src[i] = ((src[i] - 128) >> 1) + 128;

                src += s->linesize << fieldmv;

            }

        }

        /* if we deal with intensity compensation we need to scale source blocks */

        if (use_ic) {

            int i, j;

            uint8_t *src;

            src = srcY;

            for (j = 0; j < 9 + s->mspel * 2; j++) {

                int f = v->field_mode ? v->ref_field_type[dir] : (((j<<fieldmv)+src_y - (s->mspel << fieldmv)) & 1);

                for (i = 0; i < 9 + s->mspel * 2; i++)

                    src[i] = luty[f][src[i]];

                src += s->linesize << fieldmv;

            }

        }

        srcY += s->mspel * (1 + (s->linesize << fieldmv));

    }

    if (s->mspel) {

        dxy = ((my & 3) << 2) | (mx & 3);

        if (avg)

            v->vc1dsp.avg_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);

        else

            v->vc1dsp.put_vc1_mspel_pixels_tab[dxy](s->dest[0] + off, srcY, s->linesize << fieldmv, v->rnd);

    } else { // hpel mc - always used for luma

        dxy = (my & 2) | ((mx & 2) >> 1);

        if (!v->rnd)

            s->hdsp.put_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);

        else

            s->hdsp.put_no_rnd_pixels_tab[1][dxy](s->dest[0] + off, srcY, s->linesize, 8);

    }

}


static int recover(WtvContext *wtv, uint64_t broken_pos)

{

    AVIOContext *pb = wtv->pb;

    int i;

    for (i = 0; i < wtv->nb_index_entries; i++) {

        if (wtv->index_entries[i].pos > broken_pos) {

            int ret = avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET);

            if (ret < 0)

                return ret;

            wtv->pts = wtv->index_entries[i].timestamp;

            return 0;

         }

     }

     return AVERROR(EIO);

}


static always_inline void mpeg_motion_lowres(MpegEncContext *s,

                               uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,

                               int field_based, int bottom_field, int field_select,

                               uint8_t **ref_picture, h264_chroma_mc_func *pix_op,

                               int motion_x, int motion_y, int h)

{

    uint8_t *ptr_y, *ptr_cb, *ptr_cr;

    int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy, uvsx, uvsy;

    const int lowres= s->avctx->lowres;

    const int block_s= 8>>lowres;

    const int s_mask= (2<<lowres)-1;

    const int h_edge_pos = s->h_edge_pos >> lowres;

    const int v_edge_pos = s->v_edge_pos >> lowres;

    linesize   = s->current_picture.linesize[0] << field_based;

    uvlinesize = s->current_picture.linesize[1] << field_based;

    if(s->quarter_sample){ //FIXME obviously not perfect but qpel wont work in lowres anyway

        motion_x/=2;

        motion_y/=2;

    }

    if(field_based){

        motion_y += (bottom_field - field_select)*((1<<lowres)-1);

    }

    sx= motion_x & s_mask;

    sy= motion_y & s_mask;

    src_x = s->mb_x*2*block_s               + (motion_x >> (lowres+1));

    src_y =(s->mb_y*2*block_s>>field_based) + (motion_y >> (lowres+1));

    if (s->out_format == FMT_H263) {

        uvsx = ((motion_x>>1) & s_mask) | (sx&1);

        uvsy = ((motion_y>>1) & s_mask) | (sy&1);

        uvsrc_x = src_x>>1;

        uvsrc_y = src_y>>1;

    }else if(s->out_format == FMT_H261){//even chroma mv's are full pel in H261

        mx = motion_x / 4;

        my = motion_y / 4;

        uvsx = (2*mx) & s_mask;

        uvsy = (2*my) & s_mask;

        uvsrc_x = s->mb_x*block_s               + (mx >> lowres);

        uvsrc_y = s->mb_y*block_s               + (my >> lowres);

    } else {

        mx = motion_x / 2;

        my = motion_y / 2;

        uvsx = mx & s_mask;

        uvsy = my & s_mask;

        uvsrc_x = s->mb_x*block_s               + (mx >> (lowres+1));

        uvsrc_y =(s->mb_y*block_s>>field_based) + (my >> (lowres+1));

    }

    ptr_y  = ref_picture[0] + src_y * linesize + src_x;

    ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;

    ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;

    if(   (unsigned)src_x > h_edge_pos                 - (!!sx) - 2*block_s

       || (unsigned)src_y >(v_edge_pos >> field_based) - (!!sy) - h){

            ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize, 17, 17+field_based,

                             src_x, src_y<<field_based, h_edge_pos, v_edge_pos);

            ptr_y = s->edge_emu_buffer;

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

                uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;

                ff_emulated_edge_mc(uvbuf  , ptr_cb, s->uvlinesize, 9, 9+field_based,

                                 uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);

                ff_emulated_edge_mc(uvbuf+16, ptr_cr, s->uvlinesize, 9, 9+field_based,

                                 uvsrc_x, uvsrc_y<<field_based, h_edge_pos>>1, v_edge_pos>>1);

                ptr_cb= uvbuf;

                ptr_cr= uvbuf+16;

            }

    }

    if(bottom_field){ //FIXME use this for field pix too instead of the obnoxious hack which changes picture.data

        dest_y += s->linesize;

        dest_cb+= s->uvlinesize;

        dest_cr+= s->uvlinesize;

    }

    if(field_select){

        ptr_y += s->linesize;

        ptr_cb+= s->uvlinesize;

        ptr_cr+= s->uvlinesize;

    }

    sx <<= 2 - lowres;

    sy <<= 2 - lowres;

    pix_op[lowres-1](dest_y, ptr_y, linesize, h, sx, sy);

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

        uvsx <<= 2 - lowres;

        uvsy <<= 2 - lowres;

        pix_op[lowres](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);

        pix_op[lowres](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);

    }

}


static void qxl_reset_state(PCIQXLDevice *d)

{

    QXLRam *ram = d->ram;

    QXLRom *rom = d->rom;

    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));

    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));

    d->shadow_rom.update_id = cpu_to_le32(0);

    *rom = d->shadow_rom;

    qxl_rom_set_dirty(d);

    init_qxl_ram(d);

    d->num_free_res = 0;

    d->last_release = NULL;

    memset(&d->ssd.dirty, 0, sizeof(d->ssd.dirty));

}


static const uint8_t *decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){

    int i, si, di;

    uint8_t *dst;

    int bufidx;

//    src[0]&0x80;                //forbidden bit

    h->nal_ref_idc= src[0]>>5;

    h->nal_unit_type= src[0]&0x1F;

    src++; length--;

#if 0

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

        printf("%2X ", src[i]);

#endif

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

        if(src[i]) continue;

        if(i>0 && src[i-1]==0) i--;

        if(i+2<length && src[i+1]==0 && src[i+2]<=3){

            if(src[i+2]!=3){

                /* startcode, so we must be past the end */

                length=i;

            }

            break;

        }

    }

    if(i>=length-1){ //no escaped 0

        *dst_length= length;

        *consumed= length+1; //+1 for the header

        return src;

    }

    bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data

    h->rbsp_buffer[bufidx]= av_fast_realloc(h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length);

    dst= h->rbsp_buffer[bufidx];

    if (dst == NULL){

        return NULL;

    }

//printf("decoding esc\n");

    si=di=0;

    while(si<length){

        //remove escapes (very rare 1:2^22)

        if(si+2<length && src[si]==0 && src[si+1]==0 && src[si+2]<=3){

            if(src[si+2]==3){ //escape

                dst[di++]= 0;

                dst[di++]= 0;

                si+=3;

                continue;

            }else //next start code

                break;

        }

        dst[di++]= src[si++];

    }

    *dst_length= di;

    *consumed= si + 1;//+1 for the header

//FIXME store exact number of bits in the getbitcontext (it is needed for decoding)

    return dst;

}