static void vc1_mc_1mv(VC1Context *v, int dir)

{

    MpegEncContext *s = &v->s;

    H264ChromaContext *h264chroma = &v->h264chroma;

    uint8_t *srcY, *srcU, *srcV;

    int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;

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

    int i;

    uint8_t (*luty)[256], (*lutuv)[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][0][0];

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

    // store motion vectors for further use in B frames

    if (s->pict_type == AV_PICTURE_TYPE_P) {

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

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

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

        }

    }

    uvmx = (mx + ((mx & 3) == 3)) >> 1;

    uvmy = (my + ((my & 3) == 3)) >> 1;

    v->luma_mv[s->mb_x][0] = uvmx;

    v->luma_mv[s->mb_x][1] = uvmy;

    if (v->field_mode &&

        v->cur_field_type != v->ref_field_type[dir]) {

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

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

    }

    // fastuvmc shall be ignored for interlaced frame picture

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

        uvmx = uvmx + ((uvmx < 0) ? (uvmx & 1) : -(uvmx & 1));

        uvmy = uvmy + ((uvmy < 0) ? (uvmy & 1) : -(uvmy & 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];

            srcU = s->current_picture.f.data[1];

            srcV = s->current_picture.f.data[2];

            luty  = v->curr_luty;

            lutuv = v->curr_lutuv;

            use_ic = v->curr_use_ic;

        } else {

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

            srcU = s->last_picture.f.data[1];

            srcV = s->last_picture.f.data[2];

            luty  = v->last_luty;

            lutuv = v->last_lutuv;

            use_ic = v->last_use_ic;

        }

    } else {

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

        srcU = s->next_picture.f.data[1];

        srcV = s->next_picture.f.data[2];

        luty  = v->next_luty;

        lutuv = v->next_lutuv;

        use_ic = v->next_use_ic;

    }

    if (!srcY || !srcU) {

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

        return;

    }

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

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

    uvsrc_x = s->mb_x *  8 + (uvmx >> 2);

    uvsrc_y = s->mb_y *  8 + (uvmy >> 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);

        uvsrc_x = av_clip(uvsrc_x,  -8, s->mb_width  *  8);

        uvsrc_y = av_clip(uvsrc_y,  -8, s->mb_height *  8);

    } else {

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

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

        uvsrc_x = av_clip(uvsrc_x,  -8, s->avctx->coded_width  >> 1);

        uvsrc_y = av_clip(uvsrc_y,  -8, s->avctx->coded_height >> 1);

    }

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

    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;

    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;

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

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

        srcU += s->current_picture_ptr->f.linesize[1];

        srcV += s->current_picture_ptr->f.linesize[2];

    }

    /* for grayscale we should not try to read from unknown area */

    if (s->flags & CODEC_FLAG_GRAY) {

        srcU = s->edge_emu_buffer + 18 * s->linesize;

        srcV = s->edge_emu_buffer + 18 * s->linesize;

    }

    if (v->rangeredfrm || use_ic

        || s->h_edge_pos < 22 || v_edge_pos < 22

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

        || (unsigned)(src_y - 1)        > v_edge_pos    - (my&3) - 16 - 3) {

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

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

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

                                 s->linesize, s->linesize,

                                 17 + s->mspel * 2, 17 + s->mspel * 2,

                                 src_x - s->mspel, src_y - s->mspel,

                                 s->h_edge_pos, v_edge_pos);

        srcY = s->edge_emu_buffer;

        s->vdsp.emulated_edge_mc(uvbuf, srcU,

                                 s->uvlinesize, s->uvlinesize,

                                 8 + 1, 8 + 1,

                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);

        s->vdsp.emulated_edge_mc(uvbuf + 16, srcV,

                                 s->uvlinesize, s->uvlinesize,

                                 8 + 1, 8 + 1,

                                 uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, v_edge_pos >> 1);

        srcU = uvbuf;

        srcV = uvbuf + 16;

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

        if (v->rangeredfrm) {

            int i, j;

            uint8_t *src, *src2;

            src = srcY;

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

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

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

                src += s->linesize;

            }

            src  = srcU;

            src2 = srcV;

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

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

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

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

                }

                src  += s->uvlinesize;

                src2 += s->uvlinesize;

            }

        }

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

        if (use_ic) {

            int i, j;

            uint8_t *src, *src2;

            src = srcY;

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

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

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

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

                src += s->linesize;

            }

            src  = srcU;

            src2 = srcV;

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

                int f = v->field_mode ? v->ref_field_type[dir] : ((j + uvsrc_y) & 1);

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

                    src[i]  = lutuv[f][src[i]];

                    src2[i] = lutuv[f][src2[i]];

                }

                src  += s->uvlinesize;

                src2 += s->uvlinesize;

            }

        }

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

    }

    if (s->mspel) {

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

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

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

        srcY += s->linesize * 8;

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

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

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

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

        if (!v->rnd)

            s->hdsp.put_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);

        else

            s->hdsp.put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);

    }

    if (s->flags & CODEC_FLAG_GRAY) return;

    /* Chroma MC always uses qpel bilinear */

    uvmx = (uvmx & 3) << 1;

    uvmy = (uvmy & 3) << 1;

    if (!v->rnd) {

        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);

        h264chroma->put_h264_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);

    } else {

        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[1], srcU, s->uvlinesize, 8, uvmx, uvmy);

        v->vc1dsp.put_no_rnd_vc1_chroma_pixels_tab[0](s->dest[2], srcV, s->uvlinesize, 8, uvmx, uvmy);

    }

}


static inline void RENAME(yuy2ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width)

{

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

	asm volatile(

		"movq "MANGLE(bm01010101)", %%mm4\n\t"

		"mov %0, %%"REG_a"		\n\t"

		"1:				\n\t"

		"movq (%1, %%"REG_a",4), %%mm0	\n\t"

		"movq 8(%1, %%"REG_a",4), %%mm1	\n\t"

		"movq (%2, %%"REG_a",4), %%mm2	\n\t"

		"movq 8(%2, %%"REG_a",4), %%mm3	\n\t"

		PAVGB(%%mm2, %%mm0)

		PAVGB(%%mm3, %%mm1)

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

		"psrlw $8, %%mm1		\n\t"

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

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

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

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

		"packuswb %%mm0, %%mm0		\n\t"

		"packuswb %%mm1, %%mm1		\n\t"

		"movd %%mm0, (%4, %%"REG_a")	\n\t"

		"movd %%mm1, (%3, %%"REG_a")	\n\t"

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

		" js 1b				\n\t"

		: : "g" ((long)-width), "r" (src1+width*4), "r" (src2+width*4), "r" (dstU+width), "r" (dstV+width)

		: "%"REG_a

	);

#else

	int i;

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

	{

		dstU[i]= (src1[4*i + 1] + src2[4*i + 1])>>1;

		dstV[i]= (src1[4*i + 3] + src2[4*i + 3])>>1;

	}

#endif

}


static int mtv_read_header(AVFormatContext *s)

{

    MTVDemuxContext *mtv = s->priv_data;

    AVIOContext   *pb  = s->pb;

    AVStream        *st;

    unsigned int    audio_subsegments;

    avio_skip(pb, 3);

    mtv->file_size         = avio_rl32(pb);

    mtv->segments          = avio_rl32(pb);

    avio_skip(pb, 32);

    mtv->audio_identifier  = avio_rl24(pb);

    mtv->audio_br          = avio_rl16(pb);

    mtv->img_colorfmt      = avio_rl24(pb);

    mtv->img_bpp           = avio_r8(pb);

    mtv->img_width         = avio_rl16(pb);

    mtv->img_height        = avio_rl16(pb);

    mtv->img_segment_size  = avio_rl16(pb);

    /* Calculate width and height if missing from header */

    if(mtv->img_bpp>>3){

    if(!mtv->img_width && mtv->img_height)

        mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3)

                        / mtv->img_height;

    if(!mtv->img_height && mtv->img_width)

        mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3)

                        / mtv->img_width;

    }

    if(!mtv->img_height || !mtv->img_width || !mtv->img_segment_size){

        av_log(s, AV_LOG_ERROR, "width or height or segment_size is invalid and I cannot calculate them from other information\n");

        return AVERROR(EINVAL);

    }

    avio_skip(pb, 4);

    audio_subsegments = avio_rl16(pb);

    if (audio_subsegments == 0) {

        avpriv_request_sample(s, "MTV files without audio");

        return AVERROR_PATCHWELCOME;

    }

    mtv->full_segment_size =

        audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) +

        mtv->img_segment_size;

    mtv->video_fps         = (mtv->audio_br / 4) / audio_subsegments;

    // FIXME Add sanity check here

    // all systems go! init decoders

    // video - raw rgb565

    st = avformat_new_stream(s, NULL);

    if(!st)

        return AVERROR(ENOMEM);

    avpriv_set_pts_info(st, 64, 1, mtv->video_fps);

    st->codec->codec_type      = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id        = AV_CODEC_ID_RAWVIDEO;

    st->codec->pix_fmt         = AV_PIX_FMT_RGB565BE;

    st->codec->width           = mtv->img_width;

    st->codec->height          = mtv->img_height;

    st->codec->sample_rate     = mtv->video_fps;

    st->codec->extradata       = av_strdup("BottomUp");

    st->codec->extradata_size  = 9;

    // audio - mp3

    st = avformat_new_stream(s, NULL);

    if(!st)

        return AVERROR(ENOMEM);

    avpriv_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE);

    st->codec->codec_type      = AVMEDIA_TYPE_AUDIO;

    st->codec->codec_id        = AV_CODEC_ID_MP3;

    st->codec->bit_rate        = mtv->audio_br;

    st->need_parsing           = AVSTREAM_PARSE_FULL;

    // Jump over header

    if(avio_seek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE)

        return AVERROR(EIO);

    return 0;

}


static bool qht_insert__locked(struct qht *ht, struct qht_map *map,

                               struct qht_bucket *head, void *p, uint32_t hash,

                               bool *needs_resize)

{

    struct qht_bucket *b = head;

    struct qht_bucket *prev = NULL;

    struct qht_bucket *new = NULL;

    int i;

    do {

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

            if (b->pointers[i]) {

                if (unlikely(b->pointers[i] == p)) {

                    return false;

                }

            } else {

                goto found;

            }

        }

        prev = b;

        b = b->next;

    } while (b);

    b = qemu_memalign(QHT_BUCKET_ALIGN, sizeof(*b));

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

    new = b;

    i = 0;

    atomic_inc(&map->n_added_buckets);

    if (unlikely(qht_map_needs_resize(map)) && needs_resize) {

        *needs_resize = true;

    }

 found:

    /* found an empty key: acquire the seqlock and write */

    seqlock_write_begin(&head->sequence);

    if (new) {

        atomic_rcu_set(&prev->next, b);

    }

    b->hashes[i] = hash;

    /* smp_wmb() implicit in seqlock_write_begin.  */

    atomic_set(&b->pointers[i], p);

    seqlock_write_end(&head->sequence);

    return true;

}


static int copy_packet_data(AVPacket *pkt, AVPacket *src, int dup)

{

    pkt->data      = NULL;

    pkt->side_data = NULL;

    if (pkt->buf) {

        AVBufferRef *ref = av_buffer_ref(src->buf);

        if (!ref)

            return AVERROR(ENOMEM);

        pkt->buf  = ref;

        pkt->data = ref->data;

    } else {

        DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);

    }

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

    pkt->destruct = dummy_destruct_packet;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

    if (pkt->side_data_elems && dup)

        pkt->side_data = src->side_data;

    if (pkt->side_data_elems && !dup) {

        return av_copy_packet_side_data(pkt, src);

    }

    return 0;

