int ff_snow_frame_start(SnowContext *s){

   AVFrame tmp;

   int i, ret;

   int w= s->avctx->width; //FIXME round up to x16 ?

   int h= s->avctx->height;

    if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) {

        s->dsp.draw_edges(s->current_picture.data[0],

                          s->current_picture.linesize[0], w   , h   ,

                          EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);

        s->dsp.draw_edges(s->current_picture.data[1],

                          s->current_picture.linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift,

                          EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);

        s->dsp.draw_edges(s->current_picture.data[2],

                          s->current_picture.linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift,

                          EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);

    }

    ff_snow_release_buffer(s->avctx);

    av_frame_move_ref(&tmp, &s->last_picture[s->max_ref_frames-1]);

    for(i=s->max_ref_frames-1; i>0; i--)

        av_frame_move_ref(&s->last_picture[i], &s->last_picture[i-1]);

    memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);

    if(USE_HALFPEL_PLANE && s->current_picture.data[0])

        halfpel_interpol(s, s->halfpel_plane[0], &s->current_picture);

    av_frame_move_ref(&s->last_picture[0], &s->current_picture);

    av_frame_move_ref(&s->current_picture, &tmp);

    if(s->keyframe){

        s->ref_frames= 0;

    }else{

        int i;

        for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++)

            if(i && s->last_picture[i-1].key_frame)

                break;

        s->ref_frames= i;

        if(s->ref_frames==0){

            av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n");

            return -1;

        }

    }

    if ((ret = ff_get_buffer(s->avctx, &s->current_picture, AV_GET_BUFFER_FLAG_REF)) < 0)

        return ret;

    s->current_picture.key_frame= s->keyframe;

    return 0;

}


static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl,

                                   const H2645NAL *nal)

{

    const SPS *sps;

    const PPS *pps;

    int ret;

    unsigned int slice_type, tmp, i;

    int field_pic_flag, bottom_field_flag;

    int first_slice = sl == h->slice_ctx && !h->current_slice;

    int picture_structure;

    if (first_slice)

        av_assert0(!h->setup_finished);

    sl->first_mb_addr = get_ue_golomb_long(&sl->gb);

    slice_type = get_ue_golomb_31(&sl->gb);

    if (slice_type > 9) {

        av_log(h->avctx, AV_LOG_ERROR,

               "slice type %d too large at %d\n",

               slice_type, sl->first_mb_addr);

        return AVERROR_INVALIDDATA;

    }

    if (slice_type > 4) {

        slice_type -= 5;

        sl->slice_type_fixed = 1;

    } else

        sl->slice_type_fixed = 0;

    slice_type         = ff_h264_golomb_to_pict_type[slice_type];

    sl->slice_type     = slice_type;

    sl->slice_type_nos = slice_type & 3;

    if (nal->type  == H264_NAL_IDR_SLICE &&

        sl->slice_type_nos != AV_PICTURE_TYPE_I) {

        av_log(h->avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n");

        return AVERROR_INVALIDDATA;

    }

    sl->pps_id = get_ue_golomb(&sl->gb);

    if (sl->pps_id >= MAX_PPS_COUNT) {

        av_log(h->avctx, AV_LOG_ERROR, "pps_id %u out of range\n", sl->pps_id);

        return AVERROR_INVALIDDATA;

    }

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

        av_log(h->avctx, AV_LOG_ERROR,

               "non-existing PPS %u referenced\n",

               sl->pps_id);

        return AVERROR_INVALIDDATA;

    }

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

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

        av_log(h->avctx, AV_LOG_ERROR,

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

        return AVERROR_INVALIDDATA;

    }

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

    sl->frame_num = get_bits(&sl->gb, sps->log2_max_frame_num);

    if (!first_slice) {

        if (h->poc.frame_num != sl->frame_num) {

            av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n",

                   h->poc.frame_num, sl->frame_num);

            return AVERROR_INVALIDDATA;

        }

    }

    sl->mb_mbaff       = 0;

    if (sps->frame_mbs_only_flag) {

        picture_structure = PICT_FRAME;

    } else {

        if (!sps->direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) {

            av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");

            return -1;

        }

        field_pic_flag = get_bits1(&sl->gb);

        if (field_pic_flag) {

            bottom_field_flag = get_bits1(&sl->gb);

            picture_structure = PICT_TOP_FIELD + bottom_field_flag;

        } else {

            picture_structure = PICT_FRAME;

        }

    }

    sl->picture_structure      = picture_structure;

    sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;

    if (picture_structure == PICT_FRAME) {

        sl->curr_pic_num = sl->frame_num;

        sl->max_pic_num  = 1 << sps->log2_max_frame_num;

    } else {

        sl->curr_pic_num = 2 * sl->frame_num + 1;

        sl->max_pic_num  = 1 << (sps->log2_max_frame_num + 1);

    }

    if (nal->type == H264_NAL_IDR_SLICE)

        get_ue_golomb_long(&sl->gb); /* idr_pic_id */

    if (sps->poc_type == 0) {

        sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb);

        if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)

            sl->delta_poc_bottom = get_se_golomb(&sl->gb);

    }

    if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) {

        sl->delta_poc[0] = get_se_golomb(&sl->gb);

        if (pps->pic_order_present == 1 && picture_structure == PICT_FRAME)

            sl->delta_poc[1] = get_se_golomb(&sl->gb);

    }

    sl->redundant_pic_count = 0;

    if (pps->redundant_pic_cnt_present)

        sl->redundant_pic_count = get_ue_golomb(&sl->gb);

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B)

        sl->direct_spatial_mv_pred = get_bits1(&sl->gb);

    ret = ff_h264_parse_ref_count(&sl->list_count, sl->ref_count,

                                  &sl->gb, pps, sl->slice_type_nos,

                                  picture_structure, h->avctx);

    if (ret < 0)

        return ret;

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(sl, h->avctx);

       if (ret < 0) {

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

           return ret;

       }

    }

    sl->pwt.use_weight = 0;

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

        sl->pwt.luma_weight_flag[i]   = 0;

        sl->pwt.chroma_weight_flag[i] = 0;

    }

    if ((pps->weighted_pred && sl->slice_type_nos == AV_PICTURE_TYPE_P) ||

        (pps->weighted_bipred_idc == 1 &&

         sl->slice_type_nos == AV_PICTURE_TYPE_B)) {

        ret = ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count,

                                  sl->slice_type_nos, &sl->pwt, h->avctx);

        if (ret < 0)

            return ret;

    }

    sl->explicit_ref_marking = 0;

    if (nal->ref_idc) {

        ret = ff_h264_decode_ref_pic_marking(sl, &sl->gb, nal, h->avctx);

        if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))

            return AVERROR_INVALIDDATA;

    }

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I && pps->cabac) {

        tmp = get_ue_golomb_31(&sl->gb);

        if (tmp > 2) {

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

            return AVERROR_INVALIDDATA;

        }

        sl->cabac_init_idc = tmp;

    }

    sl->last_qscale_diff = 0;

    tmp = pps->init_qp + get_se_golomb(&sl->gb);

    if (tmp > 51 + 6 * (sps->bit_depth_luma - 8)) {

        av_log(h->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);

        return AVERROR_INVALIDDATA;

    }

    sl->qscale       = tmp;

    sl->chroma_qp[0] = get_chroma_qp(pps, 0, sl->qscale);

    sl->chroma_qp[1] = get_chroma_qp(pps, 1, sl->qscale);

    // FIXME qscale / qp ... stuff

    if (sl->slice_type == AV_PICTURE_TYPE_SP)

        get_bits1(&sl->gb); /* sp_for_switch_flag */

    if (sl->slice_type == AV_PICTURE_TYPE_SP ||

        sl->slice_type == AV_PICTURE_TYPE_SI)

        get_se_golomb(&sl->gb); /* slice_qs_delta */

    sl->deblocking_filter     = 1;

    sl->slice_alpha_c0_offset = 0;

    sl->slice_beta_offset     = 0;

    if (pps->deblocking_filter_parameters_present) {

        tmp = get_ue_golomb_31(&sl->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "deblocking_filter_idc %u out of range\n", tmp);

            return AVERROR_INVALIDDATA;

        }

        sl->deblocking_filter = tmp;

        if (sl->deblocking_filter < 2)

            sl->deblocking_filter ^= 1;  // 1<->0

        if (sl->deblocking_filter) {

            sl->slice_alpha_c0_offset = get_se_golomb(&sl->gb) * 2;

            sl->slice_beta_offset     = get_se_golomb(&sl->gb) * 2;

            if (sl->slice_alpha_c0_offset >  12 ||

                sl->slice_alpha_c0_offset < -12 ||

                sl->slice_beta_offset >  12     ||

                sl->slice_beta_offset < -12) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "deblocking filter parameters %d %d out of range\n",

                       sl->slice_alpha_c0_offset, sl->slice_beta_offset);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    return 0;

}


static inline void RENAME(yuv2rgb565_2)(SwsContext *c, const uint16_t *buf0,

                                        const uint16_t *buf1, const uint16_t *ubuf0,

                                        const uint16_t *ubuf1, const uint16_t *vbuf0,

                                        const uint16_t *vbuf1, const uint16_t *abuf0,

                                        const uint16_t *abuf1, uint8_t *dest,

                                        int dstW, int yalpha, int uvalpha, int y)

{

    x86_reg uv_off = c->uv_off << 1;

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

    __asm__ volatile(

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

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

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

        YSCALEYUV2RGB(%%REGBP, %5, %6)

        "pxor    %%mm7, %%mm7                   \n\t"

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

#ifdef DITHER1XBPP

        "paddusb "BLUE_DITHER"(%5), %%mm2      \n\t"

        "paddusb "GREEN_DITHER"(%5), %%mm4      \n\t"

        "paddusb "RED_DITHER"(%5), %%mm5      \n\t"

#endif

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

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

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

        :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

           "a" (&c->redDither), "m"(uv_off)

    );

}


static int virtio_scsi_parse_req(VirtIOSCSIReq *req,

                                 unsigned req_size, unsigned resp_size)

{

    VirtIODevice *vdev = (VirtIODevice *) req->dev;

    size_t in_size, out_size;

    if (iov_to_buf(req->elem.out_sg, req->elem.out_num, 0,

                   &req->req, req_size) < req_size) {

        return -EINVAL;

    }

    if (qemu_iovec_concat_iov(&req->resp_iov,

                              req->elem.in_sg, req->elem.in_num, 0,

                              resp_size) < resp_size) {

        return -EINVAL;

    }

    req->resp_size = resp_size;

    /* Old BIOSes left some padding by mistake after the req_size/resp_size.

     * As a workaround, always consider the first buffer as the virtio-scsi

     * request/response, making the payload start at the second element

     * of the iovec.

     *

     * The actual length of the response header, stored in req->resp_size,

     * does not change.

     *

     * TODO: always disable this workaround for virtio 1.0 devices.

     */

    if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {

        req_size = req->elem.out_sg[0].iov_len;

        resp_size = req->elem.in_sg[0].iov_len;

    }

    out_size = qemu_sgl_concat(req, req->elem.out_sg,

                               &req->elem.out_addr[0], req->elem.out_num,

                               req_size);

    in_size = qemu_sgl_concat(req, req->elem.in_sg,

                              &req->elem.in_addr[0], req->elem.in_num,

                              resp_size);

    if (out_size && in_size) {

        return -ENOTSUP;

    }

    if (out_size) {

        req->mode = SCSI_XFER_TO_DEV;

    } else if (in_size) {

        req->mode = SCSI_XFER_FROM_DEV;

    }

    return 0;

}


