static int inet_connect_addr(struct addrinfo *addr, bool block,

                             bool *in_progress)

{

    int sock, rc;

    if (in_progress) {

        *in_progress = false;

    }

    sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

    if (sock < 0) {

        fprintf(stderr, "%s: socket(%s): %s\n", __func__,

                inet_strfamily(addr->ai_family), strerror(errno));

        return -1;

    }

    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    if (!block) {

        socket_set_nonblock(sock);

    }

    /* connect to peer */

    do {

        rc = 0;

        if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {

            rc = -socket_error();

        }

    } while (rc == -EINTR);

    if (!block && QEMU_SOCKET_RC_INPROGRESS(rc)) {

        if (in_progress) {

            *in_progress = true;

        }

    } else if (rc < 0) {

        closesocket(sock);

        return -1;

    }

    return sock;

}


static void gen_rfci(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    /* Restore CPU state */

    gen_helper_rfci(cpu_env);

    gen_sync_exception(ctx);

#endif

}


static int opt_new_stream(const char *opt, const char *arg)

{

    AVFormatContext *oc;

    if (nb_output_files <= 0) {

        fprintf(stderr, "At least one output file must be specified\n");

        ffmpeg_exit(1);

    }

    oc = output_files[nb_output_files - 1];

    if      (!strcmp(opt, "newvideo"   )) new_video_stream   (oc);

    else if (!strcmp(opt, "newaudio"   )) new_audio_stream   (oc);

    else if (!strcmp(opt, "newsubtitle")) new_subtitle_stream(oc);

    else av_assert0(0);

    return 0;

}


void ff_vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)

{

    unsigned char *end;

    int filter_value;

    const int nstride= -stride;

    for (end= first_pixel + 8; first_pixel < end; first_pixel++) {

        filter_value =

            (first_pixel[2 * nstride] - first_pixel[ stride])

         +3*(first_pixel[0          ] - first_pixel[nstride]);

        filter_value = bounding_values[(filter_value + 4) >> 3];

        first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);

        first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);

    }

}


void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[4]){

    int w_align= 1;

    int h_align= 1;

    switch(s->pix_fmt){

    case PIX_FMT_YUV420P:

    case PIX_FMT_YUYV422:

    case PIX_FMT_UYVY422:

    case PIX_FMT_YUV422P:

    case PIX_FMT_YUV440P:

    case PIX_FMT_YUV444P:

    case PIX_FMT_GRAY8:

    case PIX_FMT_GRAY16BE:

    case PIX_FMT_GRAY16LE:

    case PIX_FMT_YUVJ420P:

    case PIX_FMT_YUVJ422P:

    case PIX_FMT_YUVJ440P:

    case PIX_FMT_YUVJ444P:

    case PIX_FMT_YUVA420P:

    case PIX_FMT_YUV420P9LE:

    case PIX_FMT_YUV420P9BE:

    case PIX_FMT_YUV420P10LE:

    case PIX_FMT_YUV420P10BE:

    case PIX_FMT_YUV422P10LE:

    case PIX_FMT_YUV422P10BE:

        w_align= 16; //FIXME check for non mpeg style codecs and use less alignment

        h_align= 16;

        if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264)

            h_align= 32; // interlaced is rounded up to 2 MBs

        break;

    case PIX_FMT_YUV411P:

    case PIX_FMT_UYYVYY411:

        w_align=32;

        h_align=8;

        break;

    case PIX_FMT_YUV410P:

        if(s->codec_id == CODEC_ID_SVQ1){

            w_align=64;

            h_align=64;

        }

    case PIX_FMT_RGB555:

        if(s->codec_id == CODEC_ID_RPZA){

            w_align=4;

            h_align=4;

        }

    case PIX_FMT_PAL8:

    case PIX_FMT_BGR8:

    case PIX_FMT_RGB8:

        if(s->codec_id == CODEC_ID_SMC){

            w_align=4;

            h_align=4;

        }

        break;

    case PIX_FMT_BGR24:

        if((s->codec_id == CODEC_ID_MSZH) || (s->codec_id == CODEC_ID_ZLIB)){

            w_align=4;

            h_align=4;

        }

        break;

    default:

        w_align= 1;

        h_align= 1;

        break;

    }

    *width = FFALIGN(*width , w_align);

    *height= FFALIGN(*height, h_align);

    if(s->codec_id == CODEC_ID_H264 || s->lowres)

        *height+=2; // some of the optimized chroma MC reads one line too much

                    // which is also done in mpeg decoders with lowres > 0

    linesize_align[0] =

    linesize_align[1] =

    linesize_align[2] =

    linesize_align[3] = STRIDE_ALIGN;

//STRIDE_ALIGN is 8 for SSE* but this does not work for SVQ1 chroma planes

//we could change STRIDE_ALIGN to 16 for x86/sse but it would increase the

//picture size unneccessarily in some cases. The solution here is not

//pretty and better ideas are welcome!

#if HAVE_MMX

    if(s->codec_id == CODEC_ID_SVQ1 || s->codec_id == CODEC_ID_VP5 ||

       s->codec_id == CODEC_ID_VP6 || s->codec_id == CODEC_ID_VP6F ||

       s->codec_id == CODEC_ID_VP6A) {

        linesize_align[0] =

        linesize_align[1] =

        linesize_align[2] = 16;

    }

#endif

}


static int h264_slice_header_parse(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 frame_num, droppable, picture_structure;

    int mb_aff_frame = 0;

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

    if (sl->first_mb_addr == 0) { // FIXME better field boundary detection

        if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {

            ff_h264_field_end(h, sl, 1);

        }

        h->current_slice = 0;

        if (!h->first_field) {

            if (h->cur_pic_ptr && !h->droppable) {

                ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,

                                          h->picture_structure == PICT_BOTTOM_FIELD);

            }

            h->cur_pic_ptr = NULL;

        }

    }

    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  == 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;

    }

    if (h->current_slice > 0 &&

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

        av_log(h->avctx, AV_LOG_ERROR, "PPS changed between slices\n");

        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;

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

    if (!h->setup_finished)

        h->poc.frame_num = frame_num;

    sl->mb_mbaff       = 0;

    droppable = nal->ref_idc == 0;

    if (sps->frame_mbs_only_flag) {

        picture_structure = PICT_FRAME;

    } else {

        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;

            mb_aff_frame      = sps->mb_aff;

        }

    }

    if (!h->setup_finished) {

        h->mb_aff_frame      = mb_aff_frame;

    }

    sl->picture_structure      = picture_structure;

    sl->mb_field_decoding_flag = picture_structure != PICT_FRAME;

    if (h->current_slice != 0) {

        if (h->picture_structure != picture_structure ||

            h->droppable         != droppable) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Changing field mode (%d -> %d) between slices is not allowed\n",

                   h->picture_structure, picture_structure);

            return AVERROR_INVALIDDATA;

        } else if (!h->cur_pic_ptr) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "unset cur_pic_ptr on slice %d\n",

                   h->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

    }

    if (picture_structure == PICT_FRAME) {

        h->curr_pic_num = h->poc.frame_num;

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

    } else {

        h->curr_pic_num = 2 * h->poc.frame_num + 1;

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

    }

    if (nal->type == NAL_IDR_SLICE)

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

    if (sps->poc_type == 0) {

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

        if (!h->setup_finished)

            h->poc.poc_lsb = poc_lsb;

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

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

            if (!h->setup_finished)

                h->poc.delta_poc_bottom = delta_poc_bottom;

        }

    }

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

        int delta_poc = get_se_golomb(&sl->gb);

        if (!h->setup_finished)

            h->poc.delta_poc[0] = delta_poc;

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

            delta_poc = get_se_golomb(&sl->gb);

            if (!h->setup_finished)

                h->poc.delta_poc[1] = delta_poc;

        }

    }

    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);

    if (ret < 0)

        return ret;

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(h, sl);

       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))

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

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

    sl->explicit_ref_marking = 0;

    if (nal->ref_idc) {

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

        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 mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)

{

    int i, csize = 1;

    void *src[3];

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

        if (tile->codsty[0].transform != tile->codsty[i].transform) {

            av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n");

            return;

        }

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

        if (tile->codsty[0].transform == FF_DWT97)

            src[i] = tile->comp[i].f_data;

        else

            src[i] = tile->comp[i].i_data;

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

        csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];

    s->dsp.mct_decode[tile->codsty[0].transform](src[0], src[1], src[2], csize);

}


static inline void RENAME(rgb2rgb_init)(void)