failed_alloc:

    av_destruct_packet(pkt);

    return AVERROR(ENOMEM);

}


static void virtio_crypto_instance_init(Object *obj)

{

    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj);

    /*

     * The default config_size is sizeof(struct virtio_crypto_config).

     * Can be overriden with virtio_crypto_set_config_size.

     */

    vcrypto->config_size = sizeof(struct virtio_crypto_config);

    object_property_add_link(obj, "cryptodev",

                             TYPE_CRYPTODEV_BACKEND,

                             (Object **)&vcrypto->conf.cryptodev,

                             virtio_crypto_check_cryptodev_is_used,

                             OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);

}


int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,

			     int mmu_idx, int is_softmmu)

{

    target_ulong physical;

    int prot, ret, access_type;

    access_type = ACCESS_INT;

    ret =

	get_physical_address(env, &physical, &prot, address, rw,

			     access_type);

    if (ret != MMU_OK) {

	env->tea = address;

	switch (ret) {

	case MMU_ITLB_MISS:

	case MMU_DTLB_MISS_READ:

	    env->exception_index = 0x040;

	    break;

	case MMU_DTLB_MULTIPLE:

	case MMU_ITLB_MULTIPLE:

	    env->exception_index = 0x140;

	    break;

	case MMU_ITLB_VIOLATION:

	    env->exception_index = 0x0a0;

	    break;

	case MMU_DTLB_MISS_WRITE:

	    env->exception_index = 0x060;

	    break;

	case MMU_DTLB_INITIAL_WRITE:

	    env->exception_index = 0x080;

	    break;

	case MMU_DTLB_VIOLATION_READ:

	    env->exception_index = 0x0a0;

	    break;

	case MMU_DTLB_VIOLATION_WRITE:

	    env->exception_index = 0x0c0;

	    break;

	case MMU_IADDR_ERROR:

	case MMU_DADDR_ERROR_READ:

	    env->exception_index = 0x0c0;

	    break;

	case MMU_DADDR_ERROR_WRITE:

	    env->exception_index = 0x100;

	    break;

	default:

	    assert(0);

	}

	return 1;

    }

    address &= TARGET_PAGE_MASK;

    physical &= TARGET_PAGE_MASK;

    return tlb_set_page(env, address, physical, prot, mmu_idx, is_softmmu);

}


static int virtio_blk_device_exit(DeviceState *dev)

{

    VirtIODevice *vdev = VIRTIO_DEVICE(dev);

    VirtIOBlock *s = VIRTIO_BLK(dev);

#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE

    remove_migration_state_change_notifier(&s->migration_state_notifier);

    virtio_blk_data_plane_destroy(s->dataplane);

    s->dataplane = NULL;

#endif

    qemu_del_vm_change_state_handler(s->change);

    unregister_savevm(dev, "virtio-blk", s);

    blockdev_mark_auto_del(s->bs);

    virtio_cleanup(vdev);

    return 0;

}


static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,

                             void *opaque, Error **errp)

{

    uint64_t value;

    MemoryRegion *mr;

    PCDIMMDevice *dimm = PC_DIMM(obj);

    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);

    mr = ddc->get_memory_region(dimm);

    value = memory_region_size(mr);

    visit_type_uint64(v, name, &value, errp);

}


target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
                             uint32_t token, uint32_t nargs, target_ulong args,
                             uint32_t nret, target_ulong rets)
{
    if ((token >= TOKEN_BASE)
        && ((token - TOKEN_BASE) < TOKEN_MAX)) {
        struct rtas_call *call = rtas_table + (token - TOKEN_BASE);
        if (call->fn) {
            call->fn(spapr, token, nargs, args, nret, rets);
    hcall_dprintf("Unknown RTAS token 0x%x\n", token);
    rtas_st(rets, 0, -3);
    return H_PARAMETER;


static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)

{

    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);

    SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);

    int ret;

    if (cmd[0] != REQUEST_SENSE && req->lun != s->qdev.lun) {

        DPRINTF("Unimplemented LUN %d\n", req->lun);

        scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));

        scsi_req_complete(&r->req, CHECK_CONDITION);

        return 0;

    }

    if (-1 == scsi_req_parse(&r->req, cmd)) {

        BADF("Unsupported command length, command %x\n", cmd[0]);

        scsi_command_complete(r, -EINVAL);

        return 0;

    }

    scsi_req_fixup(&r->req);

    DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,

            r->req.cmd.xfer, cmd[0]);

#ifdef DEBUG_SCSI

    {

        int i;

        for (i = 1; i < r->req.cmd.len; i++) {

            printf(" 0x%02x", cmd[i]);

        }

        printf("\n");

    }

#endif

    if (r->req.cmd.xfer == 0) {

        if (r->buf != NULL)

            qemu_free(r->buf);

        r->buflen = 0;

        r->buf = NULL;

        ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);

        if (ret < 0) {

            scsi_command_complete(r, ret);

            return 0;

        }

        return 0;

    }

    if (r->buflen != r->req.cmd.xfer) {

        if (r->buf != NULL)

            qemu_free(r->buf);

        r->buf = qemu_malloc(r->req.cmd.xfer);

        r->buflen = r->req.cmd.xfer;

    }

    memset(r->buf, 0, r->buflen);

    r->len = r->req.cmd.xfer;

    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {

        r->len = 0;

        return -r->req.cmd.xfer;

    } else {

        return r->req.cmd.xfer;

    }

}


void ip6_input(struct mbuf *m)

{

    struct ip6 *ip6;

    DEBUG_CALL("ip6_input");

    DEBUG_ARG("m = %lx", (long)m);

    DEBUG_ARG("m_len = %d", m->m_len);

    if (m->m_len < sizeof(struct ip6)) {

        goto bad;

    }

    ip6 = mtod(m, struct ip6 *);

    if (ip6->ip_v != IP6VERSION) {

        goto bad;

    }

    /* check ip_ttl for a correct ICMP reply */

    if (ip6->ip_hl == 0) {

        /*icmp_send_error(m, ICMP_TIMXCEED,ICMP_TIMXCEED_INTRANS, 0,"ttl");*/

        goto bad;

    }

    /*

     * Switch out to protocol's input routine.

     */

    switch (ip6->ip_nh) {

    case IPPROTO_TCP:

        /*tcp_input(m, hlen, (struct socket *)NULL);*/

        break;

    case IPPROTO_UDP:

        /*udp_input(m, hlen);*/

        break;

    case IPPROTO_ICMPV6:

        icmp6_input(m);

        break;

    default:

        m_free(m);

    }

    return;

bad:

    m_free(m);

}


void fork_start(void)

{

    pthread_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);

    pthread_mutex_lock(&exclusive_lock);

    mmap_fork_start();

}


static int write_dump_pages(DumpState *s)

{

    int ret = 0;

    DataCache page_desc, page_data;

    size_t len_buf_out, size_out;

#ifdef CONFIG_LZO

    lzo_bytep wrkmem = NULL;

#endif

    uint8_t *buf_out = NULL;

    off_t offset_desc, offset_data;

    PageDescriptor pd, pd_zero;

    uint8_t *buf;

    int endian = s->dump_info.d_endian;

    GuestPhysBlock *block_iter = NULL;

    uint64_t pfn_iter;

    /* get offset of page_desc and page_data in dump file */

    offset_desc = s->offset_page;

    offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;

    prepare_data_cache(&page_desc, s, offset_desc);

    prepare_data_cache(&page_data, s, offset_data);

    /* prepare buffer to store compressed data */

    len_buf_out = get_len_buf_out(s->page_size, s->flag_compress);

    if (len_buf_out == 0) {

        dump_error(s, "dump: failed to get length of output buffer.\n");

        goto out;

    }

#ifdef CONFIG_LZO

    wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);

#endif

    buf_out = g_malloc(len_buf_out);

    /*

     * init zero page's page_desc and page_data, because every zero page

     * uses the same page_data

     */

    pd_zero.size = cpu_convert_to_target32(s->page_size, endian);

    pd_zero.flags = cpu_convert_to_target32(0, endian);

    pd_zero.offset = cpu_convert_to_target64(offset_data, endian);

    pd_zero.page_flags = cpu_convert_to_target64(0, endian);

    buf = g_malloc0(s->page_size);

    ret = write_cache(&page_data, buf, s->page_size, false);

    g_free(buf);

    if (ret < 0) {

        dump_error(s, "dump: failed to write page data(zero page).\n");

        goto out;

    }

    offset_data += s->page_size;

    /*

     * dump memory to vmcore page by page. zero page will all be resided in the

     * first page of page section

     */

    while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {

        /* check zero page */

        if (is_zero_page(buf, s->page_size)) {

            ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),

                              false);

            if (ret < 0) {

                dump_error(s, "dump: failed to write page desc.\n");

                goto out;

            }

        } else {

            /*

             * not zero page, then:

             * 1. compress the page

             * 2. write the compressed page into the cache of page_data

             * 3. get page desc of the compressed page and write it into the

             *    cache of page_desc

             *

             * only one compression format will be used here, for

             * s->flag_compress is set. But when compression fails to work,

             * we fall back to save in plaintext.

             */

             size_out = len_buf_out;

             if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&

                    (compress2(buf_out, (uLongf *)&size_out, buf, s->page_size,

                    Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) {

                pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,

                                                   endian);

                pd.size  = cpu_convert_to_target32(size_out, endian);

                ret = write_cache(&page_data, buf_out, size_out, false);

                if (ret < 0) {

                    dump_error(s, "dump: failed to write page data.\n");

                    goto out;

                }

#ifdef CONFIG_LZO

            } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&

                    (lzo1x_1_compress(buf, s->page_size, buf_out,

                    (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&

                    (size_out < s->page_size)) {

                pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,

                                                   endian);

                pd.size  = cpu_convert_to_target32(size_out, endian);

                ret = write_cache(&page_data, buf_out, size_out, false);

                if (ret < 0) {

                    dump_error(s, "dump: failed to write page data.\n");

                    goto out;

                }

#endif

#ifdef CONFIG_SNAPPY

            } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&

                    (snappy_compress((char *)buf, s->page_size,

                    (char *)buf_out, &size_out) == SNAPPY_OK) &&

                    (size_out < s->page_size)) {

                pd.flags = cpu_convert_to_target32(

                                        DUMP_DH_COMPRESSED_SNAPPY, endian);

                pd.size  = cpu_convert_to_target32(size_out, endian);

                ret = write_cache(&page_data, buf_out, size_out, false);

                if (ret < 0) {

                    dump_error(s, "dump: failed to write page data.\n");

                    goto out;

                }

#endif

            } else {

                /*

                 * fall back to save in plaintext, size_out should be

                 * assigned to s->page_size

                 */

                pd.flags = cpu_convert_to_target32(0, endian);

                size_out = s->page_size;

                pd.size = cpu_convert_to_target32(size_out, endian);

                ret = write_cache(&page_data, buf, s->page_size, false);

                if (ret < 0) {

                    dump_error(s, "dump: failed to write page data.\n");

                    goto out;

                }

            }

            /* get and write page desc here */

            pd.page_flags = cpu_convert_to_target64(0, endian);

            pd.offset = cpu_convert_to_target64(offset_data, endian);

            offset_data += size_out;

            ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);

            if (ret < 0) {

                dump_error(s, "dump: failed to write page desc.\n");

                goto out;

            }

        }

    }

    ret = write_cache(&page_desc, NULL, 0, true);

    if (ret < 0) {

        dump_error(s, "dump: failed to sync cache for page_desc.\n");

        goto out;

    }

    ret = write_cache(&page_data, NULL, 0, true);

    if (ret < 0) {

        dump_error(s, "dump: failed to sync cache for page_data.\n");

        goto out;

    }