static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,

                              AVFormatContext *s)

{

    int i;

    int64_t pos = avio_tell(pb);

    avio_wb32(pb, 0); /* size placeholder*/

    ffio_wfourcc(pb, "moov");

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

        if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))

            continue;

        mov->tracks[i].time     = mov->time;

        mov->tracks[i].track_id = i + 1;

        if (mov->tracks[i].entry)

            build_chunks(&mov->tracks[i]);

    }

    if (mov->chapter_track)

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

            mov->tracks[i].tref_tag = MKTAG('c','h','a','p');

            mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;

        }

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

        if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {

            mov->tracks[i].tref_tag = MKTAG('h','i','n','t');

            mov->tracks[i].tref_id =

                mov->tracks[mov->tracks[i].src_track].track_id;

        }

    }

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

        if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {

            int src_trk = mov->tracks[i].src_track;

            mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;

            mov->tracks[src_trk].tref_id  = mov->tracks[i].track_id;

            //src_trk may have a different timescale than the tmcd track

            mov->tracks[i].track_duration = av_rescale(mov->tracks[src_trk].track_duration,

                                                       mov->tracks[i].timescale,

                                                       mov->tracks[src_trk].timescale);

        }

    }

    mov_write_mvhd_tag(pb, mov);

    if (mov->mode != MODE_MOV && !mov->iods_skip)

        mov_write_iods_tag(pb, mov);

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

        if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {

            mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);

        }

    }

    if (mov->flags & FF_MOV_FLAG_FRAGMENT)

        mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */

    if (mov->mode == MODE_PSP)

        mov_write_uuidusmt_tag(pb, s);

    else

        mov_write_udta_tag(pb, mov, s);

    return update_size(pb, pos);

}


static void virtio_blk_handle_read(VirtIOBlockReq *req)

{

    BlockDriverAIOCB *acb;

    uint64_t sector;

    sector = ldq_p(&req->out->sector);

    if (sector & req->dev->sector_mask) {

    acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov,

                         req->qiov.size / BDRV_SECTOR_SIZE,

                         virtio_blk_rw_complete, req);

    if (!acb) {


void FUNC(ff_simple_idct_put)(uint8_t *dest_, int line_size, DCTELEM *block)

{

    pixel *dest = (pixel *)dest_;

    int i;

    line_size /= sizeof(pixel);

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

        FUNC(idctRowCondDC)(block + i*8);

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

        FUNC(idctSparseColPut)(dest + i, line_size, block + i);

}


static void quantize_and_encode_band_cost_UPAIR7_mips(struct AACEncContext *s,

                                                      PutBitContext *pb, const float *in, float *out,

                                                      const float *scaled, int size, int scale_idx,

                                                      int cb, const float lambda, const float uplim,

                                                      int *bits, const float ROUNDING)

{

    const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];

    const float IQ  = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];

    int i;

    int qc1, qc2, qc3, qc4;

    uint8_t  *p_bits  = (uint8_t*) ff_aac_spectral_bits[cb-1];

    uint16_t *p_codes = (uint16_t*)ff_aac_spectral_codes[cb-1];

    float    *p_vec   = (float    *)ff_aac_codebook_vectors[cb-1];

    abs_pow34_v(s->scoefs, in, size);

    scaled = s->scoefs;

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

        int curidx1, curidx2, sign1, count1, sign2, count2;

        int *in_int = (int *)&in[i];

        uint8_t v_bits;

        unsigned int v_codes;

        int t0, t1, t2, t3, t4;

        const float *vec1, *vec2;

        qc1 = scaled[i  ] * Q34 + ROUND_STANDARD;

        qc2 = scaled[i+1] * Q34 + ROUND_STANDARD;

        qc3 = scaled[i+2] * Q34 + ROUND_STANDARD;

        qc4 = scaled[i+3] * Q34 + ROUND_STANDARD;

        __asm__ volatile (

            ".set push                              \n\t"

            ".set noreorder                         \n\t"

            "ori    %[t4],      $zero,      7       \n\t"

            "ori    %[sign1],   $zero,      0       \n\t"

            "ori    %[sign2],   $zero,      0       \n\t"

            "slt    %[t0],      %[t4],      %[qc1]  \n\t"

            "slt    %[t1],      %[t4],      %[qc2]  \n\t"

            "slt    %[t2],      %[t4],      %[qc3]  \n\t"

            "slt    %[t3],      %[t4],      %[qc4]  \n\t"

            "movn   %[qc1],     %[t4],      %[t0]   \n\t"

            "movn   %[qc2],     %[t4],      %[t1]   \n\t"

            "movn   %[qc3],     %[t4],      %[t2]   \n\t"

            "movn   %[qc4],     %[t4],      %[t3]   \n\t"

            "lw     %[t0],      0(%[in_int])        \n\t"

            "lw     %[t1],      4(%[in_int])        \n\t"

            "lw     %[t2],      8(%[in_int])        \n\t"

            "lw     %[t3],      12(%[in_int])       \n\t"

            "slt    %[t0],      %[t0],      $zero   \n\t"

            "movn   %[sign1],   %[t0],      %[qc1]  \n\t"

            "slt    %[t2],      %[t2],      $zero   \n\t"

            "movn   %[sign2],   %[t2],      %[qc3]  \n\t"

            "slt    %[t1],      %[t1],      $zero   \n\t"

            "sll    %[t0],      %[sign1],   1       \n\t"

            "or     %[t0],      %[t0],      %[t1]   \n\t"

            "movn   %[sign1],   %[t0],      %[qc2]  \n\t"

            "slt    %[t3],      %[t3],      $zero   \n\t"

            "sll    %[t0],      %[sign2],   1       \n\t"

            "or     %[t0],      %[t0],      %[t3]   \n\t"

            "movn   %[sign2],   %[t0],      %[qc4]  \n\t"

            "slt    %[count1],  $zero,      %[qc1]  \n\t"

            "slt    %[t1],      $zero,      %[qc2]  \n\t"

            "slt    %[count2],  $zero,      %[qc3]  \n\t"

            "slt    %[t2],      $zero,      %[qc4]  \n\t"

            "addu   %[count1],  %[count1],  %[t1]   \n\t"

            "addu   %[count2],  %[count2],  %[t2]   \n\t"

            ".set pop                               \n\t"

            : [qc1]"+r"(qc1), [qc2]"+r"(qc2),

              [qc3]"+r"(qc3), [qc4]"+r"(qc4),

              [sign1]"=&r"(sign1), [count1]"=&r"(count1),

              [sign2]"=&r"(sign2), [count2]"=&r"(count2),

              [t0]"=&r"(t0), [t1]"=&r"(t1), [t2]"=&r"(t2), [t3]"=&r"(t3),

              [t4]"=&r"(t4)

            : [in_int]"r"(in_int)

            : "t0", "t1", "t2", "t3", "t4",

              "memory"

        );

        curidx1  = 8 * qc1;

        curidx1 += qc2;

        v_codes = (p_codes[curidx1] << count1) | sign1;

        v_bits  = p_bits[curidx1] + count1;

        put_bits(pb, v_bits, v_codes);

        curidx2  = 8 * qc3;

        curidx2 += qc4;

        v_codes = (p_codes[curidx2] << count2) | sign2;

        v_bits  = p_bits[curidx2] + count2;

        put_bits(pb, v_bits, v_codes);

        if (out) {

           vec1 = &p_vec[curidx1*2];

           vec2 = &p_vec[curidx2*2];

           out[i+0] = copysignf(vec1[0] * IQ, in[i+0]);

           out[i+1] = copysignf(vec1[1] * IQ, in[i+1]);

           out[i+2] = copysignf(vec2[0] * IQ, in[i+2]);

           out[i+3] = copysignf(vec2[1] * IQ, in[i+3]);

        }

    }

}


static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,

                                      int chunk_size, RTMPPacket **prev_pkt_ptr,

                                      int *nb_prev_pkt, uint8_t hdr)

{

    uint8_t buf[16];

    int channel_id, timestamp, size;

    uint32_t ts_field; // non-extended timestamp or delta field

    uint32_t extra = 0;

    enum RTMPPacketType type;

    int written = 0;

    int ret, toread;

    RTMPPacket *prev_pkt;

    written++;

    channel_id = hdr & 0x3F;

    if (channel_id < 2) { //special case for channel number >= 64

        buf[1] = 0;

        if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1)

            return AVERROR(EIO);

        written += channel_id + 1;

        channel_id = AV_RL16(buf) + 64;

    }

    if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,

                                         channel_id)) < 0)

        return ret;

    prev_pkt = *prev_pkt_ptr;

    size  = prev_pkt[channel_id].size;

    type  = prev_pkt[channel_id].type;

    extra = prev_pkt[channel_id].extra;

    hdr >>= 6; // header size indicator

    if (hdr == RTMP_PS_ONEBYTE) {

        ts_field = prev_pkt[channel_id].ts_field;

    } else {

        if (ffurl_read_complete(h, buf, 3) != 3)

            return AVERROR(EIO);

        written += 3;

        ts_field = AV_RB24(buf);

        if (hdr != RTMP_PS_FOURBYTES) {

            if (ffurl_read_complete(h, buf, 3) != 3)

                return AVERROR(EIO);

            written += 3;

            size = AV_RB24(buf);

            if (ffurl_read_complete(h, buf, 1) != 1)

                return AVERROR(EIO);

            written++;

            type = buf[0];

            if (hdr == RTMP_PS_TWELVEBYTES) {

                if (ffurl_read_complete(h, buf, 4) != 4)

                    return AVERROR(EIO);

                written += 4;

                extra = AV_RL32(buf);

            }

        }

    }

    if (ts_field == 0xFFFFFF) {

        if (ffurl_read_complete(h, buf, 4) != 4)

            return AVERROR(EIO);

        timestamp = AV_RB32(buf);

    } else {

        timestamp = ts_field;

    }

    if (hdr != RTMP_PS_TWELVEBYTES)

        timestamp += prev_pkt[channel_id].timestamp;

    if (!prev_pkt[channel_id].read) {

        if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp,

                                         size)) < 0)

            return ret;

        p->read = written;

        p->offset = 0;

        prev_pkt[channel_id].ts_field   = ts_field;

        prev_pkt[channel_id].timestamp  = timestamp;

    } else {

        // previous packet in this channel hasn't completed reading

        RTMPPacket *prev = &prev_pkt[channel_id];

        p->data          = prev->data;

        p->size          = prev->size;

        p->channel_id    = prev->channel_id;

        p->type          = prev->type;

        p->ts_field      = prev->ts_field;

        p->extra         = prev->extra;

        p->offset        = prev->offset;

        p->read          = prev->read + written;

        p->timestamp     = prev->timestamp;

        prev->data       = NULL;

    }

    p->extra = extra;

    // save history

    prev_pkt[channel_id].channel_id = channel_id;

    prev_pkt[channel_id].type       = type;

    prev_pkt[channel_id].size       = size;

    prev_pkt[channel_id].extra      = extra;

    size = size - p->offset;

    toread = FFMIN(size, chunk_size);

    if (ffurl_read_complete(h, p->data + p->offset, toread) != toread) {

        ff_rtmp_packet_destroy(p);

        return AVERROR(EIO);

    }

    size      -= toread;

    p->read   += toread;

    p->offset += toread;

    if (size > 0) {

       RTMPPacket *prev = &prev_pkt[channel_id];

       prev->data = p->data;

       prev->read = p->read;

       prev->offset = p->offset;

       return AVERROR(EAGAIN);

    }

    prev_pkt[channel_id].read = 0; // read complete; reset if needed

    return p->read;

}