{

#if !COMPILE_TEMPLATE_SSE2

#if !COMPILE_TEMPLATE_AMD3DNOW

    rgb15to16          = RENAME(rgb15to16);

    rgb15tobgr24       = RENAME(rgb15tobgr24);

    rgb15to32          = RENAME(rgb15to32);

    rgb16tobgr24       = RENAME(rgb16tobgr24);

    rgb16to32          = RENAME(rgb16to32);

    rgb16to15          = RENAME(rgb16to15);

    rgb24tobgr16       = RENAME(rgb24tobgr16);

    rgb24tobgr15       = RENAME(rgb24tobgr15);

    rgb24tobgr32       = RENAME(rgb24tobgr32);

    rgb32to16          = RENAME(rgb32to16);

    rgb32to15          = RENAME(rgb32to15);

    rgb32tobgr24       = RENAME(rgb32tobgr24);

    rgb24to15          = RENAME(rgb24to15);

    rgb24to16          = RENAME(rgb24to16);

    rgb24tobgr24       = RENAME(rgb24tobgr24);

    shuffle_bytes_2103 = RENAME(shuffle_bytes_2103);

    rgb32tobgr16       = RENAME(rgb32tobgr16);

    rgb32tobgr15       = RENAME(rgb32tobgr15);

    yv12toyuy2         = RENAME(yv12toyuy2);

    yv12touyvy         = RENAME(yv12touyvy);

    yuv422ptoyuy2      = RENAME(yuv422ptoyuy2);

    yuv422ptouyvy      = RENAME(yuv422ptouyvy);

    yuy2toyv12         = RENAME(yuy2toyv12);

    vu9_to_vu12        = RENAME(vu9_to_vu12);

    yvu9_to_yuy2       = RENAME(yvu9_to_yuy2);

    uyvytoyuv422       = RENAME(uyvytoyuv422);

    yuyvtoyuv422       = RENAME(yuyvtoyuv422);

#endif /* !COMPILE_TEMPLATE_AMD3DNOW */

#if COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW

    planar2x           = RENAME(planar2x);

#endif /* COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW */

    rgb24toyv12        = RENAME(rgb24toyv12);

    yuyvtoyuv420       = RENAME(yuyvtoyuv420);

    uyvytoyuv420       = RENAME(uyvytoyuv420);

#endif /* !COMPILE_TEMPLATE_SSE2 */

#if !COMPILE_TEMPLATE_AMD3DNOW

    interleaveBytes    = RENAME(interleaveBytes);

#endif /* !COMPILE_TEMPLATE_AMD3DNOW */

}


static int hls_write_header(AVFormatContext *s)

{

    HLSContext *hls = s->priv_data;

    int ret, i;

    char *p;

    const char *pattern = "%d.ts";

    int basename_size = strlen(s->filename) + strlen(pattern);

    hls->number      = 0;

    hls->recording_time = hls->time * 1000000;

    hls->start_pts      = AV_NOPTS_VALUE;

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

        hls->has_video +=

            s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO;

    if (hls->has_video > 1)

        av_log(s, AV_LOG_WARNING,

               "More than a single video stream present, "

               "expect issues decoding it.\n");

    hls->oformat = av_guess_format("mpegts", NULL, NULL);

    if (!hls->oformat) {

        ret = AVERROR_MUXER_NOT_FOUND;

        goto fail;

    }

    hls->basename = av_malloc(basename_size);

    if (!hls->basename) {

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    strcpy(hls->basename, s->filename);

    p = strrchr(hls->basename, '.');

    if (p)

        *p = '\0';

    av_strlcat(hls->basename, "%d.ts", basename_size);

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

        goto fail;

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

        goto fail;

    if ((ret = avformat_write_header(hls->avf, NULL)) < 0)

        return ret;

fail:

    if (ret) {

        av_free(hls->basename);

        if (hls->avf)

            avformat_free_context(hls->avf);

    }

    return ret;

}


static inline void RENAME(bgr24ToY)(uint8_t *dst, uint8_t *src, long width)

{

#ifdef HAVE_MMX

	asm volatile(

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

		"movq "MANGLE(bgr2YCoeff)", %%mm6		\n\t"

		"movq "MANGLE(w1111)", %%mm5		\n\t"

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

		"lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"\n\t"

		ASMALIGN(4)

		"1:				\n\t"

		PREFETCH" 64(%0, %%"REG_d")	\n\t"

		"movd (%0, %%"REG_d"), %%mm0	\n\t"

		"movd 3(%0, %%"REG_d"), %%mm1	\n\t"

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

		"punpcklbw %%mm7, %%mm1		\n\t"

		"movd 6(%0, %%"REG_d"), %%mm2	\n\t"

		"movd 9(%0, %%"REG_d"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm0		\n\t"

		"pmaddwd %%mm6, %%mm1		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

		"pmaddwd %%mm6, %%mm3		\n\t"

#ifndef FAST_BGR2YV12

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

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

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

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

		"packssdw %%mm3, %%mm2		\n\t"

		"pmaddwd %%mm5, %%mm0		\n\t"

		"pmaddwd %%mm5, %%mm2		\n\t"

		"packssdw %%mm2, %%mm0		\n\t"

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

		"movd 12(%0, %%"REG_d"), %%mm4	\n\t"

		"movd 15(%0, %%"REG_d"), %%mm1	\n\t"

		"punpcklbw %%mm7, %%mm4		\n\t"

		"punpcklbw %%mm7, %%mm1		\n\t"

		"movd 18(%0, %%"REG_d"), %%mm2	\n\t"

		"movd 21(%0, %%"REG_d"), %%mm3	\n\t"

		"punpcklbw %%mm7, %%mm2		\n\t"

		"punpcklbw %%mm7, %%mm3		\n\t"

		"pmaddwd %%mm6, %%mm4		\n\t"

		"pmaddwd %%mm6, %%mm1		\n\t"

		"pmaddwd %%mm6, %%mm2		\n\t"

		"pmaddwd %%mm6, %%mm3		\n\t"

#ifndef FAST_BGR2YV12

		"psrad $8, %%mm4		\n\t"

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

		"psrad $8, %%mm2		\n\t"

		"psrad $8, %%mm3		\n\t"

#endif

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

		"packssdw %%mm3, %%mm2		\n\t"

		"pmaddwd %%mm5, %%mm4		\n\t"

		"pmaddwd %%mm5, %%mm2		\n\t"

		"add $24, %%"REG_d"		\n\t"

		"packssdw %%mm2, %%mm4		\n\t"

		"psraw $7, %%mm4		\n\t"

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

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

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

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

		" js 1b				\n\t"

		: : "r" (src+width*3), "r" (dst+width), "g" (-width)

		: "%"REG_a, "%"REG_d

	);

#else

	int i;

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

	{

		int b= src[i*3+0];

		int g= src[i*3+1];

		int r= src[i*3+2];

		dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);

	}

#endif

}


static void vvfat_close(BlockDriverState *bs)

{

    BDRVVVFATState *s = bs->opaque;

    vvfat_close_current_file(s);

    array_free(&(s->fat));

    array_free(&(s->directory));

    array_free(&(s->mapping));

    if(s->cluster_buffer)

        free(s->cluster_buffer);

}


static int ivi_mc(ivi_mc_func mc, int16_t *buf, const int16_t *ref_buf,

                  int offs, int mv_x, int mv_y, uint32_t pitch,

                  int mc_type)

{

    int ref_offs = offs + mv_y * pitch + mv_x;

    if (offs < 0 || ref_offs < 0 || !ref_buf)

        return AVERROR_INVALIDDATA;

    mc(buf + offs, ref_buf + ref_offs, pitch, mc_type);

    return 0;

}


static void test_io_channel_setup_sync(SocketAddressLegacy *listen_addr,

                                       SocketAddressLegacy *connect_addr,

                                       QIOChannel **src,

                                       QIOChannel **dst)

{

    QIOChannelSocket *lioc;

    lioc = qio_channel_socket_new();

    qio_channel_socket_listen_sync(lioc, listen_addr, &error_abort);

    if (listen_addr->type == SOCKET_ADDRESS_LEGACY_KIND_INET) {

        SocketAddressLegacy *laddr = qio_channel_socket_get_local_address(

            lioc, &error_abort);

        g_free(connect_addr->u.inet.data->port);

        connect_addr->u.inet.data->port = g_strdup(laddr->u.inet.data->port);

        qapi_free_SocketAddressLegacy(laddr);

    }

    *src = QIO_CHANNEL(qio_channel_socket_new());

    qio_channel_socket_connect_sync(

        QIO_CHANNEL_SOCKET(*src), connect_addr, &error_abort);

    qio_channel_set_delay(*src, false);

    qio_channel_wait(QIO_CHANNEL(lioc), G_IO_IN);

    *dst = QIO_CHANNEL(qio_channel_socket_accept(lioc, &error_abort));

    g_assert(*dst);

    test_io_channel_set_socket_bufs(*src, *dst);

    object_unref(OBJECT(lioc));

}


static void monitor_readline(const char *prompt, int is_password,

                             char *buf, int buf_size)

{

    readline_start(prompt, is_password, monitor_readline_cb, NULL);

    readline_show_prompt();

    monitor_readline_buf = buf;

    monitor_readline_buf_size = buf_size;

    monitor_readline_started = 1;

    while (monitor_readline_started) {

        main_loop_wait(10);

    }

}