out:

    free_data_cache(&page_desc);

    free_data_cache(&page_data);

#ifdef CONFIG_LZO

    g_free(wrkmem);

#endif

    g_free(buf_out);

    return ret;

}


static void do_ext_interrupt(CPUS390XState *env)

{

    S390CPU *cpu = s390_env_get_cpu(env);

    uint64_t mask, addr;

    LowCore *lowcore;

    ExtQueue *q;

    if (!(env->psw.mask & PSW_MASK_EXT)) {

        cpu_abort(CPU(cpu), "Ext int w/o ext mask\n");

    }

    lowcore = cpu_map_lowcore(env);

    if (env->pending_int & INTERRUPT_EXT_CLOCK_COMPARATOR) {

        lowcore->ext_int_code = cpu_to_be16(EXT_CLOCK_COMP);

        lowcore->cpu_addr = 0;

        env->pending_int &= ~INTERRUPT_EXT_CLOCK_COMPARATOR;

    } else if (env->pending_int & INTERRUPT_EXT_CPU_TIMER) {

        lowcore->ext_int_code = cpu_to_be16(EXT_CPU_TIMER);

        lowcore->cpu_addr = 0;

        env->pending_int &= ~INTERRUPT_EXT_CPU_TIMER;

    } else if (env->pending_int & INTERRUPT_EXT_SERVICE) {

        g_assert(env->ext_index >= 0);

        /*

         * FIXME: floating IRQs should be considered by all CPUs and

         *        shuld not get cleared by CPU reset.

         */

        q = &env->ext_queue[env->ext_index];

        lowcore->ext_int_code = cpu_to_be16(q->code);

        lowcore->ext_params = cpu_to_be32(q->param);

        lowcore->ext_params2 = cpu_to_be64(q->param64);

        lowcore->cpu_addr = cpu_to_be16(env->core_id | VIRTIO_SUBCODE_64);

        env->ext_index--;

        if (env->ext_index == -1) {

            env->pending_int &= ~INTERRUPT_EXT_SERVICE;

        }

    } else {

        g_assert_not_reached();

    }

    mask = be64_to_cpu(lowcore->external_new_psw.mask);

    addr = be64_to_cpu(lowcore->external_new_psw.addr);

    lowcore->external_old_psw.mask = cpu_to_be64(get_psw_mask(env));

    lowcore->external_old_psw.addr = cpu_to_be64(env->psw.addr);

    cpu_unmap_lowcore(lowcore);

    DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,

            env->psw.mask, env->psw.addr);

    load_psw(env, mask, addr);

}


static void verdex_init(MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    PXA2xxState *cpu;

    DriveInfo *dinfo;

    int be;

    MemoryRegion *address_space_mem = get_system_memory();

    uint32_t verdex_rom = 0x02000000;

    uint32_t verdex_ram = 0x10000000;

    cpu = pxa270_init(address_space_mem, verdex_ram, cpu_model ?: "pxa270-c0");

    dinfo = drive_get(IF_PFLASH, 0, 0);

    if (!dinfo && !qtest_enabled()) {

        fprintf(stderr, "A flash image must be given with the "

                "'pflash' parameter\n");

        exit(1);

    }

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    if (!pflash_cfi01_register(0x00000000, NULL, "verdex.rom", verdex_rom,

                               dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,

                               sector_len, verdex_rom / sector_len,

                               2, 0, 0, 0, 0, be)) {

        fprintf(stderr, "qemu: Error registering flash memory.\n");

        exit(1);

    }

    /* Interrupt line of NIC is connected to GPIO line 99 */

    smc91c111_init(&nd_table[0], 0x04000300,

                    qdev_get_gpio_in(cpu->gpio, 99));

}


static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    BDRVBochsState *s = bs->opaque;
    uint32_t i;
    struct bochs_header bochs;
    int ret;
    bs->read_only = 1; // no write support yet
    ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
    if (ret < 0) {
        return ret;
    if (strcmp(bochs.magic, HEADER_MAGIC) ||
        strcmp(bochs.type, REDOLOG_TYPE) ||
        strcmp(bochs.subtype, GROWING_TYPE) ||
	((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
	(le32_to_cpu(bochs.version) != HEADER_V1))) {
        error_setg(errp, "Image not in Bochs format");
        return -EINVAL;
    if (le32_to_cpu(bochs.version) == HEADER_V1) {
        bs->total_sectors = le64_to_cpu(bochs.extra.redolog_v1.disk) / 512;
    } else {
        bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
    s->catalog_size = le32_to_cpu(bochs.catalog);
    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
    ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
                     s->catalog_size * 4);
    if (ret < 0) {
        goto fail;
    for (i = 0; i < s->catalog_size; i++)
	le32_to_cpus(&s->catalog_bitmap[i]);
    s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);
    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.bitmap) - 1) / 512;
    s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;
    s->extent_size = le32_to_cpu(bochs.extent);
    if (s->catalog_size < bs->total_sectors / s->extent_size) {
        error_setg(errp, "Catalog size is too small for this disk size");
        ret = -EINVAL;
        goto fail;
    qemu_co_mutex_init(&s->lock);
    return 0;
fail:
    g_free(s->catalog_bitmap);
    return ret;


offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)

{

    offset_t offset1;

    offset_t pos= s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));

    if (whence != SEEK_CUR && whence != SEEK_SET)

        return -EINVAL;

    if (whence == SEEK_CUR) {

        offset1 = pos + (s->buf_ptr - s->buffer);

        if (offset == 0)

            return offset1;

        offset += offset1;

    }

    offset1 = offset - pos;

    if (!s->must_flush &&

        offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {

        /* can do the seek inside the buffer */

        s->buf_ptr = s->buffer + offset1;

    } else {

        if (!s->seek)

            return -EPIPE;

#ifdef CONFIG_MUXERS

        if (s->write_flag) {

            flush_buffer(s);

            s->must_flush = 1;

        } else

#endif //CONFIG_MUXERS

        {

            s->buf_end = s->buffer;

        }

        s->buf_ptr = s->buffer;

        if (s->seek(s->opaque, offset, SEEK_SET) == (offset_t)-EPIPE)

            return -EPIPE;

        s->pos = offset;

    }

    s->eof_reached = 0;

    return offset;

}


void ppc_translate_init(void)

{

    int i;

    char* p;

    size_t cpu_reg_names_size;

    static int done_init = 0;

    if (done_init)

        return;

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

    p = cpu_reg_names;

    cpu_reg_names_size = sizeof(cpu_reg_names);

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

        snprintf(p, cpu_reg_names_size, "crf%d", i);

        cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,

                                            offsetof(CPUState, crf[i]), p);

        p += 5;

        cpu_reg_names_size -= 5;

    }

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

        snprintf(p, cpu_reg_names_size, "r%d", i);

        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,

                                        offsetof(CPUState, gpr[i]), p);

        p += (i < 10) ? 3 : 4;

        cpu_reg_names_size -= (i < 10) ? 3 : 4;

#if !defined(TARGET_PPC64)

        snprintf(p, cpu_reg_names_size, "r%dH", i);

        cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUState, gprh[i]), p);

        p += (i < 10) ? 4 : 5;

        cpu_reg_names_size -= (i < 10) ? 4 : 5;

#endif

        snprintf(p, cpu_reg_names_size, "fp%d", i);

        cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,

                                            offsetof(CPUState, fpr[i]), p);

        p += (i < 10) ? 4 : 5;

        cpu_reg_names_size -= (i < 10) ? 4 : 5;

        snprintf(p, cpu_reg_names_size, "avr%dH", i);

#ifdef HOST_WORDS_BIGENDIAN

        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUState, avr[i].u64[0]), p);

#else

        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUState, avr[i].u64[1]), p);

#endif

        p += (i < 10) ? 6 : 7;

        cpu_reg_names_size -= (i < 10) ? 6 : 7;

        snprintf(p, cpu_reg_names_size, "avr%dL", i);

#ifdef HOST_WORDS_BIGENDIAN

        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUState, avr[i].u64[1]), p);

#else

        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,

                                             offsetof(CPUState, avr[i].u64[0]), p);

#endif

        p += (i < 10) ? 6 : 7;

        cpu_reg_names_size -= (i < 10) ? 6 : 7;

    }

    cpu_nip = tcg_global_mem_new(TCG_AREG0,

                                 offsetof(CPUState, nip), "nip");

    cpu_msr = tcg_global_mem_new(TCG_AREG0,

                                 offsetof(CPUState, msr), "msr");

    cpu_ctr = tcg_global_mem_new(TCG_AREG0,

                                 offsetof(CPUState, ctr), "ctr");

    cpu_lr = tcg_global_mem_new(TCG_AREG0,

                                offsetof(CPUState, lr), "lr");

    cpu_xer = tcg_global_mem_new(TCG_AREG0,

                                 offsetof(CPUState, xer), "xer");

    cpu_reserve = tcg_global_mem_new(TCG_AREG0,

                                     offsetof(CPUState, reserve), "reserve");

    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,

                                       offsetof(CPUState, fpscr), "fpscr");

    cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,

                                             offsetof(CPUState, access_type), "access_type");

    /* register helpers */

#define GEN_HELPER 2

#include "helper.h"

    done_init = 1;

}


static void gen_mtfsfi(DisasContext *ctx)

{

    int bf, sh;

    TCGv_i64 t0;

    TCGv_i32 t1;

    if (unlikely(!ctx->fpu_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_FPU);

        return;

    }

    bf = crbD(ctx->opcode) >> 2;

    sh = 7 - bf;

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

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

    gen_reset_fpstatus();

    t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));

    t1 = tcg_const_i32(1 << sh);

    gen_helper_store_fpscr(cpu_env, t0, t1);

    tcg_temp_free_i64(t0);

    tcg_temp_free_i32(t1);

    if (unlikely(Rc(ctx->opcode) != 0)) {

        tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);

        tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);

    }

    /* We can raise a differed exception */

    gen_helper_float_check_status(cpu_env);

}


void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp)

{

    int i;

    size_t pagesize = getpagesize();

    memory = (memory + pagesize - 1) & -pagesize;

    for (i = 0; i < memory / pagesize; i++) {

        memset(area + pagesize * i, 0, 1);

    }

}


static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)