int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count)

{

    int i, av_uninit(j);

    int current_ref_assigned = 0, err = 0;

    Picture *av_uninit(pic);

    if ((h->avctx->debug & FF_DEBUG_MMCO) && mmco_count == 0)

        av_log(h->avctx, AV_LOG_DEBUG, "no mmco here\n");

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

        int av_uninit(structure), av_uninit(frame_num);

        if (h->avctx->debug & FF_DEBUG_MMCO)

            av_log(h->avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode,

                   h->mmco[i].short_pic_num, h->mmco[i].long_arg);

        if (mmco[i].opcode == MMCO_SHORT2UNUSED ||

            mmco[i].opcode == MMCO_SHORT2LONG) {

            frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure);

            pic       = find_short(h, frame_num, &j);

            if (!pic) {

                if (mmco[i].opcode != MMCO_SHORT2LONG ||

                    !h->long_ref[mmco[i].long_arg]    ||

                    h->long_ref[mmco[i].long_arg]->frame_num != frame_num) {

                    av_log(h->avctx, AV_LOG_ERROR, "mmco: unref short failure\n");

                    err = AVERROR_INVALIDDATA;

                continue;

        switch (mmco[i].opcode) {

        case MMCO_SHORT2UNUSED:

            if (h->avctx->debug & FF_DEBUG_MMCO)

                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n",

                       h->mmco[i].short_pic_num, h->short_ref_count);

            remove_short(h, frame_num, structure ^ PICT_FRAME);

            break;

        case MMCO_SHORT2LONG:

                if (h->long_ref[mmco[i].long_arg] != pic)

                    remove_long(h, mmco[i].long_arg, 0);

                remove_short_at_index(h, j);

                h->long_ref[ mmco[i].long_arg ] = pic;

                if (h->long_ref[mmco[i].long_arg]) {

                    h->long_ref[mmco[i].long_arg]->long_ref = 1;

                    h->long_ref_count++;

            break;

        case MMCO_LONG2UNUSED:

            j   = pic_num_extract(h, mmco[i].long_arg, &structure);

            pic = h->long_ref[j];

            if (pic) {

                remove_long(h, j, structure ^ PICT_FRAME);

            } else if (h->avctx->debug & FF_DEBUG_MMCO)

                av_log(h->avctx, AV_LOG_DEBUG, "mmco: unref long failure\n");

            break;

        case MMCO_LONG:

                    // Comment below left from previous code as it is an interresting note.

                    /* First field in pair is in short term list or

                     * at a different long term index.

                     * This is not allowed; see 7.4.3.3, notes 2 and 3.

                     * Report the problem and keep the pair where it is,

                     * and mark this field valid.

                     */

            if (h->long_ref[mmco[i].long_arg] != h->cur_pic_ptr) {

                remove_long(h, mmco[i].long_arg, 0);

                h->long_ref[mmco[i].long_arg]           = h->cur_pic_ptr;

                h->long_ref[mmco[i].long_arg]->long_ref = 1;

                h->long_ref_count++;

            h->cur_pic_ptr->reference |= h->picture_structure;

            current_ref_assigned = 1;

            break;

        case MMCO_SET_MAX_LONG:

            assert(mmco[i].long_arg <= 16);

            // just remove the long term which index is greater than new max

            for (j = mmco[i].long_arg; j < 16; j++) {

                remove_long(h, j, 0);

            break;

        case MMCO_RESET:

            while (h->short_ref_count) {

                remove_short(h, h->short_ref[0]->frame_num, 0);

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

                remove_long(h, j, 0);

            h->frame_num  = h->cur_pic_ptr->frame_num = 0;

            h->mmco_reset = 1;

            h->cur_pic_ptr->mmco_reset = 1;

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

                h->last_pocs[j] = INT_MIN;

            break;

        default: assert(0);

    if (!current_ref_assigned) {

        /* Second field of complementary field pair; the first field of

         * which is already referenced. If short referenced, it

         * should be first entry in short_ref. If not, it must exist

         * in long_ref; trying to put it on the short list here is an

         * error in the encoded bit stream (ref: 7.4.3.3, NOTE 2 and 3).

         */

        if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) {

            /* Just mark the second field valid */

            h->cur_pic_ptr->reference = PICT_FRAME;

        } else if (h->cur_pic_ptr->long_ref) {

            av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference "

                                           "assignment for second field "

                                           "in complementary field pair "

                                           "(first field is long term)\n");

            err = AVERROR_INVALIDDATA;

        } else {

            pic = remove_short(h, h->cur_pic_ptr->frame_num, 0);

            if (pic) {

                av_log(h->avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");

                err = AVERROR_INVALIDDATA;

            if (h->short_ref_count)

                memmove(&h->short_ref[1], &h->short_ref[0],

                        h->short_ref_count * sizeof(Picture*));

            h->short_ref[0] = h->cur_pic_ptr;

            h->short_ref_count++;

            h->cur_pic_ptr->reference |= h->picture_structure;

    if (h->long_ref_count + h->short_ref_count > FFMAX(h->sps.ref_frame_count, 1)) {

        /* We have too many reference frames, probably due to corrupted

         * stream. Need to discard one frame. Prevents overrun of the

         * short_ref and long_ref buffers.

         */

        av_log(h->avctx, AV_LOG_ERROR,

               "number of reference frames (%d+%d) exceeds max (%d; probably "

               "corrupt input), discarding one\n",

               h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);

        err = AVERROR_INVALIDDATA;

        if (h->long_ref_count && !h->short_ref_count) {

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

                if (h->long_ref[i])

                    break;

            assert(i < 16);

            remove_long(h, i, 0);

        } else {

            pic = h->short_ref[h->short_ref_count - 1];

            remove_short(h, pic->frame_num, 0);

    print_short_term(h);

    print_long_term(h);

    if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){

        h->cur_pic_ptr->sync |= 1;

        if(!h->avctx->has_b_frames)

            h->sync = 2;

    return (h->avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;


static void pc_init1(ram_addr_t ram_size,

                     const char *boot_device,

                     const char *kernel_filename,

                     const char *kernel_cmdline,

                     const char *initrd_filename,

                     const char *cpu_model,

                     int pci_enabled)

{

    char *filename;

    int ret, linux_boot, i;

    ram_addr_t ram_addr, bios_offset, option_rom_offset;

    ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;

    int bios_size, isa_bios_size;

    PCIBus *pci_bus;

    ISADevice *isa_dev;

    int piix3_devfn = -1;

    CPUState *env;

    qemu_irq *cpu_irq;

    qemu_irq *isa_irq;

    qemu_irq *i8259;

    IsaIrqState *isa_irq_state;

    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

    DriveInfo *fd[MAX_FD];

    int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;

    void *fw_cfg;

    if (ram_size >= 0xe0000000 ) {

        above_4g_mem_size = ram_size - 0xe0000000;

        below_4g_mem_size = 0xe0000000;

    } else {

        below_4g_mem_size = ram_size;

    }

    linux_boot = (kernel_filename != NULL);

    /* init CPUs */

    if (cpu_model == NULL) {

#ifdef TARGET_X86_64

        cpu_model = "qemu64";

#else

        cpu_model = "qemu32";

#endif

    }

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

        env = pc_new_cpu(cpu_model);

    }

    vmport_init();

    /* allocate RAM */

    ram_addr = qemu_ram_alloc(0xa0000);

    cpu_register_physical_memory(0, 0xa0000, ram_addr);

    /* Allocate, even though we won't register, so we don't break the

     * phys_ram_base + PA assumption. This range includes vga (0xa0000 - 0xc0000),

     * and some bios areas, which will be registered later

     */

    ram_addr = qemu_ram_alloc(0x100000 - 0xa0000);

    ram_addr = qemu_ram_alloc(below_4g_mem_size - 0x100000);

    cpu_register_physical_memory(0x100000,

                 below_4g_mem_size - 0x100000,

                 ram_addr);

    /* above 4giga memory allocation */

    if (above_4g_mem_size > 0) {

#if TARGET_PHYS_ADDR_BITS == 32

        hw_error("To much RAM for 32-bit physical address");

#else

        ram_addr = qemu_ram_alloc(above_4g_mem_size);

        cpu_register_physical_memory(0x100000000ULL,

                                     above_4g_mem_size,

                                     ram_addr);

#endif

    }

    /* BIOS load */

    if (bios_name == NULL)

        bios_name = BIOS_FILENAME;

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    if (filename) {

        bios_size = get_image_size(filename);

    } else {

        bios_size = -1;

    }

    if (bios_size <= 0 ||

        (bios_size % 65536) != 0) {

        goto bios_error;

    }

    bios_offset = qemu_ram_alloc(bios_size);

    ret = load_image(filename, qemu_get_ram_ptr(bios_offset));

    if (ret != bios_size) {

    bios_error:

        fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);

        exit(1);

    }

    if (filename) {

        qemu_free(filename);

    }

    /* map the last 128KB of the BIOS in ISA space */

    isa_bios_size = bios_size;

    if (isa_bios_size > (128 * 1024))

        isa_bios_size = 128 * 1024;

    cpu_register_physical_memory(0x100000 - isa_bios_size,

                                 isa_bios_size,

                                 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);

    option_rom_offset = qemu_ram_alloc(PC_ROM_SIZE);

    cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset);

    if (using_vga) {

        /* VGA BIOS load */

        if (cirrus_vga_enabled) {

            rom_add_vga(VGABIOS_CIRRUS_FILENAME);

        } else {

            rom_add_vga(VGABIOS_FILENAME);

        }

    }

    /* map all the bios at the top of memory */

    cpu_register_physical_memory((uint32_t)(-bios_size),

                                 bios_size, bios_offset | IO_MEM_ROM);

    fw_cfg = bochs_bios_init();

    if (linux_boot) {

        load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);

    }

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

        rom_add_option(option_rom[i]);

    }

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

        char nic_oprom[1024];

        const char *model = nd_table[i].model;

        if (!nd_table[i].bootable)

            continue;

        if (model == NULL)

            model = "e1000";

        snprintf(nic_oprom, sizeof(nic_oprom), "pxe-%s.bin", model);

        rom_add_option(nic_oprom);

    }

    cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);

    i8259 = i8259_init(cpu_irq[0]);

    isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));

    isa_irq_state->i8259 = i8259;

    isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);

    if (pci_enabled) {

        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq);

    } else {

        pci_bus = NULL;

        isa_bus_new(NULL);

    }

    isa_bus_irqs(isa_irq);

    ferr_irq = isa_reserve_irq(13);

    /* init basic PC hardware */

    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);

    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);

    if (cirrus_vga_enabled) {

        if (pci_enabled) {

            pci_cirrus_vga_init(pci_bus);

        } else {

            isa_cirrus_vga_init();

        }

    } else if (vmsvga_enabled) {

        if (pci_enabled)

            pci_vmsvga_init(pci_bus);

        else

            fprintf(stderr, "%s: vmware_vga: no PCI bus\n", __FUNCTION__);

    } else if (std_vga_enabled) {

        if (pci_enabled) {

            pci_vga_init(pci_bus, 0, 0);

        } else {

            isa_vga_init();

        }

    }

    rtc_state = rtc_init(2000);

    qemu_register_boot_set(pc_boot_set, rtc_state);

    register_ioport_read(0x92, 1, 1, ioport92_read, NULL);

    register_ioport_write(0x92, 1, 1, ioport92_write, NULL);

    if (pci_enabled) {

        isa_irq_state->ioapic = ioapic_init();

    }

    pit = pit_init(0x40, isa_reserve_irq(0));

    pcspk_init(pit);

    if (!no_hpet) {

        hpet_init(isa_irq);

    }

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

        if (serial_hds[i]) {

            serial_isa_init(i, serial_hds[i]);

        }

    }

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

        if (parallel_hds[i]) {

            parallel_init(i, parallel_hds[i]);

        }

    }

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

        NICInfo *nd = &nd_table[i];

        if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))

            pc_init_ne2k_isa(nd);

        else

            pci_nic_init_nofail(nd, "e1000", NULL);

    }

    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {

        fprintf(stderr, "qemu: too many IDE bus\n");

        exit(1);

    }

    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {

        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);

    }

    if (pci_enabled) {

        pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);

    } else {

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

            isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],

	                 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);

        }

    }

    isa_dev = isa_create_simple("i8042");

    DMA_init(0);