static int cllc_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_picture_ptr, AVPacket *avpkt)
{
    CLLCContext *ctx = avctx->priv_data;
    AVFrame *pic = data;
    ThreadFrame frame = { .f = data };
    uint8_t *src = avpkt->data;
    uint32_t info_tag, info_offset;
    int data_size;
    GetBitContext gb;
    int coding_type, ret;
    if (avpkt->size < 4 + 4) {
        av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
    }
    info_offset = 0;
    info_tag    = AV_RL32(src);
    if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
        info_offset = AV_RL32(src + 4);
        if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
                   info_offset);
        }
        ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
        info_offset += 8;
        src         += info_offset;
    }
    data_size = (avpkt->size - info_offset) & ~1;
    /* Make sure our bswap16'd buffer is big enough */
    av_fast_padded_malloc(&ctx->swapped_buf,
                          &ctx->swapped_buf_size, data_size);
    if (!ctx->swapped_buf) {
        av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
        return AVERROR(ENOMEM);
    }
    /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
    ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
                          data_size / 2);
    if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
        return ret;
    /*
     * Read in coding type. The types are as follows:
     *
     * 0 - YUY2
     * 1 - BGR24 (Triples)
     * 2 - BGR24 (Quads)
     * 3 - BGRA
     */
    coding_type = (AV_RL32(src) >> 8) & 0xFF;
    av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
    switch (coding_type) {
    case 0:
        avctx->pix_fmt             = AV_PIX_FMT_YUV422P;
        avctx->bits_per_raw_sample = 8;
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
            return ret;
        ret = decode_yuv_frame(ctx, &gb, pic);
        if (ret < 0)
            return ret;
        break;
    case 1:
    case 2:
        avctx->pix_fmt             = AV_PIX_FMT_RGB24;
        avctx->bits_per_raw_sample = 8;
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
            return ret;
        ret = decode_rgb24_frame(ctx, &gb, pic);
        if (ret < 0)
            return ret;
        break;
    case 3:
        avctx->pix_fmt             = AV_PIX_FMT_ARGB;
        avctx->bits_per_raw_sample = 8;
        if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
            return ret;
        ret = decode_argb_frame(ctx, &gb, pic);
        if (ret < 0)
            return ret;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
    }
    pic->key_frame = 1;
    pic->pict_type = AV_PICTURE_TYPE_I;
    *got_picture_ptr = 1;
    return avpkt->size;
}


static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,

                                              int blocks_per_slice)

{

    int16_t prev_dc;

    int code, i, sign;

    OPEN_READER(re, gb);

    DECODE_CODEWORD(code, FIRST_DC_CB);

    prev_dc = TOSIGNED(code);

    out[0] = prev_dc;

    out += 64; // dc coeff for the next block

    code = 5;

    sign = 0;

    for (i = 1; i < blocks_per_slice; i++, out += 64) {

        DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]);

        if(code) sign ^= -(code & 1);

        else     sign  = 0;

        prev_dc += (((code + 1) >> 1) ^ sign) - sign;

        out[0] = prev_dc;

    }

    CLOSE_READER(re, gb);

}


static void avc_luma_midh_qrt_and_aver_dst_8w_msa(const uint8_t *src,

                                                  int32_t src_stride,

                                                  uint8_t *dst,

                                                  int32_t dst_stride,

                                                  int32_t height,

                                                  uint8_t horiz_offset)

{

    uint32_t multiple8_cnt;

    for (multiple8_cnt = 2; multiple8_cnt--;) {

        avc_luma_midh_qrt_and_aver_dst_4w_msa(src, src_stride, dst, dst_stride,

                                              height, horiz_offset);

        src += 4;

        dst += 4;

    }

}


static int mp_pacl_removexattr(FsContext *ctx,

                               const char *path, const char *name)

{

    int ret;

    char *buffer;

    buffer = rpath(ctx, path);

    ret  = lremovexattr(buffer, MAP_ACL_ACCESS);

    if (ret == -1 && errno == ENODATA) {

        /*

         * We don't get ENODATA error when trying to remove a

         * posix acl that is not present. So don't throw the error

         * even in case of mapped security model

         */

        errno = 0;

        ret = 0;

    }

    g_free(buffer);

    return ret;

}


static av_cold OMXContext *omx_init(void *logctx, const char *libname, const char *prefix)

{

    static const char * const libnames[] = {

        "libOMX_Core.so",

        "libOmxCore.so",

        NULL

    };

    const char* const* nameptr;

    int ret = AVERROR_ENCODER_NOT_FOUND;

    OMXContext *omx_context;

    omx_context = av_mallocz(sizeof(*omx_context));

    if (!omx_context)

        return NULL;

    if (libname) {

        ret = omx_try_load(omx_context, logctx, libname, prefix);

        if (ret < 0) {

            av_free(omx_context);

            return NULL;

        }

    } else {

        for (nameptr = libnames; *nameptr; nameptr++)

            if (!(ret = omx_try_load(omx_context, logctx, *nameptr, prefix)))

                break;

        if (!*nameptr) {

            av_free(omx_context);

            return NULL;

        }

    }

    omx_context->ptr_Init();

    return omx_context;

}


int av_get_channel_layout_nb_channels(int64_t channel_layout)

{

    int count;

    uint64_t x = channel_layout;

    for (count = 0; x; count++)

        x &= x-1; // unset lowest set bit

    return count;

}


static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)

{

    unsigned int i;

    for (i = 0; i < BF_WIDTH(MAX_IRQ); i++)

        qemu_get_be32s(f, &q->queue[i]);

    qemu_get_sbe32s(f, &q->next);

    qemu_get_sbe32s(f, &q->priority);

}


static void cs_write (void *opaque, target_phys_addr_t addr,

                      uint64_t val64, unsigned size)

{

    CSState *s = opaque;

    uint32_t saddr, iaddr, val;

    saddr = addr;

    val = val64;

    switch (saddr) {

    case Index_Address:

        if (!(s->regs[Index_Address] & MCE) && (val & MCE)

            && (s->dregs[Interface_Configuration] & (3 << 3)))

            s->aci_counter = conf.aci_counter;

        s->regs[Index_Address] = val & ~(1 << 7);

        break;

    case Index_Data:

        if (!(s->dregs[MODE_And_ID] & MODE2))

            iaddr = s->regs[Index_Address] & 0x0f;

        else

            iaddr = s->regs[Index_Address] & 0x1f;

        switch (iaddr) {

        case RESERVED:

        case RESERVED_2:

        case RESERVED_3:

            lwarn ("attempt to write %#x to reserved indirect register %d\n",

                   val, iaddr);

            break;

        case FS_And_Playback_Data_Format:

            if (s->regs[Index_Address] & MCE) {

                cs_reset_voices (s, val);

            }

            else {

                if (s->dregs[Alternate_Feature_Status] & PMCE) {

                    val = (val & ~0x0f) | (s->dregs[iaddr] & 0x0f);

                    cs_reset_voices (s, val);

                }

                else {

                    lwarn ("[P]MCE(%#x, %#x) is not set, val=%#x\n",

                           s->regs[Index_Address],

                           s->dregs[Alternate_Feature_Status],

                           val);

                    break;

                }

            }

            s->dregs[iaddr] = val;

            break;

        case Interface_Configuration:

            val &= ~(1 << 5);   /* D5 is reserved */

            s->dregs[iaddr] = val;

            if (val & PPIO) {

                lwarn ("PIO is not supported (%#x)\n", val);

                break;

            }

            if (val & PEN) {

                if (!s->dma_running) {

                    cs_reset_voices (s, s->dregs[FS_And_Playback_Data_Format]);

                }

            }

            else {

                if (s->dma_running) {

                    DMA_release_DREQ (s->dma);

                    AUD_set_active_out (s->voice, 0);

                    s->dma_running = 0;

                }

            }

            break;

        case Error_Status_And_Initialization:

            lwarn ("attempt to write to read only register %d\n", iaddr);

            break;

        case MODE_And_ID:

            dolog ("val=%#x\n", val);

            if (val & MODE2)

                s->dregs[iaddr] |= MODE2;

            else

                s->dregs[iaddr] &= ~MODE2;

            break;

        case Alternate_Feature_Enable_I:

            if (val & TE)

                lerr ("timer is not yet supported\n");

            s->dregs[iaddr] = val;

            break;

        case Alternate_Feature_Status:

            if ((s->dregs[iaddr] & PI) && !(val & PI)) {

                /* XXX: TI CI */

                qemu_irq_lower (s->pic);

                s->regs[Status] &= ~INT;

            }

            s->dregs[iaddr] = val;

            break;

        case Version_Chip_ID:

            lwarn ("write to Version_Chip_ID register %#x\n", val);

            s->dregs[iaddr] = val;

            break;

        default:

            s->dregs[iaddr] = val;

            break;

        }

        dolog ("written value %#x to indirect register %d\n", val, iaddr);

        break;

    case Status:

        if (s->regs[Status] & INT) {

            qemu_irq_lower (s->pic);

        }

        s->regs[Status] &= ~INT;

        s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI);

        break;

    case PIO_Data:

        lwarn ("attempt to write value %#x to PIO register\n", val);

        break;

    }

}


static uint64_t omap_pin_cfg_read(void *opaque, target_phys_addr_t addr,

                                  unsigned size)