{

    CuvidContext *ctx = avctx->priv_data;

    AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;

    AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;

    CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;

    AVFrame *frame = data;

    CUVIDSOURCEDATAPACKET cupkt;

    AVPacket filter_packet = { 0 };

    AVPacket filtered_packet = { 0 };

    CUdeviceptr mapped_frame = 0;

    int ret = 0, eret = 0;

    if (ctx->bsf && avpkt->size) {

        if ((ret = av_packet_ref(&filter_packet, avpkt)) < 0) {

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

            return ret;

        }

        if ((ret = av_bsf_send_packet(ctx->bsf, &filter_packet)) < 0) {

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

            av_packet_unref(&filter_packet);

            return ret;

        }

        if ((ret = av_bsf_receive_packet(ctx->bsf, &filtered_packet)) < 0) {

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

            return ret;

        }

        avpkt = &filtered_packet;

    }

    ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));

    if (ret < 0) {

        av_packet_unref(&filtered_packet);

        return ret;

    }

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

    if (avpkt->size) {

        cupkt.payload_size = avpkt->size;

        cupkt.payload = avpkt->data;

        if (avpkt->pts != AV_NOPTS_VALUE) {

            cupkt.flags = CUVID_PKT_TIMESTAMP;

            if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)

                cupkt.timestamp = av_rescale_q(avpkt->pts, avctx->pkt_timebase, (AVRational){1, 10000000});

            else

                cupkt.timestamp = avpkt->pts;

        }

    } else {

        cupkt.flags = CUVID_PKT_ENDOFSTREAM;

    }

    ret = CHECK_CU(cuvidParseVideoData(ctx->cuparser, &cupkt));

    av_packet_unref(&filtered_packet);

    if (ret < 0) {

        if (ctx->internal_error)

            ret = ctx->internal_error;

        goto error;

    }

    if (av_fifo_size(ctx->frame_queue)) {

        CUVIDPARSERDISPINFO dispinfo;

        CUVIDPROCPARAMS params;

        unsigned int pitch = 0;

        int offset = 0;

        int i;

        av_fifo_generic_read(ctx->frame_queue, &dispinfo, sizeof(CUVIDPARSERDISPINFO), NULL);

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

        params.progressive_frame = dispinfo.progressive_frame;

        params.second_field = 0;

        params.top_field_first = dispinfo.top_field_first;

        ret = CHECK_CU(cuvidMapVideoFrame(ctx->cudecoder, dispinfo.picture_index, &mapped_frame, &pitch, &params));

        if (ret < 0)

            goto error;

        if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {

            ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0);

            if (ret < 0) {

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

                goto error;

            }

            ret = ff_decode_frame_props(avctx, frame);

            if (ret < 0) {

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

                goto error;

            }

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

                CUDA_MEMCPY2D cpy = {

                    .srcMemoryType = CU_MEMORYTYPE_DEVICE,

                    .dstMemoryType = CU_MEMORYTYPE_DEVICE,

                    .srcDevice     = mapped_frame,

                    .dstDevice     = (CUdeviceptr)frame->data[i],

                    .srcPitch      = pitch,

                    .dstPitch      = frame->linesize[i],

                    .srcY          = offset,

                    .WidthInBytes  = FFMIN(pitch, frame->linesize[i]),

                    .Height        = avctx->coded_height >> (i ? 1 : 0),

                };

                ret = CHECK_CU(cuMemcpy2D(&cpy));

                if (ret < 0)

                    goto error;

                offset += avctx->coded_height;

            }

        } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {

            AVFrame *tmp_frame = av_frame_alloc();

            if (!tmp_frame) {

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

                ret = AVERROR(ENOMEM);

                goto error;

            }

            tmp_frame->format        = AV_PIX_FMT_CUDA;

            tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe);

            tmp_frame->data[0]       = (uint8_t*)mapped_frame;

            tmp_frame->linesize[0]   = pitch;

            tmp_frame->data[1]       = (uint8_t*)(mapped_frame + avctx->coded_height * pitch);

            tmp_frame->linesize[1]   = pitch;

            tmp_frame->width         = avctx->width;

            tmp_frame->height        = avctx->height;

            ret = ff_get_buffer(avctx, frame, 0);

            if (ret < 0) {

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

                av_frame_free(&tmp_frame);

                goto error;

            }

            ret = av_hwframe_transfer_data(frame, tmp_frame, 0);

            if (ret) {

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

                av_frame_free(&tmp_frame);

                goto error;

            }

            av_frame_free(&tmp_frame);

        } else {

            ret = AVERROR_BUG;

            goto error;

        }

        frame->width = avctx->width;

        frame->height = avctx->height;

        if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)

            frame->pts = av_rescale_q(dispinfo.timestamp, (AVRational){1, 10000000}, avctx->pkt_timebase);

        else

            frame->pts = dispinfo.timestamp;

        /* CUVIDs opaque reordering breaks the internal pkt logic.

         * So set pkt_pts and clear all the other pkt_ fields.

         */

        frame->pkt_pts = frame->pts;

        av_frame_set_pkt_pos(frame, -1);

        av_frame_set_pkt_duration(frame, 0);

        av_frame_set_pkt_size(frame, -1);

        frame->interlaced_frame = !dispinfo.progressive_frame;

        if (!dispinfo.progressive_frame)

            frame->top_field_first = dispinfo.top_field_first;

        *got_frame = 1;

    } else {

        *got_frame = 0;

    }

error:

    if (mapped_frame)

        eret = CHECK_CU(cuvidUnmapVideoFrame(ctx->cudecoder, mapped_frame));

    eret = CHECK_CU(cuCtxPopCurrent(&dummy));

    if (eret < 0)

        return eret;

    else

        return ret;

}


static void hotplug(void)

{

    qtest_start("-device virtio-net-pci");

    qpci_plug_device_test("virtio-net-pci", "net1", PCI_SLOT_HP, NULL);

    qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);

    test_end();

}


static void ide_identify(IDEState *s)

{

    uint16_t *p;

    unsigned int oldsize;

    memset(s->io_buffer, 0, 512);

    p = (uint16_t *)s->io_buffer;

    stw(p + 0, 0x0040);

    stw(p + 1, s->cylinders);

    stw(p + 3, s->heads);

    stw(p + 4, 512 * s->sectors); /* sectors */

    stw(p + 5, 512); /* sector size */

    stw(p + 6, s->sectors);

    stw(p + 20, 3); /* buffer type */

    stw(p + 21, 512); /* cache size in sectors */

    stw(p + 22, 4); /* ecc bytes */

    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40);

#if MAX_MULT_SECTORS > 1

    stw(p + 47, MAX_MULT_SECTORS);

#endif

    stw(p + 48, 1); /* dword I/O */

    stw(p + 49, 1 << 9); /* LBA supported, no DMA */

    stw(p + 51, 0x200); /* PIO transfer cycle */

    stw(p + 52, 0x200); /* DMA transfer cycle */

    stw(p + 54, s->cylinders);

    stw(p + 55, s->heads);

    stw(p + 56, s->sectors);

    oldsize = s->cylinders * s->heads * s->sectors;

    stw(p + 57, oldsize);

    stw(p + 58, oldsize >> 16);

    if (s->mult_sectors)

        stw(p + 59, 0x100 | s->mult_sectors);

    stw(p + 60, s->nb_sectors);

    stw(p + 61, s->nb_sectors >> 16);

    stw(p + 80, (1 << 1) | (1 << 2));

    stw(p + 82, (1 << 14));

    stw(p + 83, (1 << 14));

    stw(p + 84, (1 << 14));

    stw(p + 85, (1 << 14));

    stw(p + 86, 0);

    stw(p + 87, (1 << 14));

}


static int encode_apng(AVCodecContext *avctx, AVPacket *pkt,

                       const AVFrame *pict, int *got_packet)

{

    PNGEncContext *s = avctx->priv_data;

    int ret;

    int enc_row_size;

    size_t max_packet_size;

    APNGFctlChunk fctl_chunk = {0};

    if (pict && avctx->codec_id == AV_CODEC_ID_APNG && s->color_type == PNG_COLOR_TYPE_PALETTE) {

        uint32_t checksum = ~av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), ~0U, pict->data[1], 256 * sizeof(uint32_t));

        if (avctx->frame_number == 0) {

            s->palette_checksum = checksum;

        } else if (checksum != s->palette_checksum) {

            av_log(avctx, AV_LOG_ERROR,

                   "Input contains more than one unique palette. APNG does not support multiple palettes.\n");

            return -1;

        }

    }

    enc_row_size    = deflateBound(&s->zstream, (avctx->width * s->bits_per_pixel + 7) >> 3);

    max_packet_size =

        AV_INPUT_BUFFER_MIN_SIZE + // headers

        avctx->height * (

            enc_row_size +

            (4 + 12) * (((int64_t)enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) // fdAT * ceil(enc_row_size / IOBUF_SIZE)

        );

    if (max_packet_size > INT_MAX)

        return AVERROR(ENOMEM);

    if (avctx->frame_number == 0) {

        if (!pict)

            return AVERROR(EINVAL);

        s->bytestream = avctx->extradata = av_malloc(FF_MIN_BUFFER_SIZE);

        if (!avctx->extradata)

            return AVERROR(ENOMEM);

        ret = encode_headers(avctx, pict);

        if (ret < 0)

            return ret;

        avctx->extradata_size = s->bytestream - avctx->extradata;

        s->last_frame_packet = av_malloc(max_packet_size);

        if (!s->last_frame_packet)

            return AVERROR(ENOMEM);

    } else if (s->last_frame) {

        ret = ff_alloc_packet2(avctx, pkt, max_packet_size, 0);

        if (ret < 0)

            return ret;

        memcpy(pkt->data, s->last_frame_packet, s->last_frame_packet_size);

        pkt->size = s->last_frame_packet_size;

        pkt->pts = pkt->dts = s->last_frame->pts;

    }

    if (pict) {

        s->bytestream_start =

        s->bytestream       = s->last_frame_packet;

        s->bytestream_end   = s->bytestream + max_packet_size;

        // We're encoding the frame first, so we have to do a bit of shuffling around

        // to have the image data write to the correct place in the buffer

        fctl_chunk.sequence_number = s->sequence_number;

        ++s->sequence_number;

        s->bytestream += 26 + 12;

        ret = apng_encode_frame(avctx, pict, &fctl_chunk, &s->last_frame_fctl);

        if (ret < 0)

            return ret;

        fctl_chunk.delay_num = 0; // delay filled in during muxing

        fctl_chunk.delay_den = 0;

    } else {

        s->last_frame_fctl.dispose_op = APNG_DISPOSE_OP_NONE;

    }

    if (s->last_frame) {

        uint8_t* last_fctl_chunk_start = pkt->data;

        uint8_t buf[26];

        AV_WB32(buf + 0, s->last_frame_fctl.sequence_number);

        AV_WB32(buf + 4, s->last_frame_fctl.width);

        AV_WB32(buf + 8, s->last_frame_fctl.height);

        AV_WB32(buf + 12, s->last_frame_fctl.x_offset);

        AV_WB32(buf + 16, s->last_frame_fctl.y_offset);

        AV_WB16(buf + 20, s->last_frame_fctl.delay_num);

        AV_WB16(buf + 22, s->last_frame_fctl.delay_den);

        buf[24] = s->last_frame_fctl.dispose_op;

        buf[25] = s->last_frame_fctl.blend_op;

        png_write_chunk(&last_fctl_chunk_start, MKTAG('f', 'c', 'T', 'L'), buf, 26);

        *got_packet = 1;

    }

    if (pict) {

        if (!s->last_frame) {

            s->last_frame = av_frame_alloc();

            if (!s->last_frame)

                return AVERROR(ENOMEM);

        } else if (s->last_frame_fctl.dispose_op != APNG_DISPOSE_OP_PREVIOUS) {

            if (!s->prev_frame) {

                s->prev_frame = av_frame_alloc();

                if (!s->prev_frame)

                    return AVERROR(ENOMEM);

                s->prev_frame->format = pict->format;

                s->prev_frame->width = pict->width;

                s->prev_frame->height = pict->height;

                if ((ret = av_frame_get_buffer(s->prev_frame, 32)) < 0)

                    return ret;

            }

            // Do disposal, but not blending

            memcpy(s->prev_frame->data[0], s->last_frame->data[0],

                   s->last_frame->linesize[0] * s->last_frame->height);

            if (s->last_frame_fctl.dispose_op == APNG_DISPOSE_OP_BACKGROUND) {

                uint32_t y;

                uint8_t bpp = (s->bits_per_pixel + 7) >> 3;

                for (y = s->last_frame_fctl.y_offset; y < s->last_frame_fctl.y_offset + s->last_frame_fctl.height; ++y) {

                    size_t row_start = s->last_frame->linesize[0] * y + bpp * s->last_frame_fctl.x_offset;

                    memset(s->prev_frame->data[0] + row_start, 0, bpp * s->last_frame_fctl.width);

                }

            }

        }

        av_frame_unref(s->last_frame);

        ret = av_frame_ref(s->last_frame, (AVFrame*)pict);

        if (ret < 0)

            return ret;

        s->last_frame_fctl = fctl_chunk;

        s->last_frame_packet_size = s->bytestream - s->bytestream_start;

    } else {

        av_frame_free(&s->last_frame);

    }

    return 0;

}


BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,

                                 QEMUIOVector *qiov, int nb_sectors,

                                 BlockDriverCompletionFunc *cb, void *opaque)

{

    BlockDriver *drv = bs->drv;

    BlockDriverAIOCB *ret;

    trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);

    if (!drv)

        return NULL;

    if (bdrv_check_request(bs, sector_num, nb_sectors))

        return NULL;

    ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,

                              cb, opaque);

    if (ret) {

	/* Update stats even though technically transfer has not happened. */

	bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;

	bs->rd_ops ++;

    }

    return ret;

}


static void migrate_set_downtime(QTestState *who, const char *value)

{

    QDict *rsp;

    gchar *cmd;

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

                          "'arguments': { 'value': %s } }", value);

    rsp = qtest_qmp(who, cmd);

    g_free(cmd);

    g_assert(qdict_haskey(rsp, "return"));

    QDECREF(rsp);

}


target_ulong do_arm_semihosting(CPUARMState *env)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    CPUState *cs = CPU(cpu);

    target_ulong args;

    target_ulong arg0, arg1, arg2, arg3;

    char * s;

    int nr;

    uint32_t ret;

    uint32_t len;

#ifdef CONFIG_USER_ONLY

    TaskState *ts = cs->opaque;

#else

    CPUARMState *ts = env;

#endif

    if (is_a64(env)) {

        /* Note that the syscall number is in W0, not X0 */

        nr = env->xregs[0] & 0xffffffffU;

        args = env->xregs[1];

    } else {

        nr = env->regs[0];

        args = env->regs[1];

    }

    switch (nr) {

    case TARGET_SYS_OPEN:

        GET_ARG(0);

        GET_ARG(1);

        GET_ARG(2);

        s = lock_user_string(arg0);

        if (!s) {

            /* FIXME - should this error code be -TARGET_EFAULT ? */

            return (uint32_t)-1;

        }

        if (arg1 >= 12) {

            unlock_user(s, arg0, 0);

            return (uint32_t)-1;

        }

        if (strcmp(s, ":tt") == 0) {

            int result_fileno = arg1 < 4 ? STDIN_FILENO : STDOUT_FILENO;

            unlock_user(s, arg0, 0);

            return result_fileno;

        }

        if (use_gdb_syscalls()) {

            ret = arm_gdb_syscall(cpu, arm_semi_cb, "open,%s,%x,1a4", arg0,

                                  (int)arg2+1, gdb_open_modeflags[arg1]);

        } else {

            ret = set_swi_errno(ts, open(s, open_modeflags[arg1], 0644));

        }

        unlock_user(s, arg0, 0);

        return ret;

    case TARGET_SYS_CLOSE:

        GET_ARG(0);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "close,%x", arg0);

        } else {

            return set_swi_errno(ts, close(arg0));

        }

    case TARGET_SYS_WRITEC:

        {

          char c;

          if (get_user_u8(c, args))

              /* FIXME - should this error code be -TARGET_EFAULT ? */

              return (uint32_t)-1;

          /* Write to debug console.  stderr is near enough.  */

          if (use_gdb_syscalls()) {

                return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,1", args);

          } else {

                return write(STDERR_FILENO, &c, 1);

          }

        }

    case TARGET_SYS_WRITE0:

        if (!(s = lock_user_string(args)))

            /* FIXME - should this error code be -TARGET_EFAULT ? */

            return (uint32_t)-1;

        len = strlen(s);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "write,2,%x,%x",

                                   args, len);

        } else {

            ret = write(STDERR_FILENO, s, len);

        }

        unlock_user(s, args, 0);

        return ret;

    case TARGET_SYS_WRITE:

        GET_ARG(0);

        GET_ARG(1);

        GET_ARG(2);

        len = arg2;

        if (use_gdb_syscalls()) {

            arm_semi_syscall_len = len;

            return arm_gdb_syscall(cpu, arm_semi_cb, "write,%x,%x,%x",

                                   arg0, arg1, len);

        } else {

            s = lock_user(VERIFY_READ, arg1, len, 1);

            if (!s) {

                /* FIXME - should this error code be -TARGET_EFAULT ? */

                return (uint32_t)-1;

            }

            ret = set_swi_errno(ts, write(arg0, s, len));

            unlock_user(s, arg1, 0);

            if (ret == (uint32_t)-1)

                return -1;

            return len - ret;

        }

    case TARGET_SYS_READ:

        GET_ARG(0);

        GET_ARG(1);

        GET_ARG(2);

        len = arg2;

        if (use_gdb_syscalls()) {

            arm_semi_syscall_len = len;

            return arm_gdb_syscall(cpu, arm_semi_cb, "read,%x,%x,%x",

                                   arg0, arg1, len);

        } else {

            s = lock_user(VERIFY_WRITE, arg1, len, 0);

            if (!s) {

                /* FIXME - should this error code be -TARGET_EFAULT ? */

                return (uint32_t)-1;

            }

            do {

                ret = set_swi_errno(ts, read(arg0, s, len));

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

            unlock_user(s, arg1, len);

            if (ret == (uint32_t)-1)

                return -1;

            return len - ret;

        }

    case TARGET_SYS_READC:

       /* XXX: Read from debug console. Not implemented.  */

        return 0;

    case TARGET_SYS_ISTTY:

        GET_ARG(0);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "isatty,%x", arg0);

        } else {

            return isatty(arg0);

        }

    case TARGET_SYS_SEEK:

        GET_ARG(0);

        GET_ARG(1);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "lseek,%x,%x,0",

                                   arg0, arg1);

        } else {

            ret = set_swi_errno(ts, lseek(arg0, arg1, SEEK_SET));

            if (ret == (uint32_t)-1)

              return -1;

            return 0;

        }

    case TARGET_SYS_FLEN:

        GET_ARG(0);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_flen_cb, "fstat,%x,%x",

                                   arg0, arm_flen_buf(cpu));

        } else {

            struct stat buf;

            ret = set_swi_errno(ts, fstat(arg0, &buf));

            if (ret == (uint32_t)-1)

                return -1;

            return buf.st_size;

        }

    case TARGET_SYS_TMPNAM:

        /* XXX: Not implemented.  */

        return -1;

    case TARGET_SYS_REMOVE:

        GET_ARG(0);

        GET_ARG(1);

        if (use_gdb_syscalls()) {

            ret = arm_gdb_syscall(cpu, arm_semi_cb, "unlink,%s",

                                  arg0, (int)arg1+1);

        } else {

            s = lock_user_string(arg0);

            if (!s) {

                /* FIXME - should this error code be -TARGET_EFAULT ? */

                return (uint32_t)-1;

            }

            ret =  set_swi_errno(ts, remove(s));

            unlock_user(s, arg0, 0);

        }

        return ret;

    case TARGET_SYS_RENAME:

        GET_ARG(0);

        GET_ARG(1);

        GET_ARG(2);

        GET_ARG(3);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "rename,%s,%s",

                                   arg0, (int)arg1+1, arg2, (int)arg3+1);

        } else {

            char *s2;

            s = lock_user_string(arg0);

            s2 = lock_user_string(arg2);

            if (!s || !s2)

                /* FIXME - should this error code be -TARGET_EFAULT ? */

                ret = (uint32_t)-1;

            else

                ret = set_swi_errno(ts, rename(s, s2));

            if (s2)

                unlock_user(s2, arg2, 0);

            if (s)

                unlock_user(s, arg0, 0);

            return ret;

        }

    case TARGET_SYS_CLOCK:

        return clock() / (CLOCKS_PER_SEC / 100);

    case TARGET_SYS_TIME:

        return set_swi_errno(ts, time(NULL));

    case TARGET_SYS_SYSTEM:

        GET_ARG(0);

        GET_ARG(1);

        if (use_gdb_syscalls()) {

            return arm_gdb_syscall(cpu, arm_semi_cb, "system,%s",

                                   arg0, (int)arg1+1);

        } else {

            s = lock_user_string(arg0);

            if (!s) {

                /* FIXME - should this error code be -TARGET_EFAULT ? */

                return (uint32_t)-1;

            }

            ret = set_swi_errno(ts, system(s));

            unlock_user(s, arg0, 0);

            return ret;

        }

    case TARGET_SYS_ERRNO:

#ifdef CONFIG_USER_ONLY

        return ts->swi_errno;

#else

        return syscall_err;