#ifdef HAS_AUDIO

    audio_init(pci_enabled ? pci_bus : NULL, isa_irq);

#endif

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

        fd[i] = drive_get(IF_FLOPPY, 0, i);

    }

    floppy_controller = fdctrl_init_isa(fd);

    cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);

    if (pci_enabled && usb_enabled) {

        usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);

    }

    if (pci_enabled && acpi_enabled) {

        uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */

        i2c_bus *smbus;

        /* TODO: Populate SPD eeprom data.  */

        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,

                              isa_reserve_irq(9));

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

            DeviceState *eeprom;

            eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");

            qdev_prop_set_uint8(eeprom, "address", 0x50 + i);

            qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));

            qdev_init(eeprom);

        }

        piix4_acpi_system_hot_add_init(pci_bus);

    }

    if (i440fx_state) {

        i440fx_init_memory_mappings(i440fx_state);

    }

    if (pci_enabled) {

	int max_bus;

        int bus;

        max_bus = drive_get_max_bus(IF_SCSI);

	for (bus = 0; bus <= max_bus; bus++) {

            pci_create_simple(pci_bus, -1, "lsi53c895a");

        }

    }

    /* Add virtio console devices */

    if (pci_enabled) {

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

            if (virtcon_hds[i]) {

                pci_create_simple(pci_bus, -1, "virtio-console-pci");

            }

        }

    }

}


void *av_tree_insert(AVTreeNode **tp, void *key, int (*cmp)(void *key, const void *b), AVTreeNode **next){

    AVTreeNode *t= *tp;

    if(t){

        unsigned int v= cmp(t->elem, key);

        void *ret;

        if(!v){

            if(*next)

                return t->elem;

            else if(t->child[0]||t->child[1]){

                int i= !t->child[0];

                void *next_elem[2];

                av_tree_find(t->child[i], key, cmp, next_elem);

                key= t->elem= next_elem[i];

                v= -i;

            }else{

                *next= t;

                *tp=NULL;

                return NULL;

            }

        }

        ret= av_tree_insert(&t->child[v>>31], key, cmp, next);

        if(!ret){

            int i= (v>>31) ^ !!*next;

            AVTreeNode **child= &t->child[i];

            t->state += 2*i - 1;

            if(!(t->state&1)){

                if(t->state){

                    /* The following code is equivalent to

                    if((*child)->state*2 == -t->state)

                        rotate(child, i^1);

                    rotate(tp, i);

                    with rotate():

                    static void rotate(AVTreeNode **tp, int i){

                        AVTreeNode *t= *tp;

                        *tp= t->child[i];

                        t->child[i]= t->child[i]->child[i^1];

                        (*tp)->child[i^1]= t;

                        i= 4*t->state + 2*(*tp)->state + 12;

                          t  ->state=                     ((0x614586 >> i) & 3)-1;

                        (*tp)->state= ((*tp)->state>>1) + ((0x400EEA >> i) & 3)-1;

                    }

                    but such a rotate function is both bigger and slower

                    */

                    if((*child)->state*2 == -t->state){

                        *tp= (*child)->child[i^1];

                        (*child)->child[i^1]= (*tp)->child[i];

                        (*tp)->child[i]= *child;

                        *child= (*tp)->child[i^1];

                        (*tp)->child[i^1]= t;

                        (*tp)->child[0]->state= -((*tp)->state>0);

                        (*tp)->child[1]->state=   (*tp)->state<0 ;

                        (*tp)->state=0;

                    }else{

                        *tp= *child;

                        *child= (*child)->child[i^1];

                        (*tp)->child[i^1]= t;

                        if((*tp)->state) t->state  = 0;

                        else             t->state>>= 1;

                        (*tp)->state= -t->state;

                    }

                }

            }

            if(!(*tp)->state ^ !!*next)

                return key;

        }

        return ret;

    }else{

        *tp= *next; *next= NULL;

        (*tp)->elem= key;

        return NULL;

    }

}


static size_t refcount_array_byte_size(BDRVQcow2State *s, uint64_t entries)

{

    /* This assertion holds because there is no way we can address more than

     * 2^(64 - 9) clusters at once (with cluster size 512 = 2^9, and because

     * offsets have to be representable in bytes); due to every cluster

     * corresponding to one refcount entry, we are well below that limit */

    assert(entries < (UINT64_C(1) << (64 - 9)));

    /* Thanks to the assertion this will not overflow, because

     * s->refcount_order < 7.

     * (note: x << s->refcount_order == x * s->refcount_bits) */

    return DIV_ROUND_UP(entries << s->refcount_order, 8);

}


static inline void RENAME(hyscale)(SwsContext *c, uint16_t *dst, long dstWidth, uint8_t *src, int srcW, int xInc,

                                   int flags, int canMMX2BeUsed, int16_t *hLumFilter,

                                   int16_t *hLumFilterPos, int hLumFilterSize, void *funnyYCode,

                                   int srcFormat, uint8_t *formatConvBuffer, int16_t *mmx2Filter,

                                   int32_t *mmx2FilterPos, uint8_t *pal)