{

    struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;

    if (size != 4) {

        return omap_badwidth_read32(opaque, addr);

    }

    switch (addr) {

    case 0x00:	/* FUNC_MUX_CTRL_0 */

    case 0x04:	/* FUNC_MUX_CTRL_1 */

    case 0x08:	/* FUNC_MUX_CTRL_2 */

        return s->func_mux_ctrl[addr >> 2];

    case 0x0c:	/* COMP_MODE_CTRL_0 */

        return s->comp_mode_ctrl[0];

    case 0x10:	/* FUNC_MUX_CTRL_3 */

    case 0x14:	/* FUNC_MUX_CTRL_4 */

    case 0x18:	/* FUNC_MUX_CTRL_5 */

    case 0x1c:	/* FUNC_MUX_CTRL_6 */

    case 0x20:	/* FUNC_MUX_CTRL_7 */

    case 0x24:	/* FUNC_MUX_CTRL_8 */

    case 0x28:	/* FUNC_MUX_CTRL_9 */

    case 0x2c:	/* FUNC_MUX_CTRL_A */

    case 0x30:	/* FUNC_MUX_CTRL_B */

    case 0x34:	/* FUNC_MUX_CTRL_C */

    case 0x38:	/* FUNC_MUX_CTRL_D */

        return s->func_mux_ctrl[(addr >> 2) - 1];

    case 0x40:	/* PULL_DWN_CTRL_0 */

    case 0x44:	/* PULL_DWN_CTRL_1 */

    case 0x48:	/* PULL_DWN_CTRL_2 */

    case 0x4c:	/* PULL_DWN_CTRL_3 */

        return s->pull_dwn_ctrl[(addr & 0xf) >> 2];

    case 0x50:	/* GATE_INH_CTRL_0 */

        return s->gate_inh_ctrl[0];

    case 0x60:	/* VOLTAGE_CTRL_0 */

        return s->voltage_ctrl[0];

    case 0x70:	/* TEST_DBG_CTRL_0 */

        return s->test_dbg_ctrl[0];

    case 0x80:	/* MOD_CONF_CTRL_0 */

        return s->mod_conf_ctrl[0];

    }

    OMAP_BAD_REG(addr);

    return 0;

}


static int decode0(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq)

{

    int t;

    if (total_freq == 0)

        return AVERROR_INVALIDDATA;

    t = rc->range * (uint64_t)cumFreq / total_freq;

    rc->code1 += t + 1;

    rc->range = rc->range * (uint64_t)(freq + cumFreq) / total_freq - (t + 1);

    while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) {

        unsigned byte = bytestream2_get_byte(gb);

        rc->code = (rc->code << 8) | byte;

        rc->code1 <<= 8;

        rc->range <<= 8;

    }

    return 0;

}


static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,

                             AVPacket *avpkt)

{

    int ret;

    int new_extradata_size;

    uint8_t *new_extradata;

    HEVCContext *s = avctx->priv_data;

    if (!avpkt->size) {

        ret = ff_hevc_output_frame(s, data, 1);

        if (ret < 0)

            return ret;

        *got_output = ret;

        return 0;

    }

    new_extradata = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,

                                            &new_extradata_size);

    if (new_extradata && new_extradata_size > 0) {

        ret = hevc_decode_extradata(s, new_extradata, new_extradata_size);

        if (ret < 0)

            return ret;

    }

    s->ref = NULL;

    ret    = decode_nal_units(s, avpkt->data, avpkt->size);

    if (ret < 0)

        return ret;

    if (avctx->hwaccel) {

        if (s->ref && (ret = avctx->hwaccel->end_frame(avctx)) < 0) {

            av_log(avctx, AV_LOG_ERROR,

                   "hardware accelerator failed to decode picture\n");

            ff_hevc_unref_frame(s, s->ref, ~0);

            return ret;

        }

    } else {

        /* verify the SEI checksum */

        if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&

            s->sei.picture_hash.is_md5) {

            ret = verify_md5(s, s->ref->frame);

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

                ff_hevc_unref_frame(s, s->ref, ~0);

                return ret;

            }

        }

    }

    s->sei.picture_hash.is_md5 = 0;

    if (s->is_decoded) {

        av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);

        s->is_decoded = 0;

    }

    if (s->output_frame->buf[0]) {

        av_frame_move_ref(data, s->output_frame);

        *got_output = 1;

    }

    return avpkt->size;

}


static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0,

                                const int16_t *ubuf[2], const int16_t *bguf[2],

                                const int16_t *abuf0, uint8_t *dest,

                                int dstW, int uvalpha, int y)

{

    const int16_t *ubuf0 = ubuf[0], *ubuf1 = ubuf[1];

    const int16_t *buf1= buf0; //FIXME needed for RGB1/BGR1

    if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster

        __asm__ volatile(

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

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

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

            YSCALEYUV2RGB1(%%REGBP, %5)

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

            WRITEBGR24(%%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)

        );

    } else {

        __asm__ volatile(

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

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

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

            YSCALEYUV2RGB1b(%%REGBP, %5)

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

            WRITEBGR24(%%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)

        );

    }

}


static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)

{

    uint64_t mask;

    uint32_t sh, mb;

    sh = SH(ctx->opcode) | (shn << 5);

    mb = MB(ctx->opcode) | (mbn << 5);

    if (likely(sh == 0)) {

        if (likely(mb == 0)) {

            gen_op_load_gpr_T0(rS(ctx->opcode));

            goto do_store;

        } else if (likely(mb == 63)) {

            gen_op_load_gpr_T0(rA(ctx->opcode));

            goto do_store;

        }

        gen_op_load_gpr_T0(rS(ctx->opcode));

        gen_op_load_gpr_T1(rA(ctx->opcode));

        goto do_mask;

    }

    gen_op_load_gpr_T0(rS(ctx->opcode));

    gen_op_load_gpr_T1(rA(ctx->opcode));

    gen_op_rotli64_T0(sh);

 do_mask:

    mask = MASK(mb, 63 - sh);

    gen_andi_T0_64(ctx, mask);

    gen_andi_T1_64(ctx, ~mask);

    gen_op_or();

 do_store:

    gen_op_store_T0_gpr(rA(ctx->opcode));

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

        gen_set_Rc0(ctx);

}


static int dx2_decode_slice_410(GetBitContext *gb, AVFrame *frame,

                                int line, int left,

                                uint8_t lru[3][8])

{

    int x, y, i, j;

    int width   = frame->width;

    int ystride = frame->linesize[0];

    int ustride = frame->linesize[1];

    int vstride = frame->linesize[2];

    uint8_t *Y  = frame->data[0] + ystride * line;

    uint8_t *U  = frame->data[1] + (ustride >> 2) * line;

    uint8_t *V  = frame->data[2] + (vstride >> 2) * line;

    for (y = 0; y < left - 3 && get_bits_left(gb) > 16; y += 4) {

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

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

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

                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);

            U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;

            V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;

        }

        Y += ystride << 2;

        U += ustride;

        V += vstride;

    }

    return y;

}


void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)

{

    LOG_INT("kqemu_set_notdirty: addr=%08lx\n",

                (unsigned long)ram_addr);

    /* we only track transitions to dirty state */

    if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)

        return;

    if (nb_ram_pages_to_update >= KQEMU_MAX_RAM_PAGES_TO_UPDATE)

        nb_ram_pages_to_update = KQEMU_RAM_PAGES_UPDATE_ALL;

    else

        ram_pages_to_update[nb_ram_pages_to_update++] = ram_addr;

}


static void put_no_rnd_pixels_y2_mmx( UINT8  *block, const UINT8 *pixels, int line_size, int h)

{

  UINT8  *p;

  const UINT8 *pix;

  p = block;

  pix = pixels;

  MOVQ_ZERO(mm7);

  JUMPALIGN();

  do {

    __asm __volatile(

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

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

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

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

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

	"punpcklbw %%mm7, %%mm1\n\t"

	"punpckhbw %%mm7, %%mm2\n\t"

	"punpckhbw %%mm7, %%mm3\n\t"

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

	"paddusw %%mm3, %%mm2\n\t"

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

	"psrlw	$1, %%mm2\n\t"

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

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

	:"=m"(*p)

	:"m"(*pix),

	 "m"(*(pix+line_size))

	:"memory");

   pix += line_size;

   p +=   line_size;

  } while(--h);

}


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

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = NULL;

    struct iscsi_url *iscsi_url = NULL;

    struct IscsiTask task;

    char *initiator_name = NULL;

    int ret;

    if ((BDRV_SECTOR_SIZE % 512) != 0) {

        error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. "

                     "BDRV_SECTOR_SIZE(%lld) is not a multiple "

                     "of 512", BDRV_SECTOR_SIZE);

        return -EINVAL;

    }

    iscsi_url = iscsi_parse_full_url(iscsi, filename);

    if (iscsi_url == NULL) {

        error_report("Failed to parse URL : %s %s", filename,

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }

    memset(iscsilun, 0, sizeof(IscsiLun));

    initiator_name = parse_initiator_name(iscsi_url->target);

    iscsi = iscsi_create_context(initiator_name);

    if (iscsi == NULL) {

        error_report("iSCSI: Failed to create iSCSI context.");

        ret = -ENOMEM;

        goto out;

    }

    if (iscsi_set_targetname(iscsi, iscsi_url->target)) {

        error_report("iSCSI: Failed to set target name.");

        ret = -EINVAL;

        goto out;

    }

    if (iscsi_url->user != NULL) {

        ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user,

                                              iscsi_url->passwd);

        if (ret != 0) {

            error_report("Failed to set initiator username and password");

            ret = -EINVAL;

            goto out;

        }

    }

    /* check if we got CHAP username/password via the options */

    if (parse_chap(iscsi, iscsi_url->target) != 0) {

        error_report("iSCSI: Failed to set CHAP user/password");

        ret = -EINVAL;

        goto out;

    }

    if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) {

        error_report("iSCSI: Failed to set session type to normal.");

        ret = -EINVAL;

        goto out;

    }

    iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C);

    /* check if we got HEADER_DIGEST via the options */

    parse_header_digest(iscsi, iscsi_url->target);

    task.iscsilun = iscsilun;

    task.status = 0;

    task.complete = 0;

    task.bs = bs;

    iscsilun->iscsi = iscsi;

    iscsilun->lun   = iscsi_url->lun;

    if (iscsi_full_connect_async(iscsi, iscsi_url->portal, iscsi_url->lun,

                                 iscsi_connect_cb, &task)

        != 0) {

        error_report("iSCSI: Failed to start async connect.");

        ret = -EINVAL;

        goto out;

    }

    while (!task.complete) {

        iscsi_set_events(iscsilun);

        qemu_aio_wait();

    }

    if (task.status != 0) {

        error_report("iSCSI: Failed to connect to LUN : %s",

                     iscsi_get_error(iscsi));

        ret = -EINVAL;

        goto out;

    }

    /* Medium changer or tape. We dont have any emulation for this so this must

     * be sg ioctl compatible. We force it to be sg, otherwise qemu will try

     * to read from the device to guess the image format.

     */

    if (iscsilun->type == TYPE_MEDIUM_CHANGER ||

        iscsilun->type == TYPE_TAPE) {

        bs->sg = 1;

    }

    ret = 0;