#endif

    case TARGET_SYS_GET_CMDLINE:

        {

            /* Build a command-line from the original argv.

             *

             * The inputs are:

             *     * arg0, pointer to a buffer of at least the size

             *               specified in arg1.

             *     * arg1, size of the buffer pointed to by arg0 in

             *               bytes.

             *

             * The outputs are:

             *     * arg0, pointer to null-terminated string of the

             *               command line.

             *     * arg1, length of the string pointed to by arg0.

             */

            char *output_buffer;

            size_t input_size;

            size_t output_size;

            int status = 0;

#if !defined(CONFIG_USER_ONLY)

            const char *cmdline;

#endif

            GET_ARG(0);

            GET_ARG(1);

            input_size = arg1;

            /* Compute the size of the output string.  */

#if !defined(CONFIG_USER_ONLY)

            cmdline = semihosting_get_cmdline();

            if (cmdline == NULL) {

                cmdline = ""; /* Default to an empty line. */

            }

            output_size = strlen(cmdline) + 1; /* Count terminating 0. */

#else

            unsigned int i;

            output_size = ts->info->arg_end - ts->info->arg_start;

            if (!output_size) {

                /* We special-case the "empty command line" case (argc==0).

                   Just provide the terminating 0. */

                output_size = 1;

            }

#endif

            if (output_size > input_size) {

                 /* Not enough space to store command-line arguments.  */

                return -1;

            }

            /* Adjust the command-line length.  */

            if (SET_ARG(1, output_size - 1)) {

                /* Couldn't write back to argument block */

                return -1;

            }

            /* Lock the buffer on the ARM side.  */

            output_buffer = lock_user(VERIFY_WRITE, arg0, output_size, 0);

            if (!output_buffer) {

                return -1;

            }

            /* Copy the command-line arguments.  */

#if !defined(CONFIG_USER_ONLY)

            pstrcpy(output_buffer, output_size, cmdline);

#else

            if (output_size == 1) {

                /* Empty command-line.  */

                output_buffer[0] = '\0';

                goto out;

            }

            if (copy_from_user(output_buffer, ts->info->arg_start,

                               output_size)) {

                status = -1;

                goto out;

            }

            /* Separate arguments by white spaces.  */

            for (i = 0; i < output_size - 1; i++) {

                if (output_buffer[i] == 0) {

                    output_buffer[i] = ' ';

                }

            }

        out:

#endif

            /* Unlock the buffer on the ARM side.  */

            unlock_user(output_buffer, arg0, output_size);

            return status;

        }

    case TARGET_SYS_HEAPINFO:

        {

            target_ulong retvals[4];

            uint32_t limit;

            int i;

            GET_ARG(0);

#ifdef CONFIG_USER_ONLY

            /* Some C libraries assume the heap immediately follows .bss, so

               allocate it using sbrk.  */

            if (!ts->heap_limit) {

                abi_ulong ret;

                ts->heap_base = do_brk(0);

                limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;

                /* Try a big heap, and reduce the size if that fails.  */

                for (;;) {

                    ret = do_brk(limit);

                    if (ret >= limit) {

                        break;

                    }

                    limit = (ts->heap_base >> 1) + (limit >> 1);

                }

                ts->heap_limit = limit;

            }

            retvals[0] = ts->heap_base;

            retvals[1] = ts->heap_limit;

            retvals[2] = ts->stack_base;

            retvals[3] = 0; /* Stack limit.  */

#else

            limit = ram_size;

            /* TODO: Make this use the limit of the loaded application.  */

            retvals[0] = limit / 2;

            retvals[1] = limit;

            retvals[2] = limit; /* Stack base */

            retvals[3] = 0; /* Stack limit.  */

#endif

            for (i = 0; i < ARRAY_SIZE(retvals); i++) {

                bool fail;

                if (is_a64(env)) {

                    fail = put_user_u64(retvals[i], arg0 + i * 8);

                } else {

                    fail = put_user_u32(retvals[i], arg0 + i * 4);

                }

                if (fail) {

                    /* Couldn't write back to argument block */

                    return -1;

                }

            }

            return 0;

        }

    case TARGET_SYS_EXIT:

        if (is_a64(env)) {

            /* The A64 version of this call takes a parameter block,

             * so the application-exit type can return a subcode which

             * is the exit status code from the application.

             */

            GET_ARG(0);

            GET_ARG(1);

            if (arg0 == ADP_Stopped_ApplicationExit) {

                ret = arg1;

            } else {

                ret = 1;

            }

        } else {

            /* ARM specifies only Stopped_ApplicationExit as normal

             * exit, everything else is considered an error */

            ret = (args == ADP_Stopped_ApplicationExit) ? 0 : 1;

        }

        gdb_exit(env, ret);

        exit(ret);

    case TARGET_SYS_SYNCCACHE:

        /* Clean the D-cache and invalidate the I-cache for the specified

         * virtual address range. This is a nop for us since we don't

         * implement caches. This is only present on A64.

         */

        if (is_a64(env)) {

            return 0;

        }

        /* fall through -- invalid for A32/T32 */

    default:

        fprintf(stderr, "qemu: Unsupported SemiHosting SWI 0x%02x\n", nr);

        cpu_dump_state(cs, stderr, fprintf, 0);

        abort();

    }

}


static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb,

                                         void *logctx, int size)

{

    uint8_t *user_data;

    int e, build, i;

    if (size < 16 || size >= INT_MAX - 16)

        return AVERROR_INVALIDDATA;

    user_data = av_malloc(16 + size + 1);

    if (!user_data)

        return AVERROR(ENOMEM);

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

        user_data[i] = get_bits(gb, 8);

    user_data[i] = 0;

    e = sscanf(user_data + 16, "x264 - core %d", &build);

    if (e == 1 && build > 0)

        h->x264_build = build;

    if (e == 1 && build == 1 && !strncmp(user_data+16, "x264 - core 0000", 16))

        h->x264_build = 67;

    if (strlen(user_data + 16) > 0)

        av_log(logctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data + 16);

    av_free(user_data);

    return 0;

}


void avfilter_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)

{

    void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);

    AVFilterPad *dst = link->dstpad;

    int i;

    FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);

    if (!(filter_samples = dst->filter_samples))

        filter_samples = avfilter_default_filter_samples;

    /* prepare to copy the samples if the buffer has insufficient permissions */

    if ((dst->min_perms & samplesref->perms) != dst->min_perms ||

        dst->rej_perms & samplesref->perms) {

        av_log(link->dst, AV_LOG_DEBUG,

               "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n",

               samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms);

        link->cur_buf = avfilter_default_get_audio_buffer(link, dst->min_perms,

                                                          samplesref->audio->nb_samples);

        link->cur_buf->pts                = samplesref->pts;

        link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate;

        /* Copy actual data into new samples buffer */

        for (i = 0; samplesref->data[i]; i++)

            memcpy(link->cur_buf->data[i], samplesref->data[i], samplesref->linesize[0]);

        avfilter_unref_buffer(samplesref);

    } else

        link->cur_buf = samplesref;

    filter_samples(link, link->cur_buf);

}


static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,

                                   qemu_irq **irqs)

{

    qemu_irq *mpic;

    DeviceState *dev;

    SysBusDevice *s;

    int i, j, k;

    mpic = g_new(qemu_irq, 256);

    dev = qdev_create(NULL, "openpic");

    qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus);

    qdev_prop_set_uint32(dev, "model", params->mpic_version);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    k = 0;

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

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

            sysbus_connect_irq(s, k++, irqs[i][j]);

        }

    }

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

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

    }

    memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET,

                                s->mmio[0].memory);

    return mpic;

}


CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))

{

    const char *p;

    CharDriverState *chr;

    QemuOpts *opts;

    Error *err = NULL;

    if (strstart(filename, "chardev:", &p)) {

        return qemu_chr_find(p);

    }

    opts = qemu_chr_parse_compat(label, filename);

    if (!opts)

        return NULL;

    chr = qemu_chr_new_from_opts(opts, init, &err);

    if (err) {

        error_report_err(err);

    }

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

        qemu_chr_fe_claim_no_fail(chr);

        monitor_init(chr, MONITOR_USE_READLINE);

    }

    return chr;

}


static int net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,

                            const char *model, const char *name,

                            const char *ifname, const char *script,

                            const char *downscript, const char *vhostfdname,

                            int vnet_hdr, int fd)

{

    TAPState *s;

    s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);

    if (!s) {

        close(fd);

        return -1;

    }

    if (tap_set_sndbuf(s->fd, tap) < 0) {

        return -1;

    }

    if (tap->has_fd || tap->has_fds) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);

    } else if (tap->has_helper) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",

                 tap->helper);

    } else {

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

                 "ifname=%s,script=%s,downscript=%s", ifname, script,

                 downscript);

        if (strcmp(downscript, "no") != 0) {

            snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);

            snprintf(s->down_script_arg, sizeof(s->down_script_arg),

                     "%s", ifname);

        }

    }

    if (tap->has_vhost ? tap->vhost :

        vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {

        int vhostfd;

        if (tap->has_vhostfd) {

            vhostfd = monitor_handle_fd_param(cur_mon, vhostfdname);

            if (vhostfd == -1) {

                return -1;

            }

        } else {

            vhostfd = -1;

        }

        s->vhost_net = vhost_net_init(&s->nc, vhostfd,

                                      tap->has_vhostforce && tap->vhostforce);

        if (!s->vhost_net) {

            error_report("vhost-net requested but could not be initialized");

            return -1;

        }

    } else if (tap->has_vhostfd || tap->has_vhostfds) {

        error_report("vhostfd= is not valid without vhost");

        return -1;

    }

    return 0;

}


int qdev_prop_check_globals(void)

{

    GList *l;

    int ret = 0;

    for (l = global_props; l; l = l->next) {

        GlobalProperty *prop = l->data;

        ObjectClass *oc;

        DeviceClass *dc;

        if (prop->used) {

            continue;

        }

        if (!prop->user_provided) {

            continue;

        }

        oc = object_class_by_name(prop->driver);

        oc = object_class_dynamic_cast(oc, TYPE_DEVICE);

        if (!oc) {

            error_report("Warning: global %s.%s has invalid class name",

                       prop->driver, prop->property);

            ret = 1;

            continue;

        }

        dc = DEVICE_CLASS(oc);

        if (!dc->hotpluggable && !prop->used) {

            error_report("Warning: global %s.%s=%s not used",

                       prop->driver, prop->property, prop->value);

            ret = 1;

            continue;

        }

    }

    return ret;

}


static int qesd_init_out (HWVoiceOut *hw, audsettings_t *as)

{

    ESDVoiceOut *esd = (ESDVoiceOut *) hw;

    audsettings_t obt_as = *as;

    int esdfmt = ESD_STREAM | ESD_PLAY;

    int err;

    sigset_t set, old_set;

    sigfillset (&set);

    esdfmt |= (as->nchannels == 2) ? ESD_STEREO : ESD_MONO;

    switch (as->fmt) {

    case AUD_FMT_S8:

    case AUD_FMT_U8:

        esdfmt |= ESD_BITS8;

        obt_as.fmt = AUD_FMT_U8;

        break;

    case AUD_FMT_S32:

    case AUD_FMT_U32:

        dolog ("Will use 16 instead of 32 bit samples\n");

    case AUD_FMT_S16:

    case AUD_FMT_U16:

    deffmt:

        esdfmt |= ESD_BITS16;

        obt_as.fmt = AUD_FMT_S16;

        break;

    default:

        dolog ("Internal logic error: Bad audio format %d\n", as->fmt);

        goto deffmt;

    }

    obt_as.endianness = AUDIO_HOST_ENDIANNESS;

    audio_pcm_init_info (&hw->info, &obt_as);

    hw->samples = conf.samples;

    esd->pcm_buf = audio_calloc (AUDIO_FUNC, hw->samples, 1 << hw->info.shift);

    if (!esd->pcm_buf) {

        dolog ("Could not allocate buffer (%d bytes)\n",

               hw->samples << hw->info.shift);

        return -1;

    }

    esd->fd = -1;

    err = pthread_sigmask (SIG_BLOCK, &set, &old_set);

    if (err) {

        qesd_logerr (err, "pthread_sigmask failed\n");

        goto fail1;

    }

    esd->fd = esd_play_stream (esdfmt, as->freq, conf.dac_host, NULL);

    if (esd->fd < 0) {

        qesd_logerr (errno, "esd_play_stream failed\n");

        goto fail2;

    }

    if (audio_pt_init (&esd->pt, qesd_thread_out, esd, AUDIO_CAP, AUDIO_FUNC)) {

        goto fail3;

    }

    err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);

    if (err) {

        qesd_logerr (err, "pthread_sigmask(restore) failed\n");

    }

    return 0;

 fail3:

    if (close (esd->fd)) {

        qesd_logerr (errno, "%s: close on esd socket(%d) failed\n",

                     AUDIO_FUNC, esd->fd);

    }

    esd->fd = -1;

 fail2:

    err = pthread_sigmask (SIG_SETMASK, &old_set, NULL);

    if (err) {

        qesd_logerr (err, "pthread_sigmask(restore) failed\n");

    }

 fail1:

    qemu_free (esd->pcm_buf);

    esd->pcm_buf = NULL;

    return -1;

}