{

    if (srcFormat==PIX_FMT_YUYV422 || srcFormat==PIX_FMT_GRAY16BE)

    {

        RENAME(yuy2ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_UYVY422 || srcFormat==PIX_FMT_GRAY16LE)

    {

        RENAME(uyvyToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB32)

    {

        RENAME(bgr32ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB32_1)

    {

        RENAME(bgr32ToY)(formatConvBuffer, src+ALT32_CORR, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_BGR24)

    {

        RENAME(bgr24ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_BGR565)

    {

        RENAME(bgr16ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_BGR555)

    {

        RENAME(bgr15ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_BGR32)

    {

        RENAME(rgb32ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_BGR32_1)

    {

        RENAME(rgb32ToY)(formatConvBuffer, src+ALT32_CORR, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB24)

    {

        RENAME(rgb24ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB565)

    {

        RENAME(rgb16ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB555)

    {

        RENAME(rgb15ToY)(formatConvBuffer, src, srcW);

        src= formatConvBuffer;

    }

    else if (srcFormat==PIX_FMT_RGB8 || srcFormat==PIX_FMT_BGR8 || srcFormat==PIX_FMT_PAL8 || srcFormat==PIX_FMT_BGR4_BYTE  || srcFormat==PIX_FMT_RGB4_BYTE)

    {

        RENAME(palToY)(formatConvBuffer, src, srcW, (uint32_t*)pal);

        src= formatConvBuffer;

    }

#ifdef HAVE_MMX

    // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one).

    if (!(flags&SWS_FAST_BILINEAR) || (!canMMX2BeUsed))

#else

    if (!(flags&SWS_FAST_BILINEAR))

#endif

    {

        RENAME(hScale)(dst, dstWidth, src, srcW, xInc, hLumFilter, hLumFilterPos, hLumFilterSize);

    }

    else // fast bilinear upscale / crap downscale

    {

#if defined(ARCH_X86)

#ifdef HAVE_MMX2

        int i;

#if defined(PIC)

        uint64_t ebxsave __attribute__((aligned(8)));

#endif

        if (canMMX2BeUsed)

        {

            asm volatile(

#if defined(PIC)

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

#endif

            "pxor                  %%mm7, %%mm7     \n\t"

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

            "mov                      %1, %%"REG_D" \n\t"

            "mov                      %2, %%"REG_d" \n\t"

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

            "xor               %%"REG_a", %%"REG_a" \n\t" // i

            PREFETCH"        (%%"REG_c")            \n\t"

            PREFETCH"      32(%%"REG_c")            \n\t"

            PREFETCH"      64(%%"REG_c")            \n\t"

#ifdef ARCH_X86_64

#define FUNNY_Y_CODE \

            "movl            (%%"REG_b"), %%esi     \n\t"\

            "call                    *%4            \n\t"\

            "movl (%%"REG_b", %%"REG_a"), %%esi     \n\t"\

            "add               %%"REG_S", %%"REG_c" \n\t"\

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

            "xor               %%"REG_a", %%"REG_a" \n\t"\

#else

#define FUNNY_Y_CODE \

            "movl (%%"REG_b"), %%esi        \n\t"\

            "call         *%4                       \n\t"\

            "addl (%%"REG_b", %%"REG_a"), %%"REG_c" \n\t"\

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

            "xor               %%"REG_a", %%"REG_a" \n\t"\

#endif /* ARCH_X86_64 */

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

FUNNY_Y_CODE

#if defined(PIC)

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

#endif

            :: "m" (src), "m" (dst), "m" (mmx2Filter), "m" (mmx2FilterPos),

            "m" (funnyYCode)

#if defined(PIC)

            ,"m" (ebxsave)

#endif

            : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

            ,"%"REG_b

#endif

            );

            for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) dst[i] = src[srcW-1]*128;

        }

        else

        {

#endif /* HAVE_MMX2 */

        long xInc_shr16 = xInc >> 16;

        uint16_t xInc_mask = xInc & 0xffff;

        //NO MMX just normal asm ...

        asm volatile(

        "xor %%"REG_a", %%"REG_a"            \n\t" // i

        "xor %%"REG_d", %%"REG_d"            \n\t" // xx

        "xorl    %%ecx, %%ecx                \n\t" // 2*xalpha

        ASMALIGN(4)

        "1:                                  \n\t"

        "movzbl    (%0, %%"REG_d"), %%edi    \n\t" //src[xx]

        "movzbl   1(%0, %%"REG_d"), %%esi    \n\t" //src[xx+1]

        "subl    %%edi, %%esi                \n\t" //src[xx+1] - src[xx]

        "imull   %%ecx, %%esi                \n\t" //(src[xx+1] - src[xx])*2*xalpha

        "shll      $16, %%edi                \n\t"

        "addl    %%edi, %%esi                \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

        "mov        %1, %%"REG_D"            \n\t"

        "shrl       $9, %%esi                \n\t"

        "movw     %%si, (%%"REG_D", %%"REG_a", 2)   \n\t"

        "addw       %4, %%cx                 \n\t" //2*xalpha += xInc&0xFF

        "adc        %3, %%"REG_d"            \n\t" //xx+= xInc>>8 + carry

        "movzbl    (%0, %%"REG_d"), %%edi    \n\t" //src[xx]

        "movzbl   1(%0, %%"REG_d"), %%esi    \n\t" //src[xx+1]

        "subl    %%edi, %%esi                \n\t" //src[xx+1] - src[xx]

        "imull   %%ecx, %%esi                \n\t" //(src[xx+1] - src[xx])*2*xalpha

        "shll      $16, %%edi                \n\t"

        "addl    %%edi, %%esi                \n\t" //src[xx+1]*2*xalpha + src[xx]*(1-2*xalpha)

        "mov        %1, %%"REG_D"            \n\t"

        "shrl       $9, %%esi                \n\t"

        "movw     %%si, 2(%%"REG_D", %%"REG_a", 2)  \n\t"

        "addw       %4, %%cx                 \n\t" //2*xalpha += xInc&0xFF

        "adc        %3, %%"REG_d"            \n\t" //xx+= xInc>>8 + carry

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

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

        " jb        1b                       \n\t"

        :: "r" (src), "m" (dst), "m" (dstWidth), "m" (xInc_shr16), "m" (xInc_mask)

        : "%"REG_a, "%"REG_d, "%ecx", "%"REG_D, "%esi"

        );

#ifdef HAVE_MMX2

        } //if MMX2 can't be used

#endif

#else

        int i;

        unsigned int xpos=0;

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

        {

            register unsigned int xx=xpos>>16;

            register unsigned int xalpha=(xpos&0xFFFF)>>9;

            dst[i]= (src[xx]<<7) + (src[xx+1] - src[xx])*xalpha;

            xpos+=xInc;

        }

#endif /* defined(ARCH_X86) */

    }

    if(c->srcRange != c->dstRange && !(isRGB(c->dstFormat) || isBGR(c->dstFormat))){

        int i;

        //FIXME all pal and rgb srcFormats could do this convertion as well

        //FIXME all scalers more complex than bilinear could do half of this transform

        if(c->srcRange){

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

                dst[i]= (dst[i]*14071 + 33561947)>>14;

        }else{

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

                dst[i]= (dst[i]*19077 - 39057361)>>14;

        }

    }

}


static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap)

{

    AppleHTTPContext *c = s->priv_data;

    int ret = 0, i, j, stream_offset = 0;

    if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)

        goto fail;

    if (c->n_variants == 0) {

        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");

        ret = AVERROR_EOF;

        goto fail;

    }

    /* If the playlist only contained variants, parse each individual

     * variant playlist. */

    if (c->n_variants > 1 || c->variants[0]->n_segments == 0) {

        for (i = 0; i < c->n_variants; i++) {

            struct variant *v = c->variants[i];

            if ((ret = parse_playlist(c, v->url, v, NULL)) < 0)

                goto fail;

        }

    }

    if (c->variants[0]->n_segments == 0) {

        av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");

        ret = AVERROR_EOF;

        goto fail;

    }

    /* If this isn't a live stream, calculate the total duration of the

     * stream. */

    if (c->finished) {

        int duration = 0;

        for (i = 0; i < c->variants[0]->n_segments; i++)

            duration += c->variants[0]->segments[i]->duration;

        s->duration = duration * AV_TIME_BASE;

    }

    c->min_end_seq = INT_MAX;

    /* Open the demuxer for each variant */

    for (i = 0; i < c->n_variants; i++) {

        struct variant *v = c->variants[i];

        if (v->n_segments == 0)

            continue;

        c->max_start_seq = FFMAX(c->max_start_seq, v->start_seq_no);

        c->min_end_seq   = FFMIN(c->min_end_seq,   v->start_seq_no +

                                                   v->n_segments);

        ret = av_open_input_file(&v->ctx, v->segments[0]->url, NULL, 0, NULL);

        if (ret < 0)

            goto fail;

        url_fclose(v->ctx->pb);

        v->ctx->pb = NULL;

        v->stream_offset = stream_offset;

        /* Create new AVStreams for each stream in this variant */

        for (j = 0; j < v->ctx->nb_streams; j++) {

            AVStream *st = av_new_stream(s, i);

            if (!st) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            avcodec_copy_context(st->codec, v->ctx->streams[j]->codec);

        }

        stream_offset += v->ctx->nb_streams;

    }

    c->last_packet_dts = AV_NOPTS_VALUE;

    c->cur_seq_no = c->max_start_seq;

    /* If this is a live stream with more than 3 segments, start at the

     * third last segment. */

    if (!c->finished && c->min_end_seq - c->max_start_seq > 3)

        c->cur_seq_no = c->min_end_seq - 2;

    return 0;

fail:

    free_variant_list(c);

    return ret;

}


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

    const AVFrame *frame, int *got_packet)

{

    NVENCSTATUS nv_status;

    NvencOutputSurface *tmpoutsurf;

    int res, i = 0;

    NvencContext *ctx = avctx->priv_data;

    NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;

    NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs;

    NV_ENC_PIC_PARAMS pic_params = { 0 };

    pic_params.version = NV_ENC_PIC_PARAMS_VER;

    if (frame) {

        NV_ENC_LOCK_INPUT_BUFFER lockBufferParams = { 0 };

        NvencInputSurface *inSurf = NULL;

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

            if (!ctx->input_surfaces[i].lockCount) {

                inSurf = &ctx->input_surfaces[i];

                break;

            }

        }

        av_assert0(inSurf);

        inSurf->lockCount = 1;

        lockBufferParams.version = NV_ENC_LOCK_INPUT_BUFFER_VER;

        lockBufferParams.inputBuffer = inSurf->input_surface;

        nv_status = p_nvenc->nvEncLockInputBuffer(ctx->nvencoder, &lockBufferParams);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_ERROR, "Failed locking nvenc input buffer\n");

            return 0;

        }

        if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {

            uint8_t *buf = lockBufferParams.bufferDataPtr;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);

            buf += inSurf->height * lockBufferParams.pitch;

            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[2], frame->linesize[2],

                avctx->width >> 1, avctx->height >> 1);

            buf += (inSurf->height * lockBufferParams.pitch) >> 2;

            av_image_copy_plane(buf, lockBufferParams.pitch >> 1,

                frame->data[1], frame->linesize[1],

                avctx->width >> 1, avctx->height >> 1);

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

            uint8_t *buf = lockBufferParams.bufferDataPtr;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);

            buf += inSurf->height * lockBufferParams.pitch;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height >> 1);

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

            uint8_t *buf = lockBufferParams.bufferDataPtr;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[0], frame->linesize[0],

                avctx->width, avctx->height);

            buf += inSurf->height * lockBufferParams.pitch;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[1], frame->linesize[1],

                avctx->width, avctx->height);

            buf += inSurf->height * lockBufferParams.pitch;

            av_image_copy_plane(buf, lockBufferParams.pitch,

                frame->data[2], frame->linesize[2],

                avctx->width, avctx->height);

        } else {

            av_log(avctx, AV_LOG_FATAL, "Invalid pixel format!\n");

            return AVERROR(EINVAL);

        }

        nv_status = p_nvenc->nvEncUnlockInputBuffer(ctx->nvencoder, inSurf->input_surface);

        if (nv_status != NV_ENC_SUCCESS) {

            av_log(avctx, AV_LOG_FATAL, "Failed unlocking input buffer!\n");

            return AVERROR_EXTERNAL;

        }

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

            if (!ctx->output_surfaces[i].busy)

                break;

        if (i == ctx->max_surface_count) {

            inSurf->lockCount = 0;

            av_log(avctx, AV_LOG_FATAL, "No free output surface found!\n");

            return AVERROR_EXTERNAL;

        }

        ctx->output_surfaces[i].input_surface = inSurf;

        pic_params.inputBuffer = inSurf->input_surface;

        pic_params.bufferFmt = inSurf->format;

        pic_params.inputWidth = avctx->width;

        pic_params.inputHeight = avctx->height;

        pic_params.outputBitstream = ctx->output_surfaces[i].output_surface;

        pic_params.completionEvent = 0;

        if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {

            if (frame->top_field_first) {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;

            } else {

                pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;

            }

        } else {

            pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;

        }

        pic_params.encodePicFlags = 0;

        pic_params.inputTimeStamp = frame->pts;

        pic_params.inputDuration = 0;

        switch (avctx->codec->id) {

        case AV_CODEC_ID_H264:

          pic_params.codecPicParams.h264PicParams.sliceMode = ctx->encode_config.encodeCodecConfig.h264Config.sliceMode;

          pic_params.codecPicParams.h264PicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.h264Config.sliceModeData;

          break;

        case AV_CODEC_ID_H265:

          pic_params.codecPicParams.hevcPicParams.sliceMode = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceMode;

          pic_params.codecPicParams.hevcPicParams.sliceModeData = ctx->encode_config.encodeCodecConfig.hevcConfig.sliceModeData;

          break;

        default:

          av_log(avctx, AV_LOG_ERROR, "Unknown codec name\n");

          return AVERROR(EINVAL);

        }

        res = timestamp_queue_enqueue(&ctx->timestamp_list, frame->pts);

        if (res)

            return res;

    } else {

        pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;

    }

    nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);

    if (frame && nv_status == NV_ENC_ERR_NEED_MORE_INPUT) {

        res = out_surf_queue_enqueue(&ctx->output_surface_queue, &ctx->output_surfaces[i]);

        if (res)

            return res;

        ctx->output_surfaces[i].busy = 1;

    }

    if (nv_status != NV_ENC_SUCCESS && nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        av_log(avctx, AV_LOG_ERROR, "EncodePicture failed!\n");

        return AVERROR_EXTERNAL;

    }

    if (nv_status != NV_ENC_ERR_NEED_MORE_INPUT) {

        while (ctx->output_surface_queue.count) {

            tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_queue);

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, tmpoutsurf);

            if (res)

                return res;

        }

        if (frame) {

            res = out_surf_queue_enqueue(&ctx->output_surface_ready_queue, &ctx->output_surfaces[i]);

            if (res)

                return res;

            ctx->output_surfaces[i].busy = 1;

        }

    }

    if (ctx->output_surface_ready_queue.count && (!frame || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) {

        tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue);

        res = process_output_surface(avctx, pkt, tmpoutsurf);

        if (res)

            return res;

        tmpoutsurf->busy = 0;

        av_assert0(tmpoutsurf->input_surface->lockCount);

        tmpoutsurf->input_surface->lockCount--;

        *got_packet = 1;

    } else {

        *got_packet = 0;

    }

    return 0;

}


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