out:

    if (initiator_name != NULL) {

        g_free(initiator_name);

    }

    if (iscsi_url != NULL) {

        iscsi_destroy_url(iscsi_url);

    }

    if (ret) {

        if (iscsi != NULL) {

            iscsi_destroy_context(iscsi);

        }

        memset(iscsilun, 0, sizeof(IscsiLun));

    }

    return ret;

}


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

                        const AVFrame *pict, int *got_packet)

{

    TiffEncoderContext *s = avctx->priv_data;

    AVFrame *const p = &s->picture;

    int i;

    uint8_t *ptr;

    uint8_t *offset;

    uint32_t strips;

    uint32_t *strip_sizes = NULL;

    uint32_t *strip_offsets = NULL;

    int bytes_per_row;

    uint32_t res[2] = { 72, 1 };        // image resolution (72/1)

    uint16_t bpp_tab[] = { 8, 8, 8, 8 };

    int ret;

    int is_yuv = 0;

    uint8_t *yuv_line = NULL;

    int shift_h, shift_v;

    const AVPixFmtDescriptor* pfd;

    s->avctx = avctx;

    *p = *pict;

    p->pict_type = AV_PICTURE_TYPE_I;

    p->key_frame = 1;

    avctx->coded_frame= &s->picture;

    s->width = avctx->width;

    s->height = avctx->height;

    s->subsampling[0] = 1;

    s->subsampling[1] = 1;

    switch (avctx->pix_fmt) {

    case PIX_FMT_RGB48LE:

    case PIX_FMT_GRAY16LE:

    case PIX_FMT_RGB24:

    case PIX_FMT_GRAY8:

    case PIX_FMT_PAL8:

        pfd = &av_pix_fmt_descriptors[avctx->pix_fmt];

        s->bpp = av_get_bits_per_pixel(pfd);

        if (pfd->flags & PIX_FMT_PAL) {

            s->photometric_interpretation = 3;

        } else if (pfd->flags & PIX_FMT_RGB) {

            s->photometric_interpretation = 2;

        } else {

            s->photometric_interpretation = 1;

        }

        s->bpp_tab_size = pfd->nb_components;

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

            bpp_tab[i] = s->bpp / s->bpp_tab_size;

        }

        break;

    case PIX_FMT_MONOBLACK:

        s->bpp = 1;

        s->photometric_interpretation = 1;

        s->bpp_tab_size = 0;

        break;

    case PIX_FMT_MONOWHITE:

        s->bpp = 1;

        s->photometric_interpretation = 0;

        s->bpp_tab_size = 0;

        break;

    case PIX_FMT_YUV420P:

    case PIX_FMT_YUV422P:

    case PIX_FMT_YUV444P:

    case PIX_FMT_YUV410P:

    case PIX_FMT_YUV411P:

        s->photometric_interpretation = 6;

        avcodec_get_chroma_sub_sample(avctx->pix_fmt,

                &shift_h, &shift_v);

        s->bpp = 8 + (16 >> (shift_h + shift_v));

        s->subsampling[0] = 1 << shift_h;

        s->subsampling[1] = 1 << shift_v;

        s->bpp_tab_size = 3;

        is_yuv = 1;

        break;

    default:

        av_log(s->avctx, AV_LOG_ERROR,

               "This colors format is not supported\n");

        return -1;

    }

    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)

        //best choose for DEFLATE

        s->rps = s->height;

    else

        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip

    s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up

    strips = (s->height - 1) / s->rps + 1;

    if (!pkt->data &&

        (ret = av_new_packet(pkt, avctx->width * avctx->height * s->bpp * 2 +

                                  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");

        return ret;

    }

    ptr          = pkt->data;

    s->buf_start = pkt->data;

    s->buf       = &ptr;

    s->buf_size  = pkt->size;

    if (check_size(s, 8))

        goto fail;

    // write header

    bytestream_put_le16(&ptr, 0x4949);

    bytestream_put_le16(&ptr, 42);

    offset = ptr;

    bytestream_put_le32(&ptr, 0);

    strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);

    strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);

    bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp

                    * s->subsampling[0] * s->subsampling[1] + 7) >> 3;

    if (is_yuv){

        yuv_line = av_malloc(bytes_per_row);

        if (yuv_line == NULL){

            av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");

            goto fail;

        }

    }

#if CONFIG_ZLIB

    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {

        uint8_t *zbuf;

        int zlen, zn;

        int j;

        zlen = bytes_per_row * s->rps;

        zbuf = av_malloc(zlen);

        strip_offsets[0] = ptr - pkt->data;

        zn = 0;

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

            if (is_yuv){

                pack_yuv(s, yuv_line, j);

                memcpy(zbuf + zn, yuv_line, bytes_per_row);

                j += s->subsampling[1] - 1;

            }

            else

                memcpy(zbuf + j * bytes_per_row,

                       p->data[0] + j * p->linesize[0], bytes_per_row);

            zn += bytes_per_row;

        }

        ret = encode_strip(s, zbuf, ptr, zn, s->compr);

        av_free(zbuf);

        if (ret < 0) {

            av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");

            goto fail;

        }

        ptr += ret;

        strip_sizes[0] = ptr - pkt->data - strip_offsets[0];

    } else

#endif

    {

        if(s->compr == TIFF_LZW)

            s->lzws = av_malloc(ff_lzw_encode_state_size);

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

            if (strip_sizes[i / s->rps] == 0) {

                if(s->compr == TIFF_LZW){

                    ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),

                                       12, FF_LZW_TIFF, put_bits);

                }

                strip_offsets[i / s->rps] = ptr - pkt->data;

            }

            if (is_yuv){

                 pack_yuv(s, yuv_line, i);

                 ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);

                 i += s->subsampling[1] - 1;

            }

            else

                ret = encode_strip(s, p->data[0] + i * p->linesize[0],

                        ptr, bytes_per_row, s->compr);

            if (ret < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");

                goto fail;

            }

            strip_sizes[i / s->rps] += ret;

            ptr += ret;

            if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){

                ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);

                strip_sizes[(i / s->rps )] += ret ;

                ptr += ret;

            }

        }

        if(s->compr == TIFF_LZW)

            av_free(s->lzws);

    }

    s->num_entries = 0;

    add_entry1(s,TIFF_SUBFILE,           TIFF_LONG,             0);

    add_entry1(s,TIFF_WIDTH,             TIFF_LONG,             s->width);

    add_entry1(s,TIFF_HEIGHT,            TIFF_LONG,             s->height);

    if (s->bpp_tab_size)

    add_entry(s, TIFF_BPP,               TIFF_SHORT,    s->bpp_tab_size, bpp_tab);

    add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);

    add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);

    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);

    if (s->bpp_tab_size)

    add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);

    add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);

    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);

    add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);

    add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);

    add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);

    if(!(avctx->flags & CODEC_FLAG_BITEXACT))

    add_entry(s, TIFF_SOFTWARE_NAME,     TIFF_STRING,

              strlen(LIBAVCODEC_IDENT) + 1, LIBAVCODEC_IDENT);

    if (avctx->pix_fmt == PIX_FMT_PAL8) {

        uint16_t pal[256 * 3];

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

            uint32_t rgb = *(uint32_t *) (p->data[1] + i * 4);

            pal[i]       = ((rgb >> 16) & 0xff) * 257;

            pal[i + 256] = ((rgb >> 8 ) & 0xff) * 257;

            pal[i + 512] = ( rgb        & 0xff) * 257;

        }

        add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);

    }

    if (is_yuv){

        /** according to CCIR Recommendation 601.1 */

        uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};

        add_entry(s, TIFF_YCBCR_SUBSAMPLING, TIFF_SHORT,    2, s->subsampling);

        add_entry(s, TIFF_REFERENCE_BW,      TIFF_RATIONAL, 6, refbw);

    }

    bytestream_put_le32(&offset, ptr - pkt->data);    // write offset to dir

    if (check_size(s, 6 + s->num_entries * 12)) {

        ret = AVERROR(EINVAL);

        goto fail;

    }

    bytestream_put_le16(&ptr, s->num_entries);  // write tag count

    bytestream_put_buffer(&ptr, s->entries, s->num_entries * 12);

    bytestream_put_le32(&ptr, 0);

    pkt->size   = ptr - pkt->data;

    pkt->flags |= AV_PKT_FLAG_KEY;

    *got_packet = 1;