static void monitor_find_completion(const char *cmdline)

{

    const char *cmdname;

    char *args[MAX_ARGS];

    int nb_args, i, len;

    const char *ptype, *str;

    const mon_cmd_t *cmd;

    const KeyDef *key;

    parse_cmdline(cmdline, &nb_args, args);

#ifdef DEBUG_COMPLETION

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

        monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]);

    }

#endif

    /* if the line ends with a space, it means we want to complete the

       next arg */

    len = strlen(cmdline);

    if (len > 0 && qemu_isspace(cmdline[len - 1])) {

        if (nb_args >= MAX_ARGS)

            return;

        args[nb_args++] = qemu_strdup("");

    }

    if (nb_args <= 1) {

        /* command completion */

        if (nb_args == 0)

            cmdname = "";

        else

            cmdname = args[0];

        readline_set_completion_index(cur_mon->rs, strlen(cmdname));

        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {

            cmd_completion(cmdname, cmd->name);

        }

    } else {

        /* find the command */

        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {

            if (compare_cmd(args[0], cmd->name))

                goto found;

        }

        return;

    found:

        ptype = next_arg_type(cmd->args_type);

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

            if (*ptype != '\0') {

                ptype = next_arg_type(ptype);

                while (*ptype == '?')

                    ptype = next_arg_type(ptype);

            }

        }

        str = args[nb_args - 1];

        if (*ptype == '-' && ptype[1] != '\0') {

            ptype += 2;

        }

        switch(*ptype) {

        case 'F':

            /* file completion */

            readline_set_completion_index(cur_mon->rs, strlen(str));

            file_completion(str);

            break;

        case 'B':

            /* block device name completion */

            readline_set_completion_index(cur_mon->rs, strlen(str));

            bdrv_iterate(block_completion_it, (void *)str);

            break;

        case 's':

            /* XXX: more generic ? */

            if (!strcmp(cmd->name, "info")) {

                readline_set_completion_index(cur_mon->rs, strlen(str));

                for(cmd = info_cmds; cmd->name != NULL; cmd++) {

                    cmd_completion(str, cmd->name);

                }

            } else if (!strcmp(cmd->name, "sendkey")) {

                char *sep = strrchr(str, '-');

                if (sep)

                    str = sep + 1;

                readline_set_completion_index(cur_mon->rs, strlen(str));

                for(key = key_defs; key->name != NULL; key++) {

                    cmd_completion(str, key->name);

                }

            } else if (!strcmp(cmd->name, "help|?")) {

                readline_set_completion_index(cur_mon->rs, strlen(str));

                for (cmd = mon_cmds; cmd->name != NULL; cmd++) {

                    cmd_completion(str, cmd->name);

                }

            }

            break;

        default:

            break;

        }

    }

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

        qemu_free(args[i]);

}


static void sd_response_r1_make(SDState *sd,

                                uint8_t *response, uint32_t last_status)

{

    uint32_t mask = CARD_STATUS_B ^ ILLEGAL_COMMAND;

    uint32_t status;

    status = (sd->card_status & ~mask) | (last_status & mask);

    sd->card_status &= ~CARD_STATUS_C | APP_CMD;

    response[0] = (status >> 24) & 0xff;

    response[1] = (status >> 16) & 0xff;

    response[2] = (status >> 8) & 0xff;

    response[3] = (status >> 0) & 0xff;

}


static int mpc8_decode_frame(AVCodecContext * avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    MPCContext *c = avctx->priv_data;

    GetBitContext gb2, *gb = &gb2;

    int i, j, k, ch, cnt, res, t;

    Band *bands = c->bands;

    int off;

    int maxband, keyframe;

    int last[2];

    keyframe = c->cur_frame == 0;

    if(keyframe){

        memset(c->Q, 0, sizeof(c->Q));

        c->last_bits_used = 0;

    }

    init_get_bits(gb, buf, buf_size * 8);

    skip_bits(gb, c->last_bits_used & 7);

    if(keyframe)

        maxband = mpc8_get_mod_golomb(gb, c->maxbands + 1);

    else{

        maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2);

        if(maxband > 32) maxband -= 33;

    }

    c->last_max_band = maxband;

    /* read subband indexes */

    if(maxband){

        last[0] = last[1] = 0;

        for(i = maxband - 1; i >= 0; i--){

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

                last[ch] = get_vlc2(gb, res_vlc[last[ch] > 2].table, MPC8_RES_BITS, 2) + last[ch];

                if(last[ch] > 15) last[ch] -= 17;

                bands[i].res[ch] = last[ch];

            }

        }

        if(c->MSS){

            int mask;

            cnt = 0;

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

                if(bands[i].res[0] || bands[i].res[1])

                    cnt++;

            t = mpc8_get_mod_golomb(gb, cnt);

            mask = mpc8_get_mask(gb, cnt, t);

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

                if(bands[i].res[0] || bands[i].res[1]){

                    bands[i].msf = mask & 1;

                    mask >>= 1;

                }

        }

    }

    for(i = maxband; i < c->maxbands; i++)

        bands[i].res[0] = bands[i].res[1] = 0;

    if(keyframe){

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

            c->oldDSCF[0][i] = c->oldDSCF[1][i] = 1;

    }

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

        if(bands[i].res[0] || bands[i].res[1]){

            cnt = !!bands[i].res[0] + !!bands[i].res[1] - 1;

            if(cnt >= 0){

                t = get_vlc2(gb, scfi_vlc[cnt].table, scfi_vlc[cnt].bits, 1);

                if(bands[i].res[0]) bands[i].scfi[0] = t >> (2 * cnt);

                if(bands[i].res[1]) bands[i].scfi[1] = t & 3;

            }

        }

    }

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

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

            if(!bands[i].res[ch]) continue;

            if(c->oldDSCF[ch][i]){

                bands[i].scf_idx[ch][0] = get_bits(gb, 7) - 6;

                c->oldDSCF[ch][i] = 0;

            }else{

                t = get_vlc2(gb, dscf_vlc[1].table, MPC8_DSCF1_BITS, 2);

                if(t == 64)

                    t += get_bits(gb, 6);

                bands[i].scf_idx[ch][0] = ((bands[i].scf_idx[ch][2] + t - 25) & 0x7F) - 6;

            }

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

                if((bands[i].scfi[ch] << j) & 2)

                    bands[i].scf_idx[ch][j + 1] = bands[i].scf_idx[ch][j];

                else{

                    t = get_vlc2(gb, dscf_vlc[0].table, MPC8_DSCF0_BITS, 2);

                    if(t == 31)

                        t = 64 + get_bits(gb, 6);

                    bands[i].scf_idx[ch][j + 1] = ((bands[i].scf_idx[ch][j] + t - 25) & 0x7F) - 6;

                }

            }

        }

    }

    for(i = 0, off = 0; i < maxband; i++, off += SAMPLES_PER_BAND){

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

            res = bands[i].res[ch];

            switch(res){

            case -1:

                for(j = 0; j < SAMPLES_PER_BAND; j++)

                    c->Q[ch][off + j] = (av_lfg_get(&c->rnd) & 0x3FC) - 510;

                break;

            case 0:

                break;

            case 1:

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

                    cnt = get_vlc2(gb, q1_vlc.table, MPC8_Q1_BITS, 2);

                    t = mpc8_get_mask(gb, 18, cnt);

                    for(k = 0; k < SAMPLES_PER_BAND / 2; k++, t <<= 1)

                        c->Q[ch][off + j + k] = (t & 0x20000) ? (get_bits1(gb) << 1) - 1 : 0;

                }

                break;

            case 2:

                cnt = 6;//2*mpc8_thres[res]

                for(j = 0; j < SAMPLES_PER_BAND; j += 3){

                    t = get_vlc2(gb, q2_vlc[cnt > 3].table, MPC8_Q2_BITS, 2);

                    c->Q[ch][off + j + 0] = mpc8_idx50[t];

                    c->Q[ch][off + j + 1] = mpc8_idx51[t];

                    c->Q[ch][off + j + 2] = mpc8_idx52[t];

                    cnt = (cnt >> 1) + mpc8_huffq2[t];

                }

                break;

            case 3:

            case 4:

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

                    t = get_vlc2(gb, q3_vlc[res - 3].table, MPC8_Q3_BITS, 2) + q3_offsets[res - 3];

                    c->Q[ch][off + j + 1] = t >> 4;

                    c->Q[ch][off + j + 0] = (t & 8) ? (t & 0xF) - 16 : (t & 0xF);

                }

                break;

            case 5:

            case 6:

            case 7:

            case 8:

                cnt = 2 * mpc8_thres[res];

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

                    t = get_vlc2(gb, quant_vlc[res - 5][cnt > mpc8_thres[res]].table, quant_vlc[res - 5][cnt > mpc8_thres[res]].bits, 2) + quant_offsets[res - 5];

                    c->Q[ch][off + j] = t;

                    cnt = (cnt >> 1) + FFABS(c->Q[ch][off + j]);

                }

                break;

            default:

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

                    c->Q[ch][off + j] = get_vlc2(gb, q9up_vlc.table, MPC8_Q9UP_BITS, 2);

                    if(res != 9){

                        c->Q[ch][off + j] <<= res - 9;

                        c->Q[ch][off + j] |= get_bits(gb, res - 9);

                    }

                    c->Q[ch][off + j] -= (1 << (res - 2)) - 1;

                }

            }

        }

    }

    ff_mpc_dequantize_and_synth(c, maxband, data, avctx->channels);

    c->cur_frame++;

    c->last_bits_used = get_bits_count(gb);

    if(c->cur_frame >= c->frames)

        c->cur_frame = 0;

    *data_size =  MPC_FRAME_SIZE * 2 * avctx->channels;

    return c->cur_frame ? c->last_bits_used >> 3 : buf_size;

}


DeviceState *qdev_try_create(BusState *bus, const char *name)

{

    DeviceState *dev;

    if (object_class_by_name(name) == NULL) {

        return NULL;

    }

    dev = DEVICE(object_new(name));

    if (!dev) {

        return NULL;

    }

    if (!bus) {

        bus = sysbus_get_default();

    }

    qdev_set_parent_bus(dev, bus);

    qdev_prop_set_globals(dev);

    return dev;

}


Visitor *qobject_input_visitor_new_keyval(QObject *obj)

{

    QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);

    v->visitor.type_int64 = qobject_input_type_int64_keyval;

    v->visitor.type_uint64 = qobject_input_type_uint64_keyval;

    v->visitor.type_bool = qobject_input_type_bool_keyval;

    v->visitor.type_str = qobject_input_type_str;

    v->visitor.type_number = qobject_input_type_number_keyval;

    v->visitor.type_any = qobject_input_type_any;

    v->visitor.type_null = qobject_input_type_null;

    v->visitor.type_size = qobject_input_type_size_keyval;

    return &v->visitor;

}


void *pl080_init(uint32_t base, qemu_irq irq, int nchannels)

{

    int iomemtype;

    pl080_state *s;

    s = (pl080_state *)qemu_mallocz(sizeof(pl080_state));

    iomemtype = cpu_register_io_memory(0, pl080_readfn,

                                       pl080_writefn, s);

    cpu_register_physical_memory(base, 0x00000fff, iomemtype);

    s->base = base;

    s->irq = irq;

    s->nchannels = nchannels;

    /* ??? Save/restore.  */

    return s;

}