{

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

    if((uint64_t)atom.size > (1<<30))

        return -1;

    av_free(st->codec->extradata);

    st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);

    if (!st->codec->extradata)

        return AVERROR(ENOMEM);

    st->codec->extradata_size = atom.size;

    get_buffer(pb, st->codec->extradata, atom.size);

    return 0;

}


static uint64_t find_any_startcode(ByteIOContext *bc, int64_t pos){

    uint64_t state=0;

    if(pos >= 0)

        url_fseek(bc, pos, SEEK_SET); //note, this may fail if the stream isnt seekable, but that shouldnt matter, as in this case we simply start where we are currently

    while(bytes_left(bc)){

        state= (state<<8) | get_byte(bc);

        if((state>>56) != 'N')

            continue;

        switch(state){

        case MAIN_STARTCODE:

        case STREAM_STARTCODE:

        case KEYFRAME_STARTCODE:

        case INFO_STARTCODE:

        case INDEX_STARTCODE:

            return state;

        }

    }

    return 0;

}


static void ape_unpack_stereo(APEContext *ctx, int count)

{

    int32_t left, right;

    int32_t *decoded0 = ctx->decoded[0];

    int32_t *decoded1 = ctx->decoded[1];

    if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {

        /* We are pure silence, so we're done. */

        av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence stereo\n");

        return;

    }

    entropy_decode(ctx, count, 1);

    ape_apply_filters(ctx, decoded0, decoded1, count);

    /* Now apply the predictor decoding */

    predictor_decode_stereo(ctx, count);

    /* Decorrelate and scale to output depth */

    while (count--) {

        left = *decoded1 - (*decoded0 / 2);

        right = left + *decoded0;

        *(decoded0++) = left;

        *(decoded1++) = right;

    }

}


static void jpeg_init_destination(j_compress_ptr cinfo)

{

    VncState *vs = cinfo->client_data;

    Buffer *buffer = &vs->tight_jpeg;

    cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset;

    cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset);

}


static void ref405ep_init (ram_addr_t ram_size,

                           const char *boot_device,

                           const char *kernel_filename,

                           const char *kernel_cmdline,

                           const char *initrd_filename,

                           const char *cpu_model)

{

    char *filename;

    ppc4xx_bd_info_t bd;

    CPUPPCState *env;

    qemu_irq *pic;

    ram_addr_t sram_offset, bios_offset, bdloc;

    target_phys_addr_t ram_bases[2], ram_sizes[2];

    target_ulong sram_size;

    long bios_size;

    //int phy_addr = 0;

    //static int phy_addr = 1;

    target_ulong kernel_base, initrd_base;

    long kernel_size, initrd_size;

    int linux_boot;

    int fl_idx, fl_sectors, len;

    DriveInfo *dinfo;

    /* XXX: fix this */

    ram_bases[0] = qemu_ram_alloc(NULL, "ef405ep.ram", 0x08000000);

    ram_sizes[0] = 0x08000000;

    ram_bases[1] = 0x00000000;

    ram_sizes[1] = 0x00000000;

    ram_size = 128 * 1024 * 1024;

#ifdef DEBUG_BOARD_INIT

    printf("%s: register cpu\n", __func__);

#endif

    env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic,

                        kernel_filename == NULL ? 0 : 1);

    /* allocate SRAM */

    sram_size = 512 * 1024;

    sram_offset = qemu_ram_alloc(NULL, "ef405ep.sram", sram_size);

#ifdef DEBUG_BOARD_INIT

    printf("%s: register SRAM at offset %08lx\n", __func__, sram_offset);

#endif

    cpu_register_physical_memory(0xFFF00000, sram_size,

                                 sram_offset | IO_MEM_RAM);

    /* allocate and load BIOS */

#ifdef DEBUG_BOARD_INIT

    printf("%s: register BIOS\n", __func__);

#endif

    fl_idx = 0;

#ifdef USE_FLASH_BIOS

    dinfo = drive_get(IF_PFLASH, 0, fl_idx);

    if (dinfo) {

        bios_size = bdrv_getlength(dinfo->bdrv);

        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);

        fl_sectors = (bios_size + 65535) >> 16;

#ifdef DEBUG_BOARD_INIT

        printf("Register parallel flash %d size %lx"

               " at offset %08lx addr %lx '%s' %d\n",

               fl_idx, bios_size, bios_offset, -bios_size,

               bdrv_get_device_name(dinfo->bdrv), fl_sectors);

#endif

        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,

                              dinfo->bdrv, 65536, fl_sectors, 1,

                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,

                              1);

        fl_idx++;

    } else

#endif

    {

#ifdef DEBUG_BOARD_INIT

        printf("Load BIOS from file\n");

#endif

        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);

        if (bios_name == NULL)

            bios_name = BIOS_FILENAME;

        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

        if (filename) {

            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));

            g_free(filename);

        } else {

            bios_size = -1;

        }

        if (bios_size < 0 || bios_size > BIOS_SIZE) {

            fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n",

                    bios_name);

            exit(1);

        }

        bios_size = (bios_size + 0xfff) & ~0xfff;

        cpu_register_physical_memory((uint32_t)(-bios_size),

                                     bios_size, bios_offset | IO_MEM_ROM);

    }

    /* Register FPGA */

#ifdef DEBUG_BOARD_INIT

    printf("%s: register FPGA\n", __func__);

#endif

    ref405ep_fpga_init(0xF0300000);

    /* Register NVRAM */

#ifdef DEBUG_BOARD_INIT

    printf("%s: register NVRAM\n", __func__);

#endif

    m48t59_init(NULL, 0xF0000000, 0, 8192, 8);

    /* Load kernel */

    linux_boot = (kernel_filename != NULL);

    if (linux_boot) {

#ifdef DEBUG_BOARD_INIT

        printf("%s: load kernel\n", __func__);

#endif

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

        bd.bi_memstart = 0x00000000;

        bd.bi_memsize = ram_size;

        bd.bi_flashstart = -bios_size;

        bd.bi_flashsize = -bios_size;

        bd.bi_flashoffset = 0;

        bd.bi_sramstart = 0xFFF00000;

        bd.bi_sramsize = sram_size;

        bd.bi_bootflags = 0;

        bd.bi_intfreq = 133333333;

        bd.bi_busfreq = 33333333;

        bd.bi_baudrate = 115200;

        bd.bi_s_version[0] = 'Q';

        bd.bi_s_version[1] = 'M';

        bd.bi_s_version[2] = 'U';

        bd.bi_s_version[3] = '\0';

        bd.bi_r_version[0] = 'Q';

        bd.bi_r_version[1] = 'E';

        bd.bi_r_version[2] = 'M';

        bd.bi_r_version[3] = 'U';

        bd.bi_r_version[4] = '\0';

        bd.bi_procfreq = 133333333;

        bd.bi_plb_busfreq = 33333333;

        bd.bi_pci_busfreq = 33333333;

        bd.bi_opbfreq = 33333333;

        bdloc = ppc405_set_bootinfo(env, &bd, 0x00000001);

        env->gpr[3] = bdloc;

        kernel_base = KERNEL_LOAD_ADDR;

        /* now we can load the kernel */

        kernel_size = load_image_targphys(kernel_filename, kernel_base,

                                          ram_size - kernel_base);

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

        printf("Load kernel size %ld at " TARGET_FMT_lx,

               kernel_size, kernel_base);

        /* load initrd */

        if (initrd_filename) {

            initrd_base = INITRD_LOAD_ADDR;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              ram_size - initrd_base);

            if (initrd_size < 0) {

                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",

                        initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

        env->gpr[4] = initrd_base;

        env->gpr[5] = initrd_size;

        if (kernel_cmdline != NULL) {

            len = strlen(kernel_cmdline);

            bdloc -= ((len + 255) & ~255);

            cpu_physical_memory_write(bdloc, (void *)kernel_cmdline, len + 1);

            env->gpr[6] = bdloc;

            env->gpr[7] = bdloc + len;

        } else {

            env->gpr[6] = 0;

            env->gpr[7] = 0;

        }

        env->nip = KERNEL_LOAD_ADDR;

    } else {

        kernel_base = 0;

        kernel_size = 0;

        initrd_base = 0;

        initrd_size = 0;

        bdloc = 0;

    }

#ifdef DEBUG_BOARD_INIT

    printf("%s: Done\n", __func__);

#endif

    printf("bdloc %016lx\n", (unsigned long)bdloc);

}


void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)

{

    LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);

    if (env->sdr1 != value) {

        /* XXX: for PowerPC 64, should check that the HTABSIZE value

         *      is <= 28

         */

        env->sdr1 = value;

        tlb_flush(env, 1);

    }

}


static void memory_region_finalize(Object *obj)

{

    MemoryRegion *mr = MEMORY_REGION(obj);

    assert(QTAILQ_EMPTY(&mr->subregions));

    assert(memory_region_transaction_depth == 0);

    mr->destructor(mr);

    memory_region_clear_coalescing(mr);

    g_free((char *)mr->name);

    g_free(mr->ioeventfds);

}


static void tgen64_ori(TCGContext *s, TCGReg dest, tcg_target_ulong val)

{

    static const S390Opcode oi_insns[4] = {

        RI_OILL, RI_OILH, RI_OIHL, RI_OIHH

    };

    static const S390Opcode nif_insns[2] = {

        RIL_OILF, RIL_OIHF

    };

    int i;

    /* Look for no-op.  */

    if (val == 0) {

        return;

    }

    if (facilities & FACILITY_EXT_IMM) {

        /* Try all 32-bit insns that can perform it in one go.  */

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

            tcg_target_ulong mask = (0xffffull << i*16);

            if ((val & mask) != 0 && (val & ~mask) == 0) {

                tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);

                return;

            }

        }

        /* Try all 48-bit insns that can perform it in one go.  */

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

            tcg_target_ulong mask = (0xffffffffull << i*32);

            if ((val & mask) != 0 && (val & ~mask) == 0) {

                tcg_out_insn_RIL(s, nif_insns[i], dest, val >> i*32);

                return;

            }

        }

        /* Perform the OR via sequential modifications to the high and

           low parts.  Do this via recursion to handle 16-bit vs 32-bit

           masks in each half.  */

        tgen64_ori(s, dest, val & 0x00000000ffffffffull);

        tgen64_ori(s, dest, val & 0xffffffff00000000ull);

    } else {

        /* With no extended-immediate facility, we don't need to be so

           clever.  Just iterate over the insns and mask in the constant.  */

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

            tcg_target_ulong mask = (0xffffull << i*16);

            if ((val & mask) != 0) {

                tcg_out_insn_RI(s, oi_insns[i], dest, val >> i*16);

            }

        }

    }

}


int xen_be_init(void)

{

    xenstore = xs_daemon_open();

    if (!xenstore) {

        xen_be_printf(NULL, 0, "can't connect to xenstored\n");

        return -1;

    }

    if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) {

        goto err;

    }

    xen_xc = xc_interface_open();

    if (xen_xc == -1) {

        xen_be_printf(NULL, 0, "can't open xen interface\n");

        goto err;

    }

    return 0;

err:

    qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);

    xs_daemon_close(xenstore);

    xenstore = NULL;

    return -1;

}


static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,

                                      InputEvent *evt)