fail:

    av_free(strip_sizes);

    av_free(strip_offsets);

    av_free(yuv_line);

    return ret;

}


static int mxf_parse_structural_metadata(MXFContext *mxf)

{

    MXFPackage *material_package = NULL;

    MXFPackage *temp_package = NULL;

    int i, j, k;

    av_dlog(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count);

    /* TODO: handle multiple material packages (OP3x) */

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

        material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage);

        if (material_package) break;

    }

    if (!material_package) {

        av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n");

        return AVERROR_INVALIDDATA;

    }

    for (i = 0; i < material_package->tracks_count; i++) {

        MXFPackage *source_package = NULL;

        MXFTrack *material_track = NULL;

        MXFTrack *source_track = NULL;

        MXFTrack *temp_track = NULL;

        MXFDescriptor *descriptor = NULL;

        MXFStructuralComponent *component = NULL;

        UID *essence_container_ul = NULL;

        const MXFCodecUL *codec_ul = NULL;

        const MXFCodecUL *container_ul = NULL;

        AVStream *st;

        if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {

            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");

            continue;

        }

        if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {

            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");

            continue;

        }

        /* TODO: handle multiple source clips */

        for (j = 0; j < material_track->sequence->structural_components_count; j++) {

            /* TODO: handle timecode component */

            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);

            if (!component)

                continue;

            for (k = 0; k < mxf->packages_count; k++) {

                temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage);

                if (!temp_package)

                    continue;

                if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) {

                    source_package = temp_package;

                    break;

                }

            }

            if (!source_package) {

                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source package found\n", material_track->track_id);

                break;

            }

            for (k = 0; k < source_package->tracks_count; k++) {

                if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) {

                    av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n");

                    return AVERROR_INVALIDDATA;

                }

                if (temp_track->track_id == component->source_track_id) {

                    source_track = temp_track;

                    break;

                }

            }

            if (!source_track) {

                av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id);

                break;

            }

        }

        if (!source_track)

            continue;

        st = avformat_new_stream(mxf->fc, NULL);

        if (!st) {

            av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n");

            return AVERROR(ENOMEM);

        }

        st->id = source_track->track_id;

        st->priv_data = source_track;

        st->duration = component->duration;

        if (st->duration == -1)

            st->duration = AV_NOPTS_VALUE;

        st->start_time = component->start_position;

        avpriv_set_pts_info(st, 64, material_track->edit_rate.num, material_track->edit_rate.den);

        if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {

            av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n");

            return AVERROR_INVALIDDATA;

        }

        PRINT_KEY(mxf->fc, "data definition   ul", source_track->sequence->data_definition_ul);

        codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul);

        st->codec->codec_type = codec_ul->id;

        source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType);

        if (source_package->descriptor) {

            if (source_package->descriptor->type == MultipleDescriptor) {

                for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) {

                    MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor);

                    if (!sub_descriptor) {

                        av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n");

                        continue;

                    }

                    if (sub_descriptor->linked_track_id == source_track->track_id) {

                        descriptor = sub_descriptor;

                        break;

                    }

                }

            } else if (source_package->descriptor->type == Descriptor)

                descriptor = source_package->descriptor;

        }

        if (!descriptor) {

            av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index);

            continue;

        }

        PRINT_KEY(mxf->fc, "essence codec     ul", descriptor->essence_codec_ul);

        PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul);

        essence_container_ul = &descriptor->essence_container_ul;

        /* HACK: replacing the original key with mxf_encrypted_essence_container

         * is not allowed according to s429-6, try to find correct information anyway */

        if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) {

            av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n");

            for (k = 0; k < mxf->metadata_sets_count; k++) {

                MXFMetadataSet *metadata = mxf->metadata_sets[k];

                if (metadata->type == CryptoContext) {

                    essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul;

                    break;

                }

            }

        }

        /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */

        codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul);

        st->codec->codec_id = codec_ul->id;

        if (descriptor->extradata) {

            st->codec->extradata = descriptor->extradata;

            st->codec->extradata_size = descriptor->extradata_size;

        }

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

            container_ul = mxf_get_codec_ul(mxf_essence_container_uls, essence_container_ul);

            if (st->codec->codec_id == CODEC_ID_NONE)

                st->codec->codec_id = container_ul->id;

            st->codec->width = descriptor->width;

            st->codec->height = descriptor->height;

            if (st->codec->codec_id == CODEC_ID_RAWVIDEO)

                st->codec->pix_fmt = descriptor->pix_fmt;

            st->need_parsing = AVSTREAM_PARSE_HEADERS;

        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

            container_ul = mxf_get_codec_ul(mxf_essence_container_uls, essence_container_ul);

            if (st->codec->codec_id == CODEC_ID_NONE)

                st->codec->codec_id = container_ul->id;

            st->codec->channels = descriptor->channels;

            st->codec->bits_per_coded_sample = descriptor->bits_per_sample;

            st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den;

            /* TODO: implement CODEC_ID_RAWAUDIO */

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

                if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)

                    st->codec->codec_id = CODEC_ID_PCM_S24LE;

                else if (descriptor->bits_per_sample == 32)

                    st->codec->codec_id = CODEC_ID_PCM_S32LE;

            } else if (st->codec->codec_id == CODEC_ID_PCM_S16BE) {

                if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24)

                    st->codec->codec_id = CODEC_ID_PCM_S24BE;

                else if (descriptor->bits_per_sample == 32)

                    st->codec->codec_id = CODEC_ID_PCM_S32BE;

            } else if (st->codec->codec_id == CODEC_ID_MP2) {

                st->need_parsing = AVSTREAM_PARSE_FULL;

            }

        }

        if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) {

            av_log(mxf->fc, AV_LOG_WARNING, "only frame wrapped mappings are correctly supported\n");

            st->need_parsing = AVSTREAM_PARSE_FULL;

        }

    }

    return 0;

}


static inline int sym_quant(int c, int e, int levels)

{

    int v = ((((levels * c) >> (24 - e)) + 1) >> 1) + (levels >> 1);

    av_assert2(v >= 0 && v < levels);

    return v;

}


static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)

{

    BDRVParallelsState *s = bs->opaque;

    uint32_t index, offset, position;

    index = sector_num / s->tracks;

    offset = sector_num % s->tracks;

    // not allocated

    if ((index > s->catalog_size) || (s->catalog_bitmap[index] == 0))

	return -1;

    position = (s->catalog_bitmap[index] + offset) * 512;

//    fprintf(stderr, "sector: %llx index=%x offset=%x pointer=%x position=%x\n",

//	sector_num, index, offset, s->catalog_bitmap[index], position);

    if (lseek(s->fd, position, SEEK_SET) != position)

	return -1;

    return 0;

}


static void imx_epit_reload_compare_timer(IMXEPITState *s)

{

    if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {

        /* if the compare feature is on and timers are running */

        uint32_t tmp = imx_epit_update_count(s);

        uint64_t next;

        if (tmp > s->cmp) {

            /* It'll fire in this round of the timer */

            next = tmp - s->cmp;

        } else { /* catch it next time around */

            next = tmp - s->cmp + ((s->cr & CR_RLD) ? TIMER_MAX : s->lr);

        }

        ptimer_set_count(s->timer_cmp, next);

    }

}


static int handle_intercept(CPUS390XState *env)