static av_cold void init_coef_vlc(VLC *vlc, uint16_t **prun_table,

                                  float **plevel_table, uint16_t **pint_table,

                                  const CoefVLCTable *vlc_table)

{

    int n                        = vlc_table->n;

    const uint8_t  *table_bits   = vlc_table->huffbits;

    const uint32_t *table_codes  = vlc_table->huffcodes;

    const uint16_t *levels_table = vlc_table->levels;

    uint16_t *run_table, *level_table, *int_table;

    float *flevel_table;

    int i, l, j, k, level;

    init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0);

    run_table    = av_malloc(n * sizeof(uint16_t));

    level_table  = av_malloc(n * sizeof(uint16_t));

    flevel_table = av_malloc(n * sizeof(*flevel_table));

    int_table    = av_malloc(n * sizeof(uint16_t));

    i            = 2;

    level        = 1;

    k            = 0;

    while (i < n) {

        int_table[k] = i;

        l            = levels_table[k++];

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

            run_table[i]    = j;

            level_table[i]  = level;

            flevel_table[i] = level;

            i++;

        }

        level++;

    }

    *prun_table   = run_table;

    *plevel_table = flevel_table;

    *pint_table   = int_table;

    av_free(level_table);

}


static inline int parse_nal_units(AVCodecParserContext *s,

                                  AVCodecContext *avctx,

                                  const uint8_t *buf, int buf_size)

{

    H264ParseContext *p = s->priv_data;

    const uint8_t *buf_end = buf + buf_size;

    H2645NAL nal = { NULL };

    unsigned int pps_id;

    unsigned int slice_type;

    int state = -1, got_reset = 0;

    int field_poc[2];

    int ret;

    /* set some sane default values */

    s->pict_type         = AV_PICTURE_TYPE_I;

    s->key_frame         = 0;

    s->picture_structure = AV_PICTURE_STRUCTURE_UNKNOWN;

    ff_h264_sei_uninit(&p->sei);

    if (!buf_size)

        return 0;

    for (;;) {

        const SPS *sps;

        int src_length, consumed;

        buf = avpriv_find_start_code(buf, buf_end, &state);

        if (buf >= buf_end)

            break;

        --buf;

        src_length = buf_end - buf;

        switch (state & 0x1f) {

        case H264_NAL_SLICE:

        case H264_NAL_IDR_SLICE:

            // Do not walk the whole buffer just to decode slice header

            if ((state & 0x1f) == H264_NAL_IDR_SLICE || ((state >> 5) & 0x3) == 0) {

                /* IDR or disposable slice

                 * No need to decode many bytes because MMCOs shall not be present. */

                if (src_length > 60)

                    src_length = 60;

            } else {

                /* To decode up to MMCOs */

                if (src_length > 1000)

                    src_length = 1000;

            }

            break;

        }

        consumed = ff_h2645_extract_rbsp(buf, src_length, &nal);

        if (consumed < 0)

            break;

        ret = init_get_bits(&nal.gb, nal.data, nal.size * 8);

        if (ret < 0)

            goto fail;

        get_bits1(&nal.gb);

        nal.ref_idc = get_bits(&nal.gb, 2);

        nal.type    = get_bits(&nal.gb, 5);

        switch (nal.type) {

        case H264_NAL_SPS:

            ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps);

            break;

        case H264_NAL_PPS:

            ff_h264_decode_picture_parameter_set(&nal.gb, avctx, &p->ps,

                                                 nal.size_bits);

            break;

        case H264_NAL_SEI:

            ff_h264_sei_decode(&p->sei, &nal.gb, &p->ps, avctx);

            break;

        case H264_NAL_IDR_SLICE:

            s->key_frame = 1;

            p->poc.prev_frame_num        = 0;

            p->poc.prev_frame_num_offset = 0;

            p->poc.prev_poc_msb          =

            p->poc.prev_poc_lsb          = 0;

        /* fall through */

        case H264_NAL_SLICE:

            get_ue_golomb(&nal.gb);  // skip first_mb_in_slice

            slice_type   = get_ue_golomb_31(&nal.gb);

            s->pict_type = ff_h264_golomb_to_pict_type[slice_type % 5];

            if (p->sei.recovery_point.recovery_frame_cnt >= 0) {

                /* key frame, since recovery_frame_cnt is set */

                s->key_frame = 1;

            }

            pps_id = get_ue_golomb(&nal.gb);

            if (pps_id >= MAX_PPS_COUNT) {

                av_log(avctx, AV_LOG_ERROR,

                       "pps_id %u out of range\n", pps_id);

                goto fail;

            }

            if (!p->ps.pps_list[pps_id]) {

                av_log(avctx, AV_LOG_ERROR,

                       "non-existing PPS %u referenced\n", pps_id);

                goto fail;

            }

            p->ps.pps = (const PPS*)p->ps.pps_list[pps_id]->data;

            if (!p->ps.sps_list[p->ps.pps->sps_id]) {

                av_log(avctx, AV_LOG_ERROR,

                       "non-existing SPS %u referenced\n", p->ps.pps->sps_id);

                goto fail;

            }

            p->ps.sps = (SPS*)p->ps.sps_list[p->ps.pps->sps_id]->data;

            sps = p->ps.sps;

            p->poc.frame_num = get_bits(&nal.gb, sps->log2_max_frame_num);

            s->coded_width  = 16 * sps->mb_width;

            s->coded_height = 16 * sps->mb_height;

            s->width        = s->coded_width  - (sps->crop_right + sps->crop_left);

            s->height       = s->coded_height - (sps->crop_top   + sps->crop_bottom);

            if (s->width <= 0 || s->height <= 0) {

                s->width  = s->coded_width;

                s->height = s->coded_height;

            }

            switch (sps->bit_depth_luma) {

            case 9:

                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P9;

                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;

                else                                  s->format = AV_PIX_FMT_YUV420P9;

                break;

            case 10:

                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P10;

                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;

                else                                  s->format = AV_PIX_FMT_YUV420P10;

                break;

            case 8:

                if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P;

                else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;

                else                                  s->format = AV_PIX_FMT_YUV420P;

                break;

            default:

                s->format = AV_PIX_FMT_NONE;

            }

            avctx->profile = ff_h264_get_profile(sps);

            avctx->level   = sps->level_idc;

            if (sps->frame_mbs_only_flag) {

                p->picture_structure = PICT_FRAME;

            } else {

                if (get_bits1(&nal.gb)) { // field_pic_flag

                    p->picture_structure = PICT_TOP_FIELD + get_bits1(&nal.gb); // bottom_field_flag

                } else {

                    p->picture_structure = PICT_FRAME;

                }

            }

            if (nal.type == H264_NAL_IDR_SLICE)

                get_ue_golomb(&nal.gb); /* idr_pic_id */

            if (sps->poc_type == 0) {

                p->poc.poc_lsb = get_bits(&nal.gb, sps->log2_max_poc_lsb);

                if (p->ps.pps->pic_order_present == 1 &&

                    p->picture_structure == PICT_FRAME)

                    p->poc.delta_poc_bottom = get_se_golomb(&nal.gb);

            }

            if (sps->poc_type == 1 &&

                !sps->delta_pic_order_always_zero_flag) {

                p->poc.delta_poc[0] = get_se_golomb(&nal.gb);

                if (p->ps.pps->pic_order_present == 1 &&

                    p->picture_structure == PICT_FRAME)

                    p->poc.delta_poc[1] = get_se_golomb(&nal.gb);

            }

            /* Decode POC of this picture.

             * The prev_ values needed for decoding POC of the next picture are not set here. */

            field_poc[0] = field_poc[1] = INT_MAX;

            ff_h264_init_poc(field_poc, &s->output_picture_number, sps,

                             &p->poc, p->picture_structure, nal.ref_idc);

            /* Continue parsing to check if MMCO_RESET is present.

             * FIXME: MMCO_RESET could appear in non-first slice.

             *        Maybe, we should parse all undisposable non-IDR slice of this

             *        picture until encountering MMCO_RESET in a slice of it. */

            if (nal.ref_idc && nal.type != H264_NAL_IDR_SLICE) {

                got_reset = scan_mmco_reset(s, &nal.gb, avctx);

                if (got_reset < 0)

                    goto fail;

            }

            /* Set up the prev_ values for decoding POC of the next picture. */

            p->poc.prev_frame_num        = got_reset ? 0 : p->poc.frame_num;

            p->poc.prev_frame_num_offset = got_reset ? 0 : p->poc.frame_num_offset;

            if (nal.ref_idc != 0) {

                if (!got_reset) {

                    p->poc.prev_poc_msb = p->poc.poc_msb;

                    p->poc.prev_poc_lsb = p->poc.poc_lsb;

                } else {

                    p->poc.prev_poc_msb = 0;

                    p->poc.prev_poc_lsb =

                        p->picture_structure == PICT_BOTTOM_FIELD ? 0 : field_poc[0];

                }

            }

            if (sps->pic_struct_present_flag) {

                switch (p->sei.picture_timing.pic_struct) {

                case SEI_PIC_STRUCT_TOP_FIELD:

                case SEI_PIC_STRUCT_BOTTOM_FIELD:

                    s->repeat_pict = 0;

                    break;

                case SEI_PIC_STRUCT_FRAME:

                case SEI_PIC_STRUCT_TOP_BOTTOM:

                case SEI_PIC_STRUCT_BOTTOM_TOP:

                    s->repeat_pict = 1;

                    break;

                case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:

                case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:

                    s->repeat_pict = 2;

                    break;

                case SEI_PIC_STRUCT_FRAME_DOUBLING:

                    s->repeat_pict = 3;

                    break;

                case SEI_PIC_STRUCT_FRAME_TRIPLING:

                    s->repeat_pict = 5;

                    break;

                default:

                    s->repeat_pict = p->picture_structure == PICT_FRAME ? 1 : 0;

                    break;

                }

            } else {

                s->repeat_pict = p->picture_structure == PICT_FRAME ? 1 : 0;

            }

            if (p->picture_structure == PICT_FRAME) {

                s->picture_structure = AV_PICTURE_STRUCTURE_FRAME;

                if (sps->pic_struct_present_flag) {

                    switch (p->sei.picture_timing.pic_struct) {

                    case SEI_PIC_STRUCT_TOP_BOTTOM:

                    case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:

                        s->field_order = AV_FIELD_TT;

                        break;

                    case SEI_PIC_STRUCT_BOTTOM_TOP:

                    case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:

                        s->field_order = AV_FIELD_BB;

                        break;

                    default:

                        s->field_order = AV_FIELD_PROGRESSIVE;

                        break;

                    }

                } else {

                    if (field_poc[0] < field_poc[1])

                        s->field_order = AV_FIELD_TT;

                    else if (field_poc[0] > field_poc[1])

                        s->field_order = AV_FIELD_BB;

                    else

                        s->field_order = AV_FIELD_PROGRESSIVE;

                }

            } else {

                if (p->picture_structure == PICT_TOP_FIELD)

                    s->picture_structure = AV_PICTURE_STRUCTURE_TOP_FIELD;

                else

                    s->picture_structure = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;

                s->field_order = AV_FIELD_UNKNOWN;

            }

            av_freep(&nal.rbsp_buffer);

            return 0; /* no need to evaluate the rest */

        }

        buf += consumed;

    }

    /* didn't find a picture! */

    av_log(avctx, AV_LOG_ERROR, "missing picture in access unit\n");

fail:

    av_freep(&nal.rbsp_buffer);

    return -1;

}