{

    VirtIOInput *vinput = VIRTIO_INPUT(dev);

    virtio_input_event event;

    int qcode;

    switch (evt->kind) {

    case INPUT_EVENT_KIND_KEY:

        qcode = qemu_input_key_value_to_qcode(evt->key->key);

        if (qcode && keymap_qcode[qcode]) {

            event.type  = cpu_to_le16(EV_KEY);

            event.code  = cpu_to_le16(keymap_qcode[qcode]);

            event.value = cpu_to_le32(evt->key->down ? 1 : 0);

            virtio_input_send(vinput, &event);

        } else {

            if (evt->key->down) {

                fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,

                        qcode, QKeyCode_lookup[qcode]);

            }

        }

        break;

    case INPUT_EVENT_KIND_BTN:

        if (keymap_button[evt->btn->button]) {

            event.type  = cpu_to_le16(EV_KEY);

            event.code  = cpu_to_le16(keymap_button[evt->btn->button]);

            event.value = cpu_to_le32(evt->btn->down ? 1 : 0);

            virtio_input_send(vinput, &event);

        } else {

            if (evt->btn->down) {

                fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,

                        evt->btn->button, InputButton_lookup[evt->btn->button]);

            }

        }

        break;

    case INPUT_EVENT_KIND_REL:

        event.type  = cpu_to_le16(EV_REL);

        event.code  = cpu_to_le16(axismap_rel[evt->rel->axis]);

        event.value = cpu_to_le32(evt->rel->value);

        virtio_input_send(vinput, &event);

        break;

    case INPUT_EVENT_KIND_ABS:

        event.type  = cpu_to_le16(EV_ABS);

        event.code  = cpu_to_le16(axismap_abs[evt->abs->axis]);

        event.value = cpu_to_le32(evt->abs->value);

        virtio_input_send(vinput, &event);

        break;

    default:

        /* keep gcc happy */

        break;

    }

}


static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,

                          uint32_t *int_mask, bool queuing)

{

    UHCIAsync *async;

    int len = 0, max_len;

    uint8_t pid;

    USBDevice *dev;

    USBEndpoint *ep;

    /* Is active ? */

    if (!(td->ctrl & TD_CTRL_ACTIVE))

        return TD_RESULT_NEXT_QH;

    async = uhci_async_find_td(s, addr, td);

    if (async) {

        /* Already submitted */

        async->queue->valid = 32;

        if (!async->done)

            return TD_RESULT_ASYNC_CONT;

        if (queuing) {

            /* we are busy filling the queue, we are not prepared

               to consume completed packages then, just leave them

               in async state */

            return TD_RESULT_ASYNC_CONT;

        }

        uhci_async_unlink(async);

        goto done;

    }

    /* Allocate new packet */

    async = uhci_async_alloc(uhci_queue_get(s, td), addr);

    /* valid needs to be large enough to handle 10 frame delay

     * for initial isochronous requests

     */

    async->queue->valid = 32;

    async->isoc = td->ctrl & TD_CTRL_IOS;

    max_len = ((td->token >> 21) + 1) & 0x7ff;

    pid = td->token & 0xff;

    dev = uhci_find_device(s, (td->token >> 8) & 0x7f);

    ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);

    usb_packet_setup(&async->packet, pid, ep, addr);

    qemu_sglist_add(&async->sgl, td->buffer, max_len);

    usb_packet_map(&async->packet, &async->sgl);

    switch(pid) {

    case USB_TOKEN_OUT:

    case USB_TOKEN_SETUP:

        len = usb_handle_packet(dev, &async->packet);

        if (len >= 0)

            len = max_len;

        break;

    case USB_TOKEN_IN:

        len = usb_handle_packet(dev, &async->packet);

        break;

    default:

        /* invalid pid : frame interrupted */

        uhci_async_free(async);

        s->status |= UHCI_STS_HCPERR;

        uhci_update_irq(s);

        return TD_RESULT_STOP_FRAME;

    }

    if (len == USB_RET_ASYNC) {

        uhci_async_link(async);

        return TD_RESULT_ASYNC_START;

    }

    async->packet.result = len;

done:

    len = uhci_complete_td(s, td, async, int_mask);

    usb_packet_unmap(&async->packet, &async->sgl);

    uhci_async_free(async);

    return len;

}


static void xen_pt_region_update(XenPCIPassthroughState *s,

                                 MemoryRegionSection *sec, bool adding)

{

    PCIDevice *d = &s->dev;

    MemoryRegion *mr = sec->mr;

    int bar = -1;

    int rc;

    int op = adding ? DPCI_ADD_MAPPING : DPCI_REMOVE_MAPPING;

    struct CheckBarArgs args = {

        .s = s,

        .addr = sec->offset_within_address_space,

        .size = int128_get64(sec->size),

        .rc = false,

    };

    bar = xen_pt_bar_from_region(s, mr);

    if (bar == -1 && (!s->msix || &s->msix->mmio != mr)) {

        return;

    }

    if (s->msix && &s->msix->mmio == mr) {

        if (adding) {

            s->msix->mmio_base_addr = sec->offset_within_address_space;

            rc = xen_pt_msix_update_remap(s, s->msix->bar_index);

        }

        return;

    }

    args.type = d->io_regions[bar].type;

    pci_for_each_device(d->bus, pci_bus_num(d->bus),

                        xen_pt_check_bar_overlap, &args);

    if (args.rc) {

        XEN_PT_WARN(d, "Region: %d (addr: %#"FMT_PCIBUS

                    ", len: %#"FMT_PCIBUS") is overlapped.\n",

                    bar, sec->offset_within_address_space,

                    int128_get64(sec->size));

    }

    if (d->io_regions[bar].type & PCI_BASE_ADDRESS_SPACE_IO) {

        uint32_t guest_port = sec->offset_within_address_space;

        uint32_t machine_port = s->bases[bar].access.pio_base;

        uint32_t size = int128_get64(sec->size);

        rc = xc_domain_ioport_mapping(xen_xc, xen_domid,

                                      guest_port, machine_port, size,

                                      op);

        if (rc) {

            XEN_PT_ERR(d, "%s ioport mapping failed! (err: %i)\n",

                       adding ? "create new" : "remove old", errno);

        }

    } else {

        pcibus_t guest_addr = sec->offset_within_address_space;

        pcibus_t machine_addr = s->bases[bar].access.maddr

            + sec->offset_within_region;

        pcibus_t size = int128_get64(sec->size);

        rc = xc_domain_memory_mapping(xen_xc, xen_domid,

                                      XEN_PFN(guest_addr + XC_PAGE_SIZE - 1),

                                      XEN_PFN(machine_addr + XC_PAGE_SIZE - 1),

                                      XEN_PFN(size + XC_PAGE_SIZE - 1),

                                      op);

        if (rc) {

            XEN_PT_ERR(d, "%s mem mapping failed! (err: %i)\n",

                       adding ? "create new" : "remove old", errno);

        }

    }

}


static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)

{

    int i, j, sir_intr, p_intr, p, f;

    uint32_t level;

    sir_intr = 0;

    p_intr = 255;

    /* Find the interrupt line with the highest dynamic priority.

     * Note: 0 denotes the hightest priority.

     * If all interrupts have the same priority, the default order is IRQ_N,

     * IRQ_N-1,...,IRQ_0. */

    for (j = 0; j < s->nbanks; ++j) {

        level = s->bank[j].irqs & ~s->bank[j].mask &

                (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);

        for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,

                        level >>= f) {

            p = s->bank[j].priority[i];

            if (p <= p_intr) {

                p_intr = p;

                sir_intr = 32 * j + i;

            }

            f = ffs(level >> 1);

        }

    }

    s->sir_intr[is_fiq] = sir_intr;

}


static int coroutine_fn bdrv_co_do_writev(BdrvChild *child,

    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov,

    BdrvRequestFlags flags)

{

    if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) {

        return -EINVAL;

    }

    return bdrv_co_pwritev(child->bs, sector_num << BDRV_SECTOR_BITS,

                           nb_sectors << BDRV_SECTOR_BITS, qiov, flags);

}


static int decorrelate(TAKDecContext *s, int c1, int c2, int length)

{

    GetBitContext *gb = &s->gb;

    int32_t *p1       = s->decoded[c1] + (s->dmode > 5);

    int32_t *p2       = s->decoded[c2] + (s->dmode > 5);

    int32_t bp1       = p1[0];

    int32_t bp2       = p2[0];

    int i;

    int dshift, dfactor;

    length += s->dmode < 6;

    switch (s->dmode) {

    case 1: /* left/side */

        s->tdsp.decorrelate_ls(p1, p2, length);

        break;

    case 2: /* side/right */

        s->tdsp.decorrelate_sr(p1, p2, length);

        break;

    case 3: /* side/mid */

        s->tdsp.decorrelate_sm(p1, p2, length);

        break;

    case 4: /* side/left with scale factor */

        FFSWAP(int32_t*, p1, p2);

        FFSWAP(int32_t, bp1, bp2);

    case 5: /* side/right with scale factor */

        dshift  = get_bits_esc4(gb);

        dfactor = get_sbits(gb, 10);

        s->tdsp.decorrelate_sf(p1, p2, length, dshift, dfactor);

        break;

    case 6:

        FFSWAP(int32_t*, p1, p2);

    case 7: {

        int length2, order_half, filter_order, dval1, dval2;

        int tmp, x, code_size;

        if (length < 256)

            return AVERROR_INVALIDDATA;

        dshift       = get_bits_esc4(gb);

        filter_order = 8 << get_bits1(gb);

        dval1        = get_bits1(gb);

        dval2        = get_bits1(gb);

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

            if (!(i & 3))

                code_size = 14 - get_bits(gb, 3);

            s->filter[i] = get_sbits(gb, code_size);

        }

        order_half = filter_order / 2;

        length2    = length - (filter_order - 1);

        /* decorrelate beginning samples */

        if (dval1) {

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

                int32_t a = p1[i];

                int32_t b = p2[i];

                p1[i]     = a + b;

            }

        }

        /* decorrelate ending samples */

        if (dval2) {

            for (i = length2 + order_half; i < length; i++) {

                int32_t a = p1[i];

                int32_t b = p2[i];

                p1[i]     = a + b;

            }

        }

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

            s->residues[i] = *p2++ >> dshift;

        p1 += order_half;

        x = FF_ARRAY_ELEMS(s->residues) - filter_order;

        for (; length2 > 0; length2 -= tmp) {

            tmp = FFMIN(length2, x);

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

                s->residues[filter_order + i] = *p2++ >> dshift;

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

                int v = 1 << 9;

                if (filter_order == 16) {

                    v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,

                                                     filter_order);

                } else {

                    v += s->residues[i + 7] * s->filter[7] +

                         s->residues[i + 6] * s->filter[6] +

                         s->residues[i + 5] * s->filter[5] +

                         s->residues[i + 4] * s->filter[4] +

                         s->residues[i + 3] * s->filter[3] +

                         s->residues[i + 2] * s->filter[2] +

                         s->residues[i + 1] * s->filter[1] +

                         s->residues[i    ] * s->filter[0];

                }

                v = (av_clip_intp2(v >> 10, 13) << dshift) - *p1;

                *p1++ = v;

            }

            memmove(s->residues, &s->residues[tmp], 2 * filter_order);

        }

        emms_c();

        break;

    }

    }

    if (s->dmode > 0 && s->dmode < 6) {

        p1[0] = bp1;

        p2[0] = bp2;

    }

    return 0;

}