{

    struct kvm_run *run = env->kvm_run;

    int icpt_code = run->s390_sieic.icptcode;

    int r = 0;

    dprintf("intercept: 0x%x (at 0x%lx)\n", icpt_code,

            (long)env->kvm_run->psw_addr);

    switch (icpt_code) {

        case ICPT_INSTRUCTION:

            r = handle_instruction(env, run);

        case ICPT_WAITPSW:

        case ICPT_CPU_STOP:

            if (s390_del_running_cpu(env) == 0) {

        case ICPT_SOFT_INTERCEPT:

            fprintf(stderr, "KVM unimplemented icpt SOFT\n");

            exit(1);

        case ICPT_IO:

            fprintf(stderr, "KVM unimplemented icpt IO\n");

            exit(1);

        default:

            fprintf(stderr, "Unknown intercept code: %d\n", icpt_code);

            exit(1);

    return r;


void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes)

{

    int p, b, t;

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

        for (b = 0; b < planes[p].num_bands; b++) {

            av_freep(&planes[p].bands[b].bufs[0]);

            av_freep(&planes[p].bands[b].bufs[1]);

            av_freep(&planes[p].bands[b].bufs[2]);

            for (t = 0; t < planes[p].bands[b].num_tiles; t++)

                av_freep(&planes[p].bands[b].tiles[t].mbs);

            av_freep(&planes[p].bands[b].tiles);

        }

        av_freep(&planes[p].bands);

    }

}


static gboolean qio_channel_websock_handshake_send(QIOChannel *ioc,

                                                   GIOCondition condition,

                                                   gpointer user_data)

{

    QIOTask *task = user_data;

    QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(

        qio_task_get_source(task));

    Error *err = NULL;

    ssize_t ret;

    ret = qio_channel_write(wioc->master,

                            (char *)wioc->encoutput.buffer,

                            wioc->encoutput.offset,

                            &err);

    if (ret < 0) {

        trace_qio_channel_websock_handshake_fail(ioc);

        qio_task_set_error(task, err);

        qio_task_complete(task);

        return FALSE;

    }

    buffer_advance(&wioc->encoutput, ret);

    if (wioc->encoutput.offset == 0) {

        trace_qio_channel_websock_handshake_complete(ioc);

        qio_task_complete(task);

        return FALSE;

    }

    trace_qio_channel_websock_handshake_pending(ioc, G_IO_OUT);

    return TRUE;

}


static int pix_norm1_altivec(uint8_t *pix, int line_size)

{

    int i, s = 0;

    const vector unsigned int zero =

        (const vector unsigned int) vec_splat_u32(0);

    vector unsigned int sv = (vector unsigned int) vec_splat_u32(0);

    vector signed int sum;

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

        /* Read the potentially unaligned pixels. */

        //vector unsigned char pixl = vec_ld(0,  pix);

        //vector unsigned char pixr = vec_ld(15, pix);

        //vector unsigned char pixv = vec_perm(pixl, pixr, perm);

        vector unsigned char pixv = vec_vsx_ld(0,  pix);

        /* Square the values, and add them to our sum. */

        sv = vec_msum(pixv, pixv, sv);

        pix += line_size;

    }

    /* Sum up the four partial sums, and put the result into s. */

    sum = vec_sums((vector signed int) sv, (vector signed int) zero);

    sum = vec_splat(sum, 3);

    vec_vsx_st(sum, 0, &s);

    return s;

}


static void test_visitor_in_native_list_uint8(TestInputVisitorData *data,

                                             const void *unused)

{

    test_native_list_integer_helper(data, unused,

                                    USER_DEF_NATIVE_LIST_UNION_KIND_U8);

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);

    sc->init         = scsi_disk_initfn;

    sc->destroy      = scsi_destroy;

    sc->alloc_req    = scsi_new_request;

    sc->unit_attention_reported = scsi_disk_unit_attention_reported;

    dc->fw_name = "disk";

    dc->desc = "virtual SCSI disk or CD-ROM (legacy)";

    dc->reset = scsi_disk_reset;

    dc->props = scsi_disk_properties;

    dc->vmsd  = &vmstate_scsi_disk_state;

}


static void test_tco2_status_bits(void)

{

    TestData d;

    uint16_t ticks = 8;

    uint16_t val;

    int ret;

    d.args = "-watchdog-action none";

    test_init(&d);

    stop_tco(&d);

    clear_tco_status(&d);

    reset_on_second_timeout(true);

    set_tco_timeout(&d, ticks);

    load_tco(&d);

    start_tco(&d);

    clock_step(ticks * TCO_TICK_NSEC * 2);

    val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS);

    ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0;

    g_assert(ret == 1);

    qpci_io_writew(d.dev, d.tco_io_base + TCO2_STS, val);

    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS), ==, 0);

    qtest_end();

}


sdhci_write(SDHCIState *s, unsigned int offset, uint32_t value, unsigned size)

{

    unsigned shift =  8 * (offset & 0x3);

    uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);

    value <<= shift;

    switch (offset & ~0x3) {

    case SDHC_SYSAD:

        s->sdmasysad = (s->sdmasysad & mask) | value;

        MASKED_WRITE(s->sdmasysad, mask, value);

        /* Writing to last byte of sdmasysad might trigger transfer */

        if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&

                s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {

            SDHCI_GET_CLASS(s)->do_sdma_multi(s);

        }

        break;

    case SDHC_BLKSIZE:

        if (!TRANSFERRING_DATA(s->prnsts)) {

            MASKED_WRITE(s->blksize, mask, value);

            MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);

        }

        break;

    case SDHC_ARGUMENT:

        MASKED_WRITE(s->argument, mask, value);

        break;

    case SDHC_TRNMOD:

        /* DMA can be enabled only if it is supported as indicated by

         * capabilities register */

        if (!(s->capareg & SDHC_CAN_DO_DMA)) {

            value &= ~SDHC_TRNS_DMA;

        }

        MASKED_WRITE(s->trnmod, mask, value);

        MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);

        /* Writing to the upper byte of CMDREG triggers SD command generation */

        if ((mask & 0xFF000000) || !SDHCI_GET_CLASS(s)->can_issue_command(s)) {

            break;

        }

        SDHCI_GET_CLASS(s)->send_command(s);

        break;

    case  SDHC_BDATA:

        if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {

            SDHCI_GET_CLASS(s)->bdata_write(s, value >> shift, size);

        }

        break;

    case SDHC_HOSTCTL:

        if (!(mask & 0xFF0000)) {

            sdhci_blkgap_write(s, value >> 16);

        }

        MASKED_WRITE(s->hostctl, mask, value);

        MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8);

        MASKED_WRITE(s->wakcon, mask >> 24, value >> 24);

        if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 ||

                !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) {

            s->pwrcon &= ~SDHC_POWER_ON;

        }

        break;

    case SDHC_CLKCON:

        if (!(mask & 0xFF000000)) {

            sdhci_reset_write(s, value >> 24);

        }

        MASKED_WRITE(s->clkcon, mask, value);

        MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16);

        if (s->clkcon & SDHC_CLOCK_INT_EN) {

            s->clkcon |= SDHC_CLOCK_INT_STABLE;

        } else {

            s->clkcon &= ~SDHC_CLOCK_INT_STABLE;

        }

        break;

    case SDHC_NORINTSTS:

        if (s->norintstsen & SDHC_NISEN_CARDINT) {

            value &= ~SDHC_NIS_CARDINT;

        }

        s->norintsts &= mask | ~value;

        s->errintsts &= (mask >> 16) | ~(value >> 16);

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSTSEN:

        MASKED_WRITE(s->norintstsen, mask, value);

        MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16);

        s->norintsts &= s->norintstsen;

        s->errintsts &= s->errintstsen;

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        } else {

            s->norintsts &= ~SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    case SDHC_NORINTSIGEN:

        MASKED_WRITE(s->norintsigen, mask, value);

        MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16);

        sdhci_update_irq(s);

        break;

    case SDHC_ADMAERR:

        MASKED_WRITE(s->admaerr, mask, value);

        break;

    case SDHC_ADMASYSADDR:

        s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL |

                (uint64_t)mask)) | (uint64_t)value;

        break;

    case SDHC_ADMASYSADDR + 4:

        s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL |

                ((uint64_t)mask << 32))) | ((uint64_t)value << 32);

        break;

    case SDHC_FEAER:

        s->acmd12errsts |= value;

        s->errintsts |= (value >> 16) & s->errintstsen;

        if (s->acmd12errsts) {

            s->errintsts |= SDHC_EIS_CMD12ERR;

        }

        if (s->errintsts) {

            s->norintsts |= SDHC_NIS_ERR;

        }

        sdhci_update_irq(s);

        break;

    default:

        ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",

                size, offset, value >> shift, value >> shift);

        break;

    }

    DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",

            size, offset, value >> shift, value >> shift);

}


build_ssdt(GArray *table_data, GArray *linker,

           AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,

           PcPciInfo *pci, PcGuestInfo *guest_info)

{

    int acpi_cpus = MIN(0xff, guest_info->apic_id_limit);

    int ssdt_start = table_data->len;

    uint8_t *ssdt_ptr;

    int i;

    /* Copy header and patch values in the S3_ / S4_ / S5_ packages */

    ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));

    memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));

    if (pm->s3_disabled) {

        ssdt_ptr[acpi_s3_name[0]] = 'X';

    }

    if (pm->s4_disabled) {

        ssdt_ptr[acpi_s4_name[0]] = 'X';

    } else {

        ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt_ptr[acpi_s4_pkg[0] + 3] =

            pm->s4_val;

    }

    patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));

    ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),

                      ssdt_isa_pest[0], 16, misc->pvpanic_port);

    {

        GArray *sb_scope = build_alloc_array();

        uint8_t op = 0x10; /* ScopeOp */

        build_append_nameseg(sb_scope, "_SB_");

        /* build Processor object for each processor */

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

            uint8_t *proc = acpi_data_push(sb_scope, ACPI_PROC_SIZEOF);

            memcpy(proc, ACPI_PROC_AML, ACPI_PROC_SIZEOF);

            proc[ACPI_PROC_OFFSET_CPUHEX] = acpi_get_hex(i >> 4);

            proc[ACPI_PROC_OFFSET_CPUHEX+1] = acpi_get_hex(i);

            proc[ACPI_PROC_OFFSET_CPUID1] = i;

            proc[ACPI_PROC_OFFSET_CPUID2] = i;

        }

        /* build this code:

         *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}

         */

        /* Arg0 = Processor ID = APIC ID */

        build_append_notify_method(sb_scope, "NTFY", "CP%0.02X", acpi_cpus);

        /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */

        build_append_byte(sb_scope, 0x08); /* NameOp */

        build_append_nameseg(sb_scope, "CPON");

        {

            GArray *package = build_alloc_array();

            uint8_t op = 0x12; /* PackageOp */

            build_append_byte(package, acpi_cpus); /* NumElements */

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

                uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;

                build_append_byte(package, b);

            }

            build_package(package, op, 2);

            build_append_array(sb_scope, package);

            build_free_array(package);

        }

        {

            AcpiBuildPciBusHotplugState hotplug_state;

            Object *pci_host;

            PCIBus *bus = NULL;

            bool ambiguous;

            pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);

            if (!ambiguous && pci_host) {

                bus = PCI_HOST_BRIDGE(pci_host)->bus;

            }

            build_pci_bus_state_init(&hotplug_state, NULL);

            if (bus) {

                /* Scan all PCI buses. Generate tables to support hotplug. */

                pci_for_each_bus_depth_first(bus, build_pci_bus_begin,

                                             build_pci_bus_end, &hotplug_state);

            }

            build_append_array(sb_scope, hotplug_state.device_table);

            build_pci_bus_state_cleanup(&hotplug_state);

        }

        build_package(sb_scope, op, 3);

        build_append_array(table_data, sb_scope);

        build_free_array(sb_scope);

    }

    build_header(linker, table_data,

                 (void *)(table_data->data + ssdt_start),

                 ACPI_SSDT_SIGNATURE, table_data->len - ssdt_start, 1);

}


int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t shared,

                          Error **errp)

{

    return bdrv_check_update_perm(c->bs, perm, shared, c, errp);

}


static int mxf_write_header(AVFormatContext *s)

{

    MXFContext *mxf = s->priv_data;

    int i, ret;

    uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};

    const MXFSamplesPerFrame *spf = NULL;

    AVDictionaryEntry *t;

    int64_t timestamp = 0;

    if (!s->nb_streams)

        return -1;

    if (s->oformat == &ff_mxf_opatom_muxer && s->nb_streams !=1){

        av_log(s, AV_LOG_ERROR, "there must be exactly one stream for mxf opatom\n");

        return -1;

    }

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

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

        MXFStreamContext *sc = av_mallocz(sizeof(*sc));

        if (!sc)

            return AVERROR(ENOMEM);

        st->priv_data = sc;

        if (((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) && s->oformat != &ff_mxf_opatom_muxer) {

            av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");

            return -1;

        }

        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {

            const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(st->codec->pix_fmt);

            // TODO: should be avg_frame_rate

            AVRational rate, tbc = st->time_base;

            // Default component depth to 8

            sc->component_depth = 8;

            sc->h_chroma_sub_sample = 2;

            sc->color_siting = 0xFF;

            if (pix_desc) {

                sc->component_depth     = pix_desc->comp[0].depth_minus1 + 1;

                sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w;

            }

            switch (ff_choose_chroma_location(s, st)) {

            case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break;

            case AVCHROMA_LOC_LEFT:    sc->color_siting = 6; break;

            case AVCHROMA_LOC_TOP:     sc->color_siting = 1; break;

            case AVCHROMA_LOC_CENTER:  sc->color_siting = 3; break;

            }

            mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

            spf = ff_mxf_get_samples_per_frame(s, tbc);

            if (!spf) {

                av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",

                       tbc.den, tbc.num);

                return AVERROR(EINVAL);

            }

            mxf->time_base = spf->time_base;

            rate = av_inv_q(mxf->time_base);

            avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);

            if((ret = mxf_init_timecode(s, st, rate)) < 0)

                return ret;

            sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate;

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (sc->video_bit_rate == 50000000) {

                    if (mxf->time_base.den == 25) sc->index = 3;

                    else                          sc->index = 5;

                } else if (sc->video_bit_rate == 40000000) {

                    if (mxf->time_base.den == 25) sc->index = 7;

                    else                          sc->index = 9;

                } else if (sc->video_bit_rate == 30000000) {

                    if (mxf->time_base.den == 25) sc->index = 11;

                    else                          sc->index = 13;

                } else {

                    av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n");

                    return -1;

                }

                mxf->edit_unit_byte_count = KAG_SIZE; // system element

                mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)sc->video_bit_rate *

                    mxf->time_base.num / (8*mxf->time_base.den);

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);

                mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;

                mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);

                sc->signal_standard = 1;

            }

        } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {

            if (st->codec->sample_rate != 48000) {

                av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n");

                return -1;

            }

            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

            if (s->oformat == &ff_mxf_d10_muxer) {

                if (st->index != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n");

                    return -1;

                }

                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n");

                }

                sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1;

            } else if (s->oformat == &ff_mxf_opatom_muxer) {

                AVRational tbc = av_inv_q(mxf->audio_edit_rate);

                if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE &&

                    st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) {

                    av_log(s, AV_LOG_ERROR, "Only pcm_s16le and pcm_s24le audio codecs are implemented\n");

                    return AVERROR_PATCHWELCOME;

                }

                if (st->codec->channels != 1) {

                    av_log(s, AV_LOG_ERROR, "MXF OPAtom only supports single channel audio\n");

                    return AVERROR(EINVAL);

                }

                spf = ff_mxf_get_samples_per_frame(s, tbc);

                if (!spf){

                    av_log(s, AV_LOG_ERROR, "Unsupported timecode frame rate %d/%d\n", tbc.den, tbc.num);

                    return AVERROR(EINVAL);

                }

                mxf->time_base = st->time_base;

                if((ret = mxf_init_timecode(s, st, av_inv_q(spf->time_base))) < 0)

                    return ret;

                mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;

                mxf->edit_unit_byte_count = (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3;

                sc->index = 2;

            } else {

                mxf->slice_count = 1;

            }

        }

        if (!sc->index) {

            sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id);

            if (sc->index == -1) {

                av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, "

                       "codec not currently supported in container\n", i);

                return -1;

            }

        }

        sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul;

        memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15);

        sc->track_essence_element_key[15] = present[sc->index];

        PRINT_KEY(s, "track essence element key", sc->track_essence_element_key);

        if (!present[sc->index])

            mxf->essence_container_count++;

        present[sc->index]++;

    }

    if (s->oformat == &ff_mxf_d10_muxer || s->oformat == &ff_mxf_opatom_muxer) {

        mxf->essence_container_count = 1;

    }

    if (!(s->flags & AVFMT_FLAG_BITEXACT))

        mxf_gen_umid(s);

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

        MXFStreamContext *sc = s->streams[i]->priv_data;

        // update element count

        sc->track_essence_element_key[13] = present[sc->index];

        if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV

            sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);

        else

            sc->order = AV_RB32(sc->track_essence_element_key+12);

    }

    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))

        timestamp = ff_iso8601_to_unix_time(t->value);

    if (timestamp)

        mxf->timestamp = mxf_parse_timestamp(timestamp);

    mxf->duration = -1;

    mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track));

    if (!mxf->timecode_track)

        return AVERROR(ENOMEM);

    mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext));

    if (!mxf->timecode_track->priv_data)

        return AVERROR(ENOMEM);

    mxf->timecode_track->index = -1;

    if (!spf)

        spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });

    if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)

        return -1;

    return 0;

}


static void ide_flush_cb(void *opaque, int ret)

{

    IDEState *s = opaque;

    s->pio_aiocb = NULL;

    if (ret == -ECANCELED) {

        return;

    }

    if (ret < 0) {

        /* XXX: What sector number to set here? */

        if (ide_handle_rw_error(s, -ret, IDE_RETRY_FLUSH)) {

            return;

        }

    }

    if (s->bs) {

        block_acct_done(bdrv_get_stats(s->bs), &s->acct);

    }

    s->status = READY_STAT | SEEK_STAT;

    ide_cmd_done(s);

    ide_set_irq(s->bus);

}


static int ehci_init_transfer(EHCIPacket *p)

{

    uint32_t cpage, offset, bytes, plen;

    dma_addr_t page;

    USBBus *bus = &p->queue->ehci->bus;

    BusState *qbus = BUS(bus);

    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, qbus->parent, 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;

}


int av_opencl_register_kernel_code(const char *kernel_code)

{

    int i, ret = 0;

    LOCK_OPENCL;

    if (gpu_env.kernel_code_count >= MAX_KERNEL_CODE_NUM) {

        av_log(&openclutils, AV_LOG_ERROR,

         "Could not register kernel code, maximum number of registered kernel code %d already reached\n",

         MAX_KERNEL_CODE_NUM);

        ret = AVERROR(EINVAL);

        goto end;

    }

    for (i = 0; i < gpu_env.kernel_code_count; i++) {

        if (gpu_env.kernel_code[i].kernel_string == kernel_code) {

            av_log(&openclutils, AV_LOG_WARNING, "Same kernel code has been registered\n");

            goto end;

        }

    }

    gpu_env.kernel_code[gpu_env.kernel_code_count].kernel_string = kernel_code;

    gpu_env.kernel_code[gpu_env.kernel_code_count].is_compiled = 0;

    gpu_env.kernel_code_count++;

end:

    UNLOCK_OPENCL;

    return ret;

}