static MegasasCmd *megasas_lookup_frame(MegasasState *s,

    target_phys_addr_t frame)

{

    MegasasCmd *cmd = NULL;

    int num = 0, index;

    index = s->reply_queue_head;

    while (num < s->fw_cmds) {

        if (s->frames[index].pa && s->frames[index].pa == frame) {

            cmd = &s->frames[index];

            break;

        }

        index = megasas_next_index(s, index, s->fw_cmds);

        num++;

    }

    return cmd;

}


static int ebml_parse_elem(MatroskaDemuxContext *matroska,

                           EbmlSyntax *syntax, void *data)

{

    static const uint64_t max_lengths[EBML_TYPE_COUNT] = {

        [EBML_UINT]  = 8,

        [EBML_FLOAT] = 8,

        // max. 16 MB for strings

        [EBML_STR]   = 0x1000000,

        [EBML_UTF8]  = 0x1000000,

        // max. 256 MB for binary data

        [EBML_BIN]   = 0x10000000,

        // no limits for anything else

    };

    AVIOContext *pb = matroska->ctx->pb;

    uint32_t id = syntax->id;

    uint64_t length;

    int res;

    data = (char *)data + syntax->data_offset;

    if (syntax->list_elem_size) {

        EbmlList *list = data;

        list->elem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size);

        data = (char*)list->elem + list->nb_elem*syntax->list_elem_size;

        memset(data, 0, syntax->list_elem_size);

        list->nb_elem++;

    }

    if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) {

        matroska->current_id = 0;

        if ((res = ebml_read_length(matroska, pb, &length)) < 0)

            return res;

        if (max_lengths[syntax->type] && length > max_lengths[syntax->type]) {

            av_log(matroska->ctx, AV_LOG_ERROR,

                   "Invalid length 0x%"PRIx64" > 0x%"PRIx64" for syntax element %i\n",

                   length, max_lengths[syntax->type], syntax->type);

            return AVERROR_INVALIDDATA;

        }

    }

    switch (syntax->type) {

    case EBML_UINT:  res = ebml_read_uint  (pb, length, data);  break;

    case EBML_FLOAT: res = ebml_read_float (pb, length, data);  break;

    case EBML_STR:

    case EBML_UTF8:  res = ebml_read_ascii (pb, length, data);  break;

    case EBML_BIN:   res = ebml_read_binary(pb, length, data);  break;

    case EBML_NEST:  if ((res=ebml_read_master(matroska, length)) < 0)

                         return res;

                     if (id == MATROSKA_ID_SEGMENT)

                         matroska->segment_start = avio_tell(matroska->ctx->pb);

                     return ebml_parse_nest(matroska, syntax->def.n, data);

    case EBML_PASS:  return ebml_parse_id(matroska, syntax->def.n, id, data);

    case EBML_STOP:  return 1;

    default:         return avio_skip(pb,length)<0 ? AVERROR(EIO) : 0;

    }

    if (res == AVERROR_INVALIDDATA)

        av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n");

    else if (res == AVERROR(EIO))

        av_log(matroska->ctx, AV_LOG_ERROR, "Read error\n");

    return res;

}


static int ehci_init_transfer(EHCIPacket *p)

{

    uint32_t cpage, offset, bytes, plen;

    dma_addr_t page;

    cpage  = get_field(p->qtd.token, QTD_TOKEN_CPAGE);

    bytes  = get_field(p->qtd.token, QTD_TOKEN_TBYTES);

    offset = p->qtd.bufptr[0] & ~QTD_BUFPTR_MASK;

    qemu_sglist_init(&p->sgl, p->queue->ehci->device, 5, p->queue->ehci->as);

    while (bytes > 0) {

        if (cpage > 4) {

            fprintf(stderr, "cpage out of range (%d)\n", cpage);

            return -1;

        }

        page  = p->qtd.bufptr[cpage] & QTD_BUFPTR_MASK;

        page += offset;

        plen  = bytes;

        if (plen > 4096 - offset) {

            plen = 4096 - offset;

            offset = 0;

            cpage++;

        }

        qemu_sglist_add(&p->sgl, page, plen);

        bytes -= plen;

    }

    return 0;

}


static target_long monitor_get_pc (const struct MonitorDef *md, int val)

{

    CPUState *env = mon_get_cpu();

    if (!env)

        return 0;

    return env->eip + env->segs[R_CS].base;

}


static void gen_stswi(DisasContext *ctx)

{

    TCGv t0;

    TCGv_i32 t1, t2;

    int nb = NB(ctx->opcode);

    gen_set_access_type(ctx, ACCESS_INT);

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

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

    t0 = tcg_temp_new();

    gen_addr_register(ctx, t0);

    if (nb == 0)

        nb = 32;

    t1 = tcg_const_i32(nb);

    t2 = tcg_const_i32(rS(ctx->opcode));

    gen_helper_stsw(cpu_env, t0, t1, t2);

    tcg_temp_free(t0);

    tcg_temp_free_i32(t1);

    tcg_temp_free_i32(t2);

}


static void bufp_alloc(USBRedirDevice *dev,

    uint8_t *data, int len, int status, uint8_t ep)

{

    struct buf_packet *bufp;

    if (!dev->endpoint[EP2I(ep)].bufpq_dropping_packets &&

        dev->endpoint[EP2I(ep)].bufpq_size >

            2 * dev->endpoint[EP2I(ep)].bufpq_target_size) {

        DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);

        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;

    }

    /* Since we're interupting the stream anyways, drop enough packets to get

       back to our target buffer size */

    if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {

        if (dev->endpoint[EP2I(ep)].bufpq_size >

                dev->endpoint[EP2I(ep)].bufpq_target_size) {

            free(data);

            return;

        }

        dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;

    }

    bufp = g_malloc(sizeof(struct buf_packet));

    bufp->data   = data;

    bufp->len    = len;

    bufp->status = status;

    QTAILQ_INSERT_TAIL(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);

    dev->endpoint[EP2I(ep)].bufpq_size++;

}


static int vmdk_open_vmfs_sparse(BlockDriverState *bs,

                                 BlockDriverState *file,

                                 int flags, Error **errp)

{

    int ret;

    uint32_t magic;

    VMDK3Header header;

    VmdkExtent *extent;

    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));

    if (ret < 0) {

        error_setg_errno(errp, -ret,

                         "Could not read header from file '%s'",

                         file->filename);

        return ret;

    }

    ret = vmdk_add_extent(bs, file, false,

                          le32_to_cpu(header.disk_sectors),

                          le32_to_cpu(header.l1dir_offset) << 9,

                          0,

                          le32_to_cpu(header.l1dir_size),

                          4096,

                          le32_to_cpu(header.granularity),

                          &extent,

                          errp);

    if (ret < 0) {

        return ret;

    }

    ret = vmdk_init_tables(bs, extent, errp);

    if (ret) {

        /* free extent allocated by vmdk_add_extent */

        vmdk_free_last_extent(bs);

    }

    return ret;

}


static int au_write_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    AVCodecContext *enc = s->streams[0]->codec;

    if (!enc->codec_tag)

        return AVERROR(EINVAL);

    ffio_wfourcc(pb, ".snd");                   /* magic number */

    avio_wb32(pb, AU_HEADER_SIZE);              /* header size */

    avio_wb32(pb, AU_UNKNOWN_SIZE);             /* data size */

    avio_wb32(pb, enc->codec_tag);              /* codec ID */

    avio_wb32(pb, enc->sample_rate);

    avio_wb32(pb, enc->channels);

    avio_wb64(pb, 0); /* annotation field */

    avio_flush(pb);

    return 0;

}


static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *request)

{

    NBDClient *client = req->client;

    int csock = client->sock;

    ssize_t rc;

    client->recv_coroutine = qemu_coroutine_self();

    if (nbd_receive_request(csock, request) == -1) {

        rc = -EIO;

        goto out;

    }

    if (request->len > NBD_BUFFER_SIZE) {

        LOG("len (%u) is larger than max len (%u)",

            request->len, NBD_BUFFER_SIZE);

        rc = -EINVAL;

        goto out;

    }

    if ((request->from + request->len) < request->from) {

        LOG("integer overflow detected! "

            "you're probably being attacked");

        rc = -EINVAL;

        goto out;

    }

    TRACE("Decoding type");

    if ((request->type & NBD_CMD_MASK_COMMAND) == NBD_CMD_WRITE) {

        TRACE("Reading %u byte(s)", request->len);

        if (qemu_co_recv(csock, req->data, request->len) != request->len) {

            LOG("reading from socket failed");

            rc = -EIO;

            goto out;

        }

    }

    rc = 0;

out:

    client->recv_coroutine = NULL;

    return rc;

}


static int pci_vga_initfn(PCIDevice *dev)

{

     PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);

     VGACommonState *s = &d->vga;

     uint8_t *pci_conf = d->dev.config;

     // vga + console init

     vga_common_init(s, VGA_RAM_SIZE);

     vga_init(s);

     s->ds = graphic_console_init(s->update, s->invalidate,

                                  s->screen_dump, s->text_update, s);

     // dummy VGA (same as Bochs ID)

     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU);

     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA);

     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);

     /* XXX: VGA_RAM_SIZE must be a power of two */

     pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,

                      PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);

     if (!dev->rom_bar) {

         /* compatibility with pc-0.13 and older */

         vga_init_vbe(s);

     }

     return 0;

}


void portio_list_add(PortioList *piolist,

                     MemoryRegion *address_space,

                     uint32_t start)

{

    const MemoryRegionPortio *pio, *pio_start = piolist->ports;

    unsigned int off_low, off_high, off_last, count;

    piolist->address_space = address_space;

    /* Handle the first entry specially.  */

    off_last = off_low = pio_start->offset;

    off_high = off_low + pio_start->len;

    count = 1;

    for (pio = pio_start + 1; pio->size != 0; pio++, count++) {

        /* All entries must be sorted by offset.  */

        assert(pio->offset >= off_last);

        off_last = pio->offset;

        /* If we see a hole, break the region.  */

        if (off_last > off_high) {

            portio_list_add_1(piolist, pio_start, count, start, off_low,

                              off_high);

            /* ... and start collecting anew.  */

            pio_start = pio;

            off_low = off_last;

            off_high = off_low + pio->len;

            count = 0;

        } else if (off_last + pio->len > off_high) {

            off_high = off_last + pio->len;

        }

    }

    /* There will always be an open sub-list.  */

    portio_list_add_1(piolist, pio_start, count, start, off_low, off_high);

}


void qemu_console_resize(QEMUConsole *console, int width, int height)

{

    if (console->g_width != width || console->g_height != height) {

        console->g_width = width;

        console->g_height = height;

        if (active_console == console) {

            dpy_resize(console->ds, width, height);

        }

    }

}


static void coroutine_fn bdrv_get_block_status_co_entry(void *opaque)

{

    BdrvCoGetBlockStatusData *data = opaque;

    BlockDriverState *bs = data->bs;

    data->ret = bdrv_co_get_block_status(bs, data->sector_num, data->nb_sectors,

                                         data->pnum);

    data->done = true;